From 51e110ca563b40854763ec5a317514da8fda548c Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期日, 19 四月 2026 11:30:09 +0800
Subject: [PATCH] #优化工作档和工作号事务V3.0.0.4

---
 src/main/java/com/zy/core/plugin/FakeProcess.java |  622 ++++++++-----------------------------------------------
 1 files changed, 98 insertions(+), 524 deletions(-)

diff --git a/src/main/java/com/zy/core/plugin/FakeProcess.java b/src/main/java/com/zy/core/plugin/FakeProcess.java
index 962bacd..adbe6f4 100644
--- a/src/main/java/com/zy/core/plugin/FakeProcess.java
+++ b/src/main/java/com/zy/core/plugin/FakeProcess.java
@@ -1,16 +1,9 @@
 package com.zy.core.plugin;
 
 import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.core.common.Cools;
-import com.zy.asrs.domain.param.CreateInTaskParam;
-import com.zy.asrs.domain.param.CreateOutTaskParam;
-import com.zy.asrs.utils.Utils;
 import com.zy.asrs.entity.*;
 import com.zy.asrs.service.*;
-import com.zy.common.entity.FindCrnNoResult;
-import com.zy.common.service.CommonService;
 import com.zy.common.utils.RedisUtil;
 import com.zy.core.News;
 import com.zy.core.cache.MessageQueue;
@@ -22,16 +15,17 @@
 import com.zy.core.model.command.CrnCommand;
 import com.zy.core.model.command.StationCommand;
 import com.zy.core.model.protocol.CrnProtocol;
-import com.zy.core.model.protocol.DualCrnProtocol;
-import com.zy.core.model.protocol.StationProtocol;
+import com.zy.core.network.fake.FakeConfigKeys;
+import com.zy.core.network.fake.FakeConfigSupport;
 import com.zy.core.plugin.api.MainProcessPluginApi;
+import com.zy.core.plugin.station.FakeStationMonitor;
+import com.zy.core.plugin.station.FakeTaskGenerator;
 import com.zy.core.plugin.store.StoreInTaskContext;
 import com.zy.core.plugin.store.StoreInTaskGenerationService;
 import com.zy.core.plugin.store.StoreInTaskPolicy;
 import com.zy.core.task.MainProcessLane;
 import com.zy.core.task.MainProcessTaskSubmitter;
 import com.zy.core.thread.CrnThread;
-import com.zy.core.thread.DualCrnThread;
 import com.zy.core.thread.StationThread;
 import com.zy.core.utils.CrnOperateProcessUtils;
 import com.zy.core.utils.DualCrnOperateProcessUtils;
@@ -43,34 +37,83 @@
 import org.springframework.stereotype.Component;
 
 import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
 
 @Slf4j
 @Component
 public class FakeProcess implements MainProcessPluginApi, StoreInTaskPolicy {
-    private static final long MAIN_DISPATCH_INTERVAL_MS = 200L;
-    private static final long ASYNC_DISPATCH_INTERVAL_MS = 50L;
+    private long getMainDispatchIntervalMs() {
+        return FakeConfigSupport.getLong(FakeConfigKeys.FAKE_STATION_IDLE_LOOP_DELAY_MS, 200L);
+    }
 
-    private static final Map<Integer, Long> stationStayTimeMap = new ConcurrentHashMap<>();
+    private long getAsyncDispatchIntervalMs() {
+        return Math.max(50L, FakeConfigSupport.getLong(FakeConfigKeys.FAKE_STATION_INITIALIZE_DELAY_MS, 50L));
+    }
+
+    private long getOutStationStayTimeoutMs() {
+        return FakeConfigSupport.getLong(FakeConfigKeys.FAKE_OUT_STATION_STAY_TIMEOUT_MS, 3000L);
+    }
+
     private static volatile String enableFake = "N";
+
     private static volatile String fakeRealTaskRequestWms = "N";
     private static volatile String fakeGenerateInTask = "Y";
     private static volatile String fakeGenerateOutTask = "Y";
 
-    @Autowired
-    private WrkMastService wrkMastService;
-    @Autowired
-    private BasDevpService basDevpService;
+    private static final Map<String, Long> OUT_STATION_STAY_MARKER = new HashMap<String, Long>();
+
+    private final Object outStationStayLock = new Object();
+
+    private boolean shouldDispatchOutStationWriteInfo(String taskNo) {
+        long now = System.currentTimeMillis();
+        long timeoutMs = getOutStationStayTimeoutMs();
+        synchronized (outStationStayLock) {
+            Long lastTime = OUT_STATION_STAY_MARKER.get(taskNo);
+            if (lastTime == null || now - lastTime >= timeoutMs) {
+                OUT_STATION_STAY_MARKER.put(taskNo, now);
+                return true;
+            }
+            return false;
+        }
+    }
+
+    private void clearOutStationStayMarker(String taskNo) {
+        synchronized (outStationStayLock) {
+            OUT_STATION_STAY_MARKER.remove(taskNo);
+        }
+    }
+
+    private void dispatchOutStationWriteInfoIfReady(WrkMast wrkMast, BasCrnp basCrnp) {
+        String taskNo = wrkMast == null ? null : wrkMast.getWmsWrkNo();
+        if (taskNo == null || !shouldDispatchOutStationWriteInfo(taskNo)) {
+            return;
+        }
+        List<StationObjModel> outStationList = basCrnp.getOutStationList$();
+        if (outStationList.isEmpty()) {
+            News.info("鍫嗗灈鏈�:{} 鍑哄簱绔欑偣鏈缃�", basCrnp.getCrnNo());
+            return;
+        }
+        for (StationObjModel stationObjModel : outStationList) {
+            if (!stationObjModel.getStationId().equals(wrkMast.getSourceStaNo())) {
+                continue;
+            }
+            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
+            if (stationThread == null) {
+                continue;
+            }
+            StationCommand command = stationThread.getCommand(StationCommandType.WRITE_INFO, 9998,
+                    wrkMast.getSourceStaNo(), 0, 0);
+            stationCommandDispatcher.dispatch(stationObjModel.getDeviceNo(), command, "fake-process", "crn-out-complete-write-info");
+        }
+    }
+
     @Autowired
     private ConfigService configService;
     @Autowired
-    private LocMastService locMastService;
+    private WrkMastService wrkMastService;
     @Autowired
-    private CommonService commonService;
+    private WrkAnalysisService wrkAnalysisService;
     @Autowired
     private BasCrnpService basCrnpService;
-    @Autowired
-    private BasDualCrnpService basDualCrnpService;
     @Autowired
     private RedisUtil redisUtil;
     @Autowired
@@ -78,47 +121,52 @@
     @Autowired
     private StationOperateProcessUtils stationOperateProcessUtils;
     @Autowired
-    private WrkAnalysisService wrkAnalysisService;
-    @Autowired
     private DualCrnOperateProcessUtils dualCrnOperateProcessUtils;
-    @Autowired
-    private StoreInTaskGenerationService storeInTaskGenerationService;
     @Autowired
     private StationCommandDispatcher stationCommandDispatcher;
     @Autowired
     private MainProcessTaskSubmitter mainProcessTaskSubmitter;
+    @Autowired
+    private FakeStationMonitor fakeStationMonitor;
+    @Autowired
+    private FakeTaskGenerator fakeTaskGenerator;
 
     @Override
     public void run() {
         long startTime = System.currentTimeMillis();
         refreshFakeConfig();
+        syncConfigToComponents();
 
+        long asyncDispatchIntervalMs = getAsyncDispatchIntervalMs();
+        long mainDispatchIntervalMs = getMainDispatchIntervalMs();
         // 浠跨湡寮傛浠诲姟
-        submitAsyncTasks(ASYNC_DISPATCH_INTERVAL_MS);
+        fakeStationMonitor.submitMonitorTasks(asyncDispatchIntervalMs);
         // 浠跨湡杈撻�佺嚎鍫靛妫�娴�
-        stationOperateProcessUtils.submitCheckStationRunBlockTasks(MainProcessLane.FAKE_STATION_RUN_BLOCK, ASYNC_DISPATCH_INTERVAL_MS);
+        stationOperateProcessUtils.submitCheckStationRunBlockTasks(MainProcessLane.FAKE_STATION_RUN_BLOCK, asyncDispatchIntervalMs);
 
         // 璇锋眰鐢熸垚鍏ュ簱浠诲姟
-        generateStoreWrkFile();
+        fakeTaskGenerator.submitGenerateTasks();
 
         // 鎵ц鍫嗗灈鏈轰换鍔�
-        crnOperateUtils.submitCrnIoTasks(MainProcessLane.FAKE_CRN_IO, MAIN_DISPATCH_INTERVAL_MS);
+        crnOperateUtils.submitCrnIoTasks(MainProcessLane.FAKE_CRN_IO, mainDispatchIntervalMs);
         // 鍫嗗灈鏈轰换鍔℃墽琛屽畬鎴�
-        submitCrnIoExecuteFinishTasks(MAIN_DISPATCH_INTERVAL_MS);
+        submitCrnIoExecuteFinishTasks(mainDispatchIntervalMs);
         // 鎵ц杈撻�佺珯鐐瑰叆搴撲换鍔�
-        stationOperateProcessUtils.submitStationInTasks(MainProcessLane.FAKE_STATION_IN, MAIN_DISPATCH_INTERVAL_MS);
+        stationOperateProcessUtils.submitStationInTasks(MainProcessLane.FAKE_STATION_IN, mainDispatchIntervalMs);
         // 妫�娴嬪叆搴撲换鍔℃槸鍚﹀凡缁忓埌杈剧洰鏍囩珯鍙�
-        stationOperateProcessUtils.submitInboundStationArrivalTasks(MAIN_DISPATCH_INTERVAL_MS);
+        stationOperateProcessUtils.submitInboundStationArrivalTasks(mainDispatchIntervalMs);
         // 杈撻�佺嚎鎵ц鍫嗗灈鏈哄嚭搴撳悗鐨勭珯鍙版祦杞�
-        stationOperateProcessUtils.submitCrnStationOutTasks(MainProcessLane.FAKE_STATION_OUT, MAIN_DISPATCH_INTERVAL_MS);
+        stationOperateProcessUtils.submitCrnStationOutTasks(MainProcessLane.FAKE_STATION_OUT, mainDispatchIntervalMs);
+        // 妫�娴嬪嚭搴撲换鍔℃槸鍚﹀凡缁忓埌杈剧洰鏍囩珯鍙�
+        stationOperateProcessUtils.submitStationOutExecuteFinishTasks(mainDispatchIntervalMs);
+        // 妫�娴嬬珯鍙拌繍琛屽畬鎴愬悗鐨勪换鍔¤浆瀹屾垚
+        stationOperateProcessUtils.submitCheckTaskToCompleteTasks(mainDispatchIntervalMs);
         // 妫�娴嬪苟澶勭悊鍑哄簱鎺掑簭
-        stationOperateProcessUtils.submitCheckStationOutOrderTasks(MainProcessLane.FAKE_STATION_OUT_ORDER, MAIN_DISPATCH_INTERVAL_MS);
-        // 鐩戞帶杈撻�佺嚎缁曞湀绔欑偣
-        stationOperateProcessUtils.submitWatchCircleStationTasks(MainProcessLane.FAKE_STATION_WATCH_CIRCLE, MAIN_DISPATCH_INTERVAL_MS);
+        stationOperateProcessUtils.submitCheckStationOutOrderTasks(MainProcessLane.FAKE_STATION_OUT_ORDER, mainDispatchIntervalMs);
         // 鎵ц鍙屽伐浣嶅爢鍨涙満浠诲姟
-        dualCrnOperateProcessUtils.submitDualCrnIoTasks(MainProcessLane.FAKE_DUAL_CRN_IO, MAIN_DISPATCH_INTERVAL_MS);
+        dualCrnOperateProcessUtils.submitDualCrnIoTasks(MainProcessLane.FAKE_DUAL_CRN_IO, mainDispatchIntervalMs);
         // 鍙屽伐浣嶅爢鍨涙満浠诲姟鎵ц瀹屾垚
-        dualCrnOperateProcessUtils.submitDualCrnIoExecuteFinishTasks(MainProcessLane.FAKE_DUAL_CRN_IO_FINISH, MAIN_DISPATCH_INTERVAL_MS);
+        dualCrnOperateProcessUtils.submitDualCrnIoExecuteFinishTasks(MainProcessLane.FAKE_DUAL_CRN_IO_FINISH, mainDispatchIntervalMs);
 
         News.info("[WCS Debug] 涓荤嚎绋婻un鎵ц瀹屾垚,鑰楁椂:{}ms", System.currentTimeMillis() - startTime);
     }
@@ -148,23 +196,12 @@
         }
     }
 
-    private void submitAsyncTasks(long minIntervalMs) {
-        submitAsyncTask("checkInStationHasTask", minIntervalMs, this::checkInStationHasTask);
-        submitAsyncTask("generateFakeInTask", minIntervalMs, this::generateFakeInTask);
-        submitAsyncTask("generateFakeOutTask", minIntervalMs, this::generateFakeOutTask);
-        submitAsyncTask("calcAllStationStayTime", minIntervalMs, this::calcAllStationStayTime);
-        submitAsyncTask("checkOutStationStayTimeOut", minIntervalMs, this::checkOutStationStayTimeOut);
-        submitAsyncTask("checkInStationCrnTake", minIntervalMs, this::checkInStationCrnTake);
-    }
-
-    private void submitAsyncTask(String taskName, long minIntervalMs, Runnable task) {
-        mainProcessTaskSubmitter.submitKeyedSerialTask(
-                MainProcessLane.FAKE_ASYNC,
-                taskName,
-                taskName,
-                minIntervalMs,
-                task
-        );
+    private void syncConfigToComponents() {
+        fakeStationMonitor.setEnableFake(enableFake);
+        fakeStationMonitor.setFakeGenerateInTask(fakeGenerateInTask);
+        fakeTaskGenerator.setFakeRealTaskRequestWms(fakeRealTaskRequestWms);
+        fakeTaskGenerator.setFakeGenerateInTask(fakeGenerateInTask);
+        fakeTaskGenerator.setFakeGenerateOutTask(fakeGenerateOutTask);
     }
 
     private void submitCrnIoExecuteFinishTasks(long minIntervalMs) {
@@ -184,461 +221,19 @@
         }
     }
 
-    private void submitGenerateStoreTasks() {
-        List<BasDevp> basDevps = basDevpService.list(new QueryWrapper<>());
-        for (BasDevp basDevp : basDevps) {
-            List<StationObjModel> barcodeStations = getBarcodeStations(basDevp);
-            for (StationObjModel stationObjModel : barcodeStations) {
-                Integer stationId = stationObjModel == null ? null : stationObjModel.getStationId();
-                if (stationId == null) {
-                    continue;
-                }
-                storeInTaskGenerationService.submitGenerateStoreTask(
-                        this,
-                        basDevp,
-                        stationObjModel,
-                        MainProcessLane.FAKE_GENERATE_STORE,
-                        MAIN_DISPATCH_INTERVAL_MS,
-                        () -> storeInTaskGenerationService.generate(this, basDevp, stationObjModel)
-                );
-            }
-        }
-    }
-
-    // 妫�娴嬪叆搴撶珯鏄惁鏈変换鍔$敓鎴愶紝骞朵豢鐪熺敓鎴愭ā鎷熷叆搴撶珯鐐规暟鎹�
-    private void checkInStationHasTask() {
-        if (!enableFake.equals("Y")) {
-            return;
-        }
-
-        if (!fakeGenerateInTask.equals("Y")) {
-            return;
-        }
-
-        List<BasDevp> basDevps = basDevpService.list(new QueryWrapper<>());
-        for (BasDevp basDevp : basDevps) {
-            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
-            if (stationThread == null) {
-                continue;
-            }
-
-            Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
-
-            List<StationObjModel> list = basDevp.getInStationList$();
-            for (StationObjModel entity : list) {
-                Integer stationId = entity.getStationId();
-                if (!stationMap.containsKey(stationId)) {
-                    continue;
-                }
-
-                StationProtocol stationProtocol = stationMap.get(stationId);
-                if (stationProtocol == null) {
-                    continue;
-                }
-
-                Object lock = redisUtil.get(RedisKeyType.GENERATE_FAKE_IN_STATION_DATA_LIMIT.key + stationId);
-                if (lock != null) {
-                    continue;
-                }
-
-                // 婊¤冻鑷姩銆佹棤鐗┿�佸伐浣滃彿0锛岀敓鎴愬叆搴撴暟鎹�
-                if (stationProtocol.isAutoing()
-                        && !stationProtocol.isLoading()
-                        && stationProtocol.getTaskNo() == 0) {
-                    StationCommand command = stationThread.getCommand(StationCommandType.MOVE,
-                            commonService.getWorkNo(WrkIoType.FAKE_TASK_NO.id), stationId,
-                            entity.getBarcodeStation().getStationId(), 0);
-                    stationCommandDispatcher.dispatch(basDevp.getDevpNo(), command, "fake-process", "fake-enable-in");
-                    if (entity.getBarcodeStation() != null && entity.getBarcodeStation().getStationId() != null) {
-                        Utils.precomputeInTaskEnableRow(entity.getBarcodeStation().getStationId());
-                    }
-                    redisUtil.set(RedisKeyType.GENERATE_FAKE_IN_STATION_DATA_LIMIT.key + stationId, "lock", 5);
-                }
-            }
-        }
-    }
-
-    // 鐢熸垚浠跨湡妯℃嫙鍏ュ簱浠诲姟
-    private void generateFakeInTask() {
-        if (!enableFake.equals("Y")) {
-            return;
-        }
-
-        if (fakeRealTaskRequestWms.equals("Y")) {
-            return;
-        }
-
-        if (!fakeGenerateInTask.equals("Y")) {
-            return;
-        }
-
-        List<BasDevp> basDevps = basDevpService.list(new QueryWrapper<>());
-        for (BasDevp basDevp : basDevps) {
-            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
-            if (stationThread == null) {
-                continue;
-            }
-
-            Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
-
-            List<StationObjModel> list = basDevp.getBarcodeStationList$();
-            for (StationObjModel model : list) {
-                Integer stationId = model.getStationId();
-                if (!stationMap.containsKey(stationId)) {
-                    continue;
-                }
-
-                StationProtocol stationProtocol = stationMap.get(stationId);
-                if (stationProtocol == null) {
-                    continue;
-                }
-
-                Object object = redisUtil.get(RedisKeyType.GENERATE_FAKE_IN_TASK_LIMIT.key + stationId);
-                if (object != null) {
-                    continue;
-                }
-
-                // 婊¤冻鑷姩銆佹湁鐗┿�佹湁宸ヤ綔鍙凤紝鐢熸垚鍏ュ簱鏁版嵁
-                if (stationProtocol.isAutoing()
-                        && stationProtocol.isLoading()
-                        && stationProtocol.getTaskNo() > 0) {
-                    if (Cools.isEmpty(stationProtocol.getBarcode())) {
-                        continue;
-                    }
-
-                    // 妫�娴嬩换鍔℃槸鍚︾敓鎴�
-                    List<WrkMast> wrkMasts = wrkMastService
-                            .list(new QueryWrapper<WrkMast>().eq("barcode", stationProtocol.getBarcode()));
-                    if (!wrkMasts.isEmpty()) {
-                        continue;
-                    }
-
-                    List<LocMast> locMastList = locMastService
-                            .list(new QueryWrapper<LocMast>().eq("loc_sts", String.valueOf(LocStsType.O)));
-                    if (locMastList.isEmpty()) {
-                        continue;
-                    }
-
-                    int nextInt = new Random().nextInt(locMastList.size());
-                    LocMast locMast = locMastList.get(nextInt);
-
-                    FindCrnNoResult findCrnNoResult = commonService.findCrnNoByLocNo(locMast.getLocNo());
-                    if (findCrnNoResult == null) {
-                        continue;
-                    }
-
-                    Integer targetStationId = commonService.findInStationId(findCrnNoResult, stationId);
-                    if (targetStationId == null) {
-                        continue;
-                    }
-
-                    CreateInTaskParam taskParam = new CreateInTaskParam();
-                    taskParam.setTaskNo(String.valueOf(commonService.getWorkNo(WrkIoType.IN.id)));
-                    taskParam.setSourceStaNo(stationId);
-                    taskParam.setStaNo(targetStationId);
-                    taskParam.setLocNo(locMast.getLocNo());
-                    taskParam.setBarcode(stationProtocol.getBarcode());
-                    WrkMast wrkMast = commonService.createInTask(taskParam);
-
-                    StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(),
-                            stationId, stationId, 0);
-                    if (command == null) {
-                        News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
-                        continue;
-                    }
-                    stationCommandDispatcher.dispatch(basDevp.getDevpNo(), command, "fake-process", "fake-in-task");
-                    redisUtil.set(RedisKeyType.GENERATE_FAKE_IN_TASK_LIMIT.key + stationId, "lock", 5);
-                }
-            }
-        }
-    }
-
-    // 鐢熸垚浠跨湡妯℃嫙鍑哄簱浠诲姟
-    private void generateFakeOutTask() {
-        try {
-            if (!enableFake.equals("Y")) {
-                return;
-            }
-
-            if (fakeRealTaskRequestWms.equals("Y")) {
-                return;
-            }
-
-            if (!fakeGenerateOutTask.equals("Y")) {
-                return;
-            }
-
-            List<BasDevp> basDevps = basDevpService.list(new QueryWrapper<>());
-            for (BasDevp basDevp : basDevps) {
-                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
-                if (stationThread == null) {
-                    continue;
-                }
-
-                Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
-
-                List<StationObjModel> list = basDevp.getOutStationList$();
-                for (StationObjModel entity : list) {
-                    Integer stationId = entity.getStationId();
-                    if (!stationMap.containsKey(stationId)) {
-                        continue;
-                    }
-
-                    StationProtocol stationProtocol = stationMap.get(stationId);
-                    if (stationProtocol == null) {
-                        continue;
-                    }
-
-                    Object object = redisUtil.get(RedisKeyType.GENERATE_FAKE_OUT_TASK_LIMIT.key + stationId);
-                    if (object != null) {
-                        return;
-                    }
-
-                    // 婊¤冻鑷姩銆佹棤鐗┿�佸伐浣滃彿0锛岀敓鎴愬嚭搴撴暟鎹�
-                    if (stationProtocol.isAutoing()
-                            && !stationProtocol.isLoading()
-                            && stationProtocol.getTaskNo() == 0) {
-                        List<LocMast> locMastList = locMastService
-                                .list(new QueryWrapper<LocMast>().eq("loc_sts", String.valueOf(LocStsType.F)));
-                        if (locMastList.isEmpty()) {
-                            continue;
-                        }
-
-                        LocMast locMast = locMastList.get(0);
-
-                        CreateOutTaskParam taskParam = new CreateOutTaskParam();
-                        taskParam.setTaskNo(String.valueOf(commonService.getWorkNo(WrkIoType.OUT.id)));
-                        taskParam.setStaNo(stationId);
-                        taskParam.setLocNo(locMast.getLocNo());
-                        boolean result = commonService.createOutTask(taskParam);
-                        redisUtil.set(RedisKeyType.GENERATE_FAKE_OUT_TASK_LIMIT.key + stationId, "lock", 10);
-                    }
-                }
-            }
-        } catch (Exception e) {
-            log.error("generateFakeOutTask execute error", e);
-        }
-    }
-
-    /**
-     * 璇锋眰鐢熸垚鍏ュ簱浠诲姟
-     * 鍏ュ簱绔欙紝鏍规嵁鏉$爜鎵弿鐢熸垚鍏ュ簱宸ヤ綔妗�
-     */
-    public void generateStoreWrkFile() {
-        submitGenerateStoreTasks();
-    }
-
     @Override
     public boolean isEnabled() {
-        return !"N".equals(fakeRealTaskRequestWms);
-    }
-
-    @Override
-    public boolean matchCandidate(StoreInTaskContext context) {
-        StationProtocol stationProtocol = context.getStationProtocol();
-        return stationProtocol.isAutoing()
-                && stationProtocol.isLoading()
-                && stationProtocol.getTaskNo() > 0
-                && !Cools.isEmpty(stationProtocol.getBarcode());
+        return fakeTaskGenerator.isEnabled();
     }
 
     @Override
     public void onRequestPermitGranted(StoreInTaskContext context) {
-        redisUtil.set(getGenerateLockKey(context), "lock", 3);
+        fakeTaskGenerator.onRequestPermitGranted(context);
     }
 
     @Override
     public void afterTaskCreated(StoreInTaskContext context, WrkMast wrkMast) {
-        Integer stationId = context.getStationObjModel().getStationId();
-        StationCommand command = context.getStationThread().getCommand(StationCommandType.WRITE_INFO,
-                wrkMast.getWrkNo(), stationId, stationId, 0);
-        if (command == null) {
-            News.taskInfo(wrkMast.getWrkNo(), "鑾峰彇杈撻�佺嚎鍛戒护澶辫触");
-            return;
-        }
-        stationCommandDispatcher.dispatch(context.getBasDevp().getDevpNo(), command, "fake-process", "write-info");
-    }
-
-    // 璁$畻鎵�鏈夌珯鐐瑰仠鐣欐椂闂�
-    public void calcAllStationStayTime() {
-        List<BasDevp> basDevps = basDevpService.list(new QueryWrapper<>());
-        for (BasDevp basDevp : basDevps) {
-            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
-            if (stationThread == null) {
-                continue;
-            }
-
-            List<StationProtocol> list = stationThread.getStatus();
-            for (StationProtocol stationProtocol : list) {
-                if (stationProtocol.getTaskNo() > 0
-                        && !stationStayTimeMap.containsKey(stationProtocol.getStationId())) {
-                    stationStayTimeMap.put(stationProtocol.getStationId(), System.currentTimeMillis());
-                }
-
-                if (stationProtocol.getTaskNo() <= 0
-                        && stationStayTimeMap.containsKey(stationProtocol.getStationId())) {
-                    stationStayTimeMap.remove(stationProtocol.getStationId());
-                }
-            }
-        }
-    }
-
-    // 妫�娴嬪嚭搴撶珯鐐瑰仠鐣欐槸鍚﹁秴鏃�
-    public void checkOutStationStayTimeOut() {
-        List<BasDevp> basDevps = basDevpService.list(new QueryWrapper<>());
-        for (BasDevp basDevp : basDevps) {
-            List<StationObjModel> outStationList = basDevp.getOutStationList$();
-            if (outStationList.isEmpty()) {
-                News.info("杈撻�佺嚎:{} 鍑哄簱绔欑偣鏈缃�", basDevp.getDevpNo());
-                continue;
-            }
-
-            for (StationObjModel stationObjModel : outStationList) {
-                Object lock = redisUtil
-                        .get(RedisKeyType.CHECK_OUT_STATION_STAY_TIME_OUT_LIMIT.key + stationObjModel.getStationId());
-                if (lock != null) {
-                    continue;
-                }
-
-                Long stayTime = stationStayTimeMap.get(stationObjModel.getStationId());
-                if (stayTime == null) {
-                    continue;
-                }
-
-                if (System.currentTimeMillis() - stayTime > 1000 * 60) {
-                    StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp,
-                            stationObjModel.getDeviceNo());
-                    if (stationThread == null) {
-                        continue;
-                    }
-
-                    StationCommand command = stationThread.getCommand(StationCommandType.RESET, 0,
-                            stationObjModel.getStationId(), 0, 0);
-                    if (command == null) {
-                        continue;
-                    }
-
-                    stationCommandDispatcher.dispatch(stationObjModel.getDeviceNo(), command, "fake-process", "out-station-reset");
-                    redisUtil.set(
-                            RedisKeyType.CHECK_OUT_STATION_STAY_TIME_OUT_LIMIT.key + stationObjModel.getStationId(),
-                            "lock", 10);
-                    News.info("杈撻�佺珯鐐瑰嚭搴撻噸缃懡浠や笅鍙戞垚鍔燂紝绔欑偣鍙�={}锛屽懡浠ゆ暟鎹�={}", stationObjModel.getStationId(),
-                            JSON.toJSONString(command));
-                }
-            }
-        }
-    }
-
-    // 妫�娴嬪叆搴撶珯鐐瑰爢鍨涙満鏄惁鍙栬蛋璐х墿
-    public void checkInStationCrnTake() {
-        List<BasCrnp> basCrnps = basCrnpService.list(new QueryWrapper<>());
-        for (BasCrnp basCrnp : basCrnps) {
-            List<StationObjModel> inStationList = basCrnp.getInStationList$();
-            if (inStationList.isEmpty()) {
-                News.info("鍫嗗灈鏈�:{} 鍏ュ簱绔欑偣鏈缃�", basCrnp.getCrnNo());
-                continue;
-            }
-            checkInStationListCrnTake(inStationList);
-        }
-
-        List<BasDualCrnp> basDualCrnps = basDualCrnpService.list(new QueryWrapper<>());
-        for (BasDualCrnp basDualCrnp : basDualCrnps) {
-            List<StationObjModel> inStationList = basDualCrnp.getInStationList$();
-            if (inStationList.isEmpty()) {
-                News.info("鍙屽伐浣嶅爢鍨涙満:{} 鍏ュ簱绔欑偣鏈缃�", basDualCrnp.getCrnNo());
-                continue;
-            }
-            checkInStationListCrnTake(inStationList);
-        }
-    }
-
-    private void checkInStationListCrnTake(List<StationObjModel> inStationList) {
-        for (StationObjModel stationObjModel : inStationList) {
-            Object lock = redisUtil
-                    .get(RedisKeyType.CHECK_IN_STATION_STAY_TIME_OUT_LIMIT.key + stationObjModel.getStationId());
-            if (lock != null) {
-                continue;
-            }
-
-            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp,
-                    stationObjModel.getDeviceNo());
-            if (stationThread == null) {
-                continue;
-            }
-
-            Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap();
-            StationProtocol stationProtocol = statusMap.get(stationObjModel.getStationId());
-            if (stationProtocol == null) {
-                continue;
-            }
-
-            if (stationProtocol.getTaskNo() > 0) {
-                StationCommand command = stationThread.getCommand(StationCommandType.RESET, 0,
-                        stationObjModel.getStationId(), 0, 0);
-                if (command == null) {
-                    continue;
-                }
-
-                WrkMast wrkMast = wrkMastService.selectByWorkNo(stationProtocol.getTaskNo());
-                if (wrkMast == null) {
-                    stationCommandDispatcher.dispatch(stationObjModel.getDeviceNo(), command, "fake-process", "in-station-reset-task-over");
-                    redisUtil.set(
-                            RedisKeyType.CHECK_IN_STATION_STAY_TIME_OUT_LIMIT.key + stationObjModel.getStationId(),
-                            "lock", 10);
-                    News.info("杈撻�佺珯鐐归噸缃懡浠や笅鍙戞垚鍔�(task_over)锛岀珯鐐瑰彿={}锛屽懡浠ゆ暟鎹�={}", stationObjModel.getStationId(),
-                            JSON.toJSONString(command));
-                } else {
-                    if (wrkMast.getWrkSts() != WrkStsType.NEW_INBOUND.sts
-                            && wrkMast.getWrkSts() != WrkStsType.INBOUND_STATION_RUN.sts) {
-                        Integer crnNo = wrkMast.getCrnNo();
-                        if (crnNo != null) {
-                            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crnNo);
-                            if (crnThread == null) {
-                                continue;
-                            }
-                            CrnProtocol crnProtocol = crnThread.getStatus();
-                            if (!crnProtocol.getStatusType().equals(CrnStatusType.PUT_MOVING)
-                                    && !crnProtocol.getStatusType().equals(CrnStatusType.PUTTING)) {
-                                continue;
-                            }
-
-                            stationCommandDispatcher.dispatch(stationObjModel.getDeviceNo(), command, "fake-process", "in-station-reset-crn-fetch");
-                            redisUtil.set(RedisKeyType.CHECK_IN_STATION_STAY_TIME_OUT_LIMIT.key
-                                    + stationObjModel.getStationId(), "lock", 10);
-                            News.info("杈撻�佺珯鐐归噸缃懡浠や笅鍙戞垚鍔�(crn_fetch)锛岀珯鐐瑰彿={}锛屽懡浠ゆ暟鎹�={}", stationObjModel.getStationId(),
-                                    JSON.toJSONString(command));
-                        } else {
-                            Integer dualCrnNo = wrkMast.getDualCrnNo();
-                            DualCrnThread dualCrnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn,
-                                    dualCrnNo);
-                            if (dualCrnThread == null) {
-                                continue;
-                            }
-                            DualCrnProtocol dualCrnProtocol = dualCrnThread.getStatus();
-
-                            boolean reset = false;
-                            if (dualCrnProtocol.getTaskNo() > 0 && dualCrnProtocol.getLoaded() == 1) {
-                                reset = true;
-                            }
-
-                            if (dualCrnProtocol.getTaskNoTwo() > 0 && dualCrnProtocol.getLoadedTwo() == 1) {
-                                reset = true;
-                            }
-
-                            if (!reset) {
-                                continue;
-                            }
-
-                            stationCommandDispatcher.dispatch(stationObjModel.getDeviceNo(), command, "fake-process", "in-station-reset-dual-crn-fetch");
-                            redisUtil.set(RedisKeyType.CHECK_IN_STATION_STAY_TIME_OUT_LIMIT.key
-                                    + stationObjModel.getStationId(), "lock", 10);
-                            News.info("杈撻�佺珯鐐归噸缃懡浠や笅鍙戞垚鍔�(crn_fetch)锛岀珯鐐瑰彿={}锛屽懡浠ゆ暟鎹�={}", stationObjModel.getStationId(),
-                                    JSON.toJSONString(command));
-                        }
-                    }
-                }
-            }
-        }
+        fakeTaskGenerator.afterTaskCreated(context, wrkMast);
     }
 
     // 鍫嗗灈鏈轰换鍔℃墽琛屽畬鎴�
@@ -684,29 +279,7 @@
         } else if (wrkMast.getWrkSts() == WrkStsType.OUTBOUND_RUN.sts) {
             updateWrkSts = WrkStsType.OUTBOUND_RUN_COMPLETE.sts;
 
-            // 鐢熸垚浠跨湡绔欑偣鏁版嵁
-            List<StationObjModel> outStationList = basCrnp.getOutStationList$();
-            if (outStationList.isEmpty()) {
-                News.info("鍫嗗灈鏈�:{} 鍑哄簱绔欑偣鏈缃�", basCrnp.getCrnNo());
-                return;
-            }
-
-            for (StationObjModel stationObjModel : outStationList) {
-                if (!stationObjModel.getStationId().equals(wrkMast.getSourceStaNo())) {
-                    continue;
-                }
-
-                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp,
-                        stationObjModel.getDeviceNo());
-                if (stationThread == null) {
-                    continue;
-                }
-                // 鐢熸垚浠跨湡绔欑偣鏁版嵁
-                StationCommand command = stationThread.getCommand(StationCommandType.WRITE_INFO, 9998,
-                        wrkMast.getSourceStaNo(), 0, 0);
-                stationCommandDispatcher.dispatch(stationObjModel.getDeviceNo(), command, "fake-process", "crn-out-complete-write-info");
-                redisUtil.set(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo(), JSON.toJSONString(stationObjModel, SerializerFeature.DisableCircularReferenceDetect), 60 * 60 * 24);
-            }
+            dispatchOutStationWriteInfoIfReady(wrkMast, basCrnp);
         } else if (wrkMast.getWrkSts() == WrkStsType.LOC_MOVE_RUN.sts) {
             updateWrkSts = WrkStsType.COMPLETE_LOC_MOVE.sts;
         } else if (wrkMast.getWrkSts() == WrkStsType.CRN_MOVE_RUN.sts) {
@@ -722,6 +295,7 @@
         wrkMast.setIoTime(now);
         wrkMast.setModiTime(now);
         if (wrkMastService.updateById(wrkMast)) {
+            clearOutStationStayMarker(wrkMast.getWmsWrkNo());
             wrkAnalysisService.markCraneComplete(wrkMast, now, updateWrkSts);
             CrnCommand resetCommand = crnThread.getResetCommand(crnProtocol.getTaskNo(), crnProtocol.getCrnNo());
             MessageQueue.offer(SlaveType.Crn, crnProtocol.getCrnNo(), new Task(2, resetCommand));

--
Gitblit v1.9.1