From faaf77b2ed6609e1ec159f163cb97c79f37df532 Mon Sep 17 00:00:00 2001
From: Administrator <XS@163.COM>
Date: 星期六, 25 四月 2026 23:46:56 +0800
Subject: [PATCH] #

---
 src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java |  607 ++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 401 insertions(+), 206 deletions(-)

diff --git a/src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java b/src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java
index 52ff58a..ca02361 100644
--- a/src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java
+++ b/src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java
@@ -2,6 +2,7 @@
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.core.exception.CoolException;
 import com.zy.asrs.domain.enums.NotifyMsgType;
@@ -26,6 +27,8 @@
 import com.zy.core.model.command.CrnCommand;
 import com.zy.core.model.protocol.CrnProtocol;
 import com.zy.core.model.protocol.StationProtocol;
+import com.zy.core.task.MainProcessLane;
+import com.zy.core.task.MainProcessTaskSubmitter;
 import com.zy.core.thread.CrnThread;
 import com.zy.core.thread.StationThread;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -53,8 +56,12 @@
     private CommonService commonService;
     @Autowired
     private NotifyUtils notifyUtils;
+    @Autowired
+    private StationOperateProcessUtils stationOperateProcessUtils;
+    @Autowired
+    private MainProcessTaskSubmitter mainProcessTaskSubmitter;
 
-    public synchronized void crnIoExecute() {
+    public void crnIoExecute() {
         Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
         if (systemConfigMapObj != null) {
             HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
@@ -66,78 +73,121 @@
         }
     }
 
-    //鍏ュ嚭搴�  ===>>  鍫嗗灈鏈哄叆鍑哄簱浣滀笟涓嬪彂
-    public synchronized void crnIoExecuteNormal() {
-        List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>());
-        for (BasCrnp basCrnp : basCrnps) {
-            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo());
-            if(crnThread == null){
-                continue;
+    public void crnIoExecute(BasCrnp basCrnp) {
+        if (basCrnp == null || basCrnp.getCrnNo() == null) {
+            return;
+        }
+        Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
+        if (systemConfigMapObj != null) {
+            HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
+            if ("solver".equals(systemConfigMap.get("crnRunMethod"))) {
+                plannerExecute(basCrnp);
+            } else {
+                crnIoExecuteNormal(basCrnp);
             }
-
-            CrnProtocol crnProtocol = crnThread.getStatus();
-            if(crnProtocol == null){
-                continue;
-            }
-
-            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
-                    .eq("crn_no", basCrnp.getCrnNo())
-                    .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts)
-            );
-            if(!wrkMasts.isEmpty()){
-                continue;
-            }
-
-            // 鍙湁褰撳爢鍨涙満绌洪棽 骞朵笖 鏃犱换鍔℃椂鎵嶇户缁墽琛�
-            if (crnProtocol.getMode() == CrnModeType.AUTO.id
-                    && crnProtocol.getTaskNo() == 0
-                    && crnProtocol.getStatus() == CrnStatusType.IDLE.id
-                    && crnProtocol.getLoaded() == 0
-                    && crnProtocol.getForkPos() == 0
-                    && crnProtocol.getAlarm() == 0
-            ) {
-                // 濡傛灉鏈�杩戜竴娆℃槸鍏ュ簱妯″紡
-                if (crnProtocol.getLastIo().equals("I")) {
-                    if (basCrnp.getInEnable().equals("Y")) {
-                        this.crnExecuteIn(basCrnp, crnThread); //  鍏ュ簱
-                        crnProtocol.setLastIo("O");
-                    } else if (basCrnp.getOutEnable().equals("Y")) {
-                        this.crnExecuteOut(basCrnp, crnThread); //  鍑哄簱
-                        crnProtocol.setLastIo("I");
-                    }
-                }
-                // 濡傛灉鏈�杩戜竴娆℃槸鍑哄簱妯″紡
-                else if (crnProtocol.getLastIo().equals("O")) {
-                    if (basCrnp.getOutEnable().equals("Y")) {
-                        this.crnExecuteOut(basCrnp, crnThread); //  鍑哄簱
-                        crnProtocol.setLastIo("I");
-                    } else if (basCrnp.getInEnable().equals("Y")) {
-                        this.crnExecuteIn(basCrnp, crnThread); //  鍏ュ簱
-                        crnProtocol.setLastIo("O");
-                    }
-                }
-
-                //搴撲綅绉昏浆
-                this.crnExecuteLocTransfer(basCrnp, crnThread);
-            }
+        } else {
+            crnIoExecuteNormal(basCrnp);
         }
     }
 
-    private synchronized void crnExecuteIn(BasCrnp basCrnp, CrnThread crnThread) {
+    //鍏ュ嚭搴�  ===>>  鍫嗗灈鏈哄叆鍑哄簱浣滀笟涓嬪彂
+    public void crnIoExecuteNormal() {
+        List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>());
+        for (BasCrnp basCrnp : basCrnps) {
+            crnIoExecuteNormal(basCrnp);
+        }
+    }
+
+    public void crnIoExecuteNormal(BasCrnp basCrnp) {
+        if (basCrnp == null || basCrnp.getCrnNo() == null) {
+            return;
+        }
+
+        CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo());
+        if(crnThread == null){
+            return;
+        }
+
         CrnProtocol crnProtocol = crnThread.getStatus();
         if(crnProtocol == null){
             return;
         }
 
+        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+                .eq("crn_no", basCrnp.getCrnNo())
+                .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts)
+                .orderBy("batch_seq", false)
+        );
+        if(!wrkMasts.isEmpty()){
+            return;
+        }
+
+        // 鍙湁褰撳爢鍨涙満绌洪棽 骞朵笖 鏃犱换鍔℃椂鎵嶇户缁墽琛�
+        if (crnProtocol.getMode() == CrnModeType.AUTO.id
+                && crnProtocol.getTaskNo() == 0
+                && crnProtocol.getStatus() == CrnStatusType.IDLE.id
+                && crnProtocol.getLoaded() == 0
+                && crnProtocol.getForkPos() == 0
+                && crnProtocol.getAlarm() == 0
+        ) {
+            Object clearLock = redisUtil.get(RedisKeyType.CLEAR_CRN_TASK_LIMIT.key + basCrnp.getCrnNo());
+            if (clearLock != null) {
+                return;
+            }
+
+            // 濡傛灉鏈�杩戜竴娆℃槸鍏ュ簱妯″紡
+            if (crnProtocol.getLastIo().equals("I")) {
+                if (basCrnp.getInEnable().equals("Y")) {
+                    boolean result = this.crnExecuteIn(basCrnp, crnThread);//  鍏ュ簱
+                    crnProtocol.setLastIo("O");
+                    if (result) {
+                        return;
+                    }
+                } else if (basCrnp.getOutEnable().equals("Y")) {
+                    boolean result = this.crnExecuteOut(basCrnp, crnThread);//  鍑哄簱
+                    crnProtocol.setLastIo("I");
+                    if (result) {
+                        return;
+                    }
+                }
+            }
+            // 濡傛灉鏈�杩戜竴娆℃槸鍑哄簱妯″紡
+            else if (crnProtocol.getLastIo().equals("O")) {
+                if (basCrnp.getOutEnable().equals("Y")) {
+                    boolean result = this.crnExecuteOut(basCrnp, crnThread);//  鍑哄簱
+                    crnProtocol.setLastIo("I");
+                    if (result) {
+                        return;
+                    }
+                } else if (basCrnp.getInEnable().equals("Y")) {
+                    boolean result = this.crnExecuteIn(basCrnp, crnThread);//  鍏ュ簱
+                    crnProtocol.setLastIo("O");
+                    if (result) {
+                        return;
+                    }
+                }
+            }
+
+            //搴撲綅绉昏浆
+            this.crnExecuteLocTransfer(basCrnp, crnThread);
+        }
+    }
+
+    private boolean crnExecuteIn(BasCrnp basCrnp, CrnThread crnThread) {
+        CrnProtocol crnProtocol = crnThread.getStatus();
+        if(crnProtocol == null){
+            return false;
+        }
+
         if(!basCrnp.getInEnable().equals("Y")){
             News.info("鍫嗗灈鏈�:{} 鍙叆淇″彿涓嶆弧瓒�", basCrnp.getCrnNo());
-            return;
+            return false;
         }
 
         List<StationObjModel> inStationList = basCrnp.getInStationList$();
         if(inStationList.isEmpty()){
             News.info("鍫嗗灈鏈�:{} 鍏ュ簱绔欑偣鏈缃�", basCrnp.getCrnNo());
-            return;
+            return false;
         }
 
         Integer crnNo = basCrnp.getCrnNo();
@@ -168,6 +218,12 @@
 
             if (!stationProtocol.isInEnable()) {
                 News.taskInfo(stationProtocol.getTaskNo(), "鍙栬揣绔欑偣:{} 娌℃湁鍙叆淇″彿", stationObjModel.getStationId());
+                logTraceLimited("crn_in_wait_signal_" + crnNo + "_" + stationObjModel.getStationId(), 3,
+                        "[WCS Trace][鍫嗗灈鏈哄叆搴揮 鍙栬揣绔欑偣涓嶅彲鍏ャ�俢rnNo={}锛宻tationId={}锛宻tationTaskNo={}锛宎utoing={}锛宭oading={}锛宨nEnable={}锛宱utEnable={}锛宺unBlock={}锛宐arcode={}锛宼argetStaNo={}锛宑rnStatus={}锛宑rnTaskNo={}锛宑rnAlarm={}",
+                        crnNo, stationObjModel.getStationId(), stationProtocol.getTaskNo(),
+                        stationProtocol.isAutoing(), stationProtocol.isLoading(), stationProtocol.isInEnable(),
+                        stationProtocol.isOutEnable(), stationProtocol.isRunBlock(), stationProtocol.getBarcode(),
+                        stationProtocol.getTargetStaNo(), crnProtocol.getStatus(), crnProtocol.getTaskNo(), crnProtocol.getAlarm());
                 continue;
             }
 
@@ -204,6 +260,10 @@
             String sourceLocNo = Utils.getLocNo(stationObjModel.getDeviceRow(), stationObjModel.getDeviceBay(), stationObjModel.getDeviceLev());
 
             CrnCommand command = crnThread.getPickAndPutCommand(sourceLocNo, wrkMast.getLocNo(), wrkMast.getWrkNo(), crnNo);
+            logTraceLimited("crn_in_dispatch_" + wrkMast.getWrkNo(), 3,
+                    "[WCS Trace][鍫嗗灈鏈哄叆搴揮 鍑嗗涓嬪彂鍫嗗灈鏈哄叆搴撳懡浠ゃ�俢rnNo={}锛寃rkNo={}锛宻ourceStationId={}锛宻ourceLocNo={}锛宼argetLocNo={}锛宻tationTaskNo={}锛宑rnStatus={}锛宑rnTaskNo={}锛宑rnAlarm={}",
+                    crnNo, wrkMast.getWrkNo(), stationObjModel.getStationId(), sourceLocNo, wrkMast.getLocNo(),
+                    stationProtocol.getTaskNo(), crnProtocol.getStatus(), crnProtocol.getTaskNo(), crnProtocol.getAlarm());
 
             wrkMast.setWrkSts(WrkStsType.INBOUND_RUN.sts);
             wrkMast.setCrnNo(crnNo);
@@ -213,25 +273,42 @@
                 MessageQueue.offer(SlaveType.Crn, crnNo, new Task(2, command));
                 notifyUtils.notify(String.valueOf(SlaveType.Crn), crnNo, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_IN_TASK_RUN, null);
                 News.info("鍫嗗灈鏈哄懡浠や笅鍙戞垚鍔燂紝鍫嗗灈鏈哄彿={}锛屼换鍔℃暟鎹�={}", crnNo, JSON.toJSON(command));
+                return true;
             }
         }
+        return false;
     }
 
-    private synchronized void crnExecuteOut(BasCrnp basCrnp, CrnThread crnThread) {
+    private boolean crnExecuteOut(BasCrnp basCrnp, CrnThread crnThread) {
         CrnProtocol crnProtocol = crnThread.getStatus();
         if(crnProtocol == null){
-            return;
+            return false;
         }
 
         if(!basCrnp.getOutEnable().equals("Y")){
             News.info("鍫嗗灈鏈�:{} 鍙嚭淇″彿涓嶆弧瓒�", basCrnp.getCrnNo());
-            return;
+            return false;
         }
 
         List<StationObjModel> outStationList = basCrnp.getOutStationList$();
         if(outStationList.isEmpty()){
             News.info("鍫嗗灈鏈�:{} 鍑哄簱绔欑偣鏈缃�", basCrnp.getCrnNo());
-            return;
+            return false;
+        }
+
+        int stationMaxTaskCount = 30;
+        Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
+        if (systemConfigMapObj != null) {
+            try {
+                HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
+                stationMaxTaskCount = Integer.parseInt(systemConfigMap.getOrDefault("stationMaxTaskCountLimit", "30"));
+            } catch (Exception ignore) {}
+        }
+
+        int currentStationTaskCount = stationOperateProcessUtils.getCurrentStationTaskCount();
+        if (stationMaxTaskCount > 0 && currentStationTaskCount >= stationMaxTaskCount) {
+            News.warn("杈撻�佺珯鐐逛换鍔℃暟閲忚揪鍒颁笂闄愶紝宸插仠姝换鍔′笅鍙戙�傚綋鍓嶄换鍔℃暟={}锛屼笂闄�={}", currentStationTaskCount, stationMaxTaskCount);
+            return false;
         }
 
         Integer crnNo = basCrnp.getCrnNo();
@@ -239,6 +316,7 @@
         List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
                 .eq("crn_no", crnNo)
                 .eq("wrk_sts", WrkStsType.NEW_OUTBOUND.sts)
+                .orderBy("batch_seq", false)
         );
 
         for (WrkMast wrkMast : wrkMasts) {
@@ -268,6 +346,12 @@
 
                 if (!stationProtocol.isOutEnable()) {
                     News.info("鏀捐揣绔欑偣:{} 娌℃湁鍙嚭淇″彿", stationObjModel.getStationId());
+                    logTraceLimited("crn_out_wait_signal_" + crnNo + "_" + stationObjModel.getStationId(), 3,
+                            "[WCS Trace][鍫嗗灈鏈哄嚭搴揮 鏀捐揣绔欑偣涓嶅彲鍑恒�俢rnNo={}锛宻tationId={}锛寃rkNo={}锛宎utoing={}锛宭oading={}锛宨nEnable={}锛宱utEnable={}锛宺unBlock={}锛宻tationTaskNo={}锛宼argetStaNo={}锛宑rnStatus={}锛宑rnTaskNo={}锛宑rnAlarm={}",
+                            crnNo, stationObjModel.getStationId(), wrkMast.getWrkNo(),
+                            stationProtocol.isAutoing(), stationProtocol.isLoading(), stationProtocol.isInEnable(),
+                            stationProtocol.isOutEnable(), stationProtocol.isRunBlock(), stationProtocol.getTaskNo(),
+                            stationProtocol.getTargetStaNo(), crnProtocol.getStatus(), crnProtocol.getTaskNo(), crnProtocol.getAlarm());
                     continue;
                 }
 
@@ -293,6 +377,11 @@
                 String targetLocNo = Utils.getLocNo(stationObjModel.getDeviceRow(), stationObjModel.getDeviceBay(), stationObjModel.getDeviceLev());
 
                 CrnCommand command = crnThread.getPickAndPutCommand(wrkMast.getSourceLocNo(), targetLocNo, wrkMast.getWrkNo(), crnNo);
+                logTraceLimited("crn_out_dispatch_" + wrkMast.getWrkNo(), 3,
+                        "[WCS Trace][鍫嗗灈鏈哄嚭搴揮 鍑嗗涓嬪彂鍫嗗灈鏈哄嚭搴撳懡浠ゃ�俢rnNo={}锛寃rkNo={}锛宼argetStationId={}锛宻ourceLocNo={}锛宼argetLocNo={}锛宑rnStatus={}锛宑rnTaskNo={}锛宑rnAlarm={}",
+                        crnNo, wrkMast.getWrkNo(), stationObjModel.getStationId(),
+                        wrkMast.getSourceLocNo(), targetLocNo, crnProtocol.getStatus(),
+                        crnProtocol.getTaskNo(), crnProtocol.getAlarm());
 
                 wrkMast.setWrkSts(WrkStsType.OUTBOUND_RUN.sts);
                 wrkMast.setCrnNo(crnNo);
@@ -302,13 +391,14 @@
                     MessageQueue.offer(SlaveType.Crn, crnNo, new Task(2, command));
                     notifyUtils.notify(String.valueOf(SlaveType.Crn), crnNo, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_OUT_TASK_RUN, null);
                     News.info("鍫嗗灈鏈哄懡浠や笅鍙戞垚鍔燂紝鍫嗗灈鏈哄彿={}锛屼换鍔℃暟鎹�={}", crnNo, JSON.toJSON(command));
-                    return;
+                    return true;
                 }
             }
         }
+        return false;
     }
 
-    private synchronized boolean crnExecuteInPlanner(BasCrnp basCrnp, CrnThread crnThread, WrkMast wrkMast) {
+    private boolean crnExecuteInPlanner(BasCrnp basCrnp, CrnThread crnThread, WrkMast wrkMast) {
         CrnProtocol crnProtocol = crnThread.getStatus();
         if (crnProtocol == null) {
             return false;
@@ -401,7 +491,7 @@
         return false;
     }
 
-    private synchronized boolean crnExecuteOutPlanner(BasCrnp basCrnp, CrnThread crnThread, WrkMast wrkMast) {
+    private boolean crnExecuteOutPlanner(BasCrnp basCrnp, CrnThread crnThread, WrkMast wrkMast) {
         CrnProtocol crnProtocol = crnThread.getStatus();
         if (crnProtocol == null) {
             return false;
@@ -486,10 +576,10 @@
         return false;
     }
 
-    private synchronized void crnExecuteLocTransfer(BasCrnp basCrnp, CrnThread crnThread) {
+    private boolean crnExecuteLocTransfer(BasCrnp basCrnp, CrnThread crnThread) {
         CrnProtocol crnProtocol = crnThread.getStatus();
         if(crnProtocol == null){
-            return;
+            return false;
         }
 
         Integer crnNo = basCrnp.getCrnNo();
@@ -534,168 +624,200 @@
                 MessageQueue.offer(SlaveType.Crn, crnNo, new Task(2, command));
                 notifyUtils.notify(String.valueOf(SlaveType.Crn), crnNo, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_TRANSFER_TASK_RUN, null);
                 News.info("鍫嗗灈鏈哄懡浠や笅鍙戞垚鍔燂紝鍫嗗灈鏈哄彿={}锛屼换鍔℃暟鎹�={}", crnNo, JSON.toJSON(command));
-                return;
+                return true;
             }
         }
+        return false;
     }
 
     //鍫嗗灈鏈轰换鍔℃墽琛屽畬鎴�
-    public synchronized void crnIoExecuteFinish() {
+    public void crnIoExecuteFinish() {
         List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>());
         for (BasCrnp basCrnp : basCrnps) {
-            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo());
-            if(crnThread == null){
-                continue;
-            }
-
-            CrnProtocol crnProtocol = crnThread.getStatus();
-            if(crnProtocol == null){
-                continue;
-            }
-
-            if (crnProtocol.getMode() == CrnModeType.AUTO.id
-                    && crnProtocol.getTaskNo() > 0
-                    && crnProtocol.getStatus() == CrnStatusType.WAITING.id
-            ) {
-                Object lock = redisUtil.get(RedisKeyType.CRN_IO_EXECUTE_FINISH_LIMIT.key + basCrnp.getCrnNo());
-                if(lock != null){
-                    continue;
-                }
-
-                // 鑾峰彇寰呯‘璁ゅ伐浣滄。
-                WrkMast wrkMast = wrkMastService.selectByWorkNo(crnProtocol.getTaskNo());
-                if (wrkMast == null) {
-                    News.error("鍫嗗灈鏈哄浜庣瓑寰呯‘璁や笖浠诲姟瀹屾垚鐘舵�侊紝浣嗘湭鎵惧埌宸ヤ綔妗c�傚爢鍨涙満鍙�={}锛屽伐浣滃彿={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
-                    continue;
-                }
-
-                Long updateWrkSts = null;
-                if(wrkMast.getWrkSts() == WrkStsType.INBOUND_RUN.sts){
-                    updateWrkSts = WrkStsType.COMPLETE_INBOUND.sts;
-                    notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_IN_TASK_COMPLETE, null);
-                }else if(wrkMast.getWrkSts() == WrkStsType.OUTBOUND_RUN.sts){
-                    updateWrkSts = WrkStsType.OUTBOUND_RUN_COMPLETE.sts;
-                    notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_OUT_TASK_COMPLETE, null);
-                }else if(wrkMast.getWrkSts() == WrkStsType.LOC_MOVE_RUN.sts){
-                    updateWrkSts = WrkStsType.COMPLETE_LOC_MOVE.sts;
-                    notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_TRANSFER_TASK_COMPLETE, null);
-                }else{
-                    News.error("鍫嗗灈鏈哄浜庣瓑寰呯‘璁や笖浠诲姟瀹屾垚鐘舵�侊紝浣嗗伐浣滅姸鎬佸紓甯搞�傚爢鍨涙満鍙�={}锛屽伐浣滃彿={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
-                    continue;
-                }
-
-                wrkMast.setWrkSts(updateWrkSts);
-                wrkMast.setSystemMsg("");
-                wrkMast.setIoTime(new Date());
-                if (wrkMastService.updateById(wrkMast)) {
-                    CrnCommand resetCommand = crnThread.getResetCommand(crnProtocol.getCrnNo());
-                    MessageQueue.offer(SlaveType.Crn, crnProtocol.getCrnNo(), new Task(2, resetCommand));
-                    News.info("鍫嗗灈鏈轰换鍔$姸鎬佹洿鏂版垚鍔燂紝鍫嗗灈鏈哄彿={}锛屽伐浣滃彿={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
-                }
-
-                redisUtil.set(RedisKeyType.CRN_IO_EXECUTE_FINISH_LIMIT.key + basCrnp.getCrnNo(), "lock",10);
-            }
+            crnIoExecuteFinish(basCrnp);
         }
     }
 
-    public synchronized void plannerExecute() {
+    public void crnIoExecuteFinish(BasCrnp basCrnp) {
+        if (basCrnp == null || basCrnp.getCrnNo() == null) {
+            return;
+        }
+
+        CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo());
+        if(crnThread == null){
+            return;
+        }
+
+        CrnProtocol crnProtocol = crnThread.getStatus();
+        if(crnProtocol == null){
+            return;
+        }
+
+        if (crnProtocol.getMode() == CrnModeType.AUTO.id
+                && crnProtocol.getTaskNo() > 0
+                && crnProtocol.getStatus() == CrnStatusType.WAITING.id
+        ) {
+            Object lock = redisUtil.get(RedisKeyType.CRN_IO_EXECUTE_FINISH_LIMIT.key + basCrnp.getCrnNo());
+            if(lock != null){
+                return;
+            }
+
+            // 鑾峰彇寰呯‘璁ゅ伐浣滄。
+            WrkMast wrkMast = wrkMastService.selectByWorkNo(crnProtocol.getTaskNo());
+            if (wrkMast == null) {
+                News.error("鍫嗗灈鏈哄浜庣瓑寰呯‘璁や笖浠诲姟瀹屾垚鐘舵�侊紝浣嗘湭鎵惧埌宸ヤ綔妗c�傚爢鍨涙満鍙�={}锛屽伐浣滃彿={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
+                return;
+            }
+
+            Long updateWrkSts = null;
+            if(wrkMast.getWrkSts() == WrkStsType.INBOUND_RUN.sts){
+                updateWrkSts = WrkStsType.COMPLETE_INBOUND.sts;
+                notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_IN_TASK_COMPLETE, null);
+            }else if(wrkMast.getWrkSts() == WrkStsType.OUTBOUND_RUN.sts){
+                updateWrkSts = WrkStsType.OUTBOUND_RUN_COMPLETE.sts;
+                notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_OUT_TASK_COMPLETE, null);
+
+                List<StationObjModel> outStationList = basCrnp.getOutStationList$();
+                if(outStationList.isEmpty()){
+                    News.info("鍫嗗灈鏈�:{} 鍑哄簱绔欑偣鏈缃�", basCrnp.getCrnNo());
+                    return;
+                }
+
+                StationObjModel outStationObjModel = null;
+                for (StationObjModel stationObjModel : outStationList) {
+                    if (stationObjModel.getStationId().equals(wrkMast.getSourceStaNo())) {
+                        outStationObjModel = stationObjModel;
+                        break;
+                    }
+                }
+                redisUtil.set(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo(), JSON.toJSONString(outStationObjModel, SerializerFeature.DisableCircularReferenceDetect), 60 * 60 * 24);
+            }else if(wrkMast.getWrkSts() == WrkStsType.LOC_MOVE_RUN.sts){
+                updateWrkSts = WrkStsType.COMPLETE_LOC_MOVE.sts;
+                notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_TRANSFER_TASK_COMPLETE, null);
+            }else{
+                News.error("鍫嗗灈鏈哄浜庣瓑寰呯‘璁や笖浠诲姟瀹屾垚鐘舵�侊紝浣嗗伐浣滅姸鎬佸紓甯搞�傚爢鍨涙満鍙�={}锛屽伐浣滃彿={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
+                return;
+            }
+
+            wrkMast.setWrkSts(updateWrkSts);
+            wrkMast.setSystemMsg("");
+            wrkMast.setIoTime(new Date());
+            if (wrkMastService.updateById(wrkMast)) {
+                CrnCommand resetCommand = crnThread.getResetCommand(crnProtocol.getTaskNo(), crnProtocol.getCrnNo());
+                MessageQueue.offer(SlaveType.Crn, crnProtocol.getCrnNo(), new Task(2, resetCommand));
+                News.info("鍫嗗灈鏈轰换鍔$姸鎬佹洿鏂版垚鍔燂紝鍫嗗灈鏈哄彿={}锛屽伐浣滃彿={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
+            }
+
+            redisUtil.set(RedisKeyType.CRN_IO_EXECUTE_FINISH_LIMIT.key + basCrnp.getCrnNo(), "lock",10);
+        }
+    }
+
+    public void plannerExecute() {
+        List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>());
+        for (BasCrnp basCrnp : basCrnps) {
+            plannerExecute(basCrnp);
+        }
+    }
+
+    public void plannerExecute(BasCrnp basCrnp) {
+        if (basCrnp == null || basCrnp.getCrnNo() == null) {
+            return;
+        }
+
         int nowSec = (int) (System.currentTimeMillis() / 1000);
-        List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>());
-        for (BasCrnp basCrnp : basCrnps) {
-            String key = RedisKeyType.PLANNER_SCHEDULE.key + "CRN-" + basCrnp.getCrnNo();
-            List<Object> items = redisUtil.lGet(key, 0, -1);
-            if (items == null || items.isEmpty()) {
+        String key = RedisKeyType.PLANNER_SCHEDULE.key + "CRN-" + basCrnp.getCrnNo();
+        List<Object> items = redisUtil.lGet(key, 0, -1);
+        if (items == null || items.isEmpty()) {
+            return;
+        }
+
+        CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo());
+        if (crnThread == null) {
+            return;
+        }
+        CrnProtocol crnProtocol = crnThread.getStatus();
+        if (crnProtocol == null) {
+            return;
+        }
+        List<WrkMast> running = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+                .eq("crn_no", basCrnp.getCrnNo())
+                .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts, WrkStsType.LOC_MOVE_RUN.sts)
+        );
+        if (!running.isEmpty()) {
+            return;
+        }
+        if (!(crnProtocol.getMode() == CrnModeType.AUTO.id
+                && crnProtocol.getTaskNo() == 0
+                && crnProtocol.getStatus() == CrnStatusType.IDLE.id
+                && crnProtocol.getLoaded() == 0
+                && crnProtocol.getForkPos() == 0
+                && crnProtocol.getAlarm() == 0)) {
+            return;
+        }
+
+        for (Object v : items) {
+            String s = String.valueOf(v);
+            JSONObject obj = null;
+            try { obj = JSON.parseObject(s); } catch (Exception ignore) {}
+            if (obj == null) {
+                continue;
+            }
+            Integer startEpochSec = obj.getInteger("startEpochSec");
+            Integer endEpochSec = obj.getInteger("endEpochSec");
+            Integer taskId = obj.getInteger("taskId");
+            String taskType = obj.getString("taskType");
+            if (startEpochSec == null || taskId == null || taskType == null) {
+                continue;
+            }
+            int earlySlackSec = 5;
+            int lateSlackSec = 10;
+            Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
+            if (systemConfigMapObj != null) {
+                try {
+                    HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
+                    String es = systemConfigMap.getOrDefault("plannerEarlySlackSec", "60");
+                    String ls = systemConfigMap.getOrDefault("plannerLateSlackSec", "10");
+                    earlySlackSec = Integer.parseInt(es);
+                    lateSlackSec = Integer.parseInt(ls);
+                } catch (Exception ignore) {}
+            }
+            if (nowSec < startEpochSec - earlySlackSec) {
+                continue;
+            }
+            if (endEpochSec != null && nowSec > endEpochSec + lateSlackSec) {
+                redisUtil.lRemove(key, 1, s);
                 continue;
             }
 
-            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo());
-            if (crnThread == null) {
-                continue;
-            }
-            CrnProtocol crnProtocol = crnThread.getStatus();
-            if (crnProtocol == null) {
-                continue;
-            }
-            List<WrkMast> running = wrkMastService.selectList(new EntityWrapper<WrkMast>()
-                    .eq("crn_no", basCrnp.getCrnNo())
-                    .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts, WrkStsType.LOC_MOVE_RUN.sts)
-            );
-            if (!running.isEmpty()) {
-                continue;
-            }
-            if (!(crnProtocol.getMode() == CrnModeType.AUTO.id
-                    && crnProtocol.getTaskNo() == 0
-                    && crnProtocol.getStatus() == CrnStatusType.IDLE.id
-                    && crnProtocol.getLoaded() == 0
-                    && crnProtocol.getForkPos() == 0
-                    && crnProtocol.getAlarm() == 0)) {
+            WrkMast wrkMast = wrkMastService.selectByWorkNo(taskId);
+            if (wrkMast == null) {
+                redisUtil.lRemove(key, 1, s);
                 continue;
             }
 
-            for (Object v : items) {
-                String s = String.valueOf(v);
-                JSONObject obj = null;
-                try { obj = JSON.parseObject(s); } catch (Exception ignore) {}
-                if (obj == null) {
-                    continue;
-                }
-                Integer startEpochSec = obj.getInteger("startEpochSec");
-                Integer endEpochSec = obj.getInteger("endEpochSec");
-                Integer taskId = obj.getInteger("taskId");
-                String taskType = obj.getString("taskType");
-                if (startEpochSec == null || taskId == null || taskType == null) {
-                    continue;
-                }
-                int earlySlackSec = 5;
-                int lateSlackSec = 10;
-                Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
-                if (systemConfigMapObj != null) {
-                    try {
-                        HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
-                        String es = systemConfigMap.getOrDefault("plannerEarlySlackSec", "60");
-                        String ls = systemConfigMap.getOrDefault("plannerLateSlackSec", "10");
-                        earlySlackSec = Integer.parseInt(es);
-                        lateSlackSec = Integer.parseInt(ls);
-                    } catch (Exception ignore) {}
-                }
-                if (nowSec < startEpochSec - earlySlackSec) {
-                    continue;
-                }
-                if (endEpochSec != null && nowSec > endEpochSec + lateSlackSec) {
+            if ("IN".equalsIgnoreCase(taskType)) {
+                boolean result = this.crnExecuteInPlanner(basCrnp, crnThread, wrkMast);//鍏ュ簱
+                if (result) {
                     redisUtil.lRemove(key, 1, s);
-                    continue;
+                    return;
                 }
-
-                WrkMast wrkMast = wrkMastService.selectByWorkNo(taskId);
-                if (wrkMast == null) {
+            } else if ("OUT".equalsIgnoreCase(taskType)) {
+                boolean result = this.crnExecuteOutPlanner(basCrnp, crnThread, wrkMast);//鍑哄簱
+                if (result) {
                     redisUtil.lRemove(key, 1, s);
-                    continue;
+                    return;
                 }
-
-                if ("IN".equalsIgnoreCase(taskType)) {
-                    boolean result = this.crnExecuteInPlanner(basCrnp, crnThread, wrkMast);//鍏ュ簱
-                    if (result) {
-                        redisUtil.lRemove(key, 1, s);
-                        break;
-                    }
-                } else if ("OUT".equalsIgnoreCase(taskType)) {
-                    boolean result = this.crnExecuteOutPlanner(basCrnp, crnThread, wrkMast);//鍑哄簱
-                    if (result) {
-                        redisUtil.lRemove(key, 1, s);
-                        break;
-                    }
-                } else if ("MOVE".equalsIgnoreCase(taskType)) {
-                    boolean result = this.crnExecuteMovePlanner(basCrnp, crnThread, wrkMast);//绉诲簱
-                    if (result) {
-                        redisUtil.lRemove(key, 1, s);
-                        break;
-                    }
+            } else if ("MOVE".equalsIgnoreCase(taskType)) {
+                boolean result = this.crnExecuteMovePlanner(basCrnp, crnThread, wrkMast);//绉诲簱
+                if (result) {
+                    redisUtil.lRemove(key, 1, s);
+                    return;
                 }
             }
         }
     }
 
-    private synchronized boolean crnExecuteMovePlanner(BasCrnp basCrnp, CrnThread crnThread, WrkMast wrkMast) {
+    private boolean crnExecuteMovePlanner(BasCrnp basCrnp, CrnThread crnThread, WrkMast wrkMast) {
         CrnProtocol crnProtocol = crnThread.getStatus();
         if (crnProtocol == null) {
             return false;
@@ -746,8 +868,82 @@
         return false;
     }
 
+    public void submitCrnIoTasks(long minIntervalMs) {
+        submitCrnIoTasks(MainProcessLane.CRN_IO, minIntervalMs);
+    }
+
+    public void submitCrnIoTasks(MainProcessLane lane, long minIntervalMs) {
+        mainProcessTaskSubmitter.submitSerialTask(
+                MainProcessLane.CRN_SCAN,
+                "submitCrnIoTasks",
+                minIntervalMs,
+                () -> submitCrnIoTasksInternal(lane, minIntervalMs)
+        );
+    }
+
+    private void submitCrnIoTasksInternal(MainProcessLane lane, long minIntervalMs) {
+        List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>());
+        for (BasCrnp basCrnp : basCrnps) {
+            if (basCrnp == null || basCrnp.getCrnNo() == null) {
+                continue;
+            }
+            final BasCrnp currentCrn = basCrnp;
+            mainProcessTaskSubmitter.submitKeyedSerialTask(
+                    lane,
+                    currentCrn.getCrnNo(),
+                    "crnIoExecute",
+                    minIntervalMs,
+                    () -> crnIoExecute(currentCrn)
+            );
+        }
+    }
+
+    public void submitCrnIoExecuteFinishTasks(long minIntervalMs) {
+        submitCrnIoExecuteFinishTasks(MainProcessLane.CRN_IO_FINISH, minIntervalMs);
+    }
+
+    public void submitCrnIoExecuteFinishTasks(MainProcessLane lane, long minIntervalMs) {
+        mainProcessTaskSubmitter.submitSerialTask(
+                MainProcessLane.CRN_SCAN,
+                "submitCrnIoExecuteFinishTasks",
+                minIntervalMs,
+                () -> submitCrnIoExecuteFinishTasksInternal(lane, minIntervalMs)
+        );
+    }
+
+    private void submitCrnIoExecuteFinishTasksInternal(MainProcessLane lane, long minIntervalMs) {
+        List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>());
+        for (BasCrnp basCrnp : basCrnps) {
+            if (basCrnp == null || basCrnp.getCrnNo() == null) {
+                continue;
+            }
+            final BasCrnp currentCrn = basCrnp;
+            mainProcessTaskSubmitter.submitKeyedSerialTask(
+                    lane,
+                    currentCrn.getCrnNo(),
+                    "crnIoExecuteFinish",
+                    minIntervalMs,
+                    () -> crnIoExecuteFinish(currentCrn)
+            );
+        }
+    }
+
+    private void logTraceLimited(String lockKey, int seconds, String format, Object... arguments) {
+        String redisKey = RedisKeyType.LOG_LIMIT.key + "wcs_trace_" + lockKey;
+        try {
+            Object lock = redisUtil.get(redisKey);
+            if (lock != null) {
+                return;
+            }
+            redisUtil.set(redisKey, "lock", seconds);
+        } catch (Exception e) {
+            // 璇婃柇鏃ュ織涓嶈兘褰卞搷涓绘祦绋嬨��
+        }
+        News.info(format, arguments);
+    }
+
     //妫�娴嬫祬搴撲綅鐘舵��
-    public synchronized boolean checkShallowLocStatus(String locNo, Integer taskNo) {
+    public boolean checkShallowLocStatus(String locNo, Integer taskNo) {
         String checkDeepLocOutTaskBlockReport = "Y";
         Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
         if (systemConfigMapObj != null) {
@@ -763,18 +959,17 @@
         if (lock != null) {
             return false;
         }
-        redisUtil.set(RedisKeyType.CHECK_SHALLOW_LOC_STATUS_LIMIT.key + taskNo, "lock", 5);
 
         Integer shallowRow = Utils.getShallowRowByDeepRow(Utils.getRow(locNo));
         if (shallowRow == null) {
             return true;
         }
 
+        redisUtil.set(RedisKeyType.CHECK_SHALLOW_LOC_STATUS_LIMIT.key + taskNo, "lock", 5);
         String shallowLocNo = Utils.getLocNo(shallowRow, Utils.getBay(locNo), Utils.getLev(locNo));
         LocMast shallowLocMast = locMastService.queryByLoc(shallowLocNo);
         if (shallowLocMast == null) {
-            News.taskInfo(taskNo, "娴呭簱浣�:{} 鏁版嵁涓嶅瓨鍦�", shallowLocNo);
-            return false;
+            return true;
         }
 
         if (shallowLocMast.getLocSts().equals("O")) {

--
Gitblit v1.9.1