From 8f3a85044b6e4b56a8dd0b104ca023933f1f129c Mon Sep 17 00:00:00 2001
From: huang <1532065656@qq.com>
Date: 星期三, 03 十二月 2025 16:58:36 +0800
Subject: [PATCH] 统一卧转立扫码、卧转立、大车、大理片笼的定时器逻辑和步骤状态;添加设备拓扑图清除数据、联机状态切换按钮,

---
 mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java |  456 ++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 343 insertions(+), 113 deletions(-)

diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java b/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java
index 2156e46..627c88e 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java
@@ -148,7 +148,7 @@
             
             for (DeviceConfig device : devices) {
                 String deviceType = device.getDeviceType();
-                log.info("澶勭悊璁惧: deviceId={}, deviceType={}, deviceName={}, WORKSTATION_SCANNER甯搁噺={}, equals={}", 
+                log.debug("澶勭悊璁惧: deviceId={}, deviceType={}, deviceName={}, WORKSTATION_SCANNER甯搁噺={}, equals={}", 
                         device.getId(), deviceType, device.getDeviceName(), 
                         DeviceConfig.DeviceType.WORKSTATION_SCANNER,
                         DeviceConfig.DeviceType.WORKSTATION_SCANNER.equals(deviceType));
@@ -157,25 +157,20 @@
                         || (deviceType != null && (deviceType.contains("鎵爜") || deviceType.contains("SCANNER")));
                 boolean isLargeGlass = DeviceConfig.DeviceType.LARGE_GLASS.equals(deviceType);
                 boolean isTransfer = DeviceConfig.DeviceType.WORKSTATION_TRANSFER.equals(deviceType);
-                log.info("璁惧绫诲瀷鍒ゆ柇: deviceId={}, isLoadVehicle={}, isScanner={}, isLargeGlass={}, isTransfer={}", 
+                log.debug("璁惧绫诲瀷鍒ゆ柇: deviceId={}, isLoadVehicle={}, isScanner={}, isLargeGlass={}, isTransfer={}", 
                         device.getId(), isLoadVehicle, isScanner, isLargeGlass, isTransfer);
 
                 // 1. 鍗ц浆绔嬫壂鐮佽澶囷細鍚姩瀹氭椂鍣ㄦ壂鎻忥紙姣�10绉掑鐞嗕竴涓幓鐠僆D锛�
                 if (isScanner) {
-                    log.info("妫�娴嬪埌鎵爜璁惧锛屽噯澶囧惎鍔ㄥ畾鏃跺櫒: deviceId={}, deviceType={}, deviceName={}", 
+                    log.debug("妫�娴嬪埌鎵爜璁惧锛屽噯澶囧惎鍔ㄥ畾鏃跺櫒: deviceId={}, deviceType={}, deviceName={}", 
                             device.getId(), device.getDeviceType(), device.getDeviceName());
                     TaskStepDetail step = createStepRecord(task, device, currentOrder);
-                    // 璁剧疆姝ラ涓鸿繍琛岀姸鎬侊紝骞惰缃紑濮嬫椂闂�
-                    step.setStatus(TaskStepDetail.Status.RUNNING.name());
-                    step.setStartTime(new Date());
-                    taskStepDetailMapper.updateById(step);
-                    notificationService.notifyStepUpdate(task.getTaskId(), step);
                     
                     ScheduledFuture<?> scannerTask = startScannerTimer(task, step, device, context);
                     if (scannerTask != null) {
                         registerScheduledTask(task.getTaskId(), scannerTask);
                         stepSummaries.add(createStepSummary(device.getDeviceName(), true, "瀹氭椂鍣ㄥ凡鍚姩锛屾瘡10绉掓壂鎻忎竴娆�"));
-                        log.info("鎵爜璁惧瀹氭椂鍣ㄥ惎鍔ㄦ垚鍔�: deviceId={}, taskId={}", device.getId(), task.getTaskId());
+                        log.debug("鎵爜璁惧瀹氭椂鍣ㄥ惎鍔ㄦ垚鍔�: deviceId={}, taskId={}", device.getId(), task.getTaskId());
                     } else {
                         log.warn("鎵爜璁惧瀹氭椂鍣ㄥ惎鍔ㄥけ璐ワ紝glassIds鍙兘涓虹┖: deviceId={}, taskId={}, contextParams={}", 
                                 device.getId(), task.getTaskId(), context.getParameters());
@@ -190,20 +185,15 @@
 
                 // 2. 鍗ц浆绔嬭澶囷細鍚姩瀹氭椂鍣ㄥ畾鏈熸鏌ュ苟澶勭悊锛堜腑杞澶囷級
                 if (isTransfer) {
-                    log.info("妫�娴嬪埌鍗ц浆绔嬭澶囷紝鍑嗗鍚姩瀹氭椂鍣�: deviceId={}, deviceType={}, deviceName={}", 
+                    log.debug("妫�娴嬪埌鍗ц浆绔嬭澶囷紝鍑嗗鍚姩瀹氭椂鍣�: deviceId={}, deviceType={}, deviceName={}", 
                             device.getId(), device.getDeviceType(), device.getDeviceName());
                     TaskStepDetail step = createStepRecord(task, device, currentOrder);
-                    // 璁剧疆姝ラ涓鸿繍琛岀姸鎬侊紝骞惰缃紑濮嬫椂闂�
-                    step.setStatus(TaskStepDetail.Status.RUNNING.name());
-                    step.setStartTime(new Date());
-                    taskStepDetailMapper.updateById(step);
-                    notificationService.notifyStepUpdate(task.getTaskId(), step);
                     
                     ScheduledFuture<?> transferTask = startTransferTimer(task, step, device, context);
                     if (transferTask != null) {
                         registerScheduledTask(task.getTaskId(), transferTask);
                         stepSummaries.add(createStepSummary(device.getDeviceName(), true, "瀹氭椂鍣ㄥ凡鍚姩锛屽畾鏈熸鏌ュ苟澶勭悊鐜荤拑鎵规"));
-                        log.info("鍗ц浆绔嬭澶囧畾鏃跺櫒鍚姩鎴愬姛: deviceId={}, taskId={}", device.getId(), task.getTaskId());
+                        log.debug("鍗ц浆绔嬭澶囧畾鏃跺櫒鍚姩鎴愬姛: deviceId={}, taskId={}", device.getId(), task.getTaskId());
                     } else {
                         log.warn("鍗ц浆绔嬭澶囧畾鏃跺櫒鍚姩澶辫触: deviceId={}, taskId={}", device.getId(), task.getTaskId());
                         stepSummaries.add(createStepSummary(device.getDeviceName(), false, "鍚姩瀹氭椂鍣ㄥけ璐�"));
@@ -221,11 +211,6 @@
                     boolean isInboundVehicle = currentLoadVehicleIndex == 1; // 绗竴涓ぇ杞︽槸杩涚墖澶ц溅
                     
                     TaskStepDetail step = createStepRecord(task, device, currentOrder);
-                    // 璁剧疆姝ラ涓鸿繍琛岀姸鎬侊紝骞惰缃紑濮嬫椂闂�
-                    step.setStatus(TaskStepDetail.Status.RUNNING.name());
-                    step.setStartTime(new Date());
-                    taskStepDetailMapper.updateById(step);
-                    notificationService.notifyStepUpdate(task.getTaskId(), step);
                     
                     ScheduledFuture<?> vehicleTask;
                     if (isInboundVehicle) {
@@ -260,11 +245,6 @@
                 // 4. 澶х悊鐗囩璁惧锛氬惎鍔ㄥ畾鏃跺櫒閫昏緫澶勭悊锛堜笉娑夊強PLC浜や簰锛屽彧璐熻矗閫昏緫澶勭悊锛�
                 if (isLargeGlass) {
                     TaskStepDetail step = createStepRecord(task, device, currentOrder);
-                    // 璁剧疆姝ラ涓鸿繍琛岀姸鎬侊紝骞惰缃紑濮嬫椂闂�
-                    step.setStatus(TaskStepDetail.Status.RUNNING.name());
-                    step.setStartTime(new Date());
-                    taskStepDetailMapper.updateById(step);
-                    notificationService.notifyStepUpdate(task.getTaskId(), step);
                     
                     ScheduledFuture<?> largeGlassTask = startLargeGlassTimer(task, step, device, context);
                     if (largeGlassTask != null) {
@@ -296,7 +276,7 @@
             // 瀹氭椂鍣ㄤ細鍦ㄥ悗鍙版寔缁繍琛岋紝鐩村埌鎵嬪姩鍋滄鎴栬秴鏃�
             boolean hasScheduledTasks = !CollectionUtils.isEmpty(taskScheduledTasks.get(task.getTaskId()));
             if (hasScheduledTasks) {
-                log.info("浠诲姟宸插惎鍔ㄦ墍鏈夊畾鏃跺櫒锛屼繚鎸佽繍琛岀姸鎬�: taskId={}, scheduledTasksCount={}", 
+                log.debug("浠诲姟宸插惎鍔ㄦ墍鏈夊畾鏃跺櫒锛屼繚鎸佽繍琛岀姸鎬�: taskId={}, scheduledTasksCount={}", 
                         task.getTaskId(), taskScheduledTasks.get(task.getTaskId()).size());
                 // 浠诲姟淇濇寔 RUNNING 鐘舵�侊紝瀹氭椂鍣ㄥ湪鍚庡彴杩愯
                 // 涓嶆洿鏂颁换鍔$姸鎬佷负 COMPLETED锛岃浠诲姟鎸佺画杩愯
@@ -376,7 +356,7 @@
         try {
             TaskParameters params = context.getParameters();
             List<String> glassIds = params.getGlassIds();
-            log.info("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒鍒濆鍖�: taskId={}, deviceId={}, glassIds={}, glassIdsSize={}, isEmpty={}", 
+            log.debug("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒鍒濆鍖�: taskId={}, deviceId={}, glassIds={}, glassIdsSize={}, isEmpty={}", 
                     task.getTaskId(), device.getId(), glassIds, 
                     glassIds != null ? glassIds.size() : 0, 
                     CollectionUtils.isEmpty(glassIds));
@@ -391,19 +371,22 @@
             AtomicInteger successCount = new AtomicInteger(0);
             AtomicInteger failCount = new AtomicInteger(0);
             
-            final long CYCLE_INTERVAL_MS = 10_000; // 10绉掗棿闅�
+            // 浠庤澶囬厤缃腑鑾峰彇鎵爜闂撮殧锛岄粯璁�10绉�
+            Map<String, Object> logicParams = parseLogicParams(device);
+            Integer scanIntervalMs = getLogicParam(logicParams, "scanIntervalMs", 10_000);
             
-            log.info("鍚姩鍗ц浆绔嬫壂鐮佸畾鏃跺櫒: taskId={}, deviceId={}, glassCount={}, interval={}s, glassIds={}",
-                    task.getTaskId(), device.getId(), glassIds.size(), CYCLE_INTERVAL_MS / 1000, glassIds);
+            log.debug("鍚姩鍗ц浆绔嬫壂鐮佸畾鏃跺櫒: taskId={}, deviceId={}, glassCount={}, interval={}ms, glassIds={}",
+                    task.getTaskId(), device.getId(), glassIds.size(), scanIntervalMs, glassIds);
             
             // 鍚姩瀹氭椂浠诲姟
             ScheduledFuture<?> future = scheduledExecutor.scheduleWithFixedDelay(() -> {
                 try {
                     if (isTaskCancelled(context)) {
-                        log.info("浠诲姟宸插彇娑堬紝鍋滄鍗ц浆绔嬫壂鐮佸畾鏃跺櫒: taskId={}, deviceId={}", 
+                        log.debug("浠诲姟宸插彇娑堬紝鍋滄鍗ц浆绔嬫壂鐮佸畾鏃跺櫒: taskId={}, deviceId={}", 
                                 task.getTaskId(), device.getId());
                         return;
                     }
+                    ensureStepRunning(step, task.getTaskId());
                     // 妫�鏌ユ槸鍚﹂渶瑕佹殏鍋�
                     if (shouldPauseScanner(context)) {
                         log.debug("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒鏆傚仠: taskId={}, deviceId={}", task.getTaskId(), device.getId());
@@ -413,9 +396,25 @@
                     // 妫�鏌ユ槸鍚﹁繕鏈夊緟澶勭悊鐨勭幓鐠僆D
                     String glassId = glassIdQueue.poll();
                     if (glassId == null) {
-                        log.info("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒瀹屾垚: taskId={}, deviceId={}, processed={}/{}, success={}, fail={}",
+                        log.debug("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒瀹屾垚: taskId={}, deviceId={}, processed={}/{}, success={}, fail={}",
                                 task.getTaskId(), device.getId(), processedCount.get(), glassIds.size(),
                                 successCount.get(), failCount.get());
+                        
+                        // 娓呯┖plcRequest鍜宲lcGlassId锛堢‘淇漃LC鐘舵�佹竻鐞嗭級
+                        try {
+                            DeviceLogicHandler handler = handlerFactory.getHandler(device.getDeviceType());
+                            if (handler != null) {
+                                Map<String, Object> clearParams = new HashMap<>();
+                                clearParams.put("_taskContext", context);
+                                handler.execute(device, "clearPlc", clearParams);
+                                log.debug("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒瀹屾垚锛屽凡娓呯┖PLC璇锋眰瀛楁: taskId={}, deviceId={}", 
+                                        task.getTaskId(), device.getId());
+                            }
+                        } catch (Exception e) {
+                            log.warn("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒瀹屾垚鏃舵竻绌篜LC澶辫触: taskId={}, deviceId={}, error={}", 
+                                    task.getTaskId(), device.getId(), e.getMessage());
+                        }
+                        
                         // 鑻ヤ箣鍓嶆湭鍑虹幇澶辫触锛屽啀灏嗙姸鎬佺疆涓哄畬鎴�
                         boolean alreadyFailed = TaskStepDetail.Status.FAILED.name().equals(step.getStatus());
                         if (!alreadyFailed) {
@@ -426,6 +425,8 @@
                             }
                             taskStepDetailMapper.updateById(step);
                             notificationService.notifyStepUpdate(task.getTaskId(), step);
+                            // 鎵爜璁惧瀹屾垚鍚庡皾璇曡嚜鍔ㄦ敹灏炬暣涓换鍔�
+                            checkAndCompleteTaskIfDone(step.getTaskId());
                         }
                         deviceCoordinationService.syncDeviceStatus(device,
                                 DeviceCoordinationService.DeviceStatus.COMPLETED, context);
@@ -433,32 +434,31 @@
                     }
                     
                     int currentIndex = processedCount.incrementAndGet();
-                    log.info("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒澶勭悊绗瑊}/{}涓幓鐠�: taskId={}, deviceId={}, glassId={}",
+                    log.debug("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒澶勭悊绗瑊}/{}涓幓鐠�: taskId={}, deviceId={}, glassId={}",
                             currentIndex, glassIds.size(), task.getTaskId(), device.getId(), glassId);
                     
                     // 鎵ц鍗曟鎵弿
                     Map<String, Object> scanParams = new HashMap<>();
                     scanParams.put("glassId", glassId);
                     scanParams.put("_taskContext", context);
-                    log.info("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒鍑嗗鎵ц: taskId={}, deviceId={}, glassId={}, scanParams={}", 
+                    log.debug("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒鍑嗗鎵ц: taskId={}, deviceId={}, glassId={}, scanParams={}", 
                             task.getTaskId(), device.getId(), glassId, scanParams);
                     
                     DeviceLogicHandler handler = handlerFactory.getHandler(device.getDeviceType());
                     if (handler != null) {
-                        // 灏唋ogicParams鍚堝苟鍒皊canParams涓�
-                        Map<String, Object> logicParams = parseLogicParams(device);
+                        // 灏唋ogicParams鍚堝苟鍒皊canParams涓紙浣跨敤宸插畾涔夌殑logicParams鍙橀噺锛�
                         if (logicParams != null && !logicParams.isEmpty()) {
                             scanParams.put("_logicParams", logicParams);
                         }
-                        log.info("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒璋冪敤handler.execute: taskId={}, deviceId={}, glassId={}, operation=scanOnce, scanParamsKeys={}, scanParams={}", 
+                        log.debug("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒璋冪敤handler.execute: taskId={}, deviceId={}, glassId={}, operation=scanOnce, scanParamsKeys={}, scanParams={}", 
                                 task.getTaskId(), device.getId(), glassId, scanParams.keySet(), scanParams);
                         DevicePlcVO.OperationResult result = handler.execute(device, "scanOnce", scanParams);
-                        log.info("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒handler.execute杩斿洖: taskId={}, deviceId={}, glassId={}, success={}", 
+                        log.debug("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒handler.execute杩斿洖: taskId={}, deviceId={}, glassId={}, success={}", 
                                 task.getTaskId(), device.getId(), glassId, result.getSuccess());
                         
                         if (Boolean.TRUE.equals(result.getSuccess())) {
                             successCount.incrementAndGet();
-                            log.info("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒澶勭悊鎴愬姛: taskId={}, deviceId={}, glassId={}",
+                            log.debug("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒澶勭悊鎴愬姛: taskId={}, deviceId={}, glassId={}",
                                     task.getTaskId(), device.getId(), glassId);
                         } else {
                             failCount.incrementAndGet();
@@ -466,9 +466,10 @@
                                     task.getTaskId(), device.getId(), glassId, result.getMessage());
                         }
                         
-                        // 鏇存柊姝ラ鐘舵��
-                        updateStepStatus(step, result);
-                        // 閫氱煡姝ラ鏇存柊锛堣鍓嶇瀹炴椂鐪嬪埌姝ラ鐘舵�侊級
+                        // 鏇存柊姝ラ鐘舵�侊紙鏄剧ず杩涘害锛屼繚鎸丷UNNING鐘舵�佺洿鍒版墍鏈夌幓鐠冨鐞嗗畬鎴愶級
+                        updateStepStatusForScanner(step, result, currentIndex, glassIds.size(), 
+                                successCount.get(), failCount.get());
+                        // 閫氱煡姝ラ鏇存柊锛堣鍓嶇瀹炴椂鐪嬪埌姝ラ鐘舵�佸拰杩涘害锛�
                         notificationService.notifyStepUpdate(task.getTaskId(), step);
                         boolean opSuccess = Boolean.TRUE.equals(result.getSuccess());
                         updateTaskProgress(task, step.getStepOrder(), opSuccess);
@@ -481,7 +482,7 @@
                     log.error("鍗ц浆绔嬫壂鐮佸畾鏃跺櫒鎵ц寮傚父: taskId={}, deviceId={}", task.getTaskId(), device.getId(), e);
                     failCount.incrementAndGet();
                 }
-            }, 0, CYCLE_INTERVAL_MS, TimeUnit.MILLISECONDS);
+            }, 0, scanIntervalMs, TimeUnit.MILLISECONDS);
             
             deviceCoordinationService.syncDeviceStatus(device,
                     DeviceCoordinationService.DeviceStatus.RUNNING, context);
@@ -504,17 +505,18 @@
             Map<String, Object> logicParams = parseLogicParams(device);
             Integer monitorIntervalMs = getLogicParam(logicParams, "monitorIntervalMs", 5_000);
             
-            log.info("鍚姩鍗ц浆绔嬭澶囧畾鏃跺櫒: taskId={}, deviceId={}, interval={}ms",
+            log.debug("鍚姩鍗ц浆绔嬭澶囧畾鏃跺櫒: taskId={}, deviceId={}, interval={}ms",
                     task.getTaskId(), device.getId(), monitorIntervalMs);
             
             // 鍚姩瀹氭椂浠诲姟
             ScheduledFuture<?> future = scheduledExecutor.scheduleWithFixedDelay(() -> {
                 try {
                     if (isTaskCancelled(context)) {
-                        log.info("浠诲姟宸插彇娑堬紝鍋滄鍗ц浆绔嬭澶囧畾鏃跺櫒: taskId={}, deviceId={}",
+                        log.debug("浠诲姟宸插彇娑堬紝鍋滄鍗ц浆绔嬭澶囧畾鏃跺櫒: taskId={}, deviceId={}",
                                 task.getTaskId(), device.getId());
                         return;
                     }
+                    ensureStepRunning(step, task.getTaskId());
                     // 鏋勫缓鍙傛暟
                     Map<String, Object> params = new HashMap<>();
                     params.put("_taskContext", context);
@@ -536,10 +538,10 @@
                         if (opSuccess) {
                             String message = result.getMessage();
                             if (message != null && message.contains("鎵规宸插啓鍏LC")) {
-                                log.info("鍗ц浆绔嬭澶囧畾鏃跺櫒鎵ц鎴愬姛锛堝凡鍐欏叆PLC锛�: taskId={}, deviceId={}, message={}",
+                        log.debug("鍗ц浆绔嬭澶囧畾鏃跺櫒鎵ц鎴愬姛锛堝凡鍐欏叆PLC锛�: taskId={}, deviceId={}, message={}",
                                         task.getTaskId(), device.getId(), message);
                             } else {
-                                log.debug("鍗ц浆绔嬭澶囧畾鏃跺櫒绛夊緟涓�: taskId={}, deviceId={}, message={}",
+                        log.debug("鍗ц浆绔嬭澶囧畾鏃跺櫒绛夊緟涓�: taskId={}, deviceId={}, message={}",
                                         task.getTaskId(), device.getId(), message);
                             }
                         } else {
@@ -574,17 +576,18 @@
             final long MONITOR_INTERVAL_MS = 2_000; // 2绉掔洃鎺т竴娆�
             final AtomicInteger lastProcessedCount = new AtomicInteger(0);
             
-            log.info("鍚姩杩涚墖澶ц溅璁惧瀹氭椂鍣�: taskId={}, deviceId={}, interval={}s",
+            log.debug("鍚姩杩涚墖澶ц溅璁惧瀹氭椂鍣�: taskId={}, deviceId={}, interval={}s",
                     task.getTaskId(), device.getId(), MONITOR_INTERVAL_MS / 1000);
             
             // 鍚姩瀹氭椂浠诲姟
             ScheduledFuture<?> future = scheduledExecutor.scheduleWithFixedDelay(() -> {
                 try {
                     if (isTaskCancelled(context)) {
-                        log.info("浠诲姟宸插彇娑堬紝鍋滄杩涚墖澶ц溅瀹氭椂鍣�: taskId={}, deviceId={}",
+                        log.debug("浠诲姟宸插彇娑堬紝鍋滄杩涚墖澶ц溅瀹氭椂鍣�: taskId={}, deviceId={}",
                                 task.getTaskId(), device.getId());
                         return;
                     }
+                    ensureStepRunning(step, task.getTaskId());
                     // 妫�鏌ユ槸鍚︽湁鍗ц浆绔嬩富浣撳凡杈撳嚭銆佸噯澶囦笂澶ц溅鐨勭幓鐠冧俊鎭�
                     List<String> readyGlassIds = getTransferReadyGlassIds(context);
                     if (CollectionUtils.isEmpty(readyGlassIds)) {
@@ -600,7 +603,7 @@
                         return;
                     }
                     
-                    log.info("杩涚墖澶ц溅璁惧瀹氭椂鍣ㄦ娴嬪埌鍗ц浆绔嬭緭鍑虹殑鐜荤拑淇℃伅: taskId={}, deviceId={}, glassCount={}",
+                        log.debug("杩涚墖澶ц溅璁惧瀹氭椂鍣ㄦ娴嬪埌鍗ц浆绔嬭緭鍑虹殑鐜荤拑淇℃伅: taskId={}, deviceId={}, glassCount={}",
                             task.getTaskId(), device.getId(), currentCount);
                     
                     // 妫�鏌ュ閲�
@@ -615,10 +618,11 @@
                         if (logicParams != null && !logicParams.isEmpty()) {
                             checkParams.put("_logicParams", logicParams);
                         }
-                        DevicePlcVO.OperationResult result = handler.execute(device, "feedGlass", checkParams);
+                        // 绗竴姝ワ細鍐欏叆澶ц溅涓婃枡璇锋眰
+                        DevicePlcVO.OperationResult feedResult = handler.execute(device, "feedGlass", checkParams);
                         
-                        if (Boolean.TRUE.equals(result.getSuccess())) {
-                            log.info("杩涚墖澶ц溅璁惧瀹氭椂鍣ㄦ墽琛屾垚鍔�: taskId={}, deviceId={}, glassCount={}",
+                        if (Boolean.TRUE.equals(feedResult.getSuccess())) {
+                            log.debug("杩涚墖澶ц溅璁惧瀹氭椂鍣ㄦ墽琛屾垚鍔�: taskId={}, deviceId={}, glassCount={}",
                                     task.getTaskId(), device.getId(), readyGlassIds.size());
                             // 灏嗗凡瑁呰浇鐨勭幓鐠僆D淇濆瓨鍒板叡浜暟鎹腑锛堜緵澶х悊鐗囩浣跨敤锛�
                             setLoadedGlassIds(context, new ArrayList<>(readyGlassIds));
@@ -630,17 +634,36 @@
                         } else {
                             // 瑁呬笉涓嬶紝璁板綍瀹归噺涓嶈冻锛堟槸鍚﹂渶瑕佸奖鍝嶆壂鐮佺敱宸ヨ壓鍐嶅喅瀹氾級
                             log.warn("杩涚墖澶ц溅璁惧瀹氭椂鍣ㄥ閲忎笉瓒�: taskId={}, deviceId={}, message={}",
-                                    task.getTaskId(), device.getId(), result.getMessage());
+                                    task.getTaskId(), device.getId(), feedResult.getMessage());
                             lastProcessedCount.set(currentCount); // 璁板綍褰撳墠鏁伴噺锛岄伩鍏嶉噸澶嶆鏌�
                         }
                         
-                        // 鏇存柊姝ラ鐘舵��
-                        updateStepStatus(step, result);
-                        boolean opSuccess = Boolean.TRUE.equals(result.getSuccess());
-                        updateTaskProgress(task, step.getStepOrder(), opSuccess);
-                        if (!opSuccess) {
-                            deviceCoordinationService.syncDeviceStatus(device,
-                                    DeviceCoordinationService.DeviceStatus.FAILED, context);
+                        // 绗簩姝ワ細妫�鏌ES纭鐘舵�侊紙濡傛灉澶ц溅澶勭悊鍣ㄦ敮鎸佺殑璇濓級
+                        DevicePlcVO.OperationResult mesResult = null;
+                        try {
+                            mesResult = handler.execute(device, "checkMesConfirm", Collections.emptyMap());
+                        } catch (Exception e) {
+                            log.warn("杩涚墖澶ц溅璁惧妫�鏌ES纭鐘舵�佸紓甯�: taskId={}, deviceId={}, error={}",
+                                    task.getTaskId(), device.getId(), e.getMessage());
+                        }
+                        
+                        // 鏇存柊姝ラ鐘舵�侊紙澶ц溅璁惧淇濇寔RUNNING锛岀洿鍒癕ES纭瀹屾垚鎴栦换鍔″彇娑堬級
+                        if (mesResult != null) {
+                            updateStepStatusForVehicle(step, mesResult);
+                            boolean opSuccess = Boolean.TRUE.equals(mesResult.getSuccess());
+                            updateTaskProgress(task, step.getStepOrder(), opSuccess);
+                            if (!opSuccess) {
+                                deviceCoordinationService.syncDeviceStatus(device,
+                                        DeviceCoordinationService.DeviceStatus.FAILED, context);
+                            }
+                        } else {
+                            updateStepStatusForVehicle(step, feedResult);
+                            boolean opSuccess = Boolean.TRUE.equals(feedResult.getSuccess());
+                            updateTaskProgress(task, step.getStepOrder(), opSuccess);
+                            if (!opSuccess) {
+                                deviceCoordinationService.syncDeviceStatus(device,
+                                        DeviceCoordinationService.DeviceStatus.FAILED, context);
+                            }
                         }
                     }
                 } catch (Exception e) {
@@ -667,17 +690,18 @@
         try {
             final long MONITOR_INTERVAL_MS = 2_000; // 2绉掔洃鎺т竴娆�
             
-            log.info("鍚姩鍑虹墖澶ц溅璁惧瀹氭椂鍣�: taskId={}, deviceId={}, interval={}s",
+            log.debug("鍚姩鍑虹墖澶ц溅璁惧瀹氭椂鍣�: taskId={}, deviceId={}, interval={}s",
                     task.getTaskId(), device.getId(), MONITOR_INTERVAL_MS / 1000);
             
             // 鍚姩瀹氭椂浠诲姟
             ScheduledFuture<?> future = scheduledExecutor.scheduleWithFixedDelay(() -> {
                 try {
                     if (isTaskCancelled(context)) {
-                        log.info("浠诲姟宸插彇娑堬紝鍋滄鍑虹墖澶ц溅瀹氭椂鍣�: taskId={}, deviceId={}",
+                        log.debug("浠诲姟宸插彇娑堬紝鍋滄鍑虹墖澶ц溅瀹氭椂鍣�: taskId={}, deviceId={}",
                                 task.getTaskId(), device.getId());
                         return;
                     }
+                    ensureStepRunning(step, task.getTaskId());
                     // 妫�鏌ユ槸鍚︽湁宸插鐞嗙殑鐜荤拑淇℃伅锛堜粠澶х悊鐗囩鏉ョ殑锛�
                     List<String> processedGlassIds = getProcessedGlassIds(context);
                     if (CollectionUtils.isEmpty(processedGlassIds)) {
@@ -686,7 +710,7 @@
                         return;
                     }
                     
-                    log.info("鍑虹墖澶ц溅璁惧瀹氭椂鍣ㄦ娴嬪埌宸插鐞嗙殑鐜荤拑淇℃伅: taskId={}, deviceId={}, glassCount={}",
+                    log.debug("鍑虹墖澶ц溅璁惧瀹氭椂鍣ㄦ娴嬪埌宸插鐞嗙殑鐜荤拑淇℃伅: taskId={}, deviceId={}, glassCount={}",
                             task.getTaskId(), device.getId(), processedGlassIds.size());
                     
                     // 鎵ц鍑虹墖鎿嶄綔
@@ -701,25 +725,45 @@
                         if (logicParams != null && !logicParams.isEmpty()) {
                             checkParams.put("_logicParams", logicParams);
                         }
-                        DevicePlcVO.OperationResult result = handler.execute(device, "feedGlass", checkParams);
+                        // 绗竴姝ワ細鍐欏叆澶ц溅鍑虹墖璇锋眰
+                        DevicePlcVO.OperationResult feedResult = handler.execute(device, "feedGlass", checkParams);
                         
-                        if (Boolean.TRUE.equals(result.getSuccess())) {
-                            log.info("鍑虹墖澶ц溅璁惧瀹氭椂鍣ㄦ墽琛屾垚鍔�: taskId={}, deviceId={}, glassCount={}",
+                        if (Boolean.TRUE.equals(feedResult.getSuccess())) {
+                            log.debug("鍑虹墖澶ц溅璁惧瀹氭椂鍣ㄦ墽琛屾垚鍔�: taskId={}, deviceId={}, glassCount={}",
                                     task.getTaskId(), device.getId(), processedGlassIds.size());
                             // 娓呯┖宸插鐞嗙殑鐜荤拑ID鍒楄〃锛堝凡澶勭悊锛�
                             clearProcessedGlassIds(context);
                         } else {
                             log.debug("鍑虹墖澶ц溅璁惧瀹氭椂鍣ㄦ墽琛屽け璐�: taskId={}, deviceId={}, message={}",
-                                    task.getTaskId(), device.getId(), result.getMessage());
+                                    task.getTaskId(), device.getId(), feedResult.getMessage());
                         }
                         
-                        // 鏇存柊姝ラ鐘舵��
-                        updateStepStatus(step, result);
-                        boolean opSuccess = Boolean.TRUE.equals(result.getSuccess());
-                        updateTaskProgress(task, step.getStepOrder(), opSuccess);
-                        if (!opSuccess) {
-                            deviceCoordinationService.syncDeviceStatus(device,
-                                    DeviceCoordinationService.DeviceStatus.FAILED, context);
+                        // 绗簩姝ワ細妫�鏌ES纭鐘舵�侊紙濡傛灉澶ц溅澶勭悊鍣ㄦ敮鎸佺殑璇濓級
+                        DevicePlcVO.OperationResult mesResult = null;
+                        try {
+                            mesResult = handler.execute(device, "checkMesConfirm", Collections.emptyMap());
+                        } catch (Exception e) {
+                            log.warn("鍑虹墖澶ц溅璁惧妫�鏌ES纭鐘舵�佸紓甯�: taskId={}, deviceId={}, error={}",
+                                    task.getTaskId(), device.getId(), e.getMessage());
+                        }
+                        
+                        // 鏇存柊姝ラ鐘舵�侊紙澶ц溅璁惧淇濇寔RUNNING锛岀洿鍒癕ES纭瀹屾垚鎴栦换鍔″彇娑堬級
+                        if (mesResult != null) {
+                            updateStepStatusForVehicle(step, mesResult);
+                            boolean opSuccess = Boolean.TRUE.equals(mesResult.getSuccess());
+                            updateTaskProgress(task, step.getStepOrder(), opSuccess);
+                            if (!opSuccess) {
+                                deviceCoordinationService.syncDeviceStatus(device,
+                                        DeviceCoordinationService.DeviceStatus.FAILED, context);
+                            }
+                        } else {
+                            updateStepStatusForVehicle(step, feedResult);
+                            boolean opSuccess = Boolean.TRUE.equals(feedResult.getSuccess());
+                            updateTaskProgress(task, step.getStepOrder(), opSuccess);
+                            if (!opSuccess) {
+                                deviceCoordinationService.syncDeviceStatus(device,
+                                        DeviceCoordinationService.DeviceStatus.FAILED, context);
+                            }
                         }
                     }
                 } catch (Exception e) {
@@ -749,17 +793,18 @@
             Integer processTimeSeconds = getLogicParam(logicParams, "processTimeSeconds", 30);
             final long PROCESS_TIME_MS = processTimeSeconds * 1000;
             
-            log.info("鍚姩澶х悊鐗囩璁惧瀹氭椂鍣�: taskId={}, deviceId={}, processTime={}s",
+            log.debug("鍚姩澶х悊鐗囩璁惧瀹氭椂鍣�: taskId={}, deviceId={}, processTime={}s",
                     task.getTaskId(), device.getId(), processTimeSeconds);
             
             // 鍚姩瀹氭椂浠诲姟
             ScheduledFuture<?> future = scheduledExecutor.scheduleWithFixedDelay(() -> {
                 try {
                     if (isTaskCancelled(context)) {
-                        log.info("浠诲姟宸插彇娑堬紝鍋滄澶х悊鐗囩瀹氭椂鍣�: taskId={}, deviceId={}",
+                        log.debug("浠诲姟宸插彇娑堬紝鍋滄澶х悊鐗囩瀹氭椂鍣�: taskId={}, deviceId={}",
                                 task.getTaskId(), device.getId());
                         return;
                     }
+                    ensureStepRunning(step, task.getTaskId());
                     // 妫�鏌ユ槸鍚︽湁宸茶杞界殑鐜荤拑淇℃伅锛堜粠杩涚墖澶ц溅鏉ョ殑锛�
                     List<String> loadedGlassIds = getLoadedGlassIds(context);
                     if (CollectionUtils.isEmpty(loadedGlassIds)) {
@@ -773,7 +818,7 @@
                     if (processStartTime == null) {
                         // 绗竴娆℃娴嬪埌鐜荤拑锛岃褰曞紑濮嬪鐞嗘椂闂�
                         setProcessStartTime(context, System.currentTimeMillis());
-                        log.info("澶х悊鐗囩璁惧寮�濮嬪鐞�: taskId={}, deviceId={}, glassCount={}, processTime={}s",
+                        log.debug("澶х悊鐗囩璁惧寮�濮嬪鐞�: taskId={}, deviceId={}, glassCount={}, processTime={}s",
                                 task.getTaskId(), device.getId(), loadedGlassIds.size(), processTimeSeconds);
                         return;
                     }
@@ -787,7 +832,7 @@
                     }
                     
                     // 澶勭悊鏃堕棿宸插埌锛屽畬鎴愪换鍔℃眹鎶�
-                    log.info("澶х悊鐗囩璁惧澶勭悊瀹屾垚: taskId={}, deviceId={}, glassCount={}, processTime={}s",
+                    log.debug("澶х悊鐗囩璁惧澶勭悊瀹屾垚: taskId={}, deviceId={}, glassCount={}, processTime={}s",
                             task.getTaskId(), device.getId(), loadedGlassIds.size(), processTimeSeconds);
                     
                     // 灏嗗凡澶勭悊鐨勭幓鐠僆D杞Щ鍒板凡澶勭悊鍒楄〃锛堜緵鍑虹墖澶ц溅浣跨敤锛�
@@ -800,6 +845,8 @@
                     step.setErrorMessage(null);
                     step.setOutputData(toJson(Collections.singletonMap("glassIds", loadedGlassIds)));
                     taskStepDetailMapper.updateById(step);
+                    // 澶х悊鐗囩瀹屾垚鍚庡皾璇曡嚜鍔ㄦ敹灏炬暣涓换鍔�
+                    checkAndCompleteTaskIfDone(step.getTaskId());
                     
                 } catch (Exception e) {
                     log.error("澶х悊鐗囩璁惧瀹氭椂鍣ㄦ墽琛屽紓甯�: taskId={}, deviceId={}", task.getTaskId(), device.getId(), e);
@@ -1024,7 +1071,7 @@
                     future.cancel(false);
                 }
             }
-            log.info("宸插仠姝换鍔$殑鎵�鏈夊畾鏃跺櫒: taskId={}, count={}", taskId, futures.size());
+            log.debug("宸插仠姝换鍔$殑鎵�鏈夊畾鏃跺櫒: taskId={}, count={}", taskId, futures.size());
         }
         runningTaskContexts.remove(taskId);
     }
@@ -1040,7 +1087,7 @@
         long timeoutMs = timeoutMinutes * 60 * 1000;
         long deadline = System.currentTimeMillis() + timeoutMs;
         
-        log.info("绛夊緟瀹氭椂鍣ㄤ换鍔″畬鎴�: taskId={}, timeout={}鍒嗛挓", taskId, timeoutMinutes);
+        log.debug("绛夊緟瀹氭椂鍣ㄤ换鍔″畬鎴�: taskId={}, timeout={}鍒嗛挓", taskId, timeoutMinutes);
         
         while (System.currentTimeMillis() < deadline) {
             List<ScheduledFuture<?>> futures = taskScheduledTasks.get(taskId);
@@ -1069,7 +1116,54 @@
             }
         }
         
-        log.info("瀹氭椂鍣ㄤ换鍔$瓑寰呭畬鎴�: taskId={}", taskId);
+        log.debug("瀹氭椂鍣ㄤ换鍔$瓑寰呭畬鎴�: taskId={}", taskId);
+    }
+    
+    /**
+     * 褰撴煇涓楠ゅ彲鑳藉畬鎴愭椂锛屾鏌ヤ换鍔℃槸鍚︽墍鏈夋楠ら兘宸插畬鎴愶紝濡傛灉鏄垯鑷姩灏嗕换鍔℃爣璁颁负宸插畬鎴�
+     */
+    private void checkAndCompleteTaskIfDone(String taskId) {
+        if (taskId == null) {
+            return;
+        }
+        try {
+            MultiDeviceTask task = multiDeviceTaskMapper.selectOne(
+                    Wrappers.<MultiDeviceTask>lambdaQuery()
+                            .eq(MultiDeviceTask::getTaskId, taskId)
+            );
+            if (task == null) {
+                return;
+            }
+            // 浠呭湪浠诲姟浠嶄负RUNNING鏃舵墠灏濊瘯鑷姩鏀跺熬
+            if (!MultiDeviceTask.Status.RUNNING.name().equals(task.getStatus())) {
+                return;
+            }
+            
+            int totalSteps = task.getTotalSteps() != null ? task.getTotalSteps() : 0;
+            if (totalSteps <= 0) {
+                return;
+            }
+            
+            int completedSteps = countCompletedSteps(taskId);
+            if (completedSteps < totalSteps) {
+                return;
+            }
+            
+            // 鎵�鏈夋楠ら兘宸插畬鎴愶紝鏀跺熬浠诲姟
+            task.setStatus(MultiDeviceTask.Status.COMPLETED.name());
+            task.setEndTime(new Date());
+            multiDeviceTaskMapper.updateById(task);
+            
+            // 鍋滄鎵�鏈夊畾鏃跺櫒
+            stopScheduledTasks(taskId);
+            
+            // 閫氱煡浠诲姟瀹屾垚
+            notificationService.notifyTaskStatus(task);
+            
+            log.info("鎵�鏈夋楠ゅ凡瀹屾垚锛岃嚜鍔ㄥ皢浠诲姟鏍囪涓哄凡瀹屾垚: taskId={}, totalSteps={}", taskId, totalSteps);
+        } catch (Exception e) {
+            log.warn("妫�鏌ュ苟鑷姩瀹屾垚浠诲姟澶辫触: taskId={}", taskId, e);
+        }
     }
     
     /**
@@ -1105,6 +1199,135 @@
     }
     
     /**
+     * 纭繚姝ラ杩涘叆RUNNING鐘舵�侊紙浠呭湪绗竴娆$湡姝f墽琛屽墠璋冪敤锛�
+     */
+    private void ensureStepRunning(TaskStepDetail step, String taskId) {
+        if (step == null) {
+            return;
+        }
+        if (!TaskStepDetail.Status.RUNNING.name().equals(step.getStatus())) {
+            step.setStatus(TaskStepDetail.Status.RUNNING.name());
+            if (step.getStartTime() == null) {
+                step.setStartTime(new Date());
+            }
+            taskStepDetailMapper.updateById(step);
+            notificationService.notifyStepUpdate(taskId, step);
+        }
+    }
+    
+    /**
+     * 鏇存柊鎵爜璁惧姝ラ鐘舵�侊紙鏄剧ず杩涘害锛屼繚鎸丷UNNING鐘舵�佺洿鍒版墍鏈夌幓鐠冨鐞嗗畬鎴愶級
+     */
+    private void updateStepStatusForScanner(TaskStepDetail step, DevicePlcVO.OperationResult result,
+                                            int currentIndex, int totalCount,
+                                            int successCount, int failCount) {
+        if (step == null || result == null) {
+            return;
+        }
+        
+        boolean success = Boolean.TRUE.equals(result.getSuccess());
+        
+        // 淇濇寔RUNNING鐘舵�侊紝鐩村埌鎵�鏈夌幓鐠冨鐞嗗畬鎴愶紙鍦ㄥ畾鏃跺櫒瀹屾垚鏃跺啀璁剧疆涓篊OMPLETED锛�
+        step.setStatus(TaskStepDetail.Status.RUNNING.name());
+        
+        // 鏇存柊鏃堕棿鍜岃�楁椂锛屽墠绔彲浠ュ疄鏃剁湅鍒版墽琛岃�楁椂
+        Date now = new Date();
+        if (step.getStartTime() == null) {
+            step.setStartTime(now);
+        }
+        if (step.getStartTime() != null) {
+            step.setDurationMs(now.getTime() - step.getStartTime().getTime());
+        }
+        
+        // 鏇存柊杩涘害淇℃伅
+        String progressMessage = String.format("姝e湪澶勭悊 %d/%d (鎴愬姛:%d, 澶辫触:%d)", 
+                currentIndex, totalCount, successCount, failCount);
+        
+        if (success) {
+            // 鎴愬姛鏃舵樉绀鸿繘搴﹀拰鎴愬姛娑堟伅
+            String resultMessage = result.getMessage();
+            if (StringUtils.hasText(resultMessage)) {
+                step.setSuccessMessage(progressMessage + " - " + resultMessage);
+            } else {
+                step.setSuccessMessage(progressMessage);
+            }
+            step.setErrorMessage(null);
+        } else {
+            // 澶辫触鏃舵樉绀鸿繘搴﹀拰閿欒娑堟伅
+            String errorMessage = result.getMessage();
+            step.setErrorMessage(progressMessage + " - " + (StringUtils.hasText(errorMessage) ? errorMessage : "澶勭悊澶辫触"));
+            step.setSuccessMessage(null);
+        }
+        
+        step.setOutputData(toJson(result));
+        taskStepDetailMapper.updateById(step);
+    }
+    
+    /**
+     * 鏇存柊澶ц溅璁惧姝ラ鐘舵�侊紙淇濇寔RUNNING锛岀洿鍒版墜鍔ㄥ仠姝㈡垨浠诲姟鍙栨秷锛涘け璐ユ椂鏍囪涓篎AILED锛�
+     */
+    private void updateStepStatusForVehicle(TaskStepDetail step, DevicePlcVO.OperationResult result) {
+        if (step == null || result == null) {
+            return;
+        }
+        boolean success = Boolean.TRUE.equals(result.getSuccess());
+        boolean completed = false;
+        if (result.getData() != null && result.getData().get("completed") != null) {
+            Object flag = result.getData().get("completed");
+            if (flag instanceof Boolean) {
+                completed = (Boolean) flag;
+            } else {
+                completed = "true".equalsIgnoreCase(String.valueOf(flag));
+            }
+        }
+        Date now = new Date();
+
+        // 鍒濆鍖栧紑濮嬫椂闂�
+        if (step.getStartTime() == null) {
+            step.setStartTime(now);
+        }
+
+        if (success && !completed) {
+            // 鎴愬姛浣嗘湭瀹屾垚锛氫繚鎸丷UNNING鐘舵�侊紝浠呮洿鏂版彁绀轰俊鎭拰鑰楁椂
+            step.setStatus(TaskStepDetail.Status.RUNNING.name());
+            String message = result.getMessage();
+            step.setSuccessMessage(StringUtils.hasText(message) ? message : "澶ц溅璁惧杩愯涓�");
+            step.setErrorMessage(null);
+            if (step.getStartTime() != null) {
+                step.setDurationMs(now.getTime() - step.getStartTime().getTime());
+            }
+        } else if (success && completed) {
+            // 鎴愬姛涓擬ES宸茬‘璁ゅ畬鎴愶細鏍囪涓篊OMPLETED骞惰褰曠粨鏉熸椂闂�
+            step.setStatus(TaskStepDetail.Status.COMPLETED.name());
+            String message = result.getMessage();
+            step.setSuccessMessage(StringUtils.hasText(message) ? message : "澶ц溅璁惧浠诲姟宸插畬鎴�");
+            step.setErrorMessage(null);
+            if (step.getEndTime() == null) {
+                step.setEndTime(now);
+            }
+            if (step.getStartTime() != null && step.getEndTime() != null) {
+                step.setDurationMs(step.getEndTime().getTime() - step.getStartTime().getTime());
+            }
+            // 灏濊瘯鑷姩鏀跺熬鏁翠釜浠诲姟
+            checkAndCompleteTaskIfDone(step.getTaskId());
+        } else {
+            // 澶辫触锛氭爣璁颁负FAILED骞惰褰曠粨鏉熸椂闂�
+            step.setStatus(TaskStepDetail.Status.FAILED.name());
+            String message = result.getMessage();
+            step.setErrorMessage(message);
+            if (step.getEndTime() == null) {
+                step.setEndTime(now);
+            }
+            if (step.getStartTime() != null && step.getEndTime() != null) {
+                step.setDurationMs(step.getEndTime().getTime() - step.getStartTime().getTime());
+            }
+        }
+
+        step.setOutputData(toJson(result));
+        taskStepDetailMapper.updateById(step);
+    }
+    
+    /**
      * 鏇存柊鍗ц浆绔嬭澶囨楠ょ姸鎬侊紙鍖哄垎绛夊緟涓拰鐪熸瀹屾垚锛�
      */
     private void updateStepStatusForTransfer(TaskStepDetail step, DevicePlcVO.OperationResult result) {
@@ -1114,8 +1337,12 @@
         boolean success = Boolean.TRUE.equals(result.getSuccess());
         String message = result.getMessage();
         
-        // 鍒ゆ柇鏄惁鐪熸瀹屾垚锛堝彧鏈夊啓鍏LC鎵嶇畻瀹屾垚锛�
-        boolean isRealCompleted = success && message != null && message.contains("鎵规宸插啓鍏LC");
+        // 鍒ゆ柇鏄惁鐪熸瀹屾垚锛�
+        // 1. 鍐欏叆PLC鎴愬姛
+        // 2. 涓旂紦鍐插凡娓呯┖锛堣〃绀烘墍鏈夌幓鐠冨凡澶勭悊瀹岋紝鏃犳柊鐜荤拑锛�
+        boolean isRealCompleted = success && message != null 
+                && message.contains("鎵规宸插啓鍏LC") 
+                && message.contains("缂撳啿宸叉竻绌猴紝浠诲姟瀹屾垚");
         
         if (isRealCompleted) {
             // 鐪熸瀹屾垚锛氳缃负瀹屾垚鐘舵�侊紝骞惰缃粨鏉熸椂闂�
@@ -1123,6 +1350,23 @@
             step.setSuccessMessage(message);
             if (step.getEndTime() == null) {
                 step.setEndTime(new Date());
+            }
+            // 璁$畻鑰楁椂
+            if (step.getStartTime() != null && step.getEndTime() != null) {
+                step.setDurationMs(step.getEndTime().getTime() - step.getStartTime().getTime());
+            }
+            log.debug("鍗ц浆绔嬭澶囨楠ゅ凡瀹屾垚: stepId={}, durationMs={}", step.getId(), step.getDurationMs());
+            // 鍗ц浆绔嬩富浣撳畬鎴愬悗灏濊瘯鑷姩鏀跺熬鏁翠釜浠诲姟
+            checkAndCompleteTaskIfDone(step.getTaskId());
+        } else if (success && message != null && message.contains("鎵规宸插啓鍏LC")) {
+            // 鍐欏叆PLC鎴愬姛浣嗙紦鍐茶繕鏈夌幓鐠冿紙杞︽弧鎯呭喌锛夛紝缁х画杩愯
+            if (!TaskStepDetail.Status.RUNNING.name().equals(step.getStatus())) {
+                step.setStatus(TaskStepDetail.Status.RUNNING.name());
+            }
+            step.setSuccessMessage(message);
+            // 纭繚寮�濮嬫椂闂村凡璁剧疆
+            if (step.getStartTime() == null) {
+                step.setStartTime(new Date());
             }
         } else if (success) {
             // 绛夊緟涓細淇濇寔杩愯鐘舵�侊紝鍙洿鏂版秷鎭�
@@ -1140,6 +1384,10 @@
             step.setErrorMessage(message);
             if (step.getEndTime() == null) {
                 step.setEndTime(new Date());
+            }
+            // 璁$畻鑰楁椂
+            if (step.getStartTime() != null && step.getEndTime() != null) {
+                step.setDurationMs(step.getEndTime().getTime() - step.getStartTime().getTime());
             }
         }
         
@@ -1368,7 +1616,7 @@
     }
 
     /**
-     * 鍒嗘壒鎵ц澶ц溅璁惧鐜荤拑涓婃枡锛堝綋鐜荤拑ID鏁伴噺瓒呰繃6涓笖璁剧疆浜嗗崟鐗囬棿闅旀椂锛�
+     * 鍒嗘壒鎵ц澶ц溅璁惧鐜荤拑涓婃枡锛堝綋鐜荤拑ID鏁伴噺瓒呰繃6涓椂锛�
      */
     private StepResult executeLoadVehicleWithBatches(MultiDeviceTask task,
                                                       DeviceConfig device,
@@ -1376,13 +1624,12 @@
                                                       TaskExecutionContext context,
                                                       List<Map<String, Object>> stepSummaries) {
         List<String> allGlassIds = context.getParameters().getGlassIds();
-        Integer glassIntervalMs = context.getParameters().getGlassIntervalMs();
         int batchSize = 6; // 姣忔壒鏈�澶�6涓幓鐠僆D
         
         // 鍒嗘壒澶勭悊
         int totalBatches = (allGlassIds.size() + batchSize - 1) / batchSize;
-        log.info("澶ц溅璁惧鍒嗘壒涓婃枡: deviceId={}, totalGlassIds={}, batchSize={}, totalBatches={}, glassIntervalMs={}",
-                device.getId(), allGlassIds.size(), batchSize, totalBatches, glassIntervalMs);
+        log.debug("澶ц溅璁惧鍒嗘壒涓婃枡: deviceId={}, totalGlassIds={}, batchSize={}, totalBatches={}",
+                device.getId(), allGlassIds.size(), batchSize, totalBatches);
         
         for (int batchIndex = 0; batchIndex < totalBatches; batchIndex++) {
             int startIndex = batchIndex * batchSize;
@@ -1392,7 +1639,6 @@
             // 鍒涘缓涓存椂鍙傛暟锛屽彧鍖呭惈褰撳墠鎵规鐨勭幓鐠僆D
             TaskParameters batchParams = new TaskParameters();
             batchParams.setGlassIds(new ArrayList<>(batchGlassIds));
-            batchParams.setGlassIntervalMs(glassIntervalMs);
             batchParams.setPositionCode(context.getParameters().getPositionCode());
             batchParams.setPositionValue(context.getParameters().getPositionValue());
             
@@ -1413,20 +1659,8 @@
                 return stepResult;
             }
             
-            log.info("澶ц溅璁惧鍒嗘壒涓婃枡鎴愬姛: deviceId={}, batchIndex={}/{}, glassIds={}",
+            log.debug("澶ц溅璁惧鍒嗘壒涓婃枡鎴愬姛: deviceId={}, batchIndex={}/{}, glassIds={}",
                     device.getId(), batchIndex + 1, totalBatches, batchGlassIds);
-            
-            // 濡傛灉涓嶆槸鏈�鍚庝竴鎵癸紝绛夊緟闂撮殧锛堟ā鎷熺幓鐠冩瘡鐗囪繍鍔ㄧ殑鏃堕棿锛�
-            // 杩欎釜绛夊緟璁╁ぇ杞︽湁鏃堕棿澶勭悊褰撳墠鎵规鐨勭幓鐠冿紝鐒跺悗鍐嶄紶閫掍笅涓�鎵�
-            if (batchIndex < totalBatches - 1 && glassIntervalMs != null && glassIntervalMs > 0) {
-                try {
-                    log.info("绛夊緟鍗曠墖闂撮殧锛堟ā鎷熺幓鐠冭繍鍔ㄦ椂闂达級: glassIntervalMs={}ms, 澶ц溅鍙湪姝ゆ湡闂寸户缁鐜荤拑", glassIntervalMs);
-                    Thread.sleep(glassIntervalMs);
-                } catch (InterruptedException e) {
-                    Thread.currentThread().interrupt();
-                    return StepResult.failure(device.getDeviceName(), "绛夊緟鍗曠墖闂撮殧鏃惰涓柇");
-                }
-            }
         }
         
         // 鏇存柊涓婁笅鏂囦腑鐨勫凡鍔犺浇鐜荤拑ID
@@ -1487,7 +1721,7 @@
         Map<String, Object> params = buildOperationParams(device, context);
         // 灏哻ontext寮曠敤鏀惧叆params锛屼緵璁惧澶勭悊鍣ㄤ娇鐢紙鐢ㄤ簬璁惧鍗忚皟锛�
         params.put("_taskContext", context);
-        log.info("executeStepWithRetry鏋勫缓鍙傛暟: deviceId={}, deviceType={}, operation={}, paramsKeys={}, params={}", 
+        log.debug("executeStepWithRetry鏋勫缓鍙傛暟: deviceId={}, deviceType={}, operation={}, paramsKeys={}, params={}", 
                 device.getId(), device.getDeviceType(), determineOperation(device, params), params.keySet(), params);
         step.setInputData(toJson(params));
         taskStepDetailMapper.updateById(step);
@@ -1503,7 +1737,7 @@
                 if (retryAttempt > 0) {
                     // 閲嶈瘯鍓嶇瓑寰�
                     long waitTime = retryPolicy.calculateRetryInterval(retryAttempt);
-                    log.info("姝ラ鎵ц閲嶈瘯: deviceId={}, operation={}, retryAttempt={}/{}, waitTime={}ms", 
+                    log.debug("姝ラ鎵ц閲嶈瘯: deviceId={}, operation={}, retryAttempt={}/{}, waitTime={}ms", 
                         device.getId(), operation, retryAttempt, retryPolicy.getMaxRetryCount(), waitTime);
                     Thread.sleep(waitTime);
                     
@@ -1697,7 +1931,7 @@
             try {
                 if (retryAttempt > 0) {
                     long waitTime = retryPolicy.calculateRetryInterval(retryAttempt);
-                    log.info("浜や簰姝ラ鎵ц閲嶈瘯: deviceId={}, retryAttempt={}/{}, waitTime={}ms", 
+                    log.debug("浜や簰姝ラ鎵ц閲嶈瘯: deviceId={}, retryAttempt={}/{}, waitTime={}ms", 
                         device.getId(), retryAttempt, retryPolicy.getMaxRetryCount(), waitTime);
                     Thread.sleep(waitTime);
                     
@@ -1914,10 +2148,6 @@
                 if (taskParams.getPositionValue() != null) {
                     params.put("positionValue", taskParams.getPositionValue());
                 }
-                // 浼犻�掑崟鐗囬棿闅旈厤缃紝濡傛灉浠诲姟鍙傛暟涓湁璁剧疆锛屼紭鍏堜娇鐢ㄤ换鍔″弬鏁扮殑锛屽惁鍒欎娇鐢ㄨ澶囬厤缃殑
-                if (taskParams.getGlassIntervalMs() != null) {
-                    params.put("glassIntervalMs", taskParams.getGlassIntervalMs());
-                }
                 params.put("triggerRequest", true);
                 break;
             case DeviceConfig.DeviceType.LARGE_GLASS:
@@ -1935,13 +2165,13 @@
             case DeviceConfig.DeviceType.WORKSTATION_SCANNER:
                 // 鍗ц浆绔嬫壂鐮佽澶囷細浠庝换鍔″弬鏁颁腑鑾峰彇鐜荤拑ID鍒楄〃锛屽彇绗竴涓綔涓哄綋鍓嶈娴嬭瘯鐨勭幓鐠僆D
                 // 娉ㄦ剰锛氭壂鐮佽澶囬�氬父閫氳繃瀹氭椂鍣ㄦ墽琛岋紝浣嗗鏋滈�氳繃executeStep鎵ц锛屼篃闇�瑕佷紶閫抔lassId
-                log.info("buildOperationParams澶勭悊鎵爜璁惧: deviceId={}, taskParams.glassIds={}, isEmpty={}", 
+                log.debug("buildOperationParams澶勭悊鎵爜璁惧: deviceId={}, taskParams.glassIds={}, isEmpty={}", 
                         device.getId(), taskParams.getGlassIds(), 
                         CollectionUtils.isEmpty(taskParams.getGlassIds()));
                 if (!CollectionUtils.isEmpty(taskParams.getGlassIds())) {
                     params.put("glassId", taskParams.getGlassIds().get(0));
                     params.put("glassIds", new ArrayList<>(taskParams.getGlassIds()));
-                    log.info("buildOperationParams涓烘壂鐮佽澶囨坊鍔爂lassId: deviceId={}, glassId={}, glassIdsSize={}", 
+                    log.debug("buildOperationParams涓烘壂鐮佽澶囨坊鍔爂lassId: deviceId={}, glassId={}, glassIdsSize={}", 
                             device.getId(), taskParams.getGlassIds().get(0), taskParams.getGlassIds().size());
                 } else {
                     log.warn("buildOperationParams鎵爜璁惧glassIds涓虹┖: deviceId={}, taskParams.glassIds={}, taskParams={}", 
@@ -2017,7 +2247,7 @@
         if (!CollectionUtils.isEmpty(scannerGlassIds)) {
             context.getParameters().setGlassIds(new ArrayList<>(scannerGlassIds));
             context.setLoadedGlassIds(new ArrayList<>(scannerGlassIds));
-            log.info("鍗ц浆绔嬫壂鐮佽幏鍙栧埌鐜荤拑ID: {}", scannerGlassIds);
+            log.debug("鍗ц浆绔嬫壂鐮佽幏鍙栧埌鐜荤拑ID: {}", scannerGlassIds);
         } else {
             log.warn("鍗ц浆绔嬫壂鐮佹湭鑾峰彇鍒扮幓鐠僆D锛屽悗缁澶囧彲鑳芥棤娉曟墽琛�");
         }

--
Gitblit v1.8.0