From fc67e7de548d5fc4ba84a2c09d3e99aad2fc11d7 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期三, 29 四月 2026 20:35:19 +0800
Subject: [PATCH] #堆垛机任务执行优先级修改

---
 src/main/java/com/zy/core/utils/station/StationOutboundDispatchProcessor.java |  421 ++++++++++++++++++++++++++++++++--------------------
 1 files changed, 257 insertions(+), 164 deletions(-)

diff --git a/src/main/java/com/zy/core/utils/station/StationOutboundDispatchProcessor.java b/src/main/java/com/zy/core/utils/station/StationOutboundDispatchProcessor.java
index e4e8c42..1833aa5 100644
--- a/src/main/java/com/zy/core/utils/station/StationOutboundDispatchProcessor.java
+++ b/src/main/java/com/zy/core/utils/station/StationOutboundDispatchProcessor.java
@@ -31,6 +31,7 @@
 import org.springframework.stereotype.Component;
 import org.springframework.beans.factory.annotation.Value;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -39,7 +40,7 @@
 @Component
 public class StationOutboundDispatchProcessor {
 
-    private static final int PENDING_DISPATCH_EXPIRE_SECONDS = 60 * 10;
+    private static final int PENDING_DISPATCH_EXPIRE_SECONDS = 60 * 60 * 24;
     private static final long DEFAULT_PENDING_DISCOVER_TIMEOUT_MS = 60_000L;
     private static final long DEFAULT_PENDING_SESSION_PROTECT_MS = 90_000L;
     private static final long DEFAULT_RECENT_DISPATCH_PROTECT_MS = 60_000L;
@@ -77,172 +78,140 @@
             if (wrkMast == null || wrkMast.getWrkNo() == null) {
                 return;
             }
-            Object pendingObj = redisUtil.get(RedisKeyType.STATION_OUT_PENDING_DISPATCH_.key + wrkMast.getWrkNo());
-            if (pendingObj != null) {
-                if (!Objects.equals(wrkMast.getWrkSts(), WrkStsType.OUTBOUND_RUN_COMPLETE.sts)) {
-                    clearPendingDispatch(wrkMast.getWrkNo());
-                    return;
-                }
-
-                StationObjModel pendingStationObjModel = getOutboundSourceStation(wrkMast);
-                if (pendingStationObjModel == null
-                        || pendingStationObjModel.getDeviceNo() == null
-                        || pendingStationObjModel.getStationId() == null) {
-                    clearPendingDispatch(wrkMast.getWrkNo());
-                    return;
-                }
-
-                StationThread pendingStationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, pendingStationObjModel.getDeviceNo());
-                if (pendingStationThread != null) {
-                    List<Integer> taskNoList = pendingStationThread.getAllTaskNoList();
-                    if (taskNoList != null && taskNoList.contains(wrkMast.getWrkNo())) {
-                        Date now = new Date();
-                        wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts);
-                        wrkMast.setSystemMsg("");
-                        wrkMast.setIoTime(now);
-                        wrkMast.setModiTime(now);
-                        if (wrkMastService.updateById(wrkMast)) {
-                            wrkAnalysisService.markOutboundStationStart(wrkMast, now);
-                            notifyUtils.notify(String.valueOf(SlaveType.Devp), pendingStationObjModel.getDeviceNo(),
-                                    String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(),
-                                    NotifyMsgType.STATION_OUT_TASK_RUN, null);
-                            clearPendingDispatch(wrkMast.getWrkNo());
-                            News.info("杈撻�佽澶囧凡鍙戠幇浠诲姟鍙凤紝浠诲姟杞繍琛屼腑銆俤eviceNo={}锛屾簮绔�={}锛屽伐浣滃彿={}",
-                                    pendingStationObjModel.getDeviceNo(), pendingStationObjModel.getStationId(), wrkMast.getWrkNo());
-                        }
-                        return;
-                    }
-                }
-
-                long createdAt;
-                try {
-                    createdAt = Long.parseLong(String.valueOf(pendingObj));
-                } catch (Exception ignore) {
-                    createdAt = System.currentTimeMillis();
-                }
-                long pendingDiscoverTimeoutMs = resolvePendingDiscoverTimeoutMs();
-                if (System.currentTimeMillis() - createdAt < pendingDiscoverTimeoutMs) {
-                    return;
-                }
-
-                PendingDispatchGuardResult guardResult = evaluatePendingDispatchGuard(wrkMast, pendingStationObjModel, pendingStationThread);
-                if (guardResult.keepPending()) {
-                    News.info("杈撻�佺珯鐐圭瓑寰呮簮绔欐墽琛岃秴鏃跺悗缁х画淇濇寔绛夊緟銆傚伐浣滃彿={}锛屾簮绔�={}锛屽師鍥�={}",
-                            wrkMast.getWrkNo(),
-                            pendingStationObjModel.getStationId(),
-                            guardResult.reason());
-                    markPendingDispatch(wrkMast.getWrkNo());
-                    return;
-                }
-                clearPendingDispatch(wrkMast.getWrkNo());
-                News.warn("杈撻�佺珯鐐规墽琛岀‘璁よ秴鏃讹紝涓旀湭鍙戠幇鏈夋晥娲诲姩閾捐矾锛屽凡閲婃斁閲嶈瘯璧勬牸銆傚伐浣滃彿={}", wrkMast.getWrkNo());
-            }
-
-            StationObjModel stationObjModel = getOutboundSourceStation(wrkMast);
-            if (stationObjModel == null || stationObjModel.getDeviceNo() == null || stationObjModel.getStationId() == null) {
+            if (shouldStopAfterPendingDispatchCheck(wrkMast)) {
                 return;
             }
-
-            long sameStationCount = wrkMastService.count(new QueryWrapper<WrkMast>()
-                    .eq("wrk_sts", WrkStsType.OUTBOUND_RUN_COMPLETE.sts)
-                    .eq("source_sta_no", stationObjModel.getStationId()));
-            if (sameStationCount > 1) {
-                News.taskError(wrkMast.getWrkNo(), "鍑哄簱寮傚父锛氬悓涓�婧愮珯瀛樺湪澶氱瑪鎼繍瀹屾垚浠诲姟锛屼笉涓嬪彂鍛戒护銆傛簮绔�={}锛屾暟閲�={}",
-                        stationObjModel.getStationId(), sameStationCount);
-                return;
-            }
-
-            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
-            if (stationThread == null) {
-                return;
-            }
-
-            Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
-            StationProtocol stationProtocol = stationMap == null ? null : stationMap.get(stationObjModel.getStationId());
-            if (stationProtocol == null) {
-                return;
-            }
-
-            Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId());
-            if (lock != null) {
-                return;
-            }
-
-            if (!(stationProtocol.isAutoing()
-                    && stationProtocol.isLoading()
-                    && stationProtocol.getTaskNo() == 0)) {
-                return;
-            }
-
-            Double pathLenFactor = stationOutboundDecisionSupport.resolveOutboundPathLenFactor(wrkMast);
-            List<Integer> outOrderList = stationOutboundDecisionSupport.getAllOutOrderList();
-            OutOrderDispatchDecision dispatchDecision =
-                    stationOutboundDecisionSupport.resolveOutboundDispatchDecision(
-                            stationProtocol.getStationId(),
-                            wrkMast,
-                            outOrderList,
-                            pathLenFactor
-                    );
-            Integer moveStaNo = dispatchDecision == null ? null : dispatchDecision.getTargetStationId();
-            if (moveStaNo == null) {
-                return;
-            }
-
-            DispatchLimitConfig limitConfig =
-                    stationDispatchLoadSupport.getDispatchLimitConfig(stationProtocol.getStationId(), moveStaNo);
-            int currentStationTaskCount = stationDispatchLoadSupport.countCurrentStationTask();
-            LoadGuardState loadGuardState = stationDispatchLoadSupport.buildLoadGuardState(limitConfig);
-            LoopHitResult loopHitResult =
-                    stationDispatchLoadSupport.findPathLoopHit(
-                            limitConfig,
-                            stationProtocol.getStationId(),
-                            moveStaNo,
-                            loadGuardState,
-                            wrkMast,
-                            pathLenFactor
-                    );
-            if (stationDispatchLoadSupport.isDispatchBlocked(
-                    limitConfig,
-                    currentStationTaskCount,
-                    loadGuardState,
-                    loopHitResult.isThroughLoop())) {
-                return;
-            }
-
-            StationCommand command = stationOutboundDecisionSupport.buildOutboundMoveCommand(
-                    stationThread,
-                    wrkMast,
-                    stationProtocol.getStationId(),
-                    moveStaNo,
-                    pathLenFactor
-            );
-            if (command == null) {
-                News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
-                return;
-            }
-
-            boolean offered = offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "crnStationOutExecute");
-            if (!offered) {
-                return;
-            }
-            if (stationMoveCoordinator != null) {
-                stationMoveCoordinator.recordDispatch(
-                        wrkMast.getWrkNo(),
-                        stationProtocol.getStationId(),
-                        "crnStationOutExecute",
-                        command,
-                        false
-                );
-            }
-            markPendingDispatch(wrkMast.getWrkNo());
-            News.info("杈撻�佺珯鐐瑰嚭搴撳懡浠ゅ凡鍏ヨ澶囨墽琛岄摼璺紝绛夊緟婧愮珯鎵ц銆傜珯鐐瑰彿={}锛屽伐浣滃彿={}锛屽懡浠ゆ暟鎹�={}",
-                    stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
-            redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5);
-            loadGuardState.reserveLoopTask(loopHitResult.getLoopNo());
-            stationDispatchLoadSupport.saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult);
+            dispatchCrnStationOutTask(wrkMast);
         } catch (Exception e) {
             e.printStackTrace();
         }
+    }
+
+    public void confirmPendingCrnStationOutDispatch(WrkMast wrkMast) {
+        try {
+            shouldStopAfterPendingDispatchCheck(wrkMast);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void dispatchNextCrnStationOutTask(Integer sourceStationId) {
+        try {
+            if (sourceStationId == null) {
+                return;
+            }
+            List<WrkMast> sameSourceTaskList = loadCrnOutboundCompleteTasksBySourceStation(sourceStationId);
+            if (sameSourceTaskList.isEmpty()) {
+                return;
+            }
+            WrkMast dispatchCandidate = null;
+            int pendingTaskCount = 0;
+            int dispatchableTaskCount = 0;
+            for (WrkMast sameSourceTask : sameSourceTaskList) {
+                if (sameSourceTask == null || sameSourceTask.getWrkNo() == null) {
+                    continue;
+                }
+                if (hasPendingDispatch(sameSourceTask.getWrkNo())) {
+                    pendingTaskCount++;
+                    continue;
+                }
+                dispatchableTaskCount++;
+                if (dispatchCandidate == null) {
+                    dispatchCandidate = sameSourceTask;
+                }
+            }
+            if (dispatchCandidate == null) {
+                return;
+            }
+            if (dispatchableTaskCount > 1) {
+                News.taskError(dispatchCandidate.getWrkNo(),
+                        "鍑哄簱寮傚父锛氬悓涓�婧愮珯瀛樺湪澶氱瑪寰呬笅鍙戞惉杩愬畬鎴愪换鍔★紝涓嶄笅鍙戝懡浠ゃ�傛簮绔�={}锛屽緟涓嬪彂鏁伴噺={}锛屽緟纭鏁伴噺={}",
+                        sourceStationId, dispatchableTaskCount, pendingTaskCount);
+                return;
+            }
+            if (pendingTaskCount > 0 || sameSourceTaskList.size() > 1) {
+                News.info("婧愮珯鍑哄簱鍊欓�変换鍔″凡纭畾銆傛簮绔�={}锛屽�欓�夊伐浣滃彿={}锛屽緟纭鏁伴噺={}锛屽緟涓嬪彂鏁伴噺={}",
+                        sourceStationId,
+                        dispatchCandidate.getWrkNo(),
+                        pendingTaskCount,
+                        dispatchableTaskCount);
+            }
+            dispatchCrnStationOutTask(dispatchCandidate);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private boolean shouldStopAfterPendingDispatchCheck(WrkMast wrkMast) {
+        if (wrkMast == null || wrkMast.getWrkNo() == null) {
+            return true;
+        }
+        Object pendingDispatchMarker = redisUtil.get(RedisKeyType.STATION_OUT_PENDING_DISPATCH_.key + wrkMast.getWrkNo());
+        if (pendingDispatchMarker == null) {
+            return false;
+        }
+        return processPendingDispatch(wrkMast, pendingDispatchMarker);
+    }
+
+    private boolean processPendingDispatch(WrkMast wrkMast, Object pendingDispatchMarker) {
+        if (!Objects.equals(wrkMast.getWrkSts(), WrkStsType.OUTBOUND_RUN_COMPLETE.sts)) {
+            clearPendingDispatch(wrkMast);
+            return true;
+        }
+
+        StationObjModel sourceStationObjModel = getOutboundSourceStation(wrkMast);
+        if (sourceStationObjModel == null
+                || sourceStationObjModel.getDeviceNo() == null
+                || sourceStationObjModel.getStationId() == null) {
+            clearPendingDispatch(wrkMast);
+            return true;
+        }
+
+        StationThread sourceStationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, sourceStationObjModel.getDeviceNo());
+        if (sourceStationThread != null) {
+            List<Integer> taskNoList = sourceStationThread.getAllTaskNoList();
+            if (taskNoList != null && taskNoList.contains(wrkMast.getWrkNo())) {
+                Date now = new Date();
+                wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts);
+                wrkMast.setSystemMsg("");
+                wrkMast.setIoTime(now);
+                wrkMast.setModiTime(now);
+                if (wrkMastService.updateById(wrkMast)) {
+                    wrkAnalysisService.markOutboundStationStart(wrkMast, now);
+                    notifyUtils.notify(String.valueOf(SlaveType.Devp), sourceStationObjModel.getDeviceNo(),
+                            String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(),
+                            NotifyMsgType.STATION_OUT_TASK_RUN, null);
+                    clearPendingDispatch(wrkMast);
+                    News.info("杈撻�佽澶囧凡鍙戠幇浠诲姟鍙凤紝浠诲姟杞繍琛屼腑銆俤eviceNo={}锛屾簮绔�={}锛屽伐浣滃彿={}",
+                            sourceStationObjModel.getDeviceNo(), sourceStationObjModel.getStationId(), wrkMast.getWrkNo());
+                }
+                return true;
+            }
+        }
+
+        long createdAt;
+        try {
+            createdAt = Long.parseLong(String.valueOf(pendingDispatchMarker));
+        } catch (Exception ignore) {
+            createdAt = System.currentTimeMillis();
+        }
+        long pendingDiscoverTimeoutMs = resolvePendingDiscoverTimeoutMs();
+        if (System.currentTimeMillis() - createdAt < pendingDiscoverTimeoutMs) {
+            return true;
+        }
+
+        PendingDispatchGuardResult guardResult = evaluatePendingDispatchGuard(wrkMast, sourceStationObjModel, sourceStationThread);
+        if (guardResult.keepPending()) {
+            News.info("杈撻�佺珯鐐圭瓑寰呮簮绔欐墽琛岃秴鏃跺悗缁х画淇濇寔绛夊緟銆傚伐浣滃彿={}锛屾簮绔�={}锛屽師鍥�={}",
+                    wrkMast.getWrkNo(),
+                    sourceStationObjModel.getStationId(),
+                    guardResult.reason());
+            markPendingDispatch(wrkMast.getWrkNo());
+            return true;
+        }
+        clearPendingDispatch(wrkMast);
+        News.warn("杈撻�佺珯鐐规墽琛岀‘璁よ秴鏃讹紝涓旀湭鍙戠幇鏈夋晥娲诲姩閾捐矾锛屽凡閲婃斁閲嶈瘯璧勬牸銆傚伐浣滃彿={}", wrkMast.getWrkNo());
+        return false;
     }
 
     public void dualCrnStationOutExecute(WrkMast wrkMast) {
@@ -322,14 +291,131 @@
         if (wrkMast == null || wrkMast.getSourceStaNo() == null) {
             return null;
         }
-        BasStation basStation = basStationService.getById(wrkMast.getSourceStaNo());
+        return getOutboundSourceStation(wrkMast.getSourceStaNo());
+    }
+
+    private StationObjModel getOutboundSourceStation(Integer sourceStationId) {
+        if (sourceStationId == null) {
+            return null;
+        }
+        BasStation basStation = basStationService.getById(sourceStationId);
         if (basStation == null || basStation.getDeviceNo() == null) {
             return null;
         }
         StationObjModel stationObjModel = new StationObjModel();
-        stationObjModel.setStationId(wrkMast.getSourceStaNo());
+        stationObjModel.setStationId(sourceStationId);
         stationObjModel.setDeviceNo(basStation.getDeviceNo());
         return stationObjModel;
+    }
+
+    private void dispatchCrnStationOutTask(WrkMast wrkMast) {
+        if (wrkMast == null || wrkMast.getWrkNo() == null) {
+            return;
+        }
+        StationObjModel stationObjModel = getOutboundSourceStation(wrkMast);
+        if (stationObjModel == null || stationObjModel.getDeviceNo() == null || stationObjModel.getStationId() == null) {
+            return;
+        }
+
+        StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
+        if (stationThread == null) {
+            return;
+        }
+
+        Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
+        StationProtocol stationProtocol = stationMap == null ? null : stationMap.get(stationObjModel.getStationId());
+        if (stationProtocol == null) {
+            return;
+        }
+
+        Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId());
+        if (lock != null) {
+            return;
+        }
+
+        if (!(stationProtocol.isAutoing()
+                && stationProtocol.isLoading()
+                && stationProtocol.getTaskNo() == 0)) {
+            return;
+        }
+
+        Double pathLenFactor = stationOutboundDecisionSupport.resolveOutboundPathLenFactor(wrkMast);
+        List<Integer> outOrderList = stationOutboundDecisionSupport.getAllOutOrderList();
+        OutOrderDispatchDecision dispatchDecision =
+                stationOutboundDecisionSupport.resolveOutboundDispatchDecision(
+                        stationProtocol.getStationId(),
+                        wrkMast,
+                        outOrderList,
+                        pathLenFactor
+                );
+        Integer moveStaNo = dispatchDecision == null ? null : dispatchDecision.getTargetStationId();
+        if (moveStaNo == null) {
+            return;
+        }
+
+        DispatchLimitConfig limitConfig =
+                stationDispatchLoadSupport.getDispatchLimitConfig(stationProtocol.getStationId(), moveStaNo);
+        int currentStationTaskCount = stationDispatchLoadSupport.countCurrentStationTask();
+        LoadGuardState loadGuardState = stationDispatchLoadSupport.buildLoadGuardState(limitConfig);
+        LoopHitResult loopHitResult =
+                stationDispatchLoadSupport.findPathLoopHit(
+                        limitConfig,
+                        stationProtocol.getStationId(),
+                        moveStaNo,
+                        loadGuardState,
+                        wrkMast,
+                        pathLenFactor
+                );
+        if (stationDispatchLoadSupport.isDispatchBlocked(
+                limitConfig,
+                currentStationTaskCount,
+                loadGuardState,
+                loopHitResult.isThroughLoop())) {
+            return;
+        }
+
+        StationCommand command = stationOutboundDecisionSupport.buildOutboundMoveCommand(
+                stationThread,
+                wrkMast,
+                stationProtocol.getStationId(),
+                moveStaNo,
+                pathLenFactor
+        );
+        if (command == null) {
+            News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
+            return;
+        }
+
+        boolean offered = offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "crnStationOutExecute");
+        if (!offered) {
+            return;
+        }
+        if (stationMoveCoordinator != null) {
+            stationMoveCoordinator.recordDispatch(
+                    wrkMast.getWrkNo(),
+                    stationProtocol.getStationId(),
+                    "crnStationOutExecute",
+                    command,
+                    false
+            );
+        }
+        markPendingDispatch(wrkMast.getWrkNo());
+        News.info("杈撻�佺珯鐐瑰嚭搴撳懡浠ゅ凡鍏ヨ澶囨墽琛岄摼璺紝绛夊緟婧愮珯鎵ц銆傜珯鐐瑰彿={}锛屽伐浣滃彿={}锛屽懡浠ゆ暟鎹�={}",
+                stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
+        redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5);
+        loadGuardState.reserveLoopTask(loopHitResult.getLoopNo());
+        stationDispatchLoadSupport.saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult);
+    }
+
+    private List<WrkMast> loadCrnOutboundCompleteTasksBySourceStation(Integer sourceStationId) {
+        if (sourceStationId == null) {
+            return new ArrayList<>();
+        }
+        return wrkMastService.list(new QueryWrapper<WrkMast>()
+                .eq("wrk_sts", WrkStsType.OUTBOUND_RUN_COMPLETE.sts)
+                .eq("source_sta_no", sourceStationId)
+                .isNotNull("crn_no")
+                .orderByAsc("io_time", "wrk_no"));
     }
 
     private boolean hasPendingDispatch(Integer wrkNo) {
@@ -350,6 +436,13 @@
         redisUtil.del(RedisKeyType.STATION_OUT_PENDING_DISPATCH_.key + wrkNo);
     }
 
+    private void clearPendingDispatch(WrkMast wrkMast) {
+        if (wrkMast == null || wrkMast.getWrkNo() == null) {
+            return;
+        }
+        clearPendingDispatch(wrkMast.getWrkNo());
+    }
+
     private PendingDispatchGuardResult evaluatePendingDispatchGuard(WrkMast wrkMast,
                                                                     StationObjModel stationObjModel,
                                                                     StationThread stationThread) {

--
Gitblit v1.9.1