From 9611dc686299be640ce5e5f5990c747765161ec7 Mon Sep 17 00:00:00 2001
From: chen.llin <1442464845@qq.comm>
Date: 星期三, 21 一月 2026 10:59:38 +0800
Subject: [PATCH] agv逻辑调整2

---
 src/main/java/com/zy/asrs/task/AgvScheduler.java |  513 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 506 insertions(+), 7 deletions(-)

diff --git a/src/main/java/com/zy/asrs/task/AgvScheduler.java b/src/main/java/com/zy/asrs/task/AgvScheduler.java
index 1205b62..e04f9ef 100644
--- a/src/main/java/com/zy/asrs/task/AgvScheduler.java
+++ b/src/main/java/com/zy/asrs/task/AgvScheduler.java
@@ -1,21 +1,28 @@
 package com.zy.asrs.task;
 
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.mapper.Wrapper;
 import com.core.common.Cools;
 import com.zy.asrs.entity.Task;
 import com.zy.asrs.entity.WrkMast;
 import com.zy.asrs.mapper.WrkMastMapper;
+import com.zy.asrs.entity.WrkMastLog;
 import com.zy.asrs.service.TaskService;
+import com.zy.asrs.service.WrkMastLogService;
+import com.zy.asrs.service.WrkMastService;
 import com.zy.asrs.task.handler.AgvHandler;
+import com.zy.common.properties.SchedulerProperties;
 import com.zy.system.entity.Config;
 import com.zy.system.service.ConfigService;
-import org.springframework.scheduling.TaskScheduler;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -23,6 +30,7 @@
  * @description AGV浜や簰鐩稿叧瀹氭椂浠诲姟
  * @createDate 2025/11/18 14:18
  */
+@Slf4j
 @Component
 public class AgvScheduler {
 
@@ -38,17 +46,180 @@
     @Resource
     private WrkMastMapper wrkMastMapper;
 
+    @Resource
+    private WrkMastService wrkMastService;
+
+    @Resource
+    private WrkMastLogService wrkMastLogService;
+
+    @Resource
+    private SchedulerProperties schedulerProperties;
+
     /**
-     * 鍛煎彨agv鎼繍
+     * 璁板綍涓婃澶勭悊鐨勪换鍔D锛岀敤浜庤疆璇㈠鐞�
+     * 纭繚姣忔澶勭悊涓嶅悓鐨勪换鍔★紝閬垮厤涓�鐩村鐞嗗悓涓�涓换鍔�
+     */
+    private Long lastProcessedTaskId = null;
+    
+    /**
+     * 璁板綍涓婃鍒嗛厤绔欑偣鐨勪换鍔D锛岀敤浜庤疆璇㈠鐞�
+     */
+    private Long lastAllocatedTaskId = null;
+
+    /**
+     * 鍒嗛厤绔欑偣瀹氭椂浠诲姟
+     * 鏌ヨ鐘舵��7锛堝緟鍛煎彨AGV锛変絾娌℃湁鍒嗛厤绔欑偣鐨勪换鍔★紝涓哄叾鍒嗛厤鍙敤绔欑偣
+     * 鍙礋璐e垎閰嶇珯鐐癸紝涓嶅懠鍙獳GV
+     * 姣忔鍙鐞嗕竴涓换鍔★紝閬垮厤楂樺苟鍙戞墽琛�
+     */
+    @Scheduled(cron = "0/5 * * * * ? ")
+    private void allocateSite() {
+        if (!schedulerProperties.isEnabled()) {
+            log.debug("瀹氭椂浠诲姟allocateSite锛氳皟搴﹀櫒鏈惎鐢紝璺宠繃鎵ц");
+            return;
+        }
+        
+        // 鏋勫缓鏌ヨ鏉′欢锛氭煡璇㈡墍鏈夊緟鍛煎彨AGV浣嗘病鏈夊垎閰嶇珯鐐圭殑浠诲姟
+        EntityWrapper<Task> wrapper = new EntityWrapper<Task>();
+        wrapper.eq("wrk_sts", 7); // 寰呭懠鍙獳GV鐘舵��
+        wrapper.eq("task_type", "agv"); // AGV浠诲姟绫诲瀷
+        wrapper.andNew("(is_deleted = 0)");
+        wrapper.andNew()
+            .isNull("sta_no")
+            .or()
+            .eq("sta_no", "")
+            .or()
+            .eq("sta_no", "0");
+        wrapper.orderBy("id", true); // 鎸塱d鍗囧簭鎺掑簭
+        
+        // 濡傛灉涓婃澶勭悊杩囦换鍔★紝浠庝笅涓�涓换鍔″紑濮嬫煡璇紙杞锛�
+        if (lastAllocatedTaskId != null) {
+            wrapper.gt("id", lastAllocatedTaskId);
+        }
+        
+        // 鏌ヨ寰呭垎閰嶇珯鐐圭殑浠诲姟锛屾瘡娆″彧鏌ヨ涓�涓�
+        List<Task> taskList = taskService.selectList(
+            wrapper.last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")
+        );
+        
+        // 濡傛灉浠庝笂娆′换鍔′箣鍚庢病鏈夋壘鍒颁换鍔★紝浠庡ご寮�濮嬫煡璇紙瀹炵幇寰幆杞锛�
+        if (taskList.isEmpty() && lastAllocatedTaskId != null) {
+            lastAllocatedTaskId = null; // 閲嶇疆锛屼粠澶村紑濮�
+            taskList = taskService.selectList(
+                new EntityWrapper<Task>()
+                    .eq("wrk_sts", 7)
+                    .eq("task_type", "agv")
+                    .andNew("(is_deleted = 0)")
+                    .andNew()
+                    .isNull("sta_no")
+                    .or()
+                    .eq("sta_no", "")
+                    .or()
+                    .eq("sta_no", "0")
+                    .orderBy("id", true)
+                    .last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")
+            );
+        }
+        
+        if(taskList.isEmpty()) {
+            log.debug("瀹氭椂浠诲姟allocateSite锛氭病鏈夊緟鍒嗛厤绔欑偣鐨勪换鍔★紙wrk_sts=7锛宼ask_type=agv锛宻ta_no涓虹┖锛�");
+            return;
+        }
+        
+        // 璋冪敤鍒嗛厤绔欑偣閫昏緫
+        Task task = taskList.get(0);
+        String displayTaskId = (task.getWrkNo() != null) ? String.valueOf(task.getWrkNo()) : String.valueOf(task.getId());
+        log.info("瀹氭椂浠诲姟allocateSite锛氬紑濮嬩负浠诲姟ID锛歿}鍒嗛厤绔欑偣锛坵rk_no={}锛宨oType={}锛�", 
+            displayTaskId, task.getWrkNo(), task.getIoType());
+        
+        String errorMsg = agvHandler.allocateSiteForTask(task);
+        
+        // 妫�鏌ユ槸鍚︽垚鍔熷垎閰嶄簡绔欑偣
+        String staNo = task.getStaNo();
+        if (errorMsg == null && staNo != null && !staNo.isEmpty() && !staNo.equals("0")) {
+            // 鍒嗛厤绔欑偣鎴愬姛
+            lastAllocatedTaskId = task.getId();
+            log.info("瀹氭椂浠诲姟allocateSite锛氫换鍔D锛歿}鎴愬姛鍒嗛厤绔欑偣锛歿}锛屾洿鏂發astAllocatedTaskId涓簕}", 
+                displayTaskId, staNo, lastAllocatedTaskId);
+        } else {
+            // 鏃犳硶鍒嗛厤绔欑偣锛屼笉鏇存柊lastAllocatedTaskId锛屼笅娆′細閲嶆柊灏濊瘯
+            log.info("瀹氭椂浠诲姟allocateSite锛氫换鍔D锛歿}鏃犳硶鍒嗛厤绔欑偣锛歿}锛屼笉鏇存柊lastAllocatedTaskId锛堝綋鍓嶏細{}锛夛紝涓嬫灏嗛噸鏂板皾璇�", 
+                displayTaskId, errorMsg != null ? errorMsg : "鎵�鏈夌珯鐐归兘琚崰鐢�", lastAllocatedTaskId);
+        }
+    }
+
+    /**
+     * 鍛煎彨AGV瀹氭椂浠诲姟
+     * 鏌ヨ鐘舵��7锛堝緟鍛煎彨AGV锛変笖宸插垎閰嶇珯鐐圭殑浠诲姟锛屽懠鍙獳GV
+     * 鍛煎彨鎴愬姛鍚庯紝鐘舵�佷粠7锛堝緟鍛煎彨AGV锛夊彉涓�8锛堟鍦ㄦ惉杩愶級
+     * 姣忔鍙鐞嗕竴涓换鍔★紝閬垮厤楂樺苟鍙戞墽琛�
+     * 浣跨敤杞鏈哄埗锛岀‘淇濅笉浼氫竴鐩村鐞嗗悓涓�涓换鍔�
      */
     @Scheduled(cron = "0/5 * * * * ? ")
     private void callAgv() {
-        // 鏌ヨ寰呭懠鍙玜gv浠诲姟
-        List<Task> taskList = taskService.selectList(new EntityWrapper<Task>().eq("wrk_sts", 7));
-        if(taskList.isEmpty()) {
+        if (!schedulerProperties.isEnabled()) {
+            log.debug("瀹氭椂浠诲姟callAgv锛氳皟搴﹀櫒鏈惎鐢紝璺宠繃鎵ц");
             return;
         }
-        agvHandler.callAgv(taskList);
+        
+        // 鏋勫缓鏌ヨ鏉′欢锛氭煡璇㈢姸鎬�7锛堝緟鍛煎彨AGV锛変笖宸插垎閰嶇珯鐐圭殑浠诲姟
+        EntityWrapper<Task> wrapper = new EntityWrapper<Task>();
+        wrapper.eq("wrk_sts", 7); // 寰呭懠鍙獳GV鐘舵��
+        wrapper.eq("task_type", "agv"); // AGV浠诲姟绫诲瀷
+        wrapper.andNew("(is_deleted = 0)");
+        wrapper.isNotNull("sta_no"); // 蹇呴』鏈夌珯鐐瑰垎閰�
+        wrapper.ne("sta_no", ""); // 绔欑偣涓嶈兘涓虹┖瀛楃涓�
+        wrapper.ne("sta_no", "0"); // 绔欑偣涓嶈兘涓�0
+        wrapper.orderBy("id", true); // 鎸塱d鍗囧簭鎺掑簭
+        
+        // 濡傛灉涓婃澶勭悊杩囦换鍔★紝浠庝笅涓�涓换鍔″紑濮嬫煡璇紙杞锛�
+        if (lastProcessedTaskId != null) {
+            wrapper.gt("id", lastProcessedTaskId);
+        }
+        
+        // 鏌ヨ寰呭懠鍙玜gv浠诲姟锛屾瘡娆″彧鏌ヨ涓�涓�
+        List<Task> taskList = taskService.selectList(
+            wrapper.last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")
+        );
+        
+        // 濡傛灉浠庝笂娆′换鍔′箣鍚庢病鏈夋壘鍒颁换鍔★紝浠庡ご寮�濮嬫煡璇紙瀹炵幇寰幆杞锛�
+        if (taskList.isEmpty() && lastProcessedTaskId != null) {
+            lastProcessedTaskId = null; // 閲嶇疆锛屼粠澶村紑濮�
+            taskList = taskService.selectList(
+                new EntityWrapper<Task>()
+                    .eq("wrk_sts", 7)
+                    .eq("task_type", "agv")
+                    .andNew("(is_deleted = 0)")
+                    .isNotNull("sta_no")
+                    .ne("sta_no", "")
+                    .ne("sta_no", "0")
+                    .orderBy("id", true)
+                    .last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")
+            );
+        }
+        
+        if(taskList.isEmpty()) {
+            log.debug("瀹氭椂浠诲姟callAgv锛氭病鏈夊緟鍛煎彨AGV鐨勪换鍔★紙wrk_sts=7锛宼ask_type=agv锛宻ta_no涓嶄负绌猴級");
+            return;
+        }
+        
+        // 璋冪敤澶勭悊閫昏緫锛氬懠鍙獳GV锛屾垚鍔熷悗鐘舵�佷粠7鍙樹负8
+        Task task = taskList.get(0);
+        String displayTaskId = (task.getWrkNo() != null) ? String.valueOf(task.getWrkNo()) : String.valueOf(task.getId());
+        log.info("瀹氭椂浠诲姟callAgv锛氬紑濮嬪鐞嗕换鍔D锛歿}锛坵rk_no={}锛宨oType={}锛宻ta_no={}锛�", 
+            displayTaskId, task.getWrkNo(), task.getIoType(), task.getStaNo());
+        boolean processed = agvHandler.callAgv(taskList);
+        
+        // 鍙湁褰撲换鍔℃垚鍔熷鐞嗭紙鎴愬姛鍛煎彨AGV锛岀姸鎬佷粠7鍙樹负8锛夋椂锛屾墠鏇存柊lastProcessedTaskId
+        // 濡傛灉浠诲姟琚烦杩囷紙绔欑偣琚崰鐢ㄧ瓑锛夛紝涓嶆洿鏂發astProcessedTaskId锛屼笅娆′細閲嶆柊灏濊瘯
+        if (processed) {
+            lastProcessedTaskId = task.getId();
+            log.info("瀹氭椂浠诲姟callAgv锛氫换鍔D锛歿}鎴愬姛鍛煎彨AGV锛岀姸鎬佸凡浠�7鍙樹负8锛屾洿鏂發astProcessedTaskId涓簕}锛屼笅娆″皢澶勭悊涓嬩竴涓换鍔�", 
+                displayTaskId, lastProcessedTaskId);
+        } else {
+            log.info("瀹氭椂浠诲姟callAgv锛氫换鍔D锛歿}琚烦杩囷紝涓嶆洿鏂發astProcessedTaskId锛堝綋鍓嶏細{}锛夛紝涓嬫灏嗛噸鏂板皾璇曞鐞嗘浠诲姟", 
+                displayTaskId, lastProcessedTaskId);
+        }
     }
 
     /**
@@ -56,6 +227,9 @@
      */
     @Scheduled(cron = "0/3 * * * * ? ")
     private void createAgvOutTasks() {
+        if (!schedulerProperties.isEnabled()) {
+            return;
+        }
 
         // 鑾峰彇鍛煎彨agv閰嶇疆
         List<Config> configs = configService.selectList(new EntityWrapper<Config>().in("code", "eastCallAgvControl", "westCallAgvControl").eq("status", 1));
@@ -86,12 +260,337 @@
      */
     @Scheduled(cron = "0/10 * * * * ? ")
     private void moveTaskToHistory() {
-        List<Task> taskList = taskService.selectList(new EntityWrapper<Task>().eq("wrk_sts", 9));
+        if (!schedulerProperties.isEnabled()) {
+            return;
+        }
+        List<Task> taskList = taskService.selectList(new EntityWrapper<Task>().eq("wrk_sts", 9).andNew("(is_deleted = 0)"));
         if(taskList.isEmpty()) {
             return;
         }
         agvHandler.moveTaskToHistory(taskList);
     }
 
+    /**
+     * 妫�鏌ュ叆搴撴垚鍔熺殑浠诲姟锛屽畬缁撳搴旂殑AGV鍛煎彨鍗�
+     * 濡傛灉鍏ュ簱浠诲姟鍛煎彨AGV鍚庢病鏈夋敹鍒板洖璋冿紝浣嗗伐浣滄。宸茬粡鍏ュ簱鎴愬姛锛屽垯瀹岀粨AGV鍛煎彨鍗�
+     */
+    @Scheduled(cron = "0/10 * * * * ? ")
+    private void checkInboundCompletedTasks() {
+        if (!schedulerProperties.isEnabled()) {
+            return;
+        }
+        try {
+            // 鏌ヨ鍏ュ簱鎴愬姛鐨勫伐浣滄。锛堢姸鎬�4锛氬叆搴撳畬鎴愶紝鍏ュ簱绫诲瀷锛�1,10,53,57锛�
+            List<WrkMast> completedWrkMasts = wrkMastService.selectList(
+                new EntityWrapper<WrkMast>()
+                    .eq("wrk_sts", 4L)  // 鍏ュ簱瀹屾垚
+                    .in("io_type", 1, 10, 53, 57)  // 鍏ュ簱绫诲瀷
+                    .isNotNull("wrk_no")
+            );
+            
+            if (completedWrkMasts.isEmpty()) {
+                return;
+            }
+            
+            Date now = new Date();
+            int completedCount = 0;
+            List<Task> completedTasks = new ArrayList<>();
+            
+            for (WrkMast wrkMast : completedWrkMasts) {
+                // 鏌ユ壘瀵瑰簲鐨凙GV浠诲姟锛堜紭鍏堥�氳繃wrk_no鏌ヨ锛�
+                Wrapper<Task> taskWrapper1 = new EntityWrapper<Task>()
+                    .eq("task_type", "agv")
+                    .eq("wrk_sts", 8L)  // 宸插懠鍙獳GV鐘舵��
+                    .eq("wrk_no", wrkMast.getWrkNo())
+                    .andNew("(is_deleted = 0)");
+                List<Task> agvTasks = taskService.selectList(taskWrapper1);
+                
+                // 濡傛灉閫氳繃wrk_no娌℃壘鍒帮紝涓旀湁鏉$爜锛屽垯閫氳繃鏉$爜鏌ヨ
+                if (agvTasks.isEmpty() && !Cools.isEmpty(wrkMast.getBarcode())) {
+                    Wrapper<Task> taskWrapper2 = new EntityWrapper<Task>()
+                        .eq("task_type", "agv")
+                        .eq("wrk_sts", 8L)
+                        .eq("barcode", wrkMast.getBarcode())
+                        .andNew("(is_deleted = 0)");
+                    agvTasks = taskService.selectList(taskWrapper2);
+                }
+                
+                for (Task agvTask : agvTasks) {
+                    // 纭繚鏄叆搴撲换鍔�
+                    if (agvTask.getIoType() != null && 
+                        (agvTask.getIoType() == 1 || agvTask.getIoType() == 10 || 
+                         agvTask.getIoType() == 53 || agvTask.getIoType() == 57)) {
+                        // 鏇存柊AGV浠诲姟鐘舵�佷负瀹屾垚
+                        agvTask.setWrkSts(9L);
+                        agvTask.setModiTime(now);
+                        if (taskService.updateById(agvTask)) {
+                            completedTasks.add(agvTask);
+                            completedCount++;
+                            // taskId浣跨敤宸ヤ綔鍙凤紙wrk_no锛夛紝濡傛灉宸ヤ綔鍙蜂负绌哄垯浣跨敤浠诲姟ID
+                            String displayTaskId = (agvTask.getWrkNo() != null) ? String.valueOf(agvTask.getWrkNo()) : String.valueOf(agvTask.getId());
+                            log.info("鍏ュ簱浠诲姟宸ヤ綔妗e凡鍏ュ簱鎴愬姛锛屽畬缁揂GV鍛煎彨鍗曪紝taskId锛歿}锛寃rkNo锛歿}锛宐arcode锛歿}", 
+                                displayTaskId, wrkMast.getWrkNo(), wrkMast.getBarcode());
+                        }
+                    }
+                }
+            }
+            
+            // 绔嬪嵆灏嗗畬鎴愮殑AGV浠诲姟杞Щ鍒板巻鍙茶〃锛屼笉淇濈暀鍦═ask琛ㄤ腑
+            if (!completedTasks.isEmpty()) {
+                try {
+                    agvHandler.moveTaskToHistory(completedTasks);
+                    log.info("鍏ュ簱瀹屾垚锛屽凡灏唟}涓狝GV浠诲姟杞Щ鍒板巻鍙茶〃锛堜笉淇濈暀鍦═ask琛ㄤ腑锛�", completedTasks.size());
+                } catch (Exception e) {
+                    log.error("鍏ュ簱瀹屾垚锛岃浆绉籄GV浠诲姟鍒板巻鍙茶〃澶辫触", e);
+                }
+            }
+            
+            if (completedCount > 0) {
+                log.info("鏈妫�鏌ュ畬缁撲簡{}涓叆搴揂GV鍛煎彨鍗�", completedCount);
+            }
+        } catch (Exception e) {
+            log.error("妫�鏌ュ叆搴撴垚鍔熶换鍔″苟瀹岀粨AGV鍛煎彨鍗曞紓甯�", e);
+        }
+    }
+
+    /**
+     * 妫�鏌ュ苟淇寮傚父鐘舵�佺殑AGV浠诲姟锛氭鍦ㄦ惉杩愪絾娌℃湁鍒嗛厤绔欑偣
+     * 杩欑鎯呭喌鍙兘鏄暟鎹紓甯告垨骞跺彂闂瀵艰嚧鐨�
+     */
+    @Scheduled(cron = "0/30 * * * * ? ")
+    private void checkAbnormalTasksWithoutSite() {
+        if (!schedulerProperties.isEnabled()) {
+            return;
+        }
+        try {
+            // 鏌ヨ鐘舵�佷负8锛堟鍦ㄦ惉杩愶級浣嗘病鏈夊垎閰嶇珯鐐圭殑浠诲姟
+            List<Task> abnormalTasks = taskService.selectList(
+                new EntityWrapper<Task>()
+                    .eq("task_type", "agv")
+                    .eq("wrk_sts", 8L)  // 姝e湪鎼繍
+                    .andNew("(is_deleted = 0)")
+                    .andNew()
+                    .isNull("sta_no")
+                    .or()
+                    .eq("sta_no", "")
+                    .or()
+                    .eq("sta_no", "0")
+            );
+            
+            if (abnormalTasks.isEmpty()) {
+                return;
+            }
+            
+            log.warn("妫�娴嬪埌{}涓紓甯哥姸鎬佺殑AGV浠诲姟锛氭鍦ㄦ惉杩愪絾娌℃湁鍒嗛厤绔欑偣锛屽紑濮嬩慨澶�", abnormalTasks.size());
+            
+            Date now = new Date();
+            int fixedCount = 0;
+            int completedCount = 0;
+            
+            for (Task task : abnormalTasks) {
+                String displayTaskId = (task.getWrkNo() != null) ? String.valueOf(task.getWrkNo()) : String.valueOf(task.getId());
+                
+                // 妫�鏌ュ伐浣滄。鍜屽巻鍙叉。鐘舵��
+                WrkMast wrkMast = null;
+                WrkMastLog wrkMastLog = null;
+                
+                if (task.getWrkNo() != null) {
+                    wrkMast = wrkMastService.selectOne(
+                        new EntityWrapper<WrkMast>().eq("wrk_no", task.getWrkNo())
+                    );
+                    wrkMastLog = wrkMastLogService.selectOne(
+                        new EntityWrapper<WrkMastLog>().eq("wrk_no", task.getWrkNo())
+                    );
+                }
+                
+                // 濡傛灉宸ヤ綔妗e凡瀹屾垚鎴栧凡杞巻鍙叉。锛岀洿鎺ョ粨鏉熶换鍔�
+                boolean shouldComplete = false;
+                String reason = "";
+                
+                if (wrkMastLog != null) {
+                    shouldComplete = true;
+                    reason = "宸ヤ綔妗e凡杞巻鍙叉。";
+                } else if (wrkMast != null) {
+                    Long wrkSts = wrkMast.getWrkSts();
+                    Integer ioType = task.getIoType();
+                    
+                    if (wrkSts != null && ioType != null) {
+                        // 鍏ュ簱浠诲姟锛氱姸鎬�4鎴�5
+                        if ((ioType == 1 || ioType == 10 || ioType == 53 || ioType == 57) &&
+                            (wrkSts == 4L || wrkSts == 5L)) {
+                            shouldComplete = true;
+                            reason = String.format("宸ヤ綔妗e凡瀹屾垚锛堝叆搴擄級锛岀姸鎬侊細%d", wrkSts);
+                        }
+                        // 鍑哄簱浠诲姟锛氱姸鎬�14鎴�15
+                        else if ((ioType == 101 || ioType == 110 || ioType == 103 || ioType == 107) &&
+                                 (wrkSts == 14L || wrkSts == 15L)) {
+                            shouldComplete = true;
+                            reason = String.format("宸ヤ綔妗e凡瀹屾垚锛堝嚭搴擄級锛岀姸鎬侊細%d", wrkSts);
+                        }
+                    }
+                }
+                
+                if (shouldComplete) {
+                    // 宸ヤ綔妗e凡瀹屾垚锛岀洿鎺ョ粨鏉熶换鍔�
+                    task.setWrkSts(9L);
+                    task.setModiTime(now);
+                    if (taskService.updateById(task)) {
+                        try {
+                            agvHandler.moveTaskToHistory(Collections.singletonList(task));
+                            completedCount++;
+                            log.info("淇寮傚父浠诲姟锛歿}锛寋}锛屽凡缁撴潫浠诲姟骞惰浆绉诲埌鍘嗗彶琛紝taskId锛歿}", 
+                                reason, displayTaskId, displayTaskId);
+                        } catch (Exception e) {
+                            log.error("淇寮傚父浠诲姟锛氳浆绉讳换鍔″埌鍘嗗彶琛ㄥけ璐ワ紝taskId锛歿}", displayTaskId, e);
+                        }
+                    }
+                } else {
+                    // 宸ヤ綔妗f湭瀹屾垚锛屽皾璇曞垎閰嶇珯鐐规垨閲嶇疆鐘舵��
+                    // 鍏堝皾璇曞垎閰嶇珯鐐�
+                    String errorMsg = agvHandler.allocateSiteForTask(task);
+                    if (errorMsg == null && task.getStaNo() != null && !task.getStaNo().isEmpty() && !task.getStaNo().equals("0")) {
+                        // 鍒嗛厤绔欑偣鎴愬姛
+                        fixedCount++;
+                        log.info("淇寮傚父浠诲姟锛氬凡涓轰换鍔″垎閰嶇珯鐐癸紝taskId锛歿}锛岀珯鐐癸細{}", displayTaskId, task.getStaNo());
+                    } else {
+                        // 鏃犳硶鍒嗛厤绔欑偣锛岄噸缃姸鎬佷负7锛堝緟鍛煎彨AGV锛夛紝绛夊緟涓嬫鍒嗛厤
+                        task.setWrkSts(7L);
+                        task.setModiTime(now);
+                        if (taskService.updateById(task)) {
+                            fixedCount++;
+                            log.warn("淇寮傚父浠诲姟锛氭棤娉曞垎閰嶇珯鐐癸紝閲嶇疆鐘舵�佷负7锛堝緟鍛煎彨AGV锛夛紝taskId锛歿}锛屽師鍥狅細{}", 
+                                displayTaskId, errorMsg != null ? errorMsg : "鎵�鏈夌珯鐐归兘琚崰鐢�");
+                        }
+                    }
+                }
+            }
+            
+            if (fixedCount > 0 || completedCount > 0) {
+                log.info("淇寮傚父浠诲姟瀹屾垚锛氫慨澶嶄簡{}涓换鍔★紝缁撴潫浜唟}涓凡瀹屾垚宸ヤ綔妗g殑浠诲姟", fixedCount, completedCount);
+            }
+        } catch (Exception e) {
+            log.error("妫�鏌ュ苟淇寮傚父鐘舵�佺殑AGV浠诲姟寮傚父", e);
+        }
+    }
+
+    /**
+     * 妫�鏌GV浠诲姟瀵瑰簲鐨勫伐浣滄。鏄惁宸插畬鎴愭垨宸茶浆鍘嗗彶妗e苟瀹岀粨
+     * 澶勭悊琚烦杩囩殑AGV浠诲姟锛�
+     * 1. 濡傛灉宸ヤ綔妗e凡瀹屾垚锛坵rk_sts=4,5,14,15锛夛紝鍒欏畬缁揂GV浠诲姟
+     * 2. 濡傛灉宸ヤ綔妗h繘鍏ュ巻鍙叉。锛岀珛鍗崇粨鏉烝GV浠诲姟
+     * 3. 濡傛灉鍏ュ簱鎴愬姛锛屼篃缁撴潫鎺夋惉杩愪换鍔★紙宸插湪checkInboundCompletedTasks涓疄鐜帮級
+     */
+    @Scheduled(cron = "0/10 * * * * ? ")
+    private void checkCompletedTasksInHistory() {
+        if (!schedulerProperties.isEnabled()) {
+            return;
+        }
+        try {
+            // 鏌ヨ鐘舵�佷负8锛堝凡鍛煎彨AGV锛夌殑AGV浠诲姟
+            List<Task> agvTasks = taskService.selectList(
+                new EntityWrapper<Task>()
+                    .eq("task_type", "agv")
+                    .eq("wrk_sts", 8L)  // 宸插懠鍙獳GV鐘舵��
+                    .andNew("(is_deleted = 0)")
+            );
+            
+            if (agvTasks.isEmpty()) {
+                return;
+            }
+            
+            Date now = new Date();
+            int completedCount = 0;
+            List<Task> completedTasks = new ArrayList<>();
+            
+            for (Task agvTask : agvTasks) {
+                boolean isCompleted = false;
+                String reason = "";
+                
+                // 妫�鏌ュ伐浣滄。鏄惁瀛樺湪
+                WrkMast wrkMast = null;
+                if (agvTask.getWrkNo() != null) {
+                    wrkMast = wrkMastService.selectOne(
+                        new EntityWrapper<WrkMast>().eq("wrk_no", agvTask.getWrkNo())
+                    );
+                }
+                
+                // 妫�鏌ュ巻鍙叉。鏄惁瀛樺湪锛堟棤璁哄伐浣滄。鏄惁瀛樺湪閮介渶瑕佹鏌ワ級
+                WrkMastLog wrkMastLog = null;
+                // 浼樺厛閫氳繃wrk_no鏌ヨ鍘嗗彶妗�
+                if (agvTask.getWrkNo() != null) {
+                    wrkMastLog = wrkMastLogService.selectOne(
+                        new EntityWrapper<WrkMastLog>().eq("wrk_no", agvTask.getWrkNo())
+                    );
+                }
+                // 濡傛灉閫氳繃wrk_no娌℃壘鍒帮紝涓旀湁鏉$爜锛屽垯閫氳繃鏉$爜鏌ヨ
+                if (wrkMastLog == null && !Cools.isEmpty(agvTask.getBarcode())) {
+                    List<WrkMastLog> logList = wrkMastLogService.selectList(
+                        new EntityWrapper<WrkMastLog>().eq("barcode", agvTask.getBarcode())
+                    );
+                    if (!logList.isEmpty()) {
+                        wrkMastLog = logList.get(0); // 鍙栫涓�涓�
+                    }
+                }
+                
+                // 濡傛灉宸ヤ綔妗e瓨鍦紝妫�鏌ユ槸鍚﹀凡瀹屾垚
+                if (wrkMast != null) {
+                    Long wrkSts = wrkMast.getWrkSts();
+                    Integer ioType = agvTask.getIoType();
+                    
+                    if (wrkSts != null && ioType != null) {
+                        // 鍏ュ簱浠诲姟锛氱姸鎬�4锛堝叆搴撳畬鎴愶級鎴�5锛堝簱瀛樻洿鏂板畬鎴愶級
+                        if ((ioType == 1 || ioType == 10 || ioType == 53 || ioType == 57) &&
+                            (wrkSts == 4L || wrkSts == 5L)) {
+                            isCompleted = true;
+                            reason = String.format("宸ヤ綔妗e凡瀹屾垚锛岀姸鎬侊細%d", wrkSts);
+                        }
+                        // 鍑哄簱浠诲姟锛氱姸鎬�14锛堝凡鍑哄簱鏈‘璁わ級鎴�15锛堝嚭搴撴洿鏂板畬鎴愶級
+                        else if ((ioType == 101 || ioType == 110 || ioType == 103 || ioType == 107) &&
+                                 (wrkSts == 14L || wrkSts == 15L)) {
+                            isCompleted = true;
+                            reason = String.format("宸ヤ綔妗e凡瀹屾垚锛岀姸鎬侊細%d", wrkSts);
+                        }
+                    }
+                }
+                
+                // 1. 濡傛灉宸ヤ綔妗h繘鍏ュ巻鍙叉。锛岀珛鍗崇粨鏉烝GV浠诲姟锛堝彧瑕佸巻鍙叉。瀛樺湪灏辩粨鏉燂級
+                if (!isCompleted && wrkMastLog != null) {
+                    isCompleted = true;
+                    reason = String.format("宸ヤ綔妗e凡杞巻鍙叉。锛岀珛鍗崇粨鏉烝GV浠诲姟锛屽巻鍙叉。鐘舵�侊細%d", wrkMastLog.getWrkSts());
+                }
+                
+                // 濡傛灉宸插畬鎴愶紝鏇存柊AGV浠诲姟鐘舵�佸苟鏀堕泦鍒板垪琛�
+                if (isCompleted) {
+                    agvTask.setWrkSts(9L);
+                    agvTask.setModiTime(now);
+                    if (taskService.updateById(agvTask)) {
+                        completedTasks.add(agvTask);
+                        completedCount++;
+                        // taskId浣跨敤宸ヤ綔鍙凤紙wrk_no锛夛紝濡傛灉宸ヤ綔鍙蜂负绌哄垯浣跨敤浠诲姟ID
+                        String displayTaskId = (agvTask.getWrkNo() != null) ? String.valueOf(agvTask.getWrkNo()) : String.valueOf(agvTask.getId());
+                        log.info("{}锛屽畬缁揂GV鍛煎彨鍗曪紝taskId锛歿}锛寃rkNo锛歿}锛宐arcode锛歿}锛岀珯鐐癸細{}", 
+                            reason, displayTaskId, agvTask.getWrkNo(), agvTask.getBarcode(), agvTask.getStaNo());
+                    }
+                }
+            }
+            
+            // 绔嬪嵆灏嗗畬鎴愮殑AGV浠诲姟杞Щ鍒板巻鍙茶〃锛屼笉淇濈暀鍦═ask琛ㄤ腑
+            if (!completedTasks.isEmpty()) {
+                try {
+                    agvHandler.moveTaskToHistory(completedTasks);
+                    log.info("鍏ュ簱/鍑哄簱瀹屾垚锛屽凡灏唟}涓狝GV浠诲姟杞Щ鍒板巻鍙茶〃锛堜笉淇濈暀鍦═ask琛ㄤ腑锛�", completedTasks.size());
+                } catch (Exception e) {
+                    log.error("鍏ュ簱/鍑哄簱瀹屾垚锛岃浆绉籄GV浠诲姟鍒板巻鍙茶〃澶辫触", e);
+                }
+            }
+            
+            if (completedCount > 0) {
+                log.info("鏈妫�鏌ュ畬缁撲簡{}涓狝GV鍛煎彨鍗曪紙宸ヤ綔妗e凡瀹屾垚鎴栧凡杞巻鍙叉。锛�", completedCount);
+            }
+        } catch (Exception e) {
+            log.error("妫�鏌ュ伐浣滄。宸插畬鎴愭垨鍘嗗彶妗e畬缁撲换鍔″苟瀹岀粨AGV鍛煎彨鍗曞紓甯�", e);
+        }
+    }
+
 }
 

--
Gitblit v1.9.1