huang
2025-06-12 e206ea8f7dbb655c0d8868996dae8ff1ff5ed11a
修改看板大屏,动态获取数据
6个文件已修改
482 ■■■■ 已修改文件
JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/controller/PrimitiveTaskController.java 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/controller/TaskingLogController.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/service/TaskingLogService.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/service/impl/TaskingLogServiceImpl.java 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/KanbanData/kanbanData.vue 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UI-Project/src/views/KanbanDisplay2/kanbanDisplay2.vue 236 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/controller/PrimitiveTaskController.java
@@ -2,12 +2,12 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mes.md.entity.*;
import com.mes.md.entity.KBBTJPDrawingBP;
import com.mes.md.entity.PrimitiveTask;
import com.mes.md.mapper.KBBTJPDrawingBPMapper;
import com.mes.md.service.KBBTJPDrawingBPService;
import com.mes.md.service.PrimitiveTaskService;
import com.mes.md.service.TaskingLogService;
import com.mes.md.service.TaskingService;
import com.mes.utils.Result;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@@ -104,8 +104,8 @@
    @ApiOperation("查询 计划量 m² 片数(客户表)")
    @PostMapping("/findPlannedQuantity")
    @ResponseBody
    public Result findPlannedQuantity(@RequestBody Map<String, String> map) {
        int dayCount=Integer.valueOf(map.get("dayCount").toString());
    public Result findPlannedQuantity() {
        //int dayCount=Integer.valueOf(map.get("dayCount").toString());
        Calendar cal = Calendar.getInstance();
        //设置当前时间
        cal.setTime(new Date());
@@ -113,15 +113,30 @@
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        cal.add(Calendar.DATE, 1-dayCount);
        //cal.add(Calendar.DATE, 1-dayCount);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date startDate = cal.getTime();
        // 获取当月最后一天
        Calendar lastDayCal = (Calendar) cal.clone();
        lastDayCal.add(Calendar.MONTH, 1);
        lastDayCal.add(Calendar.DATE, -1);
        Date endDate = lastDayCal.getTime();
        // 获取当月天数
        int dayCount = lastDayCal.get(Calendar.DAY_OF_MONTH);
        QueryWrapper<KBBTJPDrawingBP> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("CAST(PlanDate AS DATE) AS CreateDate,isNull(sum(task_quantity),0) as task_quantity_sum,isNull(sum(length*width*task_quantity)/1000000,0) as area_sum")
                .gt("PlanDate",startDate).groupBy("CAST(PlanDate AS DATE)")
                .ge("PlanDate",startDate).le("PlanDate",endDate).groupBy("CAST(PlanDate AS DATE)")
                .orderByAsc("CAST(PlanDate AS DATE)");;
        List<Map> list=kBBTJPDrawingBPMapper.selectMaps((QueryWrapper)queryWrapper);
        List<Map> resultDate=new ArrayList<>();
        // 重置日历到当月第一天
        cal.setTime(startDate);
        for (int i=0;i<dayCount;i++){
            Date thisdate=cal.getTime();
            cal.add(Calendar.DATE, 1);
JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/controller/TaskingLogController.java
@@ -51,6 +51,32 @@
        }
    }
   @ApiOperation("查询单小时产量")
   @PostMapping("/findHourlyOutput")
   @ResponseBody
   public Result findHourlyOutput(@RequestBody Map<String, String> map) {
       try {
           int dayCount = Integer.valueOf(map.get("dayCount").toString());
           Map<String, Object> result = taskingLogService.findHourlyOutput(dayCount);
           return Result.build(200, "查询成功", result);
       } catch (Exception e) {
           return Result.build(199, "查询失败: " + e.getMessage(), null);
       }
   }
   @ApiOperation("查询库位数据")
   @PostMapping("/selectWareHouse")
   @ResponseBody
   public Result selectWareHouse(@RequestBody Map<String, String> map) {
       try {
           int dayCount = Integer.valueOf(map.get("dayCount").toString());
           List<Map<String, Object>> result = taskingLogService.selectWareHouse(dayCount);
           return Result.build(200, "查询成功", result);
       } catch (Exception e) {
           return Result.build(199, "查询失败: " + e.getMessage(), null);
       }
   }
    @ApiOperation("提交日志以及报工数据到九牧数据库")
    @PostMapping("/reportTaskingLog")
    @ResponseBody
JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/service/TaskingLogService.java
@@ -1,7 +1,6 @@
package com.mes.md.service;
import com.github.yulichang.base.MPJBaseService;
import com.mes.md.entity.TaskLog;
import com.mes.md.entity.TaskingLog;
import java.util.Date;
@@ -39,4 +38,17 @@
     * 回传报工数据+ 设备玻璃过片记录给 九牧
     */
    Integer reportTaskingLog();
    /**
     * 查询单小时产量
     * @param dayCount 查询天数
     */
    Map<String, Object> findHourlyOutput(int dayCount);
    /**
     * 查询库位数据
     * @param dayCount 查询天数
     * @return 库位数据列表
     */
    List<Map<String, Object>> selectWareHouse(int dayCount);
}
JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/service/impl/TaskingLogServiceImpl.java
@@ -74,10 +74,14 @@
            if (lineType != null && !lineType.isEmpty()) {
                taskingWrapper.apply("operation_record REGEXP '.*[^0-9]" + lineType + "$'");
            }
            // 按时间排序
            taskingWrapper.orderByDesc("operation_record_time");
            // 按时间排序(降序)
            //taskingWrapper.orderByDesc("operation_record_time");
            //(升序)
            taskingWrapper.orderByAsc("operation_record_time");
            // 先按sortOrder排序,再按时间排序
            //taskingWrapper.orderByAsc("sort_order", "operation_record_time");
            // 执行查询
            List<Map<String, Object>> taskingList = baseMapper.selectMaps(taskingWrapper);
@@ -116,7 +120,6 @@
        List<Map<String, Object>> listTasking1 = baseMapper.selectMaps(new QueryWrapper<TaskingLog>()
                .select("task_type, operation_record, operation_mode, DATE_FORMAT(operation_record_time, '%Y-%m-%d') as operation_record_time, count(*) as count")
                .eq("task_type", "定制")
                .eq("operation_record", "旋转1")
                .eq("operation_mode", "结束")
                .gt("operation_record_time", startDate)
@@ -124,7 +127,6 @@
                .orderByAsc("DATE_FORMAT(operation_record_time, '%Y-%m-%d')"));
        List<Map<String, Object>> listTasking2 = baseMapper.selectMaps(new QueryWrapper<TaskingLog>()
                .select("task_type,operation_record,operation_mode,DATE_FORMAT(operation_record_time, '%Y-%m-%d') as operation_record_time,count(1) as count")
                .eq("task_type", "定制")
                .eq("operation_record", "旋转2")
                .eq("operation_mode", "结束")
                .gt("operation_record_time", startDate)
@@ -274,4 +276,150 @@
        }
        return 0;
    }
    /**
     * 查询单小时产量
     * @param dayCount 查询天数
     * @return Map 包含每天两条线的平均小时产量
     */
    @Override
    public Map<String, Object> findHourlyOutput(int dayCount) {
        try {
            // 计算开始时间
            Calendar cal = Calendar.getInstance();
            cal.setTime(new Date());
            cal.set(Calendar.HOUR_OF_DAY, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.SECOND, 0);
            cal.set(Calendar.MILLISECOND, 0);
            cal.add(Calendar.DATE, -dayCount + 1);
            Date startDate = cal.getTime();
            // 查询一线数据,按天分组统计总产量和工作小时数
            QueryWrapper<TaskingLog> line1Query = new QueryWrapper<>();
            line1Query.select(
                    "DATE_FORMAT(operation_record_time, '%Y-%m-%d') as date",
                    "COUNT(*) as total_count",
                    "COUNT(DISTINCT DATE_FORMAT(operation_record_time, '%H')) as working_hours"
                )
                .eq("operation_record", "旋转1")
                .eq("operation_mode", "结束")
                .ge("operation_record_time", startDate)
                .groupBy("DATE_FORMAT(operation_record_time, '%Y-%m-%d')")
                .orderByAsc("date");
            List<Map<String, Object>> line1Results = baseMapper.selectMaps(line1Query);
            // 查询二线数据,按天分组统计总产量和工作小时数
            QueryWrapper<TaskingLog> line2Query = new QueryWrapper<>();
            line2Query.select(
                    "DATE_FORMAT(operation_record_time, '%Y-%m-%d') as date",
                    "COUNT(*) as total_count",
                    "COUNT(DISTINCT DATE_FORMAT(operation_record_time, '%H')) as working_hours"
                )
                .eq("operation_record", "旋转2")
                .eq("operation_mode", "结束")
                .ge("operation_record_time", startDate)
                .groupBy("DATE_FORMAT(operation_record_time, '%Y-%m-%d')")
                .orderByAsc("date");
            List<Map<String, Object>> line2Results = baseMapper.selectMaps(line2Query);
            // 合并结果
            Map<String, Object> result = new HashMap<>();
            Map<String, Map<String, Object>> dailyStats = new HashMap<>();
            // 处理一线数据
            for (Map<String, Object> line1Data : line1Results) {
                String date = (String) line1Data.get("date");
                int totalCount = ((Number) line1Data.get("total_count")).intValue();
                int workingHours = ((Number) line1Data.get("working_hours")).intValue();
                Map<String, Object> dailyData = new HashMap<>();
                dailyData.put("date", date);
                dailyData.put("line1Count", totalCount);
                dailyData.put("line1Hours", workingHours);
                dailyData.put("line1HourlyAvg", workingHours > 0 ? totalCount / workingHours : 0);
                dailyStats.put(date, dailyData);
            }
            // 处理二线数据
            for (Map<String, Object> line2Data : line2Results) {
                String date = (String) line2Data.get("date");
                int totalCount = ((Number) line2Data.get("total_count")).intValue();
                int workingHours = ((Number) line2Data.get("working_hours")).intValue();
                Map<String, Object> dailyData = dailyStats.computeIfAbsent(date, k -> {
                    Map<String, Object> newData = new HashMap<>();
                    newData.put("date", date);
                    return newData;
                });
                dailyData.put("line2Count", totalCount);
                dailyData.put("line2Hours", workingHours);
                dailyData.put("line2HourlyAvg", workingHours > 0 ? totalCount / workingHours : 0);
            }
            // 转换为最终的返回格式
            List<Map<String, Object>> finalStats = new ArrayList<>(dailyStats.values());
            // 按日期排序
            finalStats.sort((a, b) -> ((String)a.get("date")).compareTo((String)b.get("date")));
            result.put("dailyStats", finalStats);
            return result;
        } catch (Exception e) {
            log.error("计算单小时产量失败", e);
            throw new RuntimeException("计算单小时产量失败: " + e.getMessage());
        }
    }
    /**
     * 查询库位数据
     * 按库位统计:
     * - 标准工艺:统计上片1和上片2的记录
     * - 定制工艺:统计旋转1和旋转2的记录
     */
    @Override
    public List<Map<String, Object>> selectWareHouse(int dayCount) {
        try {
            // 计算开始时间
            Calendar cal = Calendar.getInstance();
            cal.setTime(new Date());
            cal.set(Calendar.HOUR_OF_DAY, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.SECOND, 0);
            cal.set(Calendar.MILLISECOND, 0);
            cal.add(Calendar.DATE, -dayCount + 1);
            Date startDate = cal.getTime();
            // 使用QueryWrapper构建查询
            QueryWrapper<TaskingLog> queryWrapper = new QueryWrapper<>();
            queryWrapper.select(
                    "DATE_FORMAT(operation_record_time, '%Y-%m-%d') as date",
                    "warehouse",
                    "COUNT(*) as count"
                )
                .and(wrapper -> wrapper
                    .and(w -> w
                        .eq("task_type", "标准")
                        .in("operation_record", "上片1", "上片2")
                    )
                    .or(w -> w
                        .eq("task_type", "定制")
                        .in("operation_record", "旋转1", "旋转2")
                    )
                )
                .eq("operation_mode", "结束")
                .ge("operation_record_time", startDate)
                .groupBy("DATE_FORMAT(operation_record_time, '%Y-%m-%d')", "warehouse")
                .orderByAsc("date", "warehouse");
            return baseMapper.selectMaps(queryWrapper);
        } catch (Exception e) {
            log.error("查询库位数据失败", e);
            throw new RuntimeException("查询库位数据失败: " + e.getMessage());
        }
    }
}
UI-Project/src/views/KanbanData/kanbanData.vue
@@ -62,7 +62,8 @@
// 当前激活的标签页
const activeTab = ref('yield')
const activeTab = ref('utilization')
const showTab = ref(false)
// 单小时产量数据
const yieldFormData = ref({
@@ -685,7 +686,7 @@
    <el-main>
      <el-tabs v-model="activeTab">
        <!-- 单小时产量标签页 -->
        <el-tab-pane label="单小时产量" name="yield">
        <el-tab-pane label="单小时产量"  name="yield">
          <!-- 添加目标值设置部分 -->
          <div class="target-setting">
            <el-form :inline="true" label-width="100px">
@@ -714,7 +715,7 @@
              </el-form-item>
            </el-form>
          </div>
          <el-form :inline="true" :model="yieldFormData" label-width="100px" class="form-container">
          <el-form :inline="true" :model="yieldFormData" label-width="100px" v-if="showTab" class="form-container">
            <el-form-item label="日期">
              <el-date-picker
                v-model="yieldFormData.recordDate"
@@ -746,7 +747,7 @@
            </el-form-item>
          </el-form>
          <el-table :data="yieldData"  v-loading="yieldLoading" style="width: 100%">
          <el-table :data="yieldData"  v-loading="yieldLoading" style="width: 100%" v-if="showTab">
            <el-table-column prop="recordDate" label="日期" width="180">
              <template #default="scope">
                <el-date-picker
@@ -949,7 +950,7 @@
        </el-tab-pane>
        <!-- 在制量标签页 -->
        <el-tab-pane label="在制量" name="quantity">
        <el-tab-pane label="在制量"  name="quantity">
          <!-- 添加目标值设置部分 -->
          <div class="target-setting">
            <el-form :inline="true" label-width="100px">
@@ -1001,8 +1002,8 @@
            <el-form-item label="类型">
              <el-select v-model="quantityFormData.locationCode" placeholder="选择类型" style="width: 180px">
                <el-option label="半成品" value="半成品" />
                <el-option label="7014" value="7014" />
                <el-option label="7016" value="7016" />
                <!-- <el-option label="7014" value="7014" />
                <el-option label="7016" value="7016" /> -->
              </el-select>
            </el-form-item>
            <el-form-item label="数量">
@@ -1021,7 +1022,7 @@
            </el-form-item>
          </el-form>
          <el-table :data="quantityData"  v-loading="quantityLoading" style="width: 100%">
          <el-table :data="quantityData"  v-loading="quantityLoading" style="width: 100%" >
            <el-table-column prop="recordDate" label="日期" width="180">
              <template #default="scope">
                <el-date-picker
@@ -1095,7 +1096,7 @@
        </el-tab-pane>
        <!-- 计划产量标签页 -->
        <el-tab-pane label="计划产量" name="planned">
        <el-tab-pane label="计划产量" v-if="showTab" name="planned">
          <el-form :inline="true" :model="plannedFormData" label-width="100px" class="form-container">
            <el-form-item label="日期">
              <el-date-picker
UI-Project/src/views/KanbanDisplay2/kanbanDisplay2.vue
@@ -98,12 +98,29 @@
// 计划量数据
const loadPlannedData = async () => {
  try {
    const res = await request.post('/deviceInteraction/plannedAmount/chartPlanned', {
      dayCount: 30  // 确保请求30天的数据
    });
    const res = await request.post('/deviceInteraction/primitiveTask/findPlannedQuantity', {});
    if (res.code === 200) {
      plannedData.value = res.data;
      updateOptionPlanned();
      // 确保数据存在
      if (res.data && Array.isArray(res.data)) {
        plannedData.value = res.data.map(item => ([
          {
            recordTime: item.CreateDate,
            type: '平方',
            value: item.area_sum || 0
          },
          {
            recordTime: item.CreateDate,
            type: '片数',
            value: item.task_quantity_sum || 0
          }
        ])).flat();
        updateOptionPlanned();
      } else {
        console.error('计划量数据格式不正确:', res.data);
      }
    } else {
      console.error('获取计划量数据失败:', res.message);
    }
  } catch (error) {
    console.error('获取计划量数据失败:', error);
@@ -114,11 +131,11 @@
// 单小时产量数据
const loadYieldData = async () => {
  try {
    const res = await request.post('/deviceInteraction/yield/chartYield', {
    const res = await request.post('/deviceInteraction/taskingLog/findHourlyOutput', {
      dayCount: 30  // 确保请求30天的数据
    });
    if (res.code === 200) {
      yieldData.value = res.data;
    if (res.code === 200 && res.data && res.data.dailyStats) {
      yieldData.value = res.data.dailyStats;
      updateOptionYield(yieldTarget1.value, yieldTarget2.value);
    }
  } catch (error) {
@@ -144,11 +161,60 @@
// 加载在制量数据
const loadInventoryData = async () => {
  try {
    const res = await request.post('/deviceInteraction/quantity/chartQuantity', {
      dayCount: 30  // 确保请求30天的数据
    // 获取日期数组
    const { dates } = generateMonthDates();
    // 获取半成品数据
    const resQuantity = await request.post('/deviceInteraction/quantity/chartQuantity', {
      dayCount: 30
    });
    if (res.code === 200) {
      quantityData.value = res.data;
    // 获取库位数据(7014和7016)
    const resWareHouse = await request.post('/deviceInteraction/taskingLog/selectWareHouse', {
      dayCount: 30
    });
    if (resQuantity.code === 200 && resWareHouse.code === 200) {
      // 处理半成品数据
      const semiData = Array(dates.length).fill(0);
      const data7014 = Array(dates.length).fill(0);
      const data7016 = Array(dates.length).fill(0);
      // 处理半成品数据
      if (resQuantity.data) {
        resQuantity.data.forEach(item => {
          if (item.locationCode === '半成品') {
            const date = new Date(item.recordTime || item.recordDate);
            const formattedDate = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
            const dateIndex = dates.indexOf(formattedDate);
            if (dateIndex !== -1) {
              semiData[dateIndex] = item.quantity;
            }
          }
        });
      }
      // 处理库位数据
      if (resWareHouse.data) {
        resWareHouse.data.forEach(item => {
          const dateIndex = dates.indexOf(item.date);
          if (dateIndex !== -1) {
            if (item.warehouse === '7014') {
              data7014[dateIndex] = item.count;
            } else if (item.warehouse === '7016') {
              data7016[dateIndex] = item.count;
            }
          }
        });
      }
      // 更新图表数据
      quantityData.value = {
        semiData,
        data7014,
        data7016
      };
      updateOptionQuantity(quantityTarget1.value, quantityTarget2.value, quantityTarget3.value);
    }
  } catch (error) {
@@ -207,7 +273,8 @@
  const dates = [];
  for (let i = 1; i <= daysInMonth; i++) {
    const date = new Date(currentYear, currentMonth, i);
    const formattedDate = `${date.getFullYear()}-${date.getMonth() + 1}-${i}`;
    // 修改日期格式为 YYYY-MM-DD
    const formattedDate = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(i).padStart(2, '0')}`;
    dates.push(formattedDate);
  }
@@ -236,7 +303,7 @@
  // 生成当月所有日期的数组
  const dates = [];
  for (let d = new Date(firstDayOfMonth); d <= lastDayOfMonth; d.setDate(d.getDate() + 1)) {
    dates.push(`${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`);
    dates.push(`${d.getFullYear()}-${(d.getMonth() + 1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')}`);
  }
  const daysInMonth = dates.length;
@@ -251,16 +318,15 @@
  // 根据API返回的数据结构进行分组处理
  sortedData.forEach(item => {
    const date = new Date(item.recordTime);
    const formattedDate = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
    const formattedDate = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
    const dateIndex = dates.indexOf(formattedDate);
    if (dateIndex !== -1) {
      // 根据type字段区分平方和片数
      if (item.type === '平方') {
        squareData[dateIndex] = item.value;
        totalSquare += item.value || 0;
        squareData[dateIndex] = Number(item.value) || 0;
        totalSquare += Number(item.value) || 0;
      } else if (item.type === '片数') {
        pieceData[dateIndex] = item.value;
        totalPieces += item.value || 0;
        pieceData[dateIndex] = Number(item.value) || 0;
        totalPieces += Number(item.value) || 0;
      }
    }
  });
@@ -273,7 +339,9 @@
  if (textDay && textprice && textarea) {
    // 格式化日期显示
    const formatDate = (date) => {
      return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
      const month = (date.getMonth() + 1).toString().padStart(2, '0');
      const day = date.getDate().toString().padStart(2, '0');
      return `${date.getFullYear()}-${month}-${day}`;
    };
    textDay.innerHTML = "日期:<br>" + formatDate(firstDayOfMonth) + " - " + formatDate(lastDayOfMonth);
@@ -303,16 +371,10 @@
    legend: {
      data: ['平方', '片数'],
      icon: 'roundRect',
      // x:'left',
      // y:'center',
      // orient: 'vertical',
      textStyle: {
        fontSize: 20,
        fontWeight: 'bold',
        color: 'white',
        formatter: function (name) {
          return '{vertical|' + name.split('').join('\n') + '}';
        }
        color: 'white'
      }
    },
    grid: [
@@ -368,7 +430,6 @@
        gridIndex: 0,
        axisLabel: {
          fontSize: 20,
          formatter: '{value} ',
          color: 'white',
          show: false
        },
@@ -381,7 +442,6 @@
        gridIndex: 1,
        axisLabel: {
          fontSize: 20,
          formatter: '{value} ',
          color: 'white',
          show: false
        },
@@ -444,20 +504,13 @@
    ]
  };
  // 绘制图表
  // const chartDom = document.getElementById('drawLineChart_day51');
  // if (chartDom) {
  //   const chart = echarts.init(chartDom);
  //   chart.setOption(OptionDayMode);
  //   charts.push(chart);
  // }
  draw('drawLineChart_day51', OptionDayMode)
  draw('drawLineChart_day51', OptionDayMode);
}
const updateOptionYield = (targetValue1, targetValue2) => {
  // 按日期排序并处理数据
  const sortedData = [...yieldData.value].sort((a, b) =>
    new Date(a.recordTime) - new Date(b.recordTime)
    new Date(a.date) - new Date(b.date)
  );
  // 获取当月日期数组
@@ -469,15 +522,12 @@
  // 为每个日期准备数据
  sortedData.forEach(item => {
    const date = new Date(item.recordTime);
    const formattedDate = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
    const date = new Date(item.date);
    const formattedDate = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
    const dateIndex = dates.indexOf(formattedDate);
    if (dateIndex !== -1) {
      if (item.lineNo === '一线') {
        line1Data[dateIndex] += item.yieldvalue;
      } else if (item.lineNo === '二线') {
        line2Data[dateIndex] += item.yieldvalue;
      }
      line1Data[dateIndex] = Number(item.line1HourlyAvg || 0);
      line2Data[dateIndex] = Number(item.line2HourlyAvg || 0);
    }
  });
@@ -621,7 +671,8 @@
        label: {
          show: true,
          fontSize: 20,
          color: 'white'
          color: 'white',
          formatter: '{c}'  // 显示数值
        },
        areaStyle: {
          color: '#000000',
@@ -661,7 +712,8 @@
        label: {
          show: true,
          fontSize: 20,
          color: 'white'
          color: 'white',
          formatter: '{c}'  // 显示数值
        },
        areaStyle: {
          color: 'white',
@@ -685,12 +737,6 @@
    ]
  };
  // const chartDom = document.getElementById('drawLineChart_yield');
  // if (chartDom) {
  //   const chart = echarts.init(chartDom);
  //   chart.setOption(OptionYield);
  //   charts.push(chart);
  // }
  draw('drawLineChart_yield', OptionYield)
}
@@ -710,7 +756,7 @@
  // 为每个日期准备数据
  sortedData.forEach(item => {
    const date = new Date(item.recordTime || item.recordDate);
    const formattedDate = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
    const formattedDate = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
    const dateIndex = dates.indexOf(formattedDate);
    if (dateIndex !== -1) {
      if (item.lineNo === '标准') {
@@ -768,22 +814,6 @@
        color: 'white'
      }
    },
    // toolbox: {
    //   show: true,
    //   itemSize: 20,
    //   iconStyle: {
    //     borderColor: 'white'
    //   },
    //   feature: {
    //     dataZoom: {
    //       yAxisIndex: 'none'
    //     },
    //     dataView: { readOnly: false },
    //     magicType: { type: ['line', 'bar'] },
    //     restore: {},
    //     saveAsImage: {}
    //   },
    // },
    grid: [{
      left: '5%',
      right: '1%',
@@ -949,46 +979,18 @@
    ]
  };
  // const chartDom = document.getElementById('drawLineChart_utilization');
  // if (chartDom) {
  //   const chart = echarts.init(chartDom);
  //   chart.setOption(OptionUtilization);
  //   charts.push(chart);
  // }
  draw('drawLineChart_utilization', OptionUtilization);
}
const updateOptionQuantity = (targetValue1, targetValue2, targetValue3) => {
  // 按日期排序并处理数据
  const sortedData = [...quantityData.value].sort((a, b) =>
    new Date(a.recordTime || a.recordDate) - new Date(b.recordTime || b.recordDate)
  );
  // 获取当月日期数组
  const { dates, daysInMonth } = generateMonthDates();
  // 分离各库位数据
  const semiData = Array(daysInMonth).fill(0);
  const data7014 = Array(daysInMonth).fill(0);
  const data7016 = Array(daysInMonth).fill(0);
  // 为每个日期准备数据
  sortedData.forEach(item => {
    const date = new Date(item.recordTime || item.recordDate);
    const formattedDate = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
    const dateIndex = dates.indexOf(formattedDate);
    if (dateIndex !== -1) {
      if (item.locationCode === '半成品') {
        semiData[dateIndex] = item.quantity;
      } else if (item.locationCode === '7014') {
        data7014[dateIndex] = item.quantity;
      } else if (item.locationCode === '7016') {
        data7016[dateIndex] = item.quantity;
      }
    }
  });
  // 使用quantityData中的数据
  const semiData = quantityData.value?.semiData || Array(daysInMonth).fill(0);
  const data7014 = quantityData.value?.data7014 || Array(daysInMonth).fill(0);
  const data7016 = quantityData.value?.data7016 || Array(daysInMonth).fill(0);
  // 在制量的配置 - 上中下三层布局
  const OptionQuantity = {
@@ -1283,15 +1285,11 @@
    ]
  };
  // const chartDom = document.getElementById('drawLineChart_quantity');
  // if (chartDom) {
  //   const chart = echarts.init(chartDom);
  //   chart.setOption(OptionQuantity);
  //   charts.push(chart);
  // }
  draw('drawLineChart_quantity', OptionQuantity);
}
let refreshInterval = null
let checkTargetsInterval = null
onMounted(() => {
  setScale()
@@ -1317,7 +1315,7 @@
      await loadPlannedData()
      // 设置定时刷新数据
      const refreshInterval = setInterval(async () => {
      refreshInterval = setInterval(async () => {
        try {
          await loadYieldData()
          await loadUtilizationData()
@@ -1330,7 +1328,7 @@
      }, 15000) // 每15秒刷新一次
      // 添加监听localStorage变化的定时器
      const checkTargetsInterval = setInterval(() => {
      checkTargetsInterval = setInterval(() => {
        const newYieldTarget1 = Number(localStorage.getItem('yieldTarget1'))
        const newYieldTarget2 = Number(localStorage.getItem('yieldTarget2'))
        const newUtilizationTarget1 = Number(localStorage.getItem('utilizationTarget1'))
@@ -1360,10 +1358,6 @@
        }
      }, 1000) // 每秒检查一次
      onUnmounted(() => {
        clearInterval(refreshInterval)
        clearInterval(checkTargetsInterval)
      })
    } catch (error) {
      console.error('初始化数据失败:', error)
    }
@@ -1371,7 +1365,19 @@
})
onUnmounted(() => {
  // 清理事件监听器
  window.removeEventListener('resize', handleResize)
  // 清理定时器
  if (refreshInterval) {
    clearInterval(refreshInterval)
    refreshInterval = null
  }
  if (checkTargetsInterval) {
    clearInterval(checkTargetsInterval)
    checkTargetsInterval = null
  }
  // 清理所有图表实例
  charts.forEach(chart => {
    if (chart && !chart.isDisposed()) {