From 2c2413760b6467bf62402dba7338bd3bbcbd7341 Mon Sep 17 00:00:00 2001
From: huang <1532065656@qq.com>
Date: 星期二, 20 五月 2025 14:20:38 +0800
Subject: [PATCH] 添加产量报表功能页面

---
 JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/controller/TaskingLogController.java    |   30 +
 UI-Project/src/main.js                                                                                                |    9 
 UI-Project/src/views/KanbanData/kanbanData.vue                                                                        |  206 +++++++
 UI-Project/src/lang/zh.js                                                                                             |    3 
 UI-Project/src/router/index.js                                                                                        |   15 
 JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/service/impl/TaskingLogServiceImpl.java |  149 ++++-
 JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/service/TaskingLogService.java          |   14 
 UI-Project/src/views/MechanicalReport/mechanicalReport.vue                                                            |  314 ++++++++++++
 UI-Project/src/views/KanbanDisplay2/kanbanDisplay2.vue                                                                |  739 ++++++++++++++++++----------
 9 files changed, 1,152 insertions(+), 327 deletions(-)

diff --git a/JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/controller/TaskingLogController.java b/JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/controller/TaskingLogController.java
index d10e76f..af9354e 100644
--- a/JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/controller/TaskingLogController.java
+++ b/JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/controller/TaskingLogController.java
@@ -1,12 +1,14 @@
 package com.mes.md.controller;
 
-
 import com.mes.md.service.TaskingLogService;
 import com.mes.utils.Result;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.Date;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -23,6 +25,31 @@
 
     @Autowired
     TaskingLogService taskingLogService;
+
+    @ApiOperation("鏌ヨ鎶ヨ〃")
+    @PostMapping("/mechanicalReport")
+    @ResponseBody
+    public Result mechanicalReport(
+            @RequestParam(required = false) Integer dayCount,
+            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startDate,
+            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endDate,
+            @RequestParam(required = false) String taskType,
+            @RequestParam(required = false) String operationRecord,
+            @RequestParam(required = false) String lineType) {
+        try {
+            List<Map> result = taskingLogService.selectMechanicalReport(
+                dayCount,
+                startDate,
+                endDate,
+                taskType,
+                operationRecord,
+                lineType
+            );
+            return Result.build(200, "鏌ヨ鎴愬姛", result);
+        } catch (Exception e) {
+            return Result.build(199, "鏌ヨ寮傚父", null);
+        }
+    }
 
     @ApiOperation("鎻愪氦鏃ュ織浠ュ強鎶ュ伐鏁版嵁鍒颁節鐗ф暟鎹簱")
     @PostMapping("/reportTaskingLog")
@@ -59,6 +86,5 @@
             return Result.build(199,"鎻愪氦寮傚父",map);
         }
     }
-
 }
 
diff --git a/JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/service/TaskingLogService.java b/JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/service/TaskingLogService.java
index d0cd50a..9b75a69 100644
--- a/JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/service/TaskingLogService.java
+++ b/JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/service/TaskingLogService.java
@@ -4,6 +4,7 @@
 import com.mes.md.entity.TaskLog;
 import com.mes.md.entity.TaskingLog;
 
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -21,6 +22,19 @@
      * 鏌ヨ瀹屽伐鏁伴噺-鍒嗙嚎璺�
      */
     List<Map> selectTaskingLog(int dayCount);
+
+    /**
+     * 鏌ヨ浜ч噺
+     * @param dayCount 澶╂暟
+     * @param startDate 寮�濮嬫棩鏈�
+     * @param endDate 缁撴潫鏃ユ湡
+     * @param taskType 浠诲姟绫诲瀷
+     * @param operationRecord 璁惧
+     * @param lineType 鐢熶骇绾匡紙1锛氫竴绾匡紝2锛氫簩绾匡級
+     * @return 浜ч噺鏁版嵁鍒楄〃
+     */
+    List<Map> selectMechanicalReport(int dayCount, Date startDate, Date endDate, String taskType, String operationRecord, String lineType);
+
     /**
      * 鍥炰紶鎶ュ伐鏁版嵁+ 璁惧鐜荤拑杩囩墖璁板綍缁� 涔濈墽
      */
diff --git a/JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/service/impl/TaskingLogServiceImpl.java b/JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/service/impl/TaskingLogServiceImpl.java
index b60c550..242a9f5 100644
--- a/JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/service/impl/TaskingLogServiceImpl.java
+++ b/JiuMuMesParent/moduleService/DeviceInteractionModule/src/main/java/com/mes/md/service/impl/TaskingLogServiceImpl.java
@@ -35,6 +35,60 @@
     @Autowired
     KBBTJPDrawingBPMapper kBBTJPDrawingBPMapper;
 
+    @Override
+    public List<Map> selectMechanicalReport(int dayCount, Date startDate, Date endDate, String taskType, String operationRecord, String lineType) {
+        try {
+            // 鏋勫缓鏌ヨ鏉′欢
+            QueryWrapper<TaskingLog> taskingWrapper = new QueryWrapper<>();
+
+            // 娣诲姞瀹屽伐鐘舵�佽繃婊�
+            taskingWrapper.eq("work_state", "瀹屽伐");
+
+            // 鏃堕棿鑼冨洿澶勭悊
+            if (startDate != null && endDate != null) {
+                taskingWrapper.ge("operation_record_time", startDate)
+                        .le("operation_record_time", endDate);
+            } else if (dayCount > 0) {
+                // 濡傛灉娌℃湁鏃堕棿鑼冨洿锛屼娇鐢ㄩ粯璁ょ殑dayCount
+                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, 1 - dayCount);
+                Date defaultStartDate = cal.getTime();
+                Date defaultEndDate = new Date();
+                
+                taskingWrapper.ge("operation_record_time", defaultStartDate)
+                        .le("operation_record_time", defaultEndDate);
+            }
+
+            // 娣诲姞鍙�夋潯浠�
+            if (taskType != null && !taskType.isEmpty()) {
+                taskingWrapper.eq("task_type", taskType);
+            }
+            if (operationRecord != null && !operationRecord.isEmpty()) {
+                taskingWrapper.like("operation_record", operationRecord);
+            }
+            if (lineType != null && !lineType.isEmpty()) {
+                taskingWrapper.apply("operation_record REGEXP '.*[^0-9]" + lineType + "$'");
+            }
+
+            // 鎸夋椂闂存帓搴�
+            taskingWrapper.orderByDesc("operation_record_time");
+
+            // 鎵ц鏌ヨ
+            List<Map<String, Object>> taskingList = baseMapper.selectMaps(taskingWrapper);
+
+            // 鐩存帴杩斿洖鏌ヨ缁撴灉
+            return new ArrayList<>(taskingList);
+        } catch (Exception e) {
+            log.error("鏌ヨ寮傚父", e);
+            throw e;
+        }
+    }
+
     public List<TaskingLog> findTaskingLog(){
         return new ArrayList<TaskingLog>();
     }
@@ -61,19 +115,78 @@
         List<Map> list=kBBTJPDrawingBPMapper.selectMaps((QueryWrapper)queryWrapper);
 
         List<Map<String, Object>> listTasking1 = baseMapper.selectMaps(new QueryWrapper<TaskingLog>()
-                .select("operation_record,operation_mode,DATE_FORMAT(operation_record_time, '%Y-%m-%d') as operation_record_time,count(1) as count")
+                .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)
-                .groupBy("operation_record", "operation_mode", "DATE_FORMAT(operation_record_time, '%Y-%m-%d')")
+                .groupBy("task_type", "operation_record", "operation_mode", "DATE_FORMAT(operation_record_time, '%Y-%m-%d')")
                 .orderByAsc("DATE_FORMAT(operation_record_time, '%Y-%m-%d')"));
         List<Map<String, Object>> listTasking2 = baseMapper.selectMaps(new QueryWrapper<TaskingLog>()
-                .select("operation_record,operation_mode,DATE_FORMAT(operation_record_time, '%Y-%m-%d') as operation_record_time,count(1) as count")
+                .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)
-                .groupBy("operation_record", "operation_mode", "DATE_FORMAT(operation_record_time, '%Y-%m-%d')")
+                .groupBy("task_type", "operation_record", "operation_mode", "DATE_FORMAT(operation_record_time, '%Y-%m-%d')")
                 .orderByAsc("DATE_FORMAT(operation_record_time, '%Y-%m-%d')"));
+
+        //鏍囧噯涓婄墖璁板綍
+        List<Map<String, Object>> loadTaskingList1 = 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)
+                .groupBy("task_type", "operation_record", "operation_mode", "DATE_FORMAT(operation_record_time, '%Y-%m-%d')")
+                .orderByAsc("DATE_FORMAT(operation_record_time, '%Y-%m-%d')"));
+        List<Map<String, Object>> loadTaskingList2 = 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", "涓婄墖2")
+                .eq("operation_mode", "缁撴潫")
+                .gt("operation_record_time", startDate)
+                .groupBy("task_type", "operation_record", "operation_mode", "DATE_FORMAT(operation_record_time, '%Y-%m-%d')")
+                .orderByAsc("DATE_FORMAT(operation_record_time, '%Y-%m-%d')"));
+
+        // 瀛樺偍姣忔潯绾胯矾鐨勬暟鎹�
+        Map<String, Map<String, Integer>> lineDataMap = new HashMap<>();
+        lineDataMap.put("line1", new HashMap<>());
+        lineDataMap.put("line2", new HashMap<>());
+
+        // 澶勭悊绗竴鏉$嚎璺暟鎹�
+        // 澶勭悊鏃嬭浆1缁撴潫璁板綍
+        for (Map<String, Object> map : listTasking1) {
+            String date = map.get("operation_record_time").toString();
+            int count = Integer.parseInt(map.get("count").toString());
+            Map<String, Integer> line1Map = lineDataMap.get("line1");
+            line1Map.put(date, line1Map.getOrDefault(date, 0) + count);
+        }
+        // 澶勭悊绾胯矾1涓婄墖璁板綍
+        for (Map<String, Object> map : loadTaskingList1) {
+            String date = map.get("operation_record_time").toString();
+            int count = Integer.parseInt(map.get("count").toString());
+            Map<String, Integer> line1Map = lineDataMap.get("line1");
+            line1Map.put(date, line1Map.getOrDefault(date, 0) + count);
+        }
+
+        // 澶勭悊绗簩鏉$嚎璺暟鎹�
+        // 澶勭悊鏃嬭浆2缁撴潫璁板綍
+        for (Map<String, Object> map : listTasking2) {
+            String date = map.get("operation_record_time").toString();
+            int count = Integer.parseInt(map.get("count").toString());
+            Map<String, Integer> line2Map = lineDataMap.get("line2");
+            line2Map.put(date, line2Map.getOrDefault(date, 0) + count);
+        }
+        // 澶勭悊绾胯矾2涓婄墖璁板綍
+        for (Map<String, Object> map : loadTaskingList2) {
+            String date = map.get("operation_record_time").toString();
+            int count = Integer.parseInt(map.get("count").toString());
+            Map<String, Integer> line2Map = lineDataMap.get("line2");
+            line2Map.put(date, line2Map.getOrDefault(date, 0) + count);
+        }
+
+
         //log.info("瀹㈡埛琛ㄨ鍒掗噺锛歿},{},{}",list,listTasking1,listTasking2);
         List<Map> Result=new ArrayList<>();
         for (int i=0;i<dayCount;i++){
@@ -84,28 +197,14 @@
             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
             String dateString = sdf.format(thisdate);
             thisMap.put("date",dateString);
-            if (listTasking1.size()>0&&listTasking1.get(0).get("operation_record_time").toString().equals(dateString)){
+            
+            // 鑾峰彇涓�绾挎暟鎹�
+            thisMap.put("line1", lineDataMap.get("line1").getOrDefault(dateString, 0));
+            
+            // 鑾峰彇浜岀嚎鏁版嵁
+            thisMap.put("line2", lineDataMap.get("line2").getOrDefault(dateString, 0));
 
-                thisMap.put("line1",listTasking1.get(0).get("count"));
-                listTasking1.remove(0);
-            }else{
-                thisMap.put("line1",0);
-            }
-            if (listTasking2.size()>0&&listTasking2.get(0).get("operation_record_time").toString().equals(dateString)){
-                thisMap.put("line2",listTasking2.get(0).get("count"));
-                listTasking2.remove(0);
-            }else{
-                thisMap.put("line2",0);
-            }
-//            if(list.size()>0){
-//                log.info("瀵规瘮:{},{},{}",
-//                        list.get(0).get("CreateDate"),
-//                        dateString,
-//                        list.get(0).get("CreateDate").toString().equals(dateString));
-//            }
-
-            if (list.size()>0&&list.get(0).get("CreateDate").toString().equals(dateString)){
-
+            if (list.size()>0 && list.get(0).get("CreateDate").toString().equals(dateString)){
                 thisMap.put("plan",list.get(0).get("task_quantity_sum"));
                 list.remove(0);
             }else{
diff --git a/UI-Project/src/lang/zh.js b/UI-Project/src/lang/zh.js
index 90d509c..f5d29e7 100644
--- a/UI-Project/src/lang/zh.js
+++ b/UI-Project/src/lang/zh.js
@@ -150,7 +150,8 @@
         sendContent: '鍙戦�佸唴瀹�',
         warehouse:'浠撳簱',
         notCompleteCount:'鏈畬鎴愰噺',
-        notCompleteArea:'鏈畬鎴愰潰绉�'
+        notCompleteArea:'鏈畬鎴愰潰绉�',
+        OrderNo:'璁㈠崟鍙�'
     },
     machine: {
         mechanicalArm:'鑷姩涓婄墖鏈�',
diff --git a/UI-Project/src/main.js b/UI-Project/src/main.js
index cb42b7c..48470da 100644
--- a/UI-Project/src/main.js
+++ b/UI-Project/src/main.js
@@ -8,7 +8,9 @@
 import 'element-plus/dist/index.css'
 import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
 import VXETable from 'vxe-table'
+import { VxeButton, VxeLoading, VxeTooltip } from 'vxe-pc-ui'
 import 'vxe-table/lib/style.css'
+import 'vxe-pc-ui/lib/style.css'
 import i18n from '@/lang'
 import Echarts from "vue-echarts"
 import * as echarts from "echarts";
@@ -22,16 +24,19 @@
 const app = createApp(App)
 app.component('v-chart', echarts)
 //app.config.globalProperties.$echarts = echarts
-
+ 
 for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
   app.component(key, component)
 }
-
+ 
 const pinia = createPinia()
 pinia.use(piniaPluginPersistedstate )
 app.use(VXETable)
 app.use(pinia)
 app.use(router)
+app.use(VxeButton)
+app.use(VxeLoading)
+app.use(VxeTooltip)
 // app.use(ElementPlus)
 app.use(ElementPlus,{
     locale: zhCn,
diff --git a/UI-Project/src/router/index.js b/UI-Project/src/router/index.js
index ae55a04..c98495d 100644
--- a/UI-Project/src/router/index.js
+++ b/UI-Project/src/router/index.js
@@ -93,11 +93,13 @@
           path: 'KanbanDisplay2/kanbanDisplay2',
           name: 'kanbanDisplay2',
           component: () => import('../views/KanbanDisplay2/kanbanDisplay2.vue'),
+          props: true,
           children: [
             {
               path: '/KanbanDisplay2/kanbanDisplay2',
               name: 'kanbanDisplay2',
               component: () => import('../views/KanbanDisplay2/kanbanDisplay2.vue'),
+              props: true
             }
           ]
         },
@@ -115,6 +117,19 @@
           ]
         },
         {
+          /*----------- 鎶ヨ〃 ----------------*/
+          path: 'MechanicalReport/mechanicalReport',
+          name: 'mechanicalReport',
+          component: () => import('../views/MechanicalReport/mechanicalReport.vue'),
+          children: [
+            {
+              path: '/MechanicalReport/mechanicalReport',
+              name: 'mechanicalReport',
+              component: () => import('../views/MechanicalReport/mechanicalReport.vue'),
+            }
+          ]
+        },
+        {
           /*----------- 璁惧鐘舵�� ----------------*/
           path: 'MechanicalMonitor/mechanicalMonitor',
           name: 'mechanicalMonitor',
diff --git a/UI-Project/src/views/KanbanData/kanbanData.vue b/UI-Project/src/views/KanbanData/kanbanData.vue
index da17064..87a17e9 100644
--- a/UI-Project/src/views/KanbanData/kanbanData.vue
+++ b/UI-Project/src/views/KanbanData/kanbanData.vue
@@ -2,9 +2,25 @@
 import { ref, onMounted, onBeforeUnmount } from 'vue'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import request from '@/utils/request'
+import { useRoute, useRouter } from 'vue-router'
+
+const router = useRouter()
+const route = useRoute()
 
 // 鍔犺浇鍒濆鏁版嵁
 onMounted(() => {
+  // 浠巐ocalStorage鑾峰彇瀛樺偍鐨勭洰鏍囧��
+  yieldTargetValue1.value = localStorage.getItem('yieldTarget1') ? Number(localStorage.getItem('yieldTarget1')) : 0
+  yieldTargetValue2.value = localStorage.getItem('yieldTarget2') ? Number(localStorage.getItem('yieldTarget2')) : 0
+  
+  utilizationTargetValue1.value = localStorage.getItem('utilizationTarget1') ? Number(localStorage.getItem('utilizationTarget1')) : 0
+  utilizationTargetValue2.value = localStorage.getItem('utilizationTarget2') ? Number(localStorage.getItem('utilizationTarget2')) : 0
+  
+  quantityTargetValue1.value = localStorage.getItem('quantityTarget1') ? Number(localStorage.getItem('quantityTarget1')) : 0
+  quantityTargetValue2.value = localStorage.getItem('quantityTarget2') ? Number(localStorage.getItem('quantityTarget2')) : 0
+  quantityTargetValue3.value = localStorage.getItem('quantityTarget3') ? Number(localStorage.getItem('quantityTarget3')) : 0
+  
+  // 鍔犺浇鍏朵粬鏁版嵁
   loadYieldData()
   loadUtilizationData()
   loadQuantityData()
@@ -54,6 +70,8 @@
   lineNo: '',
   yieldvalue: null
 })
+const yieldTargetValue1 = ref() // 涓�绾跨洰鏍囧��
+const yieldTargetValue2 = ref() // 浜岀嚎鐩爣鍊�
 const yieldData = ref([])
 const yieldLoading = ref(false)
 
@@ -63,6 +81,8 @@
   lineNo: '',
   utilizationRate: null
 })
+const utilizationTargetValue1 = ref() // 鏍囧噯绾跨洰鏍囧��
+const utilizationTargetValue2 = ref() // 瀹氬埗绾跨洰鏍囧��
 const utilizationData = ref([])
 const utilizationLoading = ref(false)
 
@@ -79,6 +99,9 @@
   locationCode: '',
   quantity: null
 })
+const quantityTargetValue1 = ref(4000) // 鍗婃垚鍝佺洰鏍囧��
+const quantityTargetValue2 = ref(4000) // 7014鐩爣鍊�
+const quantityTargetValue3 = ref(4000) // 7016鐩爣鍊�
 const quantityData = ref([])
 const quantityLoading = ref(false)
 
@@ -235,9 +258,9 @@
   }
 
   try {
-    const recordTimeStr = `${yieldFormData.value.recordDate} 00:00:00`;
+    const recordTimeStr = `${yieldFormData.value.recordDate} 00:00:00`
     
-    await request({
+    const res = await request({
       url: '/deviceInteraction/yield/addYield',
       method: 'post',
       data: {
@@ -245,9 +268,14 @@
         recordTime: recordTimeStr
       }
     })
-    ElMessage.success('娣诲姞鎴愬姛')
-    resetYieldForm()
-    loadYieldData() // 鍒锋柊鏁版嵁
+    
+    if (res.code === 200) {
+      ElMessage.success('娣诲姞鎴愬姛')
+      resetYieldForm()
+      loadYieldData() // 鍒锋柊鏁版嵁
+    } else {
+      ElMessage.error(res.message || '娣诲姞澶辫触')
+    }
   } catch (error) {
     ElMessage.error('娣诲姞澶辫触')
     console.error(error)
@@ -266,9 +294,9 @@
   }
 
   try {
-    const recordTimeStr = `${utilizationFormData.value.recordDate} 00:00:00`;
+    const recordTimeStr = `${utilizationFormData.value.recordDate} 00:00:00`
     
-    await request({
+    const res = await request({
       url: '/deviceInteraction/utilization/addUtilization',
       method: 'post',
       data: {
@@ -276,9 +304,14 @@
         recordTime: recordTimeStr
       }
     })
-    ElMessage.success('娣诲姞鎴愬姛')
-    resetUtilizationForm()
-    loadUtilizationData() // 鍒锋柊鏁版嵁
+    
+    if (res.code === 200) {
+      ElMessage.success('娣诲姞鎴愬姛')
+      resetUtilizationForm()
+      loadUtilizationData() // 鍒锋柊鏁版嵁
+    } else {
+      ElMessage.error(res.message || '娣诲姞澶辫触')
+    }
   } catch (error) {
     ElMessage.error('娣诲姞澶辫触')
     console.error(error)
@@ -297,14 +330,9 @@
   }
 
   try {
-    // 鎷兼帴鏃ユ湡鏃堕棿瀛楃涓诧紝纭繚鏄綋澶╃殑00:00:00
-    const dateStr = quantityFormData.value.recordDate;
-    const recordTimeStr = `${dateStr} 00:00:00`;
+    const recordTimeStr = `${quantityFormData.value.recordDate} 00:00:00`
     
-
-    const locationCode = quantityFormData.value.locationCode;
-    
-    await request({
+    const res = await request({
       url: '/deviceInteraction/quantity/addQuantity',
       method: 'post',
       data: {
@@ -312,9 +340,14 @@
         recordTime: recordTimeStr
       }
     })
-    ElMessage.success('娣诲姞鎴愬姛')
-    resetQuantityForm()
-    loadQuantityData() // 鍒锋柊鏁版嵁
+    
+    if (res.code === 200) {
+      ElMessage.success('娣诲姞鎴愬姛')
+      resetQuantityForm()
+      loadQuantityData() // 鍒锋柊鏁版嵁
+    } else {
+      ElMessage.error(res.message || '娣诲姞澶辫触')
+    }
   } catch (error) {
     ElMessage.error('娣诲姞澶辫触')
     console.error(error)
@@ -358,7 +391,7 @@
 // 閲嶇疆琛ㄥ崟
 const resetYieldForm = () => {
   yieldFormData.value = {
-    recordDate: yieldFormData.value.recordDate, // 淇濇寔褰撳墠閫夋嫨鐨勬棩鏈�
+    recordDate: yieldFormData.value.recordDate,
     lineNo: '',
     yieldvalue: null
   }
@@ -366,7 +399,7 @@
 
 const resetUtilizationForm = () => {
   utilizationFormData.value = {
-    recordDate: utilizationFormData.value.recordDate, // 淇濇寔褰撳墠閫夋嫨鐨勬棩鏈�
+    recordDate: utilizationFormData.value.recordDate,
     lineNo: '',
     utilizationRate: null
   }
@@ -374,7 +407,7 @@
 
 const resetQuantityForm = () => {
   quantityFormData.value = {
-    recordDate: quantityFormData.value.recordDate, // 淇濇寔褰撳墠閫夋嫨鐨勬棩鏈�
+    recordDate: quantityFormData.value.recordDate,
     locationCode: '',
     quantity: null
   }
@@ -621,6 +654,30 @@
     }
   }
 }
+
+
+// 淇敼璁剧疆鐩爣鍊肩殑鏂规硶
+const setYieldTarget = () => {
+  // 鏇存柊浜ч噺鐩爣鍊煎苟淇濆瓨鍒發ocalStorage
+  localStorage.setItem('yieldTarget1', yieldTargetValue1.value.toString())
+  localStorage.setItem('yieldTarget2', yieldTargetValue2.value.toString())
+  ElMessage.success('鐩爣鍊艰缃垚鍔�')
+}
+
+const setUtilizationTarget = () => {
+  // 鏇存柊鍒╃敤鐜囩洰鏍囧�煎苟淇濆瓨鍒發ocalStorage
+  localStorage.setItem('utilizationTarget1', utilizationTargetValue1.value.toString())
+  localStorage.setItem('utilizationTarget2', utilizationTargetValue2.value.toString())
+  ElMessage.success('鐩爣鍊艰缃垚鍔�')
+}
+
+const setQuantityTarget = () => {
+  // 鏇存柊鍦ㄥ埗閲忕洰鏍囧�煎苟淇濆瓨鍒發ocalStorage
+  localStorage.setItem('quantityTarget1', quantityTargetValue1.value.toString())
+  localStorage.setItem('quantityTarget2', quantityTargetValue2.value.toString())
+  localStorage.setItem('quantityTarget3', quantityTargetValue3.value.toString())
+  ElMessage.success('鐩爣鍊艰缃垚鍔�')
+}
 </script>
 
 <template>
@@ -629,6 +686,34 @@
       <el-tabs v-model="activeTab">
         <!-- 鍗曞皬鏃朵骇閲忔爣绛鹃〉 -->
         <el-tab-pane label="鍗曞皬鏃朵骇閲�" name="yield">
+          <!-- 娣诲姞鐩爣鍊艰缃儴鍒� -->
+          <div class="target-setting">
+            <el-form :inline="true" label-width="100px">
+              <el-form-item label="涓�绾跨洰鏍囧��">
+                <el-input-number
+                  v-model="yieldTargetValue1"
+                  :precision="0"
+                  :step="100"
+                  :min="0"
+                  controls-position="right"
+                  style="width: 180px"
+                />
+              </el-form-item>
+              <el-form-item label="浜岀嚎鐩爣鍊�">
+                <el-input-number
+                  v-model="yieldTargetValue2"
+                  :precision="0"
+                  :step="100"
+                  :min="0"
+                  controls-position="right"
+                  style="width: 180px"
+                />
+              </el-form-item>
+              <el-form-item>
+                <el-button type="primary" @click="setYieldTarget">璁剧疆鐩爣鍊�</el-button>
+              </el-form-item>
+            </el-form>
+          </div>
           <el-form :inline="true" :model="yieldFormData" label-width="100px" class="form-container">
             <el-form-item label="鏃ユ湡">
               <el-date-picker
@@ -732,6 +817,36 @@
 
         <!-- 鍒╃敤鐜囨爣绛鹃〉 -->
         <el-tab-pane label="鍒╃敤鐜�" name="utilization">
+          <!-- 娣诲姞鐩爣鍊艰缃儴鍒� -->
+          <div class="target-setting">
+            <el-form :inline="true" label-width="100px">
+              <el-form-item label="鏍囧噯绾跨洰鏍囧��">
+                <el-input-number
+                  v-model="utilizationTargetValue1"
+                  :precision="2"
+                  :step="0.1"
+                  :min="0"
+                  :max="100"
+                  controls-position="right"
+                  style="width: 180px"
+                />
+              </el-form-item>
+              <el-form-item label="瀹氬埗绾跨洰鏍囧��">
+                <el-input-number
+                  v-model="utilizationTargetValue2"
+                  :precision="2"
+                  :step="0.1"
+                  :min="0"
+                  :max="100"
+                  controls-position="right"
+                  style="width: 180px"
+                />
+              </el-form-item>
+              <el-form-item>
+                <el-button type="primary" @click="setUtilizationTarget">璁剧疆鐩爣鍊�</el-button>
+              </el-form-item>
+            </el-form>
+          </div>
           <el-form :inline="true" :model="utilizationFormData" label-width="100px" class="form-container">
             <el-form-item label="鏃ユ湡">
               <el-date-picker
@@ -835,6 +950,44 @@
 
         <!-- 鍦ㄥ埗閲忔爣绛鹃〉 -->
         <el-tab-pane label="鍦ㄥ埗閲�" name="quantity">
+          <!-- 娣诲姞鐩爣鍊艰缃儴鍒� -->
+          <div class="target-setting">
+            <el-form :inline="true" label-width="100px">
+              <el-form-item label="鍗婃垚鍝佺洰鏍囧��">
+                <el-input-number
+                  v-model="quantityTargetValue1"
+                  :precision="0"
+                  :step="100"
+                  :min="0"
+                  controls-position="right"
+                  style="width: 180px"
+                />
+              </el-form-item>
+              <el-form-item label="7014鐩爣鍊�">
+                <el-input-number
+                  v-model="quantityTargetValue2"
+                  :precision="0"
+                  :step="100"
+                  :min="0"
+                  controls-position="right"
+                  style="width: 180px"
+                />
+              </el-form-item>
+              <el-form-item label="7016鐩爣鍊�">
+                <el-input-number
+                  v-model="quantityTargetValue3"
+                  :precision="0"
+                  :step="100"
+                  :min="0"
+                  controls-position="right"
+                  style="width: 180px"
+                />
+              </el-form-item>
+              <el-form-item>
+                <el-button type="primary" @click="setQuantityTarget">璁剧疆鐩爣鍊�</el-button>
+              </el-form-item>
+            </el-form>
+          </div>
           <el-form :inline="true" :model="quantityFormData" label-width="100px" class="form-container">
             <el-form-item label="鏃ユ湡">
               <el-date-picker
@@ -1047,6 +1200,13 @@
 </template>
 
 <style scoped>
+.target-setting {
+  margin-bottom: 20px;
+  background-color: #f5f7fa;
+  padding: 20px;
+  border-radius: 4px;
+}
+
 .form-container {
   margin-bottom: 20px;
   background-color: #f5f7fa;
diff --git a/UI-Project/src/views/KanbanDisplay2/kanbanDisplay2.vue b/UI-Project/src/views/KanbanDisplay2/kanbanDisplay2.vue
index 7fc3917..b32a997 100644
--- a/UI-Project/src/views/KanbanDisplay2/kanbanDisplay2.vue
+++ b/UI-Project/src/views/KanbanDisplay2/kanbanDisplay2.vue
@@ -1,12 +1,61 @@
 <script setup>
-import { ref, onMounted, onUnmounted, nextTick } from 'vue'
+import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue'
 import * as echarts from 'echarts'
 import request from '@/utils/request'
+import { useRoute } from 'vue-router'
 
+const route = useRoute()
 const dashboardRef = ref(null)
 const standardWidth = 2220 // 璁捐绋挎爣鍑嗗搴�
-const standardHeight = 1224 // 璁捐绋挎爣鍑嗛珮搴︼紝
+const standardHeight = 1224 // 璁捐绋挎爣鍑嗛珮搴�
 
+// 浠庤矾鐢卞弬鏁颁腑鑾峰彇鐩爣鍊�
+const yieldTarget1 = ref(Number(localStorage.getItem('yieldTarget1')) || Number(route.query.yieldTarget1) || 0)
+const yieldTarget2 = ref(Number(localStorage.getItem('yieldTarget2')) || Number(route.query.yieldTarget2) || 0)
+const utilizationTarget1 = ref(Number(localStorage.getItem('utilizationTarget1')) || Number(route.query.utilizationTarget1) || 0)
+const utilizationTarget2 = ref(Number(localStorage.getItem('utilizationTarget2')) || Number(route.query.utilizationTarget2) || 0)
+const quantityTarget1 = ref(Number(localStorage.getItem('quantityTarget1')) || Number(route.query.quantityTarget1) || 0)
+const quantityTarget2 = ref(Number(localStorage.getItem('quantityTarget2')) || Number(route.query.quantityTarget2) || 0)
+const quantityTarget3 = ref(Number(localStorage.getItem('quantityTarget3')) || Number(route.query.quantityTarget3) || 0)
+
+// 鐩戝惉璺敱鍙傛暟鍙樺寲
+watch(() => route.query, (newQuery) => {
+  if (newQuery.yieldTarget1) {
+    yieldTarget1.value = Number(newQuery.yieldTarget1)
+    localStorage.setItem('yieldTarget1', newQuery.yieldTarget1)
+    updateOptionYield(yieldTarget1.value, yieldTarget2.value)
+  }
+  if (newQuery.yieldTarget2) {
+    yieldTarget2.value = Number(newQuery.yieldTarget2)
+    localStorage.setItem('yieldTarget2', newQuery.yieldTarget2)
+    updateOptionYield(yieldTarget1.value, yieldTarget2.value)
+  }
+  if (newQuery.utilizationTarget1) {
+    utilizationTarget1.value = Number(newQuery.utilizationTarget1)
+    localStorage.setItem('utilizationTarget1', newQuery.utilizationTarget1)
+    updateOptionUtilization(utilizationTarget1.value, utilizationTarget2.value)
+  }
+  if (newQuery.utilizationTarget2) {
+    utilizationTarget2.value = Number(newQuery.utilizationTarget2)
+    localStorage.setItem('utilizationTarget2', newQuery.utilizationTarget2)
+    updateOptionUtilization(utilizationTarget1.value, utilizationTarget2.value)
+  }
+  if (newQuery.quantityTarget1) {
+    quantityTarget1.value = Number(newQuery.quantityTarget1)
+    localStorage.setItem('quantityTarget1', newQuery.quantityTarget1)
+    updateOptionQuantity(quantityTarget1.value, quantityTarget2.value, quantityTarget3.value)
+  }
+  if (newQuery.quantityTarget2) {
+    quantityTarget2.value = Number(newQuery.quantityTarget2)
+    localStorage.setItem('quantityTarget2', newQuery.quantityTarget2)
+    updateOptionQuantity(quantityTarget1.value, quantityTarget2.value, quantityTarget3.value)
+  }
+  if (newQuery.quantityTarget3) {
+    quantityTarget3.value = Number(newQuery.quantityTarget3)
+    localStorage.setItem('quantityTarget3', newQuery.quantityTarget3)
+    updateOptionQuantity(quantityTarget1.value, quantityTarget2.value, quantityTarget3.value)
+  }
+}, { deep: true })
 
 // 璁$畻缂╂斁姣斾緥骞跺簲鐢�
 const setScale = () => {
@@ -70,7 +119,7 @@
     });
     if (res.code === 200) {
       yieldData.value = res.data;
-      updateOptionYield();
+      updateOptionYield(yieldTarget1.value, yieldTarget2.value);
     }
   } catch (error) {
     console.error('鑾峰彇鍗曞皬鏃朵骇閲忔暟鎹け璐�:', error);
@@ -85,7 +134,7 @@
     });
     if (res.code === 200) {
       utilizationData.value = res.data;
-      updateOptionUtilization();
+      updateOptionUtilization(utilizationTarget1.value, utilizationTarget2.value);
     }
   } catch (error) {
     console.error('鑾峰彇鍒╃敤鐜囨暟鎹け璐�:', error);
@@ -100,7 +149,7 @@
     });
     if (res.code === 200) {
       quantityData.value = res.data;
-      updateOptionQuantity();
+      updateOptionQuantity(quantityTarget1.value, quantityTarget2.value, quantityTarget3.value);
     }
   } catch (error) {
     console.error('鑾峰彇鍦ㄥ埗閲忔暟鎹け璐�:', error);
@@ -405,7 +454,7 @@
   draw('drawLineChart_day51', OptionDayMode)
 }
 
-const updateOptionYield = () => {
+const updateOptionYield = (targetValue1, targetValue2) => {
   // 鎸夋棩鏈熸帓搴忓苟澶勭悊鏁版嵁
   const sortedData = [...yieldData.value].sort((a, b) =>
     new Date(a.recordTime) - new Date(b.recordTime)
@@ -434,14 +483,32 @@
 
   // 鍗曞皬鏃朵骇閲忕殑閰嶇疆 - 鍒嗕笂涓嬩袱涓瓙鍥捐〃
   const OptionYield = {
-    title: {
-      text: '鍗曞皬鏃朵骇閲�',
-      textStyle: {
-        fontSize: 20,
-        fontWeight: 'bold',
-        color: 'white'
-      }
-    },
+    title: [
+      {
+        text: '鍗曞皬鏃朵骇閲�',
+        textStyle: {
+          fontSize: 20,
+          fontWeight: 'bold',
+          color: 'white'
+        }
+      },
+      {
+        text: '鐩爣' + targetValue1,
+        bottom: 140, //
+        textStyle: {
+          color: 'white',
+          fontSize: 17
+        },
+      },
+      {
+        text: '鐩爣' + targetValue2,
+        bottom: 35, // 
+        textStyle: {
+          color: 'white',
+          fontSize: 17
+        },
+      },
+    ],
     tooltip: {
       trigger: 'axis',
       axisPointer: {
@@ -454,10 +521,11 @@
       x: 'left',
       y: 'center',
       orient: 'vertical',
+      itemGap: 90,
       textStyle: {
         fontSize: 20,
         fontWeight: 'bold',
-        color: 'white',
+        color: 'white'
       }
     },
     grid: [{
@@ -558,6 +626,20 @@
         areaStyle: {
           color: '#000000',
           opacity: 0.3
+        },
+        markLine: {
+          data: [
+            {
+              yAxis: targetValue1,
+              name: 'Line',
+              label: {
+                formatter: '',
+              },
+              lineStyle: {
+                width: 2,
+              }
+            }
+          ]
         }
       },
       {
@@ -584,6 +666,20 @@
         areaStyle: {
           color: 'white',
           opacity: 0.3
+        },
+        markLine: {
+          data: [
+            {
+              yAxis: targetValue2,
+              name: 'Line',
+              label: {
+                formatter: '',
+              },
+              lineStyle: {
+                width: 2,
+              }
+            }
+          ]
         }
       }
     ]
@@ -598,7 +694,7 @@
   draw('drawLineChart_yield', OptionYield)
 }
 
-const updateOptionUtilization = () => {
+const updateOptionUtilization = (targetValue1, targetValue2) => {
   // 鎸夋棩鏈熸帓搴忓苟澶勭悊鏁版嵁
   const sortedData = [...utilizationData.value].sort((a, b) =>
     new Date(a.recordTime || a.recordDate) - new Date(b.recordTime || b.recordDate)
@@ -627,14 +723,32 @@
 
   // 鍒╃敤鐜囩殑閰嶇疆 - 鍒嗕笂涓嬩袱涓瓙鍥捐〃
   const OptionUtilization = {
-    title: {
-      text: '鍒╃敤鐜�',
-      textStyle: {
-        fontSize: 20,
-        fontWeight: 'bold',
-        color: 'white'
-      }
-    },
+    title: [
+      {
+        text: '鍒╃敤鐜�',
+        textStyle: {
+          fontSize: 20,
+          fontWeight: 'bold',
+          color: 'white'
+        }
+      },
+      {
+        text: '鐩爣' + targetValue1 + '%',
+        bottom: 140, //
+        textStyle: {
+          color: 'white',
+          fontSize: 17
+        },
+      },
+      {
+        text: '鐩爣' + targetValue2 + '%',
+        bottom: 35, // 
+        textStyle: {
+          color: 'white',
+          fontSize: 17
+        },
+      },
+    ],
     tooltip: {
       trigger: 'axis',
       axisPointer: {
@@ -647,6 +761,7 @@
       x: 'left',
       y: 'center',
       orient: 'vertical',
+      itemGap: 90,
       textStyle: {
         fontSize: 20,
         fontWeight: 'bold',
@@ -774,6 +889,20 @@
         areaStyle: {
           color: '#000000',
           opacity: 0.3
+        },
+        markLine: {
+          data: [
+            {
+              yAxis: targetValue1,
+              name: 'Line',
+              label: {
+                formatter: '',
+              },
+              lineStyle: {
+                width: 2,
+              }
+            }
+          ]
         }
       },
       {
@@ -801,6 +930,20 @@
         areaStyle: {
           color: 'white',
           opacity: 0.3
+        },
+        markLine: {
+          data: [
+            {
+              yAxis: targetValue2,
+              name: "line",
+              label: {
+                formatter: '',
+              },
+              lineStyle: {
+                width: 2,
+              }
+            }
+          ]
         }
       }
     ]
@@ -812,12 +955,13 @@
   //   chart.setOption(OptionUtilization);
   //   charts.push(chart);
   // }
-  draw('drawLineChart_utilization',OptionUtilization);
-  
+  draw('drawLineChart_utilization', OptionUtilization);
+
 }
 
-const updateOptionQuantity = () => {
+const updateOptionQuantity = (targetValue1, targetValue2, targetValue3) => {
   // 鎸夋棩鏈熸帓搴忓苟澶勭悊鏁版嵁
+
   const sortedData = [...quantityData.value].sort((a, b) =>
     new Date(a.recordTime || a.recordDate) - new Date(b.recordTime || b.recordDate)
   );
@@ -848,7 +992,7 @@
 
   // 鍦ㄥ埗閲忕殑閰嶇疆 - 涓婁腑涓嬩笁灞傚竷灞�
   const OptionQuantity = {
-    title: {
+    title: [{
       text: '鍦ㄥ埗閲�',
       textStyle: {
         fontSize: 20,
@@ -856,6 +1000,31 @@
         color: 'white'
       }
     },
+    {
+      text: '鐩爣' + targetValue1,
+      bottom: 160, //
+      textStyle: {
+        color: 'white',
+        fontSize: 17
+      },
+    },
+    {
+      text: '鐩爣' + targetValue2,
+      bottom: 95, // 
+      textStyle: {
+        color: 'white',
+        fontSize: 17
+      },
+    },
+    {
+      text: '鐩爣' + targetValue3,
+      bottom: 20, // 
+      textStyle: {
+        color: 'white',
+        fontSize: 17
+      },
+    },
+    ],
     tooltip: {
       trigger: 'axis',
       axisPointer: {
@@ -868,6 +1037,7 @@
       x: 'left',
       y: 'center',
       orient: 'vertical',
+      itemGap: 50,
       textStyle: {
         fontSize: 20,
         fontWeight: 'bold',
@@ -1014,6 +1184,20 @@
         areaStyle: {
           color: '#91cc75',
           opacity: 0.3
+        },
+        markLine: {
+          data: [
+            {
+              yAxis: targetValue1,
+              name: 'Line',
+              label: {
+                formatter: '',
+              },
+              lineStyle: {
+                width: 2,
+              }
+            }
+          ]
         }
       },
       {
@@ -1040,6 +1224,20 @@
         areaStyle: {
           color: '#000000',
           opacity: 0.3
+        },
+        markLine: {
+          data: [
+            {
+              yAxis: targetValue2,
+              name: 'Line',
+              label: {
+                formatter: '',
+              },
+              lineStyle: {
+                width: 2,
+              }
+            }
+          ]
         }
       },
       {
@@ -1066,6 +1264,20 @@
         areaStyle: {
           color: 'white',
           opacity: 0.3
+        },
+        markLine: {
+          data: [
+            {
+              yAxis: targetValue3,
+              name: 'Line',
+              label: {
+                formatter: '',
+              },
+              lineStyle: {
+                width: 2,
+              }
+            }
+          ]
         }
       }
     ]
@@ -1077,7 +1289,7 @@
   //   chart.setOption(OptionQuantity);
   //   charts.push(chart);
   // }
-  draw('drawLineChart_quantity',OptionQuantity);
+  draw('drawLineChart_quantity', OptionQuantity);
 }
 
 
@@ -1086,33 +1298,87 @@
   window.addEventListener('resize', handleResize)
 
   // 纭繚DOM鍔犺浇瀹屾垚鍚庡啀鍒濆鍖栧浘琛�
-  nextTick(() => {
-    loadNotCompleteData();
-    loadYieldData();
-    loadUtilizationData();
-    loadInventoryData();
-    loadPlannedData();
-  });
+  nextTick(async () => {
+    try {
+      // 浠巐ocalStorage涓幏鍙栫洰鏍囧�硷紝濡傛灉娌℃湁鍒欎粠璺敱鍙傛暟鑾峰彇锛岄兘娌℃湁鍒欎娇鐢ㄩ粯璁ゅ��0
+      yieldTarget1.value = Number(localStorage.getItem('yieldTarget1')) || Number(route.query.yieldTarget1) || 0
+      yieldTarget2.value = Number(localStorage.getItem('yieldTarget2')) || Number(route.query.yieldTarget2) || 0
+      utilizationTarget1.value = Number(localStorage.getItem('utilizationTarget1')) || Number(route.query.utilizationTarget1) || 0
+      utilizationTarget2.value = Number(localStorage.getItem('utilizationTarget2')) || Number(route.query.utilizationTarget2) || 0
+      quantityTarget1.value = Number(localStorage.getItem('quantityTarget1')) || Number(route.query.quantityTarget1) || 0
+      quantityTarget2.value = Number(localStorage.getItem('quantityTarget2')) || Number(route.query.quantityTarget2) || 0
+      quantityTarget3.value = Number(localStorage.getItem('quantityTarget3')) || Number(route.query.quantityTarget3) || 0
 
-  // 璁剧疆瀹氭椂鍒锋柊
-  const refreshInterval = setInterval(() => {
-    loadYieldData();
-    loadUtilizationData();
-    loadInventoryData();
-    loadPlannedData();
-    console.log('鏁版嵁宸插埛鏂�');
-  }, 30000); // 姣忓垎閽熷埛鏂颁竴娆�
+      // 鎸夐『搴忓姞杞芥暟鎹�
+      await loadNotCompleteData()
+      await loadYieldData()
+      await loadUtilizationData()
+      await loadInventoryData()
+      await loadPlannedData()
 
-  onUnmounted(() => {
-    clearInterval(refreshInterval);
-  });
+      // 璁剧疆瀹氭椂鍒锋柊鏁版嵁
+      const refreshInterval = setInterval(async () => {
+        try {
+          await loadYieldData()
+          await loadUtilizationData()
+          await loadInventoryData()
+          await loadPlannedData()
+          console.log('鏁版嵁宸插埛鏂�')
+        } catch (error) {
+          console.error('鏁版嵁鍒锋柊澶辫触:', error)
+        }
+      }, 15000) // 姣�15绉掑埛鏂颁竴娆�
+
+      // 娣诲姞鐩戝惉localStorage鍙樺寲鐨勫畾鏃跺櫒
+      const checkTargetsInterval = setInterval(() => {
+        const newYieldTarget1 = Number(localStorage.getItem('yieldTarget1'))
+        const newYieldTarget2 = Number(localStorage.getItem('yieldTarget2'))
+        const newUtilizationTarget1 = Number(localStorage.getItem('utilizationTarget1'))
+        const newUtilizationTarget2 = Number(localStorage.getItem('utilizationTarget2'))
+        const newQuantityTarget1 = Number(localStorage.getItem('quantityTarget1'))
+        const newQuantityTarget2 = Number(localStorage.getItem('quantityTarget2'))
+        const newQuantityTarget3 = Number(localStorage.getItem('quantityTarget3'))
+
+        // 妫�鏌ョ洰鏍囧�兼槸鍚︽湁鍙樺寲
+        if (newYieldTarget1 !== yieldTarget1.value || newYieldTarget2 !== yieldTarget2.value) {
+          yieldTarget1.value = newYieldTarget1
+          yieldTarget2.value = newYieldTarget2
+          updateOptionYield(newYieldTarget1, newYieldTarget2)
+        }
+        if (newUtilizationTarget1 !== utilizationTarget1.value || newUtilizationTarget2 !== utilizationTarget2.value) {
+          utilizationTarget1.value = newUtilizationTarget1
+          utilizationTarget2.value = newUtilizationTarget2
+          updateOptionUtilization(newUtilizationTarget1, newUtilizationTarget2)
+        }
+        if (newQuantityTarget1 !== quantityTarget1.value || 
+            newQuantityTarget2 !== quantityTarget2.value || 
+            newQuantityTarget3 !== quantityTarget3.value) {
+          quantityTarget1.value = newQuantityTarget1
+          quantityTarget2.value = newQuantityTarget2
+          quantityTarget3.value = newQuantityTarget3
+          updateOptionQuantity(newQuantityTarget1, newQuantityTarget2, newQuantityTarget3)
+        }
+      }, 1000) // 姣忕妫�鏌ヤ竴娆�
+
+      onUnmounted(() => {
+        clearInterval(refreshInterval)
+        clearInterval(checkTargetsInterval)
+      })
+    } catch (error) {
+      console.error('鍒濆鍖栨暟鎹け璐�:', error)
+    }
+  })
 })
 
 onUnmounted(() => {
   window.removeEventListener('resize', handleResize)
+  // 娓呯悊鎵�鏈夊浘琛ㄥ疄渚�
   charts.forEach(chart => {
-    chart.dispose()
+    if (chart && !chart.isDisposed()) {
+      chart.dispose()
+    }
   })
+  charts.length = 0
 })
 
 </script>
@@ -1139,8 +1405,8 @@
                 鎬昏鍒掗噺-鐗囨暟銆佸钩鏂�</div>
               <div id="textDay" style="font-size: 20px;height: 30px;margin-left: 20px;margin-top: 20px;">鏃ユ湡锛�</div>
               <br>
-              <div id="textprice" style="font-size: 20px;height: 30px;margin-left: 20px;margin-top: 20px;">鐗囨暟锛�</div>
               <div id="textarea" style="font-size: 20px;height: 30px;margin-left: 20px;margin-top: 20px;">骞虫柟鏁帮細</div>
+              <div id="textprice" style="font-size: 20px;height: 30px;margin-left: 20px;margin-top: 20px;">鐗囨暟锛�</div>
             </div>
           </div>
 
@@ -1167,206 +1433,148 @@
 
 <script>
 export default {
-  mounted() {
-
-    const OptionYear = {
-      tooltip: {
-        trigger: 'axis',
-        axisPointer: {
-          type: 'shadow',
-          label: {
-            fontSize: 16,
-            color: 'white' // 璁剧疆鎻愮ず妗嗘枃瀛楅鑹蹭负鐧借壊
+  data() {
+    return {
+      timer: null,
+      OptionYear: {
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow',
+            label: {
+              fontSize: 16,
+              color: 'white' // 璁剧疆鎻愮ず妗嗘枃瀛楅鑹蹭负鐧借壊
+            }
           }
-        }
-      },
-      legend: {
-        data: ['璁″垝閲�', '涓�绾�', '浜岀嚎'],
-        icon: 'roundRect',
-        itemGap: 50,
-        y:'bottom',
-        textStyle: {
-          fontSize: 20,
-          fontWeight: 'bold',
-          color: 'white'
-        }
-      },
-      // toolbox: {
-      //   show: true,
-      //   feature: {
-      //     dataZoom: {
-      //       yAxisIndex: 'none'
-      //     },
-      //     dataView: { readOnly: false },
-      //     magicType: { type: ['line', 'bar'] },
-      //     restore: {},
-      //     saveAsImage: {}
-      //   },
-      //   iconStyle: {
-      //     color: 'white' // 璁剧疆宸ュ叿妗嗗浘鏍囬鑹蹭负鐧借壊
-      //   }
-      // },
-      grid: {
-        left: '3%',
-        right: '4%',
-        bottom: '20%',
-        top: '10%',
-        containLabel: true
-      },
-      xAxis: [
-        {
-          type: 'category',
-          axisTick: { alignWithLabel: true },
-          boundaryGap: true,
-          axisLabel: {
+        },
+        title: {
+          text: '宸插畬鎴�                    宸插畬鎴�',
+          left: '48%',
+          bottom: 0, // 
+          textStyle: {
+            color: 'white',
+            fontSize: 16
+          },
+        },
+        legend: {
+          data: ['璁″垝閲�', '涓�绾�', '浜岀嚎'],
+          icon: 'roundRect',
+          itemGap: 90,
+          y: '80%',
+          textStyle: {
             fontSize: 20,
-            interval: 'auto',
-            margin: 15,
-            formatter: (value, index) => {
-              // 濡傛灉鏄棩鏈熸牸寮�
-              if (value.includes('-')) {
-                // 瀵圭涓�涓棩鏈熸樉绀哄畬鏁村勾鏈堟棩
-                if (index === 0) {
-                  return value;  // 杩斿洖瀹屾暣鏃ユ湡 (渚嬪: 2024-03-21)
+            fontWeight: 'bold',
+            color: 'white'
+          }
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          bottom: '20%',
+          top: '10%',
+          containLabel: true
+        },
+        xAxis: [
+          {
+            type: 'category',
+            axisTick: { alignWithLabel: true },
+            boundaryGap: true,
+            axisLabel: {
+              fontSize: 20,
+              interval: 'auto',
+              formatter: (value, index) => {
+                // 濡傛灉鏄棩鏈熸牸寮�
+                if (value.includes('-')) {
+                  // 瀵圭涓�涓棩鏈熸樉绀哄畬鏁村勾鏈堟棩
+                  if (index === 0) {
+                    return value;  // 杩斿洖瀹屾暣鏃ユ湡 (渚嬪: 2024-03-21)
+                  }
+                  // 鍏朵粬鏃ユ湡鍙樉绀烘湀-鏃�
+                  return value.split('-').slice(1).join('-');  // (渚嬪: 03-21)
                 }
-                // 鍏朵粬鏃ユ湡鍙樉绀烘湀-鏃�
-                return value.split('-').slice(1).join('-');  // (渚嬪: 03-21)
-              }
-              return value;
+                return value;
+              },
+              color: 'white' // 璁剧疆 x 杞存爣绛鹃鑹蹭负鐧借壊
             },
-            color: 'white' // 璁剧疆 x 杞存爣绛鹃鑹蹭负鐧借壊
-          },
-          nameTextStyle: {
-            fontSize: 20,
-            color: 'white' // 璁剧疆 x 杞村悕绉伴鑹蹭负鐧借壊
-          },
-          position: 'top'
-        }
-      ],
-      yAxis: [
-        {
-          type: 'value',
-          axisLabel: {
-            fontSize: 20,
-            color: 'white' // 璁剧疆 y 杞存爣绛鹃鑹蹭负鐧借壊
-          },
-          nameTextStyle: {
-            fontSize: 20,
-            color: 'white' // 璁剧疆 y 杞村悕绉伴鑹蹭负鐧借壊
+            nameTextStyle: {
+              fontSize: 20,
+              color: 'white' // 璁剧疆 x 杞村悕绉伴鑹蹭负鐧借壊
+            },
+            position: 'top',
+            offset: 15 // 璋冩暣 x 杞存爣绛剧殑浣嶇疆
           }
-        }
-      ],
-      series: [
-        {
-          name: '璁″垝閲�',
-          type: 'bar',
-          barWidth: '30%',
-          barGap: '10%',
-          label: {
-            show: true,
-            fontSize: 16,
-            formatter: (params) => params.value,
-            color: 'white',
-            position: 'top'
+        ],
+        yAxis: [
+          {
+            type: 'value',
+            axisLabel: {
+              fontSize: 20,
+              color: 'white' // 璁剧疆 y 杞存爣绛鹃鑹蹭负鐧借壊
+            },
+            nameTextStyle: {
+              fontSize: 20,
+              color: 'white' // 璁剧疆 y 杞村悕绉伴鑹蹭负鐧借壊
+            }
           }
-        },
-        {
-          name: '涓�绾�',
-          type: 'bar',
-          barWidth: '30%',
-          barGap: '10%',
-          label: {
-            show: true,
-            fontSize: 16,
-            formatter: (params) => params.value,
-            color: 'white',
-            position: 'top'
+        ],
+        series: [
+          {
+            name: '璁″垝閲�',
+            type: 'bar',
+            barWidth: '30%',
+            barGap: '10%',
+            label: {
+              show: true,
+              fontSize: 16,
+              formatter: (params) => params.value,
+              color: 'white',
+              position: 'top'
+            }
           },
-        },
-        {
-          name: '浜岀嚎',
-          type: 'bar',
-          barWidth: '30%',
-          barGap: '10%',
-          itemStyle: {
-            color: '#4a86e8'
+          {
+            name: '涓�绾�',
+            type: 'bar',
+            barWidth: '30%',
+            barGap: '10%',
+            label: {
+              show: true,
+              fontSize: 16,
+              formatter: (params) => params.value,
+              color: 'white',
+              position: 'top'
+            }
           },
-          label: {
-            show: true,
-            fontSize: 16,
-            formatter: (params) => params.value,
-            color: 'white',
-            position: 'top'
-          },
-        }
-      ]
+          {
+            name: '浜岀嚎',
+            type: 'bar',
+            barWidth: '30%',
+            barGap: '10%',
+            itemStyle: {
+              color: '#4a86e8'
+            },
+            label: {
+              show: true,
+              fontSize: 16,
+              formatter: (params) => params.value,
+              color: 'white',
+              position: 'top'
+            }
+          }
+        ]
+      }
     };
-
-
-    // 璇锋眰褰撴棩浜ч噺
-    // request.post('/deviceInteraction/primitiveTask/findDailyOutput',
-    //   {
-    //     "dayCount": 1
-    //   }).then((res) => {
-    //     if (res.code == 200) {
-    //       const modeOptions = res.data;
-    //       console.log("鑾峰彇褰撴棩浜ч噺",modeOptions);
-    //       this.drawDay('drawLineChart_day11', OptionYear, modeOptions);
-    //       // this.drawDay('drawLineChart_day31', OptionYear, modeOptions);
-    //       // this.drawYear('drawLineChart_day51', OptionDayMode, modeOptions);
-    //     } else {
-    //       console.error('璇锋眰褰撴棩浜ч噺鏁版嵁澶辫触:', error);
-    //     }
-    //   });
-
-    //璇锋眰鏃ヤ骇閲�-鏈�
-    request.post('/deviceInteraction/primitiveTask/findDailyOutput',
-      {
-        "dayCount": 30
-      }).then((res) => {
-        if (res.code == 200) {
-          const modeOptions = res.data;
-          const modeOptions2 = [res.data[res.data.length - 1]];
-          // this.drawDay('drawLineChart_day11', OptionYear, modeOptions);
-          //this.drawDay('drawLineChart_day31', OptionYear, modeOptions);
-          // this.drawYear('drawLineChart_day51', OptionDayMode, modeOptions);
-          this.drawDay('drawLineChart_day11', OptionYear, modeOptions2);
-        } else {
-          console.error('璇锋眰鏃ヤ骇閲�-鏈堟暟鎹け璐�:', error);
-        }
-      });
-    //璇锋眰璁″垝閲�
-    // request.post('/deviceInteraction/primitiveTask/findPlannedQuantity',
-    //   {
-    //     "dayCount": 30
-    //   }).then((res) => {
-    //     if (res.code == 200) {
-    //       const modeOptions = res.data;
-    //       this.drawYear('drawLineChart_day51', OptionDayMode, modeOptions);
-    //       let textDay = document.getElementById('textDay');
-    //       let textprice = document.getElementById('textprice');
-    //       let textarea = document.getElementById('textarea');
-
-    //       let y_pingfang = res.data.map(v => { return v.area_sum });
-    //       let y_pianshu = res.data.map(v => { return v.task_quantity_sum });
-    //       let y_pingfang_sum = 0;
-    //       let y_pianshu_sum = 0;
-    //       for (let i = 0; i < y_pingfang.length; i++) {
-    //         y_pingfang_sum += y_pingfang[i];
-    //       }
-    //       for (let i = 0; i < y_pianshu.length; i++) {
-    //         y_pianshu_sum += y_pianshu[i];
-    //       }
-
-    //       textDay.innerHTML = "鏃ユ湡锛�" + "<br>" + res.data[0].CreateDate + " - " + res.data[res.data.length - 1].CreateDate;
-    //       textprice.innerHTML = "鐗囨暟锛�" + y_pianshu_sum;
-    //       textarea.innerHTML = "骞虫柟鏁帮細" + Number(y_pingfang_sum).toFixed(2);
-    //       // this.drawYear('drawLineChart_day51', OptionDayMode, modeOptions);
-    //     } else {
-    //       console.error('璇锋眰璁″垝閲�-鏈堟暟鎹け璐�:', error);
-    //     }
-    //   });
-
+  },
+  mounted() {
+    this.fetchData();
+    // 姣忓崐鍒嗛挓鍒锋柊涓�娆℃暟鎹�
+    this.timer = setInterval(() => {
+      this.fetchData();
+    }, 30000);
+  },
+  beforeDestroy() {
+    if (this.timer) {
+      clearInterval(this.timer);
+    }
   },
   methods: {
     draw(name, Option) {
@@ -1374,9 +1582,6 @@
       myChart.setOption(Option);
     },
     drawDay(name, Option, data) {
-      // console.log(data);
-      //Option.title.text="鏃ョ湅鏉�";
-      //鏃ョ湅鏉�- 璁″垝閲忥紝涓�绾垮畬鎴愶紝浜岀嚎瀹屾垚锛堢墖鏁帮級
       let x_data = data.map(v => { return v.date });
       let y_jihua = data.map(v => { return v.plan });
       let y_one = data.map(v => { return v.line1 });
@@ -1388,7 +1593,6 @@
       this.draw(name, Option);
     },
     drawYear(name, Option, data) {
-      //璁″垝閲�- 骞虫柟锛岀墖鏁�
       let x_data = data.map(v => { return v.CreateDate });
       let y_pingfang = data.map(v => { return v.area_sum });
       let y_pianshu = data.map(v => { return v.task_quantity_sum });
@@ -1398,37 +1602,24 @@
       Option.series[1].data = y_pianshu;
       this.draw(name, Option);
     },
-    requsstData() {
-
-    },
-    // // 娓叉煋鍗曞皬鏃朵骇閲忓浘琛�
-    // drawYieldChart(data) {
-    //   const option = { ...OptionYield };
-    //   option.xAxis.data = data.map(v => v.date);
-    //   option.series[0].data = data.map(v => v.line1_yield);
-    //   option.series[1].data = data.map(v => v.line2_yield);
-    //   this.draw('drawLineChart_yield', option);
-    // },
-    // // 娓叉煋鍒╃敤鐜囧浘琛�
-    // drawUtilizationChart(data) {
-    //   const option = { ...OptionUtilization };
-    //   option.xAxis.data = data.map(v => v.date);
-    //   option.series[0].data = data.map(v => v.line1_utilization);
-    //   option.series[1].data = data.map(v => v.line2_utilization);
-    //   this.draw('drawLineChart_utilization', option);
-    // },
-    // // 娓叉煋鍦ㄥ埗閲忓浘琛�
-    // drawQuantityChart(data) {
-    //   const option = { ...OptionQuantity };
-    //   option.xAxis.data = data.map(v => v.date);
-    //   option.series[0].data = data.map(v => v.semi_finished);
-    //   option.series[1].data = data.map(v => v.location_7014);
-    //   option.series[2].data = data.map(v => v.location_7016);
-    //   this.draw('drawLineChart_quantity', option);
-    // },
-
+    fetchData() {
+      // 璇锋眰鏃ヤ骇閲�-鏈�
+      request.post('/deviceInteraction/primitiveTask/findDailyOutput', {
+        "dayCount": 30
+      }).then((res) => {
+        if (res.code == 200) {
+          const modeOptions = res.data;
+          const modeOptions2 = [res.data[res.data.length - 1]];
+          this.drawDay('drawLineChart_day11', this.OptionYear, modeOptions2);
+        } else {
+          console.error('璇锋眰鏃ヤ骇閲�-鏈堟暟鎹け璐�:', res);
+        }
+      }).catch((error) => {
+        console.error('璇锋眰鏁版嵁鏃跺彂鐢熼敊璇�:', error);
+      });
+    }
   }
-}
+};
 </script>
 
 <style scoped>
diff --git a/UI-Project/src/views/MechanicalReport/mechanicalReport.vue b/UI-Project/src/views/MechanicalReport/mechanicalReport.vue
new file mode 100644
index 0000000..0fe464b
--- /dev/null
+++ b/UI-Project/src/views/MechanicalReport/mechanicalReport.vue
@@ -0,0 +1,314 @@
+<script setup>
+import { ref, onMounted, reactive, onUnmounted } from 'vue'
+import { ElMessage } from 'element-plus'
+import request from '@/utils/request'
+
+const timer = ref(null)
+const xGrid = ref()
+const tableData = ref([])
+const loading = ref(false)
+
+// 绛涢�夋潯浠�
+const filterForm = ref({
+  startDate: null,
+  endDate: null,
+  taskType: '',
+  operationRecord: '',
+  lineType: ''
+})
+
+// 鑾峰彇鏈湀绗竴澶╁拰鏈�鍚庝竴澶�
+const getCurrentMonthRange = () => {
+  const now = new Date()
+  const firstDay = new Date(now.getFullYear(), now.getMonth(), 1)
+  const lastDay = new Date(now.getFullYear(), now.getMonth() + 1, 0)
+  return {
+    startDate: formatDate(firstDay),
+    endDate: formatDate(lastDay)
+  }
+}
+
+// 鏍煎紡鍖栨棩鏈熶负 yyyy-MM-dd HH:mm:ss
+const formatDate = (date, isEndDate = false) => {
+  const year = date.getFullYear()
+  const month = String(date.getMonth() + 1).padStart(2, '0')
+  const day = String(date.getDate()).padStart(2, '0')
+  const time = isEndDate ? '23:59:59' : '00:00:00'
+  return `${year}-${month}-${day} ${time}`
+}
+
+// 鏍煎紡鍖栬〃鏍间腑鐨勬椂闂存樉绀�
+const formatTableDateTime = ({ cellValue }) => {
+  if (!cellValue) return ''
+  try {
+    // 澶勭悊ISO鏍煎紡鐨勬椂闂村瓧绗︿覆
+    const date = new Date(cellValue)
+    if (isNaN(date.getTime())) return cellValue
+
+    const year = date.getFullYear()
+    const month = String(date.getMonth() + 1).padStart(2, '0')
+    const day = String(date.getDate()).padStart(2, '0')
+    const hours = String(date.getHours()).padStart(2, '0')
+    const minutes = String(date.getMinutes()).padStart(2, '0')
+    const seconds = String(date.getSeconds()).padStart(2, '0')
+    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
+  } catch (error) {
+    console.error('鏃ユ湡鏍煎紡鍖栭敊璇�:', error)
+    return cellValue
+  }
+}
+
+// 娣诲姞鏃ユ湡閫夋嫨鐨勯檺鍒堕�昏緫
+const validateDateRange = (startDate, endDate) => {
+  if (!startDate || !endDate) return true
+  
+  const start = new Date(startDate)
+  const end = new Date(endDate)
+  
+  // 璁$畻涓や釜鏃ユ湡涔嬮棿鐨勬绉掑樊
+  const diffTime = Math.abs(end - start)
+  // 杞崲涓哄ぉ鏁�
+  const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))
+  
+  // 妫�鏌ユ槸鍚﹁秴杩�31澶�
+  return diffDays <= 31
+}
+
+const gridOptions = reactive({
+  border: true,
+  height: '500px',
+  showOverflow: true,
+  loading: loading,
+  exportConfig: {},
+  columnConfig: {
+    resizable: true
+  },
+  toolbarConfig:
+  {
+    print: true,
+    export: true,
+    custom: true,
+    zoom: true
+  },
+  columns: [
+    { type: 'seq', width: 60, title: '搴忓彿' },
+    { field: 'glass_id', title: '鐜荤拑ID', width: 120 },
+    { field: 'batch_number', title: '鎵规鍙�', width: 120 },
+    { field: 'scan_id', title: '鎵弿ID', width: 120 },
+    { field: 'operation_record_time', title: '鎿嶄綔鏃堕棿', width: 180, formatter: formatTableDateTime },
+    { field: 'task_type', title: '绫诲瀷', width: 100 },
+    { field: 'operation_record', title: '璁惧鍚嶇О', width: 120 },
+    { field: 'operation_mode', title: '鎿嶄綔妯″紡', width: 100 },
+    { field: 'drawing_marking', title: '鍥剧焊鏍囪', width: 120 },
+    { field: 'state', title: '鐘舵��', width: 100 },
+    { field: 'work_state', title: '宸ヤ綔鐘舵��', width: 100 },
+    { field: 'glass_state', title: '鐜荤拑鐘舵��', width: 100 },
+    { field: 'line_configuration_id', title: '浜х嚎ID', width: 100 },
+    { field: 'is_marking', title: '鏄惁鏍囪', width: 100 },
+    { field: 'is_send', title: '鍙戦�佺姸鎬�', width: 100 },
+    { field: 'is_silk_screen', title: '鏄惁涓濆嵃', width: 100 },
+    { field: 'length', title: '闀垮害', width: 100 },
+    { field: 'width', title: '瀹藉害', width: 100 },
+    { field: 'thickness', title: '鍘氬害', width: 100 },
+    { field: 'program_id', title: '绋嬪簭ID', width: 120 },
+    { field: 'silk_screen_x', title: '涓濆嵃X', width: 100 },
+    { field: 'silk_screen_y', title: '涓濆嵃Y', width: 100 },
+    { field: 'task_quantity', title: '浠诲姟鏁伴噺', width: 100 },
+    { field: 'task_sequence', title: '浠诲姟搴忓垪', width: 100 }
+  ],
+  data: tableData
+})
+
+// 鑾峰彇鏁版嵁
+const fetchData = async () => {
+  loading.value = true
+  try {
+    if (!filterForm.value.startDate || !filterForm.value.endDate) {
+      ElMessage.warning('璇烽�夋嫨鏃堕棿鑼冨洿')
+      loading.value = false
+      return
+    }
+
+    // 楠岃瘉鏃ユ湡鑼冨洿
+    if (!validateDateRange(filterForm.value.startDate, filterForm.value.endDate)) {
+      ElMessage.warning('鏃堕棿鑼冨洿涓嶈兘瓒呰繃涓�涓湀')
+      loading.value = false
+      return
+    }
+
+    const startDate = formatDate(new Date(filterForm.value.startDate), false)  // 寮�濮嬫棩鏈熶娇鐢� 00:00:00
+    const endDate = formatDate(new Date(filterForm.value.endDate), true)      // 缁撴潫鏃ユ湡浣跨敤 23:59:59
+
+    const params = {
+      dayCount: 0,
+      startDate: startDate,
+      endDate: endDate,
+      taskType: filterForm.value.taskType || null,
+      operationRecord: filterForm.value.operationRecord || null,
+      lineType: filterForm.value.lineType || null
+    }
+
+    const response = await request({
+      url: '/deviceInteraction/taskingLog/mechanicalReport',
+      method: 'post',
+      params: params
+    })
+
+    if (response && response.code === 200) {
+      if (Array.isArray(response.data)) {
+        //console.log('璁剧疆琛ㄦ牸鏁版嵁:', response.data)
+        gridOptions.data = response.data
+      } else {
+        gridOptions.data = []
+        ElMessage.warning('鏆傛棤鏁版嵁')
+      }
+    } else {
+      gridOptions.data = []
+      ElMessage.error(response?.message || '鏌ヨ澶辫触')
+    }
+  } catch (error) {
+    console.error('鑾峰彇鏁版嵁澶辫触:', error)
+    ElMessage.error('鑾峰彇鏁版嵁澶辫触锛�' + (error.message || '鏈煡閿欒'))
+    gridOptions.data = []
+  } finally {
+    loading.value = false
+  }
+}
+
+// 閲嶇疆绛涢�夋潯浠�
+const resetFilter = () => {
+  const today = new Date()
+  const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1)
+
+  filterForm.value = {
+    startDate: formatDate(firstDayOfMonth),
+    endDate: formatDate(today),
+    taskType: '',
+    operationRecord: '',
+    lineType: ''
+  }
+  fetchData()
+}
+
+// 闄愬埗缁撴潫鏃ユ湡涓嶈兘瓒呰繃寮�濮嬫棩鏈熶竴涓湀
+const disabledEndDate = (time) => {
+  if (!filterForm.value.startDate) {
+    return false
+  }
+  const startDate = new Date(filterForm.value.startDate)
+  const oneMonthLater = new Date(startDate)
+  oneMonthLater.setMonth(oneMonthLater.getMonth() + 1)
+  return time.getTime() > oneMonthLater.getTime()
+}
+
+// 闄愬埗寮�濮嬫棩鏈熶笉鑳界缁撴潫鏃ユ湡瓒呰繃涓�涓湀
+const disabledStartDate = (time) => {
+  if (!filterForm.value.endDate) {
+    return false
+  }
+  const endDate = new Date(filterForm.value.endDate)
+  const oneMonthEarlier = new Date(endDate)
+  oneMonthEarlier.setMonth(oneMonthEarlier.getMonth() - 1)
+  return time.getTime() < oneMonthEarlier.getTime()
+}
+
+// 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
+onMounted(() => {
+  resetFilter()
+  // 姣忓垎閽熷埛鏂颁竴娆℃暟鎹�
+  timer.value = setInterval(fetchData, 60000)
+})
+
+// 椤甸潰鍗歌浇鏃舵竻闄ゅ畾鏃跺櫒
+onUnmounted(() => {
+  if (timer.value) {
+    clearInterval(timer.value)
+  }
+})
+
+
+</script>
+
+<template>
+  <div class="mechanical-report">
+    <!-- 绛涢�夋潯浠� -->
+    <el-card class="filter-card">
+      <el-form :inline="true" :model="filterForm" class="filter-form">
+        <el-form-item label="寮�濮嬫棩鏈�" required>
+          <el-date-picker v-model="filterForm.startDate" type="date" placeholder="閫夋嫨寮�濮嬫棩鏈�" format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD" :disabledDate="disabledStartDate" />
+        </el-form-item>
+        <el-form-item label="缁撴潫鏃ユ湡" required>
+          <el-date-picker v-model="filterForm.endDate" type="date" placeholder="閫夋嫨缁撴潫鏃ユ湡" format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD" :disabledDate="disabledEndDate" />
+        </el-form-item>
+        <el-form-item label="绫诲瀷">
+          <el-select v-model="filterForm.taskType" placeholder="璇烽�夋嫨绫诲瀷" style="width: 100px;" clearable>
+            <el-option label="鍏ㄩ儴" value="" />
+            <el-option label="瀹氬埗" value="瀹氬埗" />
+            <el-option label="鏍囧噯" value="鏍囧噯" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="璁惧鍚嶇О">
+          <el-select v-model="filterForm.operationRecord" placeholder="璇烽�夋嫨璁惧" style="width: 100px;" clearable>
+            <el-option label="鍏ㄩ儴" value="" />
+            <el-option label="涓婄墖" value="涓婄墖" />
+            <el-option label="纾ㄨ竟" value="纾ㄨ竟" />
+            <el-option label="缈荤墖" value="缈荤墖" />
+            <el-option label="鎵撴爣" value="鎵撴爣" />
+            <el-option label="涓濆嵃" value="涓濆嵃" />
+            <el-option label="鏃嬭浆" value="鏃嬭浆" />
+
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鐢熶骇绾�">
+          <el-select v-model="filterForm.lineType" placeholder="璇烽�夋嫨鐢熶骇绾�" style="width: 100px;" clearable>
+            <el-option label="鍏ㄩ儴" value="" />
+            <el-option label="涓�绾�" value="1" />
+            <el-option label="浜岀嚎" value="2" />
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="fetchData">鏌ヨ</el-button>
+          <el-button @click="resetFilter">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <!-- 鏁版嵁琛ㄦ牸 -->
+    <el-card class="table-card">
+      <vxe-grid v-bind="gridOptions"></vxe-grid>
+      <div class="total-info">
+        <el-tag type="info" style="font-size: 22px; padding: 8px 16px;">鎬绘暟閲�: {{ gridOptions.data.length }}</el-tag>
+      </div>
+    </el-card>
+    
+  </div>
+</template>
+
+<style scoped>
+.mechanical-report {
+  padding: 20px;
+}
+
+.filter-card {
+  margin-bottom: 20px;
+}
+
+.filter-form {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+}
+
+.table-card {
+  margin-top: 20px;
+}
+
+.total-info {
+  margin-top: 2px;
+  display: left;
+  padding-right: 20px;
+  font-weight: bold;
+}
+</style>
\ No newline at end of file

--
Gitblit v1.8.0