#
Administrator
2026-04-25 faaf77b2ed6609e1ec159f163cb97c79f37df532
src/main/java/com/zy/core/utils/StationOperateProcessUtils.java
@@ -26,6 +26,8 @@
import com.zy.core.model.Task;
import com.zy.core.model.command.StationCommand;
import com.zy.core.model.protocol.StationProtocol;
import com.zy.core.task.MainProcessLane;
import com.zy.core.task.MainProcessTaskSubmitter;
import com.zy.core.thread.StationThread;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -56,9 +58,329 @@
    private BasStationService basStationService;
    @Autowired
    private StationCycleCapacityService stationCycleCapacityService;
    @Autowired
    private MainProcessTaskSubmitter mainProcessTaskSubmitter;
    public void submitStationEnableInTasks(long minIntervalMs) {
        submitStationEnableInTasks(MainProcessLane.STATION_ENABLE_IN, minIntervalMs);
    }
    public void submitStationEnableInTasks(MainProcessLane lane, long minIntervalMs) {
        mainProcessTaskSubmitter.submitSerialTask(
                MainProcessLane.STATION_SCAN,
                "submitStationEnableInTasks",
                minIntervalMs,
                new Runnable() {
                    @Override
                    public void run() {
                        submitStationEnableInTasksInternal(lane, minIntervalMs);
                    }
                }
        );
    }
    private void submitStationEnableInTasksInternal(MainProcessLane lane, long minIntervalMs) {
        List<BasDevp> basDevps = basDevpService.selectList(new EntityWrapper<BasDevp>());
        for (final BasDevp basDevp : basDevps) {
            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
            if (stationThread == null) {
                continue;
            }
            Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
            if (stationMap == null || stationMap.isEmpty()) {
                continue;
            }
            List<StationObjModel> list = basDevp.getInStationList$();
            for (final StationObjModel stationObjModel : list) {
                Integer stationId = stationObjModel == null ? null : stationObjModel.getStationId();
                if (stationId == null || !stationMap.containsKey(stationId)) {
                    continue;
                }
                mainProcessTaskSubmitter.submitKeyedSerialTask(
                        lane,
                        stationId,
                        "stationEnableInExecute",
                        minIntervalMs,
                        new Runnable() {
                            @Override
                            public void run() {
                                stationEnableInExecute(basDevp, stationObjModel);
                            }
                        }
                );
            }
        }
    }
    public void submitStationInTasks(long minIntervalMs) {
        submitStationInTasks(MainProcessLane.STATION_IN, minIntervalMs);
    }
    public void submitStationInTasks(MainProcessLane lane, long minIntervalMs) {
        mainProcessTaskSubmitter.submitSerialTask(
                MainProcessLane.STATION_SCAN,
                "submitStationInTasks",
                minIntervalMs,
                new Runnable() {
                    @Override
                    public void run() {
                        submitStationInTasksInternal(lane, minIntervalMs);
                    }
                }
        );
    }
    private void submitStationInTasksInternal(MainProcessLane lane, long minIntervalMs) {
        List<BasDevp> basDevps = basDevpService.selectList(new EntityWrapper<BasDevp>());
        for (final BasDevp basDevp : basDevps) {
            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
            if (stationThread == null) {
                continue;
            }
            Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
            if (stationMap == null || stationMap.isEmpty()) {
                continue;
            }
            List<StationObjModel> list = basDevp.getBarcodeStationList$();
            for (final StationObjModel stationObjModel : list) {
                Integer stationId = stationObjModel == null ? null : stationObjModel.getStationId();
                if (stationId == null || !stationMap.containsKey(stationId)) {
                    continue;
                }
                mainProcessTaskSubmitter.submitKeyedSerialTask(
                        lane,
                        stationId,
                        "stationInExecute",
                        minIntervalMs,
                        new Runnable() {
                            @Override
                            public void run() {
                                stationInExecute(basDevp, stationObjModel);
                            }
                        }
                );
            }
        }
    }
    public void submitCrnStationOutTasks(long minIntervalMs) {
        submitCrnStationOutTasks(MainProcessLane.STATION_OUT, minIntervalMs);
    }
    public void submitCrnStationOutTasks(MainProcessLane lane, long minIntervalMs) {
        mainProcessTaskSubmitter.submitSerialTask(
                MainProcessLane.STATION_SCAN,
                "submitCrnStationOutTasks",
                minIntervalMs,
                new Runnable() {
                    @Override
                    public void run() {
                        submitCrnStationOutTasksInternal(lane, minIntervalMs);
                    }
                }
        );
    }
    private void submitCrnStationOutTasksInternal(MainProcessLane lane, long minIntervalMs) {
        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
                .eq("wrk_sts", WrkStsType.OUTBOUND_RUN_COMPLETE.sts)
                .isNotNull("crn_no")
        );
        for (final WrkMast wrkMast : wrkMasts) {
            Integer laneKey = getCrnStationOutLaneKey(wrkMast);
            mainProcessTaskSubmitter.submitKeyedSerialTask(
                    lane,
                    laneKey,
                    "crnStationOutExecute",
                    minIntervalMs,
                    new Runnable() {
                        @Override
                        public void run() {
                            crnStationOutExecute(wrkMast);
                        }
                    }
            );
        }
    }
    public void submitDualCrnStationOutTasks(long minIntervalMs) {
        submitDualCrnStationOutTasks(MainProcessLane.DUAL_STATION_OUT, minIntervalMs);
    }
    public void submitDualCrnStationOutTasks(MainProcessLane lane, long minIntervalMs) {
        mainProcessTaskSubmitter.submitSerialTask(
                MainProcessLane.STATION_SCAN,
                "submitDualCrnStationOutTasks",
                minIntervalMs,
                new Runnable() {
                    @Override
                    public void run() {
                        submitDualCrnStationOutTasksInternal(lane, minIntervalMs);
                    }
                }
        );
    }
    private void submitDualCrnStationOutTasksInternal(MainProcessLane lane, long minIntervalMs) {
        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
                .eq("wrk_sts", WrkStsType.OUTBOUND_RUN_COMPLETE.sts)
                .isNotNull("dual_crn_no")
        );
        for (final WrkMast wrkMast : wrkMasts) {
            Integer laneKey = wrkMast == null ? null : wrkMast.getSourceStaNo();
            if (laneKey == null) {
                laneKey = wrkMast == null ? null : wrkMast.getWrkNo();
            }
            mainProcessTaskSubmitter.submitKeyedSerialTask(
                    lane,
                    laneKey,
                    "dualCrnStationOutExecute",
                    minIntervalMs,
                    new Runnable() {
                        @Override
                        public void run() {
                            dualCrnStationOutExecute(wrkMast);
                        }
                    }
            );
        }
    }
    public void submitStationOutExecuteFinishTasks(long minIntervalMs) {
        submitStationOutExecuteFinishTasks(MainProcessLane.STATION_OUT_FINISH, minIntervalMs);
    }
    public void submitStationOutExecuteFinishTasks(MainProcessLane lane, long minIntervalMs) {
        mainProcessTaskSubmitter.submitSerialTask(
                MainProcessLane.STATION_SCAN,
                "submitStationOutExecuteFinishTasks",
                minIntervalMs,
                new Runnable() {
                    @Override
                    public void run() {
                        submitStationOutExecuteFinishTasksInternal(lane, minIntervalMs);
                    }
                }
        );
    }
    private void submitStationOutExecuteFinishTasksInternal(MainProcessLane lane, long minIntervalMs) {
        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("wrk_sts", WrkStsType.STATION_RUN.sts));
        for (final WrkMast wrkMast : wrkMasts) {
            Integer laneKey = wrkMast == null ? null : wrkMast.getStaNo();
            if (laneKey == null) {
                laneKey = wrkMast == null ? null : wrkMast.getWrkNo();
            }
            mainProcessTaskSubmitter.submitKeyedSerialTask(
                    lane,
                    laneKey,
                    "stationOutExecuteFinish",
                    minIntervalMs,
                    new Runnable() {
                        @Override
                        public void run() {
                            stationOutExecuteFinish(wrkMast);
                        }
                    }
            );
        }
    }
    public void submitCheckTaskToCompleteTasks(long minIntervalMs) {
        submitCheckTaskToCompleteTasks(MainProcessLane.STATION_COMPLETE, minIntervalMs);
    }
    public void submitCheckTaskToCompleteTasks(MainProcessLane lane, long minIntervalMs) {
        mainProcessTaskSubmitter.submitSerialTask(
                MainProcessLane.STATION_SCAN,
                "submitCheckTaskToCompleteTasks",
                minIntervalMs,
                new Runnable() {
                    @Override
                    public void run() {
                        submitCheckTaskToCompleteTasksInternal(lane, minIntervalMs);
                    }
                }
        );
    }
    private void submitCheckTaskToCompleteTasksInternal(MainProcessLane lane, long minIntervalMs) {
        List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("wrk_sts", WrkStsType.STATION_RUN_COMPLETE.sts));
        for (final WrkMast wrkMast : wrkMasts) {
            Integer laneKey = wrkMast == null ? null : wrkMast.getStaNo();
            if (laneKey == null) {
                laneKey = wrkMast == null ? null : wrkMast.getWrkNo();
            }
            mainProcessTaskSubmitter.submitKeyedSerialTask(
                    lane,
                    laneKey,
                    "checkTaskToComplete",
                    minIntervalMs,
                    new Runnable() {
                        @Override
                        public void run() {
                            checkTaskToComplete(wrkMast);
                        }
                    }
            );
        }
    }
    public void submitCheckStationRunBlockTasks(long minIntervalMs) {
        submitCheckStationRunBlockTasks(MainProcessLane.STATION_RUN_BLOCK, minIntervalMs);
    }
    public void submitCheckStationRunBlockTasks(MainProcessLane lane, long minIntervalMs) {
        mainProcessTaskSubmitter.submitSerialTask(
                MainProcessLane.STATION_SCAN,
                "submitCheckStationRunBlockTasks",
                minIntervalMs,
                new Runnable() {
                    @Override
                    public void run() {
                        submitCheckStationRunBlockTasksInternal(lane, minIntervalMs);
                    }
                }
        );
    }
    private void submitCheckStationRunBlockTasksInternal(MainProcessLane lane, long minIntervalMs) {
        List<BasDevp> basDevps = basDevpService.selectList(new EntityWrapper<BasDevp>());
        for (final BasDevp basDevp : basDevps) {
            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
            if (stationThread == null) {
                continue;
            }
            List<StationProtocol> statusList = stationThread.getStatus();
            for (StationProtocol stationProtocol : statusList) {
                final Integer stationId = stationProtocol == null ? null : stationProtocol.getStationId();
                if (stationId == null) {
                    continue;
                }
                if (!stationProtocol.isAutoing()
                        || !stationProtocol.isLoading()
                        || stationProtocol.getTaskNo() <= 0
                        || !stationProtocol.isRunBlock()) {
                    continue;
                }
                mainProcessTaskSubmitter.submitKeyedSerialTask(
                        lane,
                        stationId,
                        "checkStationRunBlock",
                        minIntervalMs,
                        new Runnable() {
                            @Override
                            public void run() {
                                checkStationRunBlock(basDevp, stationId);
                            }
                        }
                );
            }
        }
    }
    //执行输送站点入库任务
    public synchronized void stationInExecute() {
    public void stationInExecute() {
        try {
            DispatchLimitConfig limitConfig = getDispatchLimitConfig();
            int[] currentStationTaskCountRef = new int[]{countCurrentStationTask()};
@@ -75,73 +397,8 @@
                List<StationObjModel> list = basDevp.getBarcodeStationList$();
                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.STATION_IN_EXECUTE_LIMIT.key + stationId);
                    if (lock != null) {
                        continue;
                    }
                    //满足自动、有物、有工作号
                    if (stationProtocol.isAutoing()
                            && stationProtocol.isLoading()
                            && stationProtocol.getTaskNo() > 0
                    ) {
                        //检测任务是否生成
                        WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("barcode", stationProtocol.getBarcode()));
                        if (wrkMast == null) {
                            continue;
                        }
                        if (wrkMast.getWrkSts() == WrkStsType.INBOUND_DEVICE_RUN.sts) {
                            continue;
                        }
                        String locNo = wrkMast.getLocNo();
                        FindCrnNoResult findCrnNoResult = commonService.findCrnNoByLocNo(locNo);
                        if (findCrnNoResult == null) {
                            News.taskInfo(wrkMast.getWrkNo(), "{}工作,未匹配到堆垛机", wrkMast.getWrkNo());
                            continue;
                        }
                        Integer targetStationId = commonService.findInStationId(findCrnNoResult, stationId);
                        if (targetStationId == null) {
                            News.taskInfo(wrkMast.getWrkNo(), "{}站点,搜索入库站点失败", stationId);
                            continue;
                        }
                        LoopHitResult loopHitResult = findPathLoopHit(limitConfig, stationProtocol.getStationId(), targetStationId, loadGuardState);
                        if (isDispatchBlocked(limitConfig, currentStationTaskCountRef[0], loadGuardState, loopHitResult.isThroughLoop())) {
                            return;
                        }
                        StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationId, targetStationId, 0);
                        if (command == null) {
                            News.taskInfo(wrkMast.getWrkNo(), "{}工作,获取输送线命令失败", wrkMast.getWrkNo());
                            continue;
                        }
                        wrkMast.setWrkSts(WrkStsType.INBOUND_DEVICE_RUN.sts);
                        wrkMast.setSourceStaNo(stationProtocol.getStationId());
                        wrkMast.setStaNo(targetStationId);
                        wrkMast.setSystemMsg("");
                        wrkMast.setIoTime(new Date());
                        if (wrkMastService.updateById(wrkMast)) {
                            MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command));
                            News.info("输送站点入库命令下发成功,站点号={},工作号={},命令数据={}", stationId, wrkMast.getWrkNo(), JSON.toJSONString(command));
                            redisUtil.set(RedisKeyType.STATION_IN_EXECUTE_LIMIT.key + stationId, "lock", 5);
                            loadGuardState.reserveLoopTask(loopHitResult.getLoopNo());
                            saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult);
                        }
                    if (stationInExecute(basDevp, entity, limitConfig, currentStationTaskCountRef, loadGuardState)) {
                        return;
                    }
                }
            }
@@ -150,8 +407,184 @@
        }
    }
    public void stationEnableInExecute(BasDevp basDevp, StationObjModel stationObjModel) {
        try {
            if (basDevp == null || stationObjModel == null || stationObjModel.getStationId() == null) {
                return;
            }
            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
            if (stationThread == null) {
                return;
            }
            Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
            if (stationMap == null) {
                return;
            }
            Integer stationId = stationObjModel.getStationId();
            if (!stationMap.containsKey(stationId)) {
                return;
            }
            StationProtocol stationProtocol = stationMap.get(stationId);
            if (stationProtocol == null) {
                return;
            }
            Object lock = redisUtil.get(RedisKeyType.GENERATE_ENABLE_IN_STATION_DATA_LIMIT.key + stationId);
            if (lock != null) {
                return;
            }
            if (stationProtocol.isAutoing()
                    && stationProtocol.isLoading()
                    && stationProtocol.getTaskNo() == 0
                    && stationProtocol.isEnableIn()
            ) {
                StationObjModel barcodeStation = stationObjModel.getBarcodeStation();
                if (barcodeStation == null || barcodeStation.getStationId() == null) {
                    return;
                }
                StationCommand command = stationThread.getCommand(StationCommandType.MOVE, commonService.getWorkNo(WrkIoType.ENABLE_IN.id), stationId, barcodeStation.getStationId(), 0);
                if (command == null) {
                    News.info("{}站点启动入库失败,获取输送线命令失败", stationId);
                    return;
                }
                MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command));
                redisUtil.set(RedisKeyType.GENERATE_ENABLE_IN_STATION_DATA_LIMIT.key + stationId, "lock", 15);
                News.info("{}站点启动入库成功,数据包:{}", stationId, JSON.toJSONString(command));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void stationInExecute(BasDevp basDevp, StationObjModel stationObjModel) {
        try {
            DispatchLimitConfig limitConfig = getDispatchLimitConfig();
            int[] currentStationTaskCountRef = new int[]{countCurrentStationTask()};
            LoadGuardState loadGuardState = buildLoadGuardState(limitConfig);
            stationInExecute(basDevp, stationObjModel, limitConfig, currentStationTaskCountRef, loadGuardState);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private boolean stationInExecute(BasDevp basDevp,
                                     StationObjModel stationObjModel,
                                     DispatchLimitConfig limitConfig,
                                     int[] currentStationTaskCountRef,
                                     LoadGuardState loadGuardState) {
        if (basDevp == null || stationObjModel == null || stationObjModel.getStationId() == null) {
            return false;
        }
        StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
        if (stationThread == null) {
            return false;
        }
        Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
        Integer stationId = stationObjModel.getStationId();
        if (stationMap == null || !stationMap.containsKey(stationId)) {
            return false;
        }
        StationProtocol stationProtocol = stationMap.get(stationId);
        if (stationProtocol == null) {
            return false;
        }
        Object lock = redisUtil.get(RedisKeyType.STATION_IN_EXECUTE_LIMIT.key + stationId);
        if (lock != null) {
            return false;
        }
        //满足自动、有物、有工作号
        if (stationProtocol.isAutoing()
                && stationProtocol.isLoading()
                && stationProtocol.getTaskNo() > 0
        ) {
            //检测任务是否生成
            WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>()
                    .eq("barcode", stationProtocol.getBarcode())
                    .eq("io_type", WrkIoType.IN.id)
            );
            if (wrkMast == null) {
                logDebugLimited("station_in_wait_wrk_" + stationId + "_" + stationProtocol.getTaskNo(), 3,
                        "[WCS Debug][条码站入库] 条码站已有站点任务号但未找到入库工作档,等待任务生成。stationId={},stationTaskNo={},barcode={},isLoading={},isAutoing={}",
                        stationId, stationProtocol.getTaskNo(), stationProtocol.getBarcode(),
                        stationProtocol.isLoading(), stationProtocol.isAutoing());
                return false;
            }
            if (wrkMast.getWrkSts() == WrkStsType.INBOUND_DEVICE_RUN.sts) {
                logDebugLimited("station_in_already_run_" + wrkMast.getWrkNo(), 5,
                        "[WCS Debug][条码站入库] 入库工作档已处于设备上走状态,等待输送线/PLC状态推进。stationId={},wrkNo={},barcode={},locNo={},wrkSts={}",
                        stationId, wrkMast.getWrkNo(), stationProtocol.getBarcode(),
                        wrkMast.getLocNo(), wrkMast.getWrkSts());
                return false;
            }
            String locNo = wrkMast.getLocNo();
            News.info("[WCS Debug][条码站入库] 准备匹配入库目标站。stationId={},stationTaskNo={},wrkNo={},barcode={},locNo={},wrkSts={}",
                    stationId, stationProtocol.getTaskNo(), wrkMast.getWrkNo(),
                    stationProtocol.getBarcode(), locNo, wrkMast.getWrkSts());
            FindCrnNoResult findCrnNoResult = commonService.findCrnNoByLocNo(locNo);
            if (findCrnNoResult == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}工作,未匹配到堆垛机", wrkMast.getWrkNo());
                return false;
            }
            Integer targetStationId = commonService.findInStationId(findCrnNoResult, stationId);
            if (targetStationId == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}站点,搜索入库站点失败", stationId);
                return false;
            }
            LoopHitResult loopHitResult = findPathLoopHit(limitConfig, stationProtocol.getStationId(), targetStationId, loadGuardState);
            if (isDispatchBlocked(limitConfig, currentStationTaskCountRef[0], loadGuardState, loopHitResult.isThroughLoop())) {
                logDebugLimited("station_in_dispatch_blocked_" + wrkMast.getWrkNo(), 3,
                        "[WCS Debug][条码站入库] 入库输送命令暂缓,下发容量/环线负载受限。stationId={},targetStationId={},wrkNo={},currentStationTaskCount={},throughLoop={},loopNo={},hitStationId={}",
                        stationId, targetStationId, wrkMast.getWrkNo(), currentStationTaskCountRef[0],
                        loopHitResult.isThroughLoop(), loopHitResult.getLoopNo(), loopHitResult.getHitStationId());
                return true;
            }
            long commandStartMs = System.currentTimeMillis();
            StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationId, targetStationId, 0);
            News.info("[WCS Debug][条码站入库] 获取入库输送命令完成。stationId={},targetStationId={},wrkNo={},costMs={},command={}",
                    stationId, targetStationId, wrkMast.getWrkNo(),
                    System.currentTimeMillis() - commandStartMs, JSON.toJSONString(command));
            if (command == null) {
                News.taskInfo(wrkMast.getWrkNo(), "{}工作,获取输送线命令失败", wrkMast.getWrkNo());
                return false;
            }
            wrkMast.setWrkSts(WrkStsType.INBOUND_DEVICE_RUN.sts);
            wrkMast.setSourceStaNo(stationProtocol.getStationId());
            wrkMast.setStaNo(targetStationId);
            wrkMast.setSystemMsg("");
            wrkMast.setIoTime(new Date());
            if (wrkMastService.updateById(wrkMast)) {
                MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command));
                News.info("输送站点入库命令下发成功,站点号={},工作号={},命令数据={}", stationId, wrkMast.getWrkNo(), JSON.toJSONString(command));
                News.info("[WCS Debug][条码站入库] 入库输送命令已入队。stationId={},targetStationId={},wrkNo={},barcode={},locNo={},deviceNo={}",
                        stationId, targetStationId, wrkMast.getWrkNo(), stationProtocol.getBarcode(),
                        locNo, basDevp.getDevpNo());
                redisUtil.set(RedisKeyType.STATION_IN_EXECUTE_LIMIT.key + stationId, "lock", 5);
                loadGuardState.reserveLoopTask(loopHitResult.getLoopNo());
                saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult);
            }
        }
        return false;
    }
    //执行堆垛机输送站点出库任务
    public synchronized void crnStationOutExecute() {
    public void crnStationOutExecute() {
        try {
            DispatchLimitConfig limitConfig = getDispatchLimitConfig();
            int[] currentStationTaskCountRef = new int[]{countCurrentStationTask()};
@@ -164,75 +597,8 @@
            List<Integer> outOrderList = getAllOutOrderList();
            for (WrkMast wrkMast : wrkMasts) {
                Object infoObj = redisUtil.get(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo());
                if (infoObj == null) {
                    News.info("出库任务{}数据缓存不存在", wrkMast.getWrkNo());
                    continue;
                }
                StationObjModel stationObjModel = JSON.parseObject(infoObj.toString(), StationObjModel.class);
                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
                if (stationThread == null) {
                    continue;
                }
                Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
                StationProtocol stationProtocol = stationMap.get(stationObjModel.getStationId());
                if (stationProtocol == null) {
                    continue;
                }
                Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId());
                if (lock != null) {
                    continue;
                }
                //满足自动、有物、工作号0
                if (stationProtocol.isAutoing()
                        && stationProtocol.isLoading()
                        && stationProtocol.getTaskNo() == 0
                ) {
                    Integer moveStaNo = wrkMast.getStaNo();
                    if (!outOrderList.isEmpty()) {
                        List<NavigateNode> nodes = navigateUtils.calcByStationId(stationProtocol.getStationId(), wrkMast.getStaNo());
                        for (int i = nodes.size() - 1; i >= 0; i--) {
                            NavigateNode node = nodes.get(i);
                            JSONObject v = JSONObject.parseObject(node.getNodeValue());
                            if (v != null) {
                                Integer stationId = v.getInteger("stationId");
                                if (outOrderList.contains(stationId)) {
                                    moveStaNo = stationId;
                                    break;
                                }
                            }
                        }
                    }
                    LoopHitResult loopHitResult = findPathLoopHit(limitConfig, stationProtocol.getStationId(), moveStaNo, loadGuardState);
                    if (isDispatchBlocked(limitConfig, currentStationTaskCountRef[0], loadGuardState, loopHitResult.isThroughLoop())) {
                        return;
                    }
                    StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), moveStaNo, 0);
                    if (command == null) {
                        News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败");
                        continue;
                    }
                    wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts);
                    wrkMast.setSystemMsg("");
                    wrkMast.setIoTime(new Date());
                    if (wrkMastService.updateById(wrkMast)) {
                        MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command));
                        News.info("输送站点出库命令下发成功,站点号={},工作号={},命令数据={}", stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
                        redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5);
                        redisUtil.del(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo());
                        currentStationTaskCountRef[0]++;
                        loadGuardState.reserveLoopTask(loopHitResult.getLoopNo());
                        saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult);
                    }
                if (crnStationOutExecute(wrkMast, limitConfig, currentStationTaskCountRef, loadGuardState, outOrderList)) {
                    return;
                }
            }
        } catch (Exception e) {
@@ -240,58 +606,194 @@
        }
    }
    private Integer getCrnStationOutLaneKey(WrkMast wrkMast) {
        if (wrkMast == null) {
            return null;
        }
        Object infoObj = redisUtil.get(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo());
        if (infoObj != null) {
            try {
                StationObjModel stationObjModel = JSON.parseObject(infoObj.toString(), StationObjModel.class);
                if (stationObjModel != null && stationObjModel.getStationId() != null) {
                    return stationObjModel.getStationId();
                }
            } catch (Exception e) {
                News.error("[WCS Debug][站点出库] 解析出库缓存站点失败,工作号={},cache={}", wrkMast.getWrkNo(), infoObj);
            }
        }
        if (wrkMast.getSourceStaNo() != null) {
            return wrkMast.getSourceStaNo();
        }
        if (wrkMast.getStaNo() != null) {
            return wrkMast.getStaNo();
        }
        return wrkMast.getWrkNo();
    }
    public void crnStationOutExecute(WrkMast wrkMast) {
        try {
            DispatchLimitConfig limitConfig = getDispatchLimitConfig();
            int[] currentStationTaskCountRef = new int[]{countCurrentStationTask()};
            LoadGuardState loadGuardState = buildLoadGuardState(limitConfig);
            List<Integer> outOrderList = getAllOutOrderList();
            crnStationOutExecute(wrkMast, limitConfig, currentStationTaskCountRef, loadGuardState, outOrderList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private boolean crnStationOutExecute(WrkMast wrkMast,
                                         DispatchLimitConfig limitConfig,
                                         int[] currentStationTaskCountRef,
                                         LoadGuardState loadGuardState,
                                         List<Integer> outOrderList) {
        if (wrkMast == null || wrkMast.getWrkNo() == null) {
            return false;
        }
        Object infoObj = redisUtil.get(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo());
        if (infoObj == null) {
            News.info("出库任务{}数据缓存不存在", wrkMast.getWrkNo());
            return false;
        }
        StationObjModel stationObjModel = JSON.parseObject(infoObj.toString(), StationObjModel.class);
        if (stationObjModel == null) {
            return false;
        }
        StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
        if (stationThread == null) {
            return false;
        }
        Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
        StationProtocol stationProtocol = stationMap == null ? null : stationMap.get(stationObjModel.getStationId());
        if (stationProtocol == null) {
            return false;
        }
        Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId());
        if (lock != null) {
            return false;
        }
        //满足自动、有物、工作号0
        if (stationProtocol.isAutoing()
                && stationProtocol.isLoading()
                && stationProtocol.getTaskNo() == 0
        ) {
            Integer moveStaNo = wrkMast.getStaNo();
            if (outOrderList != null && !outOrderList.isEmpty()) {
                List<NavigateNode> nodes = navigateUtils.calcByStationId(stationProtocol.getStationId(), wrkMast.getStaNo());
                for (int i = nodes.size() - 1; i >= 0; i--) {
                    NavigateNode node = nodes.get(i);
                    JSONObject v = JSONObject.parseObject(node.getNodeValue());
                    if (v != null) {
                        Integer stationId = v.getInteger("stationId");
                        if (outOrderList.contains(stationId)) {
                            moveStaNo = stationId;
                            break;
                        }
                    }
                }
            }
            LoopHitResult loopHitResult = findPathLoopHit(limitConfig, stationProtocol.getStationId(), moveStaNo, loadGuardState);
            if (isDispatchBlocked(limitConfig, currentStationTaskCountRef[0], loadGuardState, loopHitResult.isThroughLoop())) {
                return true;
            }
            StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), moveStaNo, 0);
            if (command == null) {
                News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败");
                return false;
            }
            wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts);
            wrkMast.setSystemMsg("");
            wrkMast.setIoTime(new Date());
            if (wrkMastService.updateById(wrkMast)) {
                MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command));
                News.info("输送站点出库命令下发成功,站点号={},工作号={},命令数据={}", stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
                redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5);
                redisUtil.del(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo());
                currentStationTaskCountRef[0]++;
                loadGuardState.reserveLoopTask(loopHitResult.getLoopNo());
                saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult);
            }
        }
        return false;
    }
    //执行双工位堆垛机输送站点出库任务
    public synchronized void dualCrnStationOutExecute() {
    public void dualCrnStationOutExecute() {
        try {
            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
                    .eq("wrk_sts", WrkStsType.OUTBOUND_RUN_COMPLETE.sts)
                    .isNotNull("dual_crn_no")
            );
            for (WrkMast wrkMast : wrkMasts) {
                Object infoObj = redisUtil.get(RedisKeyType.DUAL_CRN_OUT_TASK_STATION_INFO.key + wrkMast.getWrkNo());
                if (infoObj == null) {
                    News.info("出库任务{}数据缓存不存在", wrkMast.getWrkNo());
                    continue;
                dualCrnStationOutExecute(wrkMast);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void dualCrnStationOutExecute(WrkMast wrkMast) {
        try {
            if (wrkMast == null || wrkMast.getWrkNo() == null) {
                return;
            }
            Object infoObj = redisUtil.get(RedisKeyType.DUAL_CRN_OUT_TASK_STATION_INFO.key + wrkMast.getWrkNo());
            if (infoObj == null) {
                News.info("出库任务{}数据缓存不存在", wrkMast.getWrkNo());
                return;
            }
            StationObjModel stationObjModel = JSON.parseObject(infoObj.toString(), StationObjModel.class);
            if (stationObjModel == 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;
            }
            //满足自动、有物、工作号0
            if (stationProtocol.isAutoing()
                    && stationProtocol.isLoading()
                    && stationProtocol.getTaskNo() == 0
            ) {
                StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), wrkMast.getStaNo(), 0);
                if (command == null) {
                    News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败");
                    return;
                }
                StationObjModel stationObjModel = JSON.parseObject(infoObj.toString(), StationObjModel.class);
                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
                if (stationThread == null) {
                    continue;
                }
                Map<Integer, StationProtocol> stationMap = stationThread.getStatusMap();
                StationProtocol stationProtocol = stationMap.get(stationObjModel.getStationId());
                if (stationProtocol == null) {
                    continue;
                }
                Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId());
                if (lock != null) {
                    continue;
                }
                //满足自动、有物、工作号0
                if (stationProtocol.isAutoing()
                        && stationProtocol.isLoading()
                        && stationProtocol.getTaskNo() == 0
                ) {
                    StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), wrkMast.getStaNo(), 0);
                    if (command == null) {
                        News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败");
                        continue;
                    }
                    wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts);
                    wrkMast.setSystemMsg("");
                    wrkMast.setIoTime(new Date());
                    if (wrkMastService.updateById(wrkMast)) {
                        MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command));
                        notifyUtils.notify(String.valueOf(SlaveType.Devp), stationObjModel.getDeviceNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.STATION_OUT_TASK_RUN, null);
                        News.info("输送站点出库命令下发成功,站点号={},工作号={},命令数据={}", stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
                        redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5);
                        redisUtil.del(RedisKeyType.DUAL_CRN_OUT_TASK_STATION_INFO.key + wrkMast.getWrkNo());
                    }
                wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts);
                wrkMast.setSystemMsg("");
                wrkMast.setIoTime(new Date());
                if (wrkMastService.updateById(wrkMast)) {
                    MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command));
                    notifyUtils.notify(String.valueOf(SlaveType.Devp), stationObjModel.getDeviceNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.STATION_OUT_TASK_RUN, null);
                    News.info("输送站点出库命令下发成功,站点号={},工作号={},命令数据={}", stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
                    redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5);
                    redisUtil.del(RedisKeyType.DUAL_CRN_OUT_TASK_STATION_INFO.key + wrkMast.getWrkNo());
                }
            }
        } catch (Exception e) {
@@ -300,41 +802,52 @@
    }
    //检测输送站点出库任务执行完成
    public synchronized void stationOutExecuteFinish() {
    public void stationOutExecuteFinish() {
        try {
            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("wrk_sts", WrkStsType.STATION_RUN.sts));
            for (WrkMast wrkMast : wrkMasts) {
                Integer wrkNo = wrkMast.getWrkNo();
                Integer targetStaNo = wrkMast.getStaNo();
                stationOutExecuteFinish(wrkMast);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
                boolean complete = false;
                BasStation basStation = basStationService.selectOne(new EntityWrapper<BasStation>().eq("station_id", targetStaNo));
                if (basStation == null) {
                    continue;
                }
    public void stationOutExecuteFinish(WrkMast wrkMast) {
        try {
            if (wrkMast == null) {
                return;
            }
            Integer wrkNo = wrkMast.getWrkNo();
            Integer targetStaNo = wrkMast.getStaNo();
                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basStation.getDeviceNo());
                if (stationThread == null) {
                    continue;
                }
            boolean complete = false;
            BasStation basStation = basStationService.selectOne(new EntityWrapper<BasStation>().eq("station_id", targetStaNo));
            if (basStation == null) {
                return;
            }
                Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap();
                StationProtocol stationProtocol = statusMap.get(basStation.getStationId());
                if (stationProtocol == null) {
                    continue;
                }
            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basStation.getDeviceNo());
            if (stationThread == null) {
                return;
            }
                if (stationProtocol.getTaskNo().equals(wrkNo)) {
                    complete = true;
                }
            Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap();
            StationProtocol stationProtocol = statusMap == null ? null : statusMap.get(basStation.getStationId());
            if (stationProtocol == null) {
                return;
            }
                if (complete) {
                    wrkMast.setWrkSts(WrkStsType.STATION_RUN_COMPLETE.sts);
                    wrkMast.setIoTime(new Date());
                    wrkMastService.updateById(wrkMast);
                    notifyUtils.notify(String.valueOf(SlaveType.Devp), basStation.getDeviceNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.STATION_OUT_TASK_RUN_COMPLETE, null);
                    redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_COMPLETE_LIMIT.key + wrkMast.getWrkNo(), "lock", 60);
                }
            if (stationProtocol.getTaskNo().equals(wrkNo)) {
                complete = true;
            }
            if (complete) {
                wrkMast.setWrkSts(WrkStsType.STATION_RUN_COMPLETE.sts);
                wrkMast.setIoTime(new Date());
                wrkMastService.updateById(wrkMast);
                notifyUtils.notify(String.valueOf(SlaveType.Devp), basStation.getDeviceNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.STATION_OUT_TASK_RUN_COMPLETE, null);
                redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_COMPLETE_LIMIT.key + wrkMast.getWrkNo(), "lock", 60);
            }
        } catch (Exception e) {
            e.printStackTrace();
@@ -342,44 +855,55 @@
    }
    // 检测任务转完成
    public synchronized void checkTaskToComplete() {
    public void checkTaskToComplete() {
        try {
            List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("wrk_sts", WrkStsType.STATION_RUN_COMPLETE.sts));
            for (WrkMast wrkMast : wrkMasts) {
                Integer wrkNo = wrkMast.getWrkNo();
                Integer targetStaNo = wrkMast.getStaNo();
                checkTaskToComplete(wrkMast);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
                Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_COMPLETE_LIMIT.key + wrkNo);
                if (lock != null) {
                    continue;
                }
    public void checkTaskToComplete(WrkMast wrkMast) {
        try {
            if (wrkMast == null) {
                return;
            }
            Integer wrkNo = wrkMast.getWrkNo();
            Integer targetStaNo = wrkMast.getStaNo();
                boolean complete = false;
                BasStation basStation = basStationService.selectOne(new EntityWrapper<BasStation>().eq("station_id", targetStaNo));
                if (basStation == null) {
                    continue;
                }
            Object lock = redisUtil.get(RedisKeyType.STATION_OUT_EXECUTE_COMPLETE_LIMIT.key + wrkNo);
            if (lock != null) {
                return;
            }
                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basStation.getDeviceNo());
                if (stationThread == null) {
                    continue;
                }
            boolean complete = false;
            BasStation basStation = basStationService.selectOne(new EntityWrapper<BasStation>().eq("station_id", targetStaNo));
            if (basStation == null) {
                return;
            }
                Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap();
                StationProtocol stationProtocol = statusMap.get(basStation.getStationId());
                if (stationProtocol == null) {
                    continue;
                }
            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basStation.getDeviceNo());
            if (stationThread == null) {
                return;
            }
                if (!stationProtocol.getTaskNo().equals(wrkNo)) {
                    complete = true;
                }
            Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap();
            StationProtocol stationProtocol = statusMap == null ? null : statusMap.get(basStation.getStationId());
            if (stationProtocol == null) {
                return;
            }
                if (complete) {
                    wrkMast.setWrkSts(WrkStsType.COMPLETE_OUTBOUND.sts);
                    wrkMast.setIoTime(new Date());
                    wrkMastService.updateById(wrkMast);
                }
            if (!stationProtocol.getTaskNo().equals(wrkNo)) {
                complete = true;
            }
            if (complete) {
                wrkMast.setWrkSts(WrkStsType.COMPLETE_OUTBOUND.sts);
                wrkMast.setIoTime(new Date());
                wrkMastService.updateById(wrkMast);
            }
        } catch (Exception e) {
            e.printStackTrace();
@@ -387,7 +911,7 @@
    }
    //检测输送站点是否运行堵塞
    public synchronized void checkStationRunBlock() {
    public void checkStationRunBlock() {
        try {
            List<BasDevp> basDevps = basDevpService.selectList(new EntityWrapper<>());
            for (BasDevp basDevp : basDevps) {
@@ -523,13 +1047,154 @@
        }
    }
    public void checkStationRunBlock(BasDevp basDevp, Integer stationId) {
        try {
            if (basDevp == null || stationId == null) {
                return;
            }
            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getDevpNo());
            if (stationThread == null) {
                return;
            }
            Map<Integer, StationProtocol> statusMap = stationThread.getStatusMap();
            StationProtocol stationProtocol = statusMap == null ? null : statusMap.get(stationId);
            if (stationProtocol == null) {
                return;
            }
            List<Integer> runBlockReassignLocStationList = new ArrayList<>();
            for (StationObjModel stationObjModel : basDevp.getRunBlockReassignLocStationList$()) {
                runBlockReassignLocStationList.add(stationObjModel.getStationId());
            }
            if (!(stationProtocol.isAutoing()
                    && stationProtocol.isLoading()
                    && stationProtocol.getTaskNo() > 0
                    && stationProtocol.isRunBlock())) {
                return;
            }
            WrkMast wrkMast = wrkMastService.selectByWorkNo(stationProtocol.getTaskNo());
            if (wrkMast == null) {
                News.info("输送站点号={} 运行阻塞,但无法找到对应任务,工作号={}", stationProtocol.getStationId(), stationProtocol.getTaskNo());
                return;
            }
            Object lock = redisUtil.get(RedisKeyType.CHECK_STATION_RUN_BLOCK_LIMIT_.key + stationProtocol.getTaskNo());
            if (lock != null) {
                return;
            }
            redisUtil.set(RedisKeyType.CHECK_STATION_RUN_BLOCK_LIMIT_.key + stationProtocol.getTaskNo(), "lock", 15);
            if (wrkMast.getIoType() == WrkIoType.IN.id && runBlockReassignLocStationList.contains(stationProtocol.getStationId())) {
                //站点处于重新分配库位区域
                //运行堵塞,重新申请任务
                String response = wmsOperateUtils.applyReassignTaskLocNo(wrkMast.getWrkNo(), stationProtocol.getStationId());
                if (response == null) {
                    News.taskError(wrkMast.getWrkNo(), "请求WMS重新分配库位接口失败,接口未响应!!!response:{}", response);
                    return;
                }
                JSONObject jsonObject = JSON.parseObject(response);
                if (jsonObject.getInteger("code").equals(200)) {
                    StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                    String sourceLocNo = wrkMast.getLocNo();
                    String locNo = dto.getLocNo();
                    LocMast sourceLocMast = locMastService.queryByLoc(sourceLocNo);
                    if (sourceLocMast == null) {
                        News.taskInfo(wrkMast.getWrkNo(), "库位号:{} 源库位信息不存在", sourceLocNo);
                        return;
                    }
                    if (!sourceLocMast.getLocSts().equals("S")) {
                        News.taskInfo(wrkMast.getWrkNo(), "库位号:{} 源库位状态不处于入库预约", sourceLocNo);
                        return;
                    }
                    LocMast locMast = locMastService.queryByLoc(locNo);
                    if (locMast == null) {
                        News.taskInfo(wrkMast.getWrkNo(), "库位号:{} 目标库位信息不存在", locNo);
                        return;
                    }
                    if (!locMast.getLocSts().equals("O")) {
                        News.taskInfo(wrkMast.getWrkNo(), "库位号:{} 目标库位状态不处于空库位", locNo);
                        return;
                    }
                    FindCrnNoResult findCrnNoResult = commonService.findCrnNoByLocNo(locNo);
                    if (findCrnNoResult == null) {
                        News.taskInfo(wrkMast.getWrkNo(), "{}工作,未匹配到堆垛机", wrkMast.getWrkNo());
                        return;
                    }
                    Integer crnNo = findCrnNoResult.getCrnNo();
                    Integer targetStationId = commonService.findInStationId(findCrnNoResult, stationProtocol.getStationId());
                    if (targetStationId == null) {
                        News.taskInfo(wrkMast.getWrkNo(), "{}站点,搜索入库站点失败", stationProtocol.getStationId());
                        return;
                    }
                    StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), targetStationId, 0);
                    if (command == null) {
                        News.taskInfo(wrkMast.getWrkNo(), "{}工作,获取输送线命令失败", wrkMast.getWrkNo());
                        return;
                    }
                    //更新源库位
                    sourceLocMast.setLocSts("O");
                    sourceLocMast.setModiTime(new Date());
                    locMastService.updateById(sourceLocMast);
                    //更新目标库位
                    locMast.setLocSts("S");
                    locMast.setModiTime(new Date());
                    locMastService.updateById(locMast);
                    //更新工作档数据
                    wrkMast.setLocNo(locNo);
                    wrkMast.setStaNo(targetStationId);
                    if (findCrnNoResult.getCrnType().equals(SlaveType.Crn)) {
                        wrkMast.setCrnNo(crnNo);
                    } else if (findCrnNoResult.getCrnType().equals(SlaveType.DualCrn)) {
                        wrkMast.setDualCrnNo(crnNo);
                    } else {
                        throw new CoolException("未知设备类型");
                    }
                    if (wrkMastService.updateById(wrkMast)) {
                        MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command));
                    }
                } else {
                    News.error("请求WMS接口失败!!!response:{}", response);
                }
            } else {
                //运行堵塞,重新计算路线
                StationCommand command = stationThread.getCommand(StationCommandType.MOVE, wrkMast.getWrkNo(), stationProtocol.getStationId(), wrkMast.getStaNo(), 0);
                if (command == null) {
                    News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败");
                    return;
                }
                MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command));
                News.info("输送站点堵塞后重新计算路径命令下发成功,站点号={},工作号={},命令数据={}", stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取输送线任务数量
    public synchronized int getCurrentStationTaskCount() {
    public int getCurrentStationTaskCount() {
        return countCurrentStationTask();
    }
    // 检测出库排序
    public synchronized void checkStationOutOrder() {
    public void checkStationOutOrder() {
        List<BasDevp> basDevps = basDevpService.selectList(new EntityWrapper<BasDevp>());
        for (BasDevp basDevp : basDevps) {
            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getId());
@@ -649,7 +1314,7 @@
    }
    // 监控绕圈站点
    public synchronized void watchCircleStation() {
    public void watchCircleStation() {
        List<BasDevp> basDevps = basDevpService.selectList(new EntityWrapper<BasDevp>());
        for (BasDevp basDevp : basDevps) {
            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, basDevp.getId());
@@ -916,6 +1581,20 @@
        redisUtil.expire(RedisKeyType.STATION_CYCLE_LOAD_RESERVE.key, LOOP_LOAD_RESERVE_EXPIRE_SECONDS);
    }
    private void logDebugLimited(String lockKey, int seconds, String format, Object... arguments) {
        String redisKey = RedisKeyType.LOG_LIMIT.key + "wcs_debug_" + lockKey;
        try {
            Object lock = redisUtil.get(redisKey);
            if (lock != null) {
                return;
            }
            redisUtil.set(redisKey, "lock", seconds);
        } catch (Exception e) {
            // 诊断日志不能影响主流程。
        }
        News.info(format, arguments);
    }
    private DispatchLimitConfig getDispatchLimitConfig() {
        DispatchLimitConfig config = new DispatchLimitConfig();
        Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);