From 9c094af56e63348c55adddeee00be696a0af78c4 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期六, 21 三月 2026 16:42:37 +0800
Subject: [PATCH] #

---
 src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java |  309 ++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 253 insertions(+), 56 deletions(-)

diff --git a/src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java b/src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java
index 0f93ef3..903d756 100644
--- a/src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java
+++ b/src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java
@@ -3,14 +3,17 @@
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.serializer.SerializerFeature;
-import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.core.common.Cools;
 import com.core.exception.CoolException;
 import com.zy.asrs.domain.enums.NotifyMsgType;
 import com.zy.asrs.domain.param.CreateLocMoveTaskParam;
+import com.zy.asrs.entity.BasStation;
 import com.zy.asrs.entity.BasCrnp;
 import com.zy.asrs.entity.LocMast;
 import com.zy.asrs.entity.WrkMast;
 import com.zy.asrs.service.BasCrnpService;
+import com.zy.asrs.service.BasStationService;
 import com.zy.asrs.service.LocMastService;
 import com.zy.asrs.service.WrkMastService;
 import com.zy.asrs.utils.NotifyUtils;
@@ -32,6 +35,8 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -47,6 +52,8 @@
     @Autowired
     private LocMastService locMastService;
     @Autowired
+    private BasStationService basStationService;
+    @Autowired
     private RedisUtil redisUtil;
     @Autowired
     private WmsOperateUtils wmsOperateUtils;
@@ -54,6 +61,8 @@
     private CommonService commonService;
     @Autowired
     private NotifyUtils notifyUtils;
+    @Autowired
+    private StationOperateProcessUtils stationOperateProcessUtils;
 
     public synchronized void crnIoExecute() {
         Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
@@ -69,23 +78,25 @@
 
     //鍏ュ嚭搴�  ===>>  鍫嗗灈鏈哄叆鍑哄簱浣滀笟涓嬪彂
     public synchronized void crnIoExecuteNormal() {
-        List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>());
+        List<BasCrnp> basCrnps = basCrnpService.list(new QueryWrapper<>());
+        Map<Integer, BasCrnp> dispatchCrnMap = new HashMap<>();
+        Map<Integer, CrnThread> dispatchThreadMap = new HashMap<>();
+        Map<Integer, CrnProtocol> dispatchProtocolMap = new HashMap<>();
         for (BasCrnp basCrnp : basCrnps) {
             CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo());
-            if(crnThread == null){
+            if (crnThread == null) {
                 continue;
             }
 
             CrnProtocol crnProtocol = crnThread.getStatus();
-            if(crnProtocol == null){
+            if (crnProtocol == null) {
                 continue;
             }
 
-            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+            long runningCount = wrkMastService.count(new QueryWrapper<WrkMast>()
                     .eq("crn_no", basCrnp.getCrnNo())
-                    .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts)
-            );
-            if(!wrkMasts.isEmpty()){
+                    .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts, WrkStsType.LOC_MOVE_RUN.sts));
+            if (runningCount > 0) {
                 continue;
             }
 
@@ -101,47 +112,106 @@
                 if (clearLock != null) {
                     continue;
                 }
+                dispatchCrnMap.put(basCrnp.getCrnNo(), basCrnp);
+                dispatchThreadMap.put(basCrnp.getCrnNo(), crnThread);
+                dispatchProtocolMap.put(basCrnp.getCrnNo(), crnProtocol);
+            }
+        }
 
-                // 濡傛灉鏈�杩戜竴娆℃槸鍏ュ簱妯″紡
-                if (crnProtocol.getLastIo().equals("I")) {
-                    if (basCrnp.getInEnable().equals("Y")) {
-                        boolean result = this.crnExecuteIn(basCrnp, crnThread);//  鍏ュ簱
-                        crnProtocol.setLastIo("O");
-                        if (result) {
-                            break;
-                        }
-                    } else if (basCrnp.getOutEnable().equals("Y")) {
-                        boolean result = this.crnExecuteOut(basCrnp, crnThread);//  鍑哄簱
-                        crnProtocol.setLastIo("I");
-                        if (result) {
-                            break;
-                        }
-                    }
-                }
-                // 濡傛灉鏈�杩戜竴娆℃槸鍑哄簱妯″紡
-                else if (crnProtocol.getLastIo().equals("O")) {
-                    if (basCrnp.getOutEnable().equals("Y")) {
-                        boolean result = this.crnExecuteOut(basCrnp, crnThread);//  鍑哄簱
-                        crnProtocol.setLastIo("I");
-                        if (result) {
-                            break;
-                        }
-                    } else if (basCrnp.getInEnable().equals("Y")) {
-                        boolean result = this.crnExecuteIn(basCrnp, crnThread);//  鍏ュ簱
-                        crnProtocol.setLastIo("O");
-                        if (result) {
-                            break;
-                        }
-                    }
-                }
+        if (dispatchCrnMap.isEmpty()) {
+            return;
+        }
 
-                //搴撲綅绉昏浆
-                boolean transfer = this.crnExecuteLocTransfer(basCrnp, crnThread);
+        List<WrkMast> taskQueue = wrkMastService.list(new QueryWrapper<WrkMast>()
+                .in("crn_no", new ArrayList<>(dispatchCrnMap.keySet()))
+                .in("wrk_sts",
+                        WrkStsType.INBOUND_DEVICE_RUN.sts,
+                        WrkStsType.NEW_OUTBOUND.sts,
+                        WrkStsType.NEW_LOC_MOVE.sts));
+        taskQueue.sort(Comparator
+                .comparingInt(this::resolveBatchOutboundRank)
+                .thenComparingInt(this::resolveBatchSeqOrder)
+                .thenComparingDouble(this::resolveTaskIoPri)
+                .thenComparingLong(this::resolveTaskQueueTime)
+                .thenComparingInt(this::resolveTaskQueueNo));
+
+        for (WrkMast wrkMast : taskQueue) {
+            if (wrkMast == null || wrkMast.getCrnNo() == null) {
+                continue;
+            }
+
+            Integer crnNo = wrkMast.getCrnNo();
+            BasCrnp basCrnp = dispatchCrnMap.get(crnNo);
+            CrnThread crnThread = dispatchThreadMap.get(crnNo);
+            CrnProtocol crnProtocol = dispatchProtocolMap.get(crnNo);
+            if (basCrnp == null || crnThread == null || crnProtocol == null) {
+                continue;
+            }
+
+            if (wrkMast.getWrkSts() != null && wrkMast.getWrkSts() == WrkStsType.INBOUND_DEVICE_RUN.sts) {
+                boolean result = this.crnExecuteInPlanner(basCrnp, crnThread, wrkMast);
+                if (result) {
+                    crnProtocol.setLastIo("O");
+                    return;
+                }
+                continue;
+            }
+
+            if (wrkMast.getWrkSts() != null && wrkMast.getWrkSts() == WrkStsType.NEW_OUTBOUND.sts) {
+                boolean result = this.crnExecuteOutPlanner(basCrnp, crnThread, wrkMast);
+                if (result) {
+                    crnProtocol.setLastIo("I");
+                    return;
+                }
+                continue;
+            }
+
+            if (wrkMast.getWrkSts() != null && wrkMast.getWrkSts() == WrkStsType.NEW_LOC_MOVE.sts) {
+                boolean transfer = this.crnExecuteMovePlanner(basCrnp, crnThread, wrkMast);
                 if (transfer) {
-                    break;
+                    return;
                 }
             }
         }
+    }
+
+    private int resolveBatchOutboundRank(WrkMast wrkMast) {
+        return isBatchOutboundTask(wrkMast) ? 0 : 1;
+    }
+
+    private int resolveBatchSeqOrder(WrkMast wrkMast) {
+        if (!isBatchOutboundTask(wrkMast) || wrkMast.getBatchSeq() == null) {
+            return Integer.MAX_VALUE;
+        }
+        return wrkMast.getBatchSeq();
+    }
+
+    private double resolveTaskIoPri(WrkMast wrkMast) {
+        if (wrkMast == null || wrkMast.getIoPri() == null) {
+            return Double.MAX_VALUE;
+        }
+        return wrkMast.getIoPri();
+    }
+
+    private long resolveTaskQueueTime(WrkMast wrkMast) {
+        if (wrkMast == null) {
+            return Long.MAX_VALUE;
+        }
+        Date queueTime = wrkMast.getAppeTime() != null ? wrkMast.getAppeTime() : wrkMast.getIoTime();
+        return queueTime == null ? Long.MAX_VALUE : queueTime.getTime();
+    }
+
+    private int resolveTaskQueueNo(WrkMast wrkMast) {
+        if (wrkMast == null || wrkMast.getWrkNo() == null) {
+            return Integer.MAX_VALUE;
+        }
+        return wrkMast.getWrkNo();
+    }
+
+    private boolean isBatchOutboundTask(WrkMast wrkMast) {
+        return wrkMast != null
+                && Integer.valueOf(WrkIoType.OUT.id).equals(wrkMast.getIoType())
+                && !Cools.isEmpty(wrkMast.getBatch());
     }
 
     private synchronized boolean crnExecuteIn(BasCrnp basCrnp, CrnThread crnThread) {
@@ -199,12 +269,16 @@
                 continue;
             }
 
+            if (!wrkMast.getCrnNo().equals(basCrnp.getCrnNo())) {
+                continue;
+            }
+
             if(wrkMast.getWrkSts() != WrkStsType.INBOUND_DEVICE_RUN.sts){
                 continue;
             }
 
             // 鑾峰彇搴撲綅淇℃伅
-            LocMast locMast = locMastService.selectById(wrkMast.getLocNo());
+            LocMast locMast = locMastService.getById(wrkMast.getLocNo());
             if (locMast == null) {
                 News.taskInfo(wrkMast.getWrkNo(), "鐩爣搴撲綅:{} 淇℃伅涓嶅瓨鍦�", wrkMast.getLocNo());
                 continue;
@@ -257,14 +331,25 @@
             return false;
         }
 
+        if (isOutboundStationTaskLimitReached()) {
+            return false;
+        }
+
         Integer crnNo = basCrnp.getCrnNo();
 
-        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+        List<WrkMast> wrkMasts = wrkMastService.list(new QueryWrapper<WrkMast>()
                 .eq("crn_no", crnNo)
                 .eq("wrk_sts", WrkStsType.NEW_OUTBOUND.sts)
+                .orderBy(true, true, "batch_seq")
         );
 
         for (WrkMast wrkMast : wrkMasts) {
+            if (isOutboundTargetStationTaskLimitReached(wrkMast)) {
+                continue;
+            }
+            if (!allowBatchOutboundExecute(wrkMast)) {
+                continue;
+            }
             for (StationObjModel stationObjModel : outStationList) {
                 StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
                 if (stationThread == null) {
@@ -295,7 +380,7 @@
                 }
 
                 // 鑾峰彇搴撲綅淇℃伅
-                LocMast locMast = locMastService.selectById(wrkMast.getSourceLocNo());
+                LocMast locMast = locMastService.getById(wrkMast.getSourceLocNo());
                 if (locMast == null) {
                     News.taskInfo(wrkMast.getWrkNo(), "婧愬簱浣�:{} 淇℃伅涓嶅瓨鍦�", wrkMast.getSourceLocNo());
                     continue;
@@ -389,7 +474,7 @@
             }
 
             // 鑾峰彇搴撲綅淇℃伅
-            LocMast locMast = locMastService.selectById(wrkMast.getLocNo());
+            LocMast locMast = locMastService.getById(wrkMast.getLocNo());
             if (locMast == null) {
                 News.taskInfo(wrkMast.getWrkNo(), "鐩爣搴撲綅:{} 淇℃伅涓嶅瓨鍦�", wrkMast.getLocNo());
                 continue;
@@ -442,7 +527,19 @@
             return false;
         }
 
+        if (isOutboundStationTaskLimitReached()) {
+            return false;
+        }
+
         Integer crnNo = basCrnp.getCrnNo();
+
+        if (isOutboundTargetStationTaskLimitReached(wrkMast)) {
+            return false;
+        }
+
+        if (!allowBatchOutboundExecute(wrkMast)) {
+            return false;
+        }
 
         for (StationObjModel stationObjModel : outStationList) {
             StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
@@ -474,7 +571,7 @@
             }
 
             // 鑾峰彇搴撲綅淇℃伅
-            LocMast locMast = locMastService.selectById(wrkMast.getSourceLocNo());
+            LocMast locMast = locMastService.getById(wrkMast.getSourceLocNo());
             if (locMast == null) {
                 News.taskInfo(wrkMast.getWrkNo(), "婧愬簱浣�:{} 淇℃伅涓嶅瓨鍦�", wrkMast.getSourceLocNo());
                 continue;
@@ -510,6 +607,106 @@
         return false;
     }
 
+    private boolean allowBatchOutboundExecute(WrkMast wrkMast) {
+        if (wrkMast == null || Cools.isEmpty(wrkMast.getBatch())) {
+            return true;
+        }
+
+        if (Cools.isEmpty(wrkMast.getBatchSeq())) {
+            News.taskInfo(wrkMast.getWrkNo(), "鎵规:{} 缂哄皯鎵规搴忓彿锛屾殏涓嶅厑璁稿爢鍨涙満鍑哄簱", wrkMast.getBatch());
+            return false;
+        }
+
+        WrkMast firstBatchWrkMast = wrkMastService.getOne(new QueryWrapper<WrkMast>()
+                .eq("io_type", WrkIoType.OUT.id)
+                .eq("batch", wrkMast.getBatch())
+                .orderByAsc("batch_seq")
+                .orderByAsc("wrk_no")
+                .last("limit 1"));
+        if (firstBatchWrkMast == null) {
+            return true;
+        }
+
+        if (Cools.isEmpty(firstBatchWrkMast.getBatchSeq())) {
+            News.taskInfo(wrkMast.getWrkNo(), "鎵规:{} 瀛樺湪鏈厤缃壒娆″簭鍙风殑浠诲姟锛屾殏涓嶅厑璁稿爢鍨涙満鍑哄簱", wrkMast.getBatch());
+            return false;
+        }
+
+        boolean currentIsFirstBatchTask = wrkMast.getWrkNo().equals(firstBatchWrkMast.getWrkNo());
+        boolean firstBatchTaskExecuted = firstBatchWrkMast.getWrkSts() != null
+                && !firstBatchWrkMast.getWrkSts().equals(WrkStsType.NEW_OUTBOUND.sts);
+        if (!currentIsFirstBatchTask && !firstBatchTaskExecuted) {
+            News.taskInfo(wrkMast.getWrkNo(), "鎵规:{} 棣栦釜搴忓彿浠诲姟:{} 灏氭湭鎵ц锛屽綋鍓嶄换鍔℃殏涓嶅厑璁稿嚭搴�", wrkMast.getBatch(), firstBatchWrkMast.getWrkNo());
+            return false;
+        }
+
+        int batchRunningLimit = getSystemConfigInt("crnOutBatchRunningLimit", 5);
+        if (batchRunningLimit <= 0) {
+            return true;
+        }
+
+        long batchRunningCount = wrkMastService.count(new QueryWrapper<WrkMast>()
+                .eq("io_type", WrkIoType.OUT.id)
+                .eq("batch", wrkMast.getBatch())
+                .notIn("wrk_sts",
+                        WrkStsType.NEW_OUTBOUND.sts,
+                        WrkStsType.COMPLETE_OUTBOUND.sts,
+                        WrkStsType.SETTLE_OUTBOUND.sts));
+        if (batchRunningCount >= batchRunningLimit) {
+            News.taskInfo(wrkMast.getWrkNo(), "鎵规:{} 鎵ц涓换鍔℃暟杈惧埌涓婇檺锛屽綋鍓�={}锛屼笂闄�={}", wrkMast.getBatch(), batchRunningCount, batchRunningLimit);
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean isOutboundStationTaskLimitReached() {
+        int stationMaxTaskCount = getSystemConfigInt("stationMaxTaskCountLimit", 30);
+        if (stationMaxTaskCount <= 0) {
+            return false;
+        }
+
+        int currentStationTaskCount = stationOperateProcessUtils.getCurrentStationTaskCount();
+        if (currentStationTaskCount >= stationMaxTaskCount) {
+            News.warn("杈撻�佺珯鐐逛换鍔℃暟閲忚揪鍒颁笂闄愶紝宸插仠姝换鍔′笅鍙戙�傚綋鍓嶄换鍔℃暟={}锛屼笂闄�={}", currentStationTaskCount, stationMaxTaskCount);
+            return true;
+        }
+        return false;
+    }
+
+    private boolean isOutboundTargetStationTaskLimitReached(WrkMast wrkMast) {
+        if (wrkMast == null || wrkMast.getStaNo() == null) {
+            return false;
+        }
+        BasStation basStation = basStationService.getById(wrkMast.getStaNo());
+        if (basStation == null || basStation.getOutTaskLimit() == null || basStation.getOutTaskLimit() < 0) {
+            return false;
+        }
+        int currentStationTaskCount = stationOperateProcessUtils.getCurrentOutboundTaskCountByTargetStation(wrkMast.getStaNo());
+        if (currentStationTaskCount >= basStation.getOutTaskLimit()) {
+            News.taskInfo(wrkMast.getWrkNo(),
+                    "鐩爣鍑哄簱绔�:{} 宸茶揪鍑哄簱浠诲姟涓婇檺锛屽綋鍓�={}锛屼笂闄�={}",
+                    wrkMast.getStaNo(),
+                    currentStationTaskCount,
+                    basStation.getOutTaskLimit());
+            return true;
+        }
+        return false;
+    }
+
+    private int getSystemConfigInt(String code, int defaultValue) {
+        Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
+        if (systemConfigMapObj == null) {
+            return defaultValue;
+        }
+        try {
+            HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
+            return Integer.parseInt(systemConfigMap.getOrDefault(code, String.valueOf(defaultValue)));
+        } catch (Exception ignore) {
+            return defaultValue;
+        }
+    }
+
     private synchronized boolean crnExecuteLocTransfer(BasCrnp basCrnp, CrnThread crnThread) {
         CrnProtocol crnProtocol = crnThread.getStatus();
         if(crnProtocol == null){
@@ -518,14 +715,14 @@
 
         Integer crnNo = basCrnp.getCrnNo();
 
-        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+        List<WrkMast> wrkMasts = wrkMastService.list(new QueryWrapper<WrkMast>()
                 .eq("crn_no", crnNo)
                 .eq("wrk_sts", WrkStsType.NEW_LOC_MOVE.sts)
         );
 
         for (WrkMast wrkMast : wrkMasts) {
             // 鑾峰彇婧愬簱浣嶄俊鎭�
-            LocMast sourceLocMast = locMastService.selectById(wrkMast.getSourceLocNo());
+            LocMast sourceLocMast = locMastService.getById(wrkMast.getSourceLocNo());
             if (sourceLocMast == null) {
                 News.taskInfo(wrkMast.getWrkNo(), "婧愬簱浣�:{} 淇℃伅涓嶅瓨鍦�", wrkMast.getSourceLocNo());
                 continue;
@@ -537,7 +734,7 @@
             }
             
             // 鑾峰彇搴撲綅淇℃伅
-            LocMast locMast = locMastService.selectById(wrkMast.getLocNo());
+            LocMast locMast = locMastService.getById(wrkMast.getLocNo());
             if (locMast == null) {
                 News.taskInfo(wrkMast.getWrkNo(), "搴撲綅:{} 淇℃伅涓嶅瓨鍦�", wrkMast.getLocNo());
                 continue;
@@ -566,7 +763,7 @@
 
     //鍫嗗灈鏈轰换鍔℃墽琛屽畬鎴�
     public synchronized void crnIoExecuteFinish() {
-        List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>());
+        List<BasCrnp> basCrnps = basCrnpService.list(new QueryWrapper<>());
         for (BasCrnp basCrnp : basCrnps) {
             CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo());
             if(crnThread == null){
@@ -640,7 +837,7 @@
 
     public synchronized void plannerExecute() {
         int nowSec = (int) (System.currentTimeMillis() / 1000);
-        List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>());
+        List<BasCrnp> basCrnps = basCrnpService.list(new QueryWrapper<>());
         for (BasCrnp basCrnp : basCrnps) {
             String key = RedisKeyType.PLANNER_SCHEDULE.key + "CRN-" + basCrnp.getCrnNo();
             List<Object> items = redisUtil.lGet(key, 0, -1);
@@ -656,7 +853,7 @@
             if (crnProtocol == null) {
                 continue;
             }
-            List<WrkMast> running = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+            List<WrkMast> running = wrkMastService.list(new QueryWrapper<WrkMast>()
                     .eq("crn_no", basCrnp.getCrnNo())
                     .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts, WrkStsType.LOC_MOVE_RUN.sts)
             );
@@ -748,7 +945,7 @@
         }
 
         // 鑾峰彇婧愬簱浣嶄俊鎭�
-        LocMast sourceLocMast = locMastService.selectById(wrkMast.getSourceLocNo());
+        LocMast sourceLocMast = locMastService.getById(wrkMast.getSourceLocNo());
         if (sourceLocMast == null) {
             News.taskInfo(wrkMast.getWrkNo(), "婧愬簱浣�:{} 淇℃伅涓嶅瓨鍦�", wrkMast.getSourceLocNo());
             return false;
@@ -760,7 +957,7 @@
         }
 
         // 鑾峰彇搴撲綅淇℃伅
-        LocMast locMast = locMastService.selectById(wrkMast.getLocNo());
+        LocMast locMast = locMastService.getById(wrkMast.getLocNo());
         if (locMast == null) {
             News.taskInfo(wrkMast.getWrkNo(), "搴撲綅:{} 淇℃伅涓嶅瓨鍦�", wrkMast.getLocNo());
             return false;

--
Gitblit v1.9.1