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

---
 src/main/java/com/zy/core/trace/StationTaskTraceRegistry.java |   81 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 81 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/zy/core/trace/StationTaskTraceRegistry.java b/src/main/java/com/zy/core/trace/StationTaskTraceRegistry.java
index f983082..5c8b962 100644
--- a/src/main/java/com/zy/core/trace/StationTaskTraceRegistry.java
+++ b/src/main/java/com/zy/core/trace/StationTaskTraceRegistry.java
@@ -4,7 +4,10 @@
 import com.zy.asrs.domain.vo.StationTaskTraceEventVo;
 import com.zy.asrs.domain.vo.StationTaskTraceSegmentVo;
 import com.zy.asrs.domain.vo.StationTaskTraceVo;
+import com.zy.asrs.entity.WrkMast;
+import com.zy.asrs.service.WrkMastService;
 import com.zy.common.utils.RedisUtil;
+import com.zy.core.enums.WrkStsType;
 import com.zy.core.model.command.StationCommand;
 import com.zy.core.enums.RedisKeyType;
 import lombok.Data;
@@ -36,6 +39,9 @@
 
     @Autowired
     private RedisUtil redisUtil;
+
+    @Autowired
+    private WrkMastService wrkMastService;
 
     private final Map<Integer, TraceTaskState> taskStateMap = new ConcurrentHashMap<>();
     private volatile boolean loadedFromRedis = false;
@@ -149,6 +155,7 @@
     public List<StationTaskTraceVo> listLatestTraces() {
         ensureCacheLoaded();
         cleanupExpired();
+        reconcileInactiveBusinessTasks();
         List<StationTaskTraceVo> result = new ArrayList<>();
         for (TraceTaskState state : taskStateMap.values()) {
             if (state != null) {
@@ -166,6 +173,23 @@
         return result;
     }
 
+    public List<StationTaskTraceVo> listActiveTraces() {
+        List<StationTaskTraceVo> latestTraces = listLatestTraces();
+        List<StationTaskTraceVo> result = new ArrayList<>();
+        for (StationTaskTraceVo traceVo : latestTraces) {
+            if (traceVo == null) {
+                continue;
+            }
+            String status = traceVo.getStatus();
+            if (STATUS_WAITING.equals(status)
+                    || STATUS_RUNNING.equals(status)
+                    || STATUS_REROUTED.equals(status)) {
+                result.add(traceVo);
+            }
+        }
+        return result;
+    }
+
     private void cleanupExpired() {
         long now = System.currentTimeMillis();
         for (Map.Entry<Integer, TraceTaskState> entry : taskStateMap.entrySet()) {
@@ -175,6 +199,59 @@
                 removePersistedState(entry.getKey());
             }
         }
+    }
+
+    private void reconcileInactiveBusinessTasks() {
+        if (wrkMastService == null) {
+            return;
+        }
+        for (TraceTaskState state : taskStateMap.values()) {
+            if (state == null || state.isTerminal()) {
+                continue;
+            }
+            WrkMast wrkMast;
+            try {
+                wrkMast = wrkMastService.selectByWorkNo(state.taskNo);
+            } catch (Exception ignore) {
+                continue;
+            }
+            if (wrkMast == null) {
+                Integer currentStationId = state.currentStationId != null ? state.currentStationId : state.finalTargetStationId;
+                Map<String, Object> details = new LinkedHashMap<>();
+                details.put("reason", "wrk_missing");
+                state.markTerminal(state.traceVersion, STATUS_FINISHED, currentStationId, null,
+                        "AUTO_FINISHED", "杈撻�佷换鍔℃。宸蹭笉瀛樺湪锛岃建杩硅嚜鍔ㄧ粨鏉�", details);
+                persistState(state);
+                continue;
+            }
+            if (isStationTraceActiveWrkStatus(wrkMast.getWrkSts())) {
+                continue;
+            }
+            Integer currentStationId = state.currentStationId != null ? state.currentStationId : state.finalTargetStationId;
+            Map<String, Object> details = new LinkedHashMap<>();
+            details.put("reason", "wrk_status_transition");
+            details.put("wrkSts", wrkMast.getWrkSts());
+            details.put("wrkStsDesc", wrkMast.getWrkSts$());
+            if (isManualWrkStatus(wrkMast.getWrkSts())) {
+                state.markTerminal(state.traceVersion, STATUS_CANCELLED, currentStationId, null,
+                        "AUTO_CANCELLED", "杈撻�佷换鍔″凡閫�鍑鸿繍琛岋紝杞ㄨ抗鑷姩缁撴潫", details);
+            } else {
+                state.markTerminal(state.traceVersion, STATUS_FINISHED, currentStationId, null,
+                        "AUTO_FINISHED", "杈撻�佷换鍔″凡缁撴潫锛岃建杩硅嚜鍔ㄧ粨鏉�", details);
+            }
+            persistState(state);
+        }
+    }
+
+    private boolean isStationTraceActiveWrkStatus(Long wrkSts) {
+        return Objects.equals(wrkSts, WrkStsType.INBOUND_DEVICE_RUN.sts)
+                || Objects.equals(wrkSts, WrkStsType.STATION_RUN.sts);
+    }
+
+    private boolean isManualWrkStatus(Long wrkSts) {
+        return Objects.equals(wrkSts, WrkStsType.INBOUND_MANUAL.sts)
+                || Objects.equals(wrkSts, WrkStsType.OUTBOUND_MANUAL.sts)
+                || Objects.equals(wrkSts, WrkStsType.LOC_MOVE_MANUAL.sts);
     }
 
     private void ensureCacheLoaded() {
@@ -548,6 +625,10 @@
             return terminalExpireAt != null && terminalExpireAt <= now;
         }
 
+        private synchronized boolean isTerminal() {
+            return isTerminalStatus(this.status);
+        }
+
         private synchronized StationTaskTraceVo toVo() {
             StationTaskTraceVo vo = new StationTaskTraceVo();
             vo.setTaskNo(taskNo);

--
Gitblit v1.9.1