#
Junjie
昨天 51a1786ef3e4e016d5f3f7bad8c2e2e8a84247a6
src/main/java/com/zy/core/utils/CrnOperateProcessUtils.java
@@ -4,14 +4,18 @@
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.common.Cools;
import com.core.exception.CoolException;
import com.zy.asrs.domain.enums.NotifyMsgType;
import com.zy.asrs.domain.param.CreateLocMoveTaskParam;
import com.zy.asrs.entity.BasStation;
import com.zy.asrs.entity.BasCrnp;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.BasCrnpService;
import com.zy.asrs.service.BasStationService;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.service.WrkAnalysisService;
import com.zy.asrs.service.WrkMastService;
import com.zy.asrs.utils.NotifyUtils;
import com.zy.asrs.utils.Utils;
@@ -32,6 +36,8 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -47,6 +53,8 @@
    @Autowired
    private LocMastService locMastService;
    @Autowired
    private BasStationService basStationService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private WmsOperateUtils wmsOperateUtils;
@@ -56,6 +64,10 @@
    private NotifyUtils notifyUtils;
    @Autowired
    private StationOperateProcessUtils stationOperateProcessUtils;
    @Autowired
    private WrkAnalysisService wrkAnalysisService;
    private static final String CRN_OUT_REQUIRE_STATION_OUT_ENABLE_CONFIG = "crnOutRequireStationOutEnable";
    public synchronized void crnIoExecute() {
        Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
@@ -72,23 +84,24 @@
    //入出库  ===>>  堆垛机入出库作业下发
    public synchronized void crnIoExecuteNormal() {
        List<BasCrnp> basCrnps = basCrnpService.list(new QueryWrapper<>());
        Map<Integer, BasCrnp> dispatchCrnMap = new HashMap<>();
        Map<Integer, CrnThread> dispatchThreadMap = new HashMap<>();
        Map<Integer, CrnProtocol> dispatchProtocolMap = new HashMap<>();
        for (BasCrnp basCrnp : basCrnps) {
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo());
            if(crnThread == null){
            if (crnThread == null) {
                continue;
            }
            CrnProtocol crnProtocol = crnThread.getStatus();
            if(crnProtocol == null){
            if (crnProtocol == null) {
                continue;
            }
            List<WrkMast> wrkMasts = wrkMastService.list(new QueryWrapper<WrkMast>()
            long runningCount = wrkMastService.count(new QueryWrapper<WrkMast>()
                    .eq("crn_no", basCrnp.getCrnNo())
                    .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts, WrkStsType.LOC_MOVE_RUN.sts)
                    .orderBy(true, false, "batch_seq")
            );
            if(!wrkMasts.isEmpty()){
                    .in("wrk_sts", WrkStsType.INBOUND_RUN.sts, WrkStsType.OUTBOUND_RUN.sts, WrkStsType.LOC_MOVE_RUN.sts));
            if (runningCount > 0) {
                continue;
            }
@@ -104,47 +117,106 @@
                if (clearLock != null) {
                    continue;
                }
                dispatchCrnMap.put(basCrnp.getCrnNo(), basCrnp);
                dispatchThreadMap.put(basCrnp.getCrnNo(), crnThread);
                dispatchProtocolMap.put(basCrnp.getCrnNo(), crnProtocol);
            }
        }
                // 如果最近一次是入库模式
                if (crnProtocol.getLastIo().equals("I")) {
                    if (basCrnp.getInEnable().equals("Y")) {
                        boolean result = this.crnExecuteIn(basCrnp, crnThread);//  入库
                        crnProtocol.setLastIo("O");
                        if (result) {
                            break;
                        }
                    } else if (basCrnp.getOutEnable().equals("Y")) {
                        boolean result = this.crnExecuteOut(basCrnp, crnThread);//  出库
                        crnProtocol.setLastIo("I");
                        if (result) {
                            break;
                        }
                    }
                }
                // 如果最近一次是出库模式
                else if (crnProtocol.getLastIo().equals("O")) {
                    if (basCrnp.getOutEnable().equals("Y")) {
                        boolean result = this.crnExecuteOut(basCrnp, crnThread);//  出库
                        crnProtocol.setLastIo("I");
                        if (result) {
                            break;
                        }
                    } else if (basCrnp.getInEnable().equals("Y")) {
                        boolean result = this.crnExecuteIn(basCrnp, crnThread);//  入库
                        crnProtocol.setLastIo("O");
                        if (result) {
                            break;
                        }
                    }
                }
        if (dispatchCrnMap.isEmpty()) {
            return;
        }
                //库位移转
                boolean transfer = this.crnExecuteLocTransfer(basCrnp, crnThread);
        List<WrkMast> taskQueue = wrkMastService.list(new QueryWrapper<WrkMast>()
                .in("crn_no", new ArrayList<>(dispatchCrnMap.keySet()))
                .in("wrk_sts",
                        WrkStsType.INBOUND_STATION_RUN_COMPLETE.sts,
                        WrkStsType.NEW_OUTBOUND.sts,
                        WrkStsType.NEW_LOC_MOVE.sts));
        taskQueue.sort(Comparator
                .comparingInt(this::resolveBatchOutboundRank)
                .thenComparingInt(this::resolveBatchSeqOrder)
                .thenComparingDouble(this::resolveTaskIoPri)
                .thenComparingLong(this::resolveTaskQueueTime)
                .thenComparingInt(this::resolveTaskQueueNo));
        for (WrkMast wrkMast : taskQueue) {
            if (wrkMast == null || wrkMast.getCrnNo() == null) {
                continue;
            }
            Integer crnNo = wrkMast.getCrnNo();
            BasCrnp basCrnp = dispatchCrnMap.get(crnNo);
            CrnThread crnThread = dispatchThreadMap.get(crnNo);
            CrnProtocol crnProtocol = dispatchProtocolMap.get(crnNo);
            if (basCrnp == null || crnThread == null || crnProtocol == null) {
                continue;
            }
            if (wrkMast.getWrkSts() != null && wrkMast.getWrkSts() == WrkStsType.INBOUND_STATION_RUN_COMPLETE.sts) {
                boolean result = this.crnExecuteInPlanner(basCrnp, crnThread, wrkMast);
                if (result) {
                    crnProtocol.setLastIo("O");
                    return;
                }
                continue;
            }
            if (wrkMast.getWrkSts() != null && wrkMast.getWrkSts() == WrkStsType.NEW_OUTBOUND.sts) {
                boolean result = this.crnExecuteOutPlanner(basCrnp, crnThread, wrkMast);
                if (result) {
                    crnProtocol.setLastIo("I");
                    return;
                }
                continue;
            }
            if (wrkMast.getWrkSts() != null && wrkMast.getWrkSts() == WrkStsType.NEW_LOC_MOVE.sts) {
                boolean transfer = this.crnExecuteMovePlanner(basCrnp, crnThread, wrkMast);
                if (transfer) {
                    break;
                    return;
                }
            }
        }
    }
    private int resolveBatchOutboundRank(WrkMast wrkMast) {
        return isBatchOutboundTask(wrkMast) ? 0 : 1;
    }
    private int resolveBatchSeqOrder(WrkMast wrkMast) {
        if (!isBatchOutboundTask(wrkMast) || wrkMast.getBatchSeq() == null) {
            return Integer.MAX_VALUE;
        }
        return wrkMast.getBatchSeq();
    }
    private double resolveTaskIoPri(WrkMast wrkMast) {
        if (wrkMast == null || wrkMast.getIoPri() == null) {
            return Double.MAX_VALUE;
        }
        return wrkMast.getIoPri();
    }
    private long resolveTaskQueueTime(WrkMast wrkMast) {
        if (wrkMast == null) {
            return Long.MAX_VALUE;
        }
        Date queueTime = wrkMast.getAppeTime() != null ? wrkMast.getAppeTime() : wrkMast.getIoTime();
        return queueTime == null ? Long.MAX_VALUE : queueTime.getTime();
    }
    private int resolveTaskQueueNo(WrkMast wrkMast) {
        if (wrkMast == null || wrkMast.getWrkNo() == null) {
            return Integer.MAX_VALUE;
        }
        return wrkMast.getWrkNo();
    }
    private boolean isBatchOutboundTask(WrkMast wrkMast) {
        return wrkMast != null
                && Integer.valueOf(WrkIoType.OUT.id).equals(wrkMast.getIoType())
                && !Cools.isEmpty(wrkMast.getBatch());
    }
    private synchronized boolean crnExecuteIn(BasCrnp basCrnp, CrnThread crnThread) {
@@ -206,7 +278,7 @@
                continue;
            }
            if(wrkMast.getWrkSts() != WrkStsType.INBOUND_DEVICE_RUN.sts){
            if(wrkMast.getWrkSts() != WrkStsType.INBOUND_STATION_RUN_COMPLETE.sts){
                continue;
            }
@@ -233,11 +305,14 @@
            CrnCommand command = crnThread.getPickAndPutCommand(sourceLocNo, wrkMast.getLocNo(), wrkMast.getWrkNo(), crnNo);
            Date now = new Date();
            wrkMast.setWrkSts(WrkStsType.INBOUND_RUN.sts);
            wrkMast.setCrnNo(crnNo);
            wrkMast.setSystemMsg("");
            wrkMast.setIoTime(new Date());
            wrkMast.setIoTime(now);
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                wrkAnalysisService.markCraneStart(wrkMast, now);
                MessageQueue.offer(SlaveType.Crn, crnNo, new Task(2, command));
                notifyUtils.notify(String.valueOf(SlaveType.Crn), crnNo, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_IN_TASK_RUN, null);
                News.info("堆垛机命令下发成功,堆垛机号={},任务数据={}", crnNo, JSON.toJSON(command));
@@ -264,18 +339,7 @@
            return false;
        }
        int stationMaxTaskCount = 30;
        Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
        if (systemConfigMapObj != null) {
            try {
                HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
                stationMaxTaskCount = Integer.parseInt(systemConfigMap.getOrDefault("stationMaxTaskCountLimit", "30"));
            } catch (Exception ignore) {}
        }
        int currentStationTaskCount = stationOperateProcessUtils.getCurrentStationTaskCount();
        if (stationMaxTaskCount > 0 && currentStationTaskCount >= stationMaxTaskCount) {
            News.warn("输送站点任务数量达到上限,已停止任务下发。当前任务数={},上限={}", currentStationTaskCount, stationMaxTaskCount);
        if (isOutboundStationTaskLimitReached()) {
            return false;
        }
@@ -288,6 +352,12 @@
        );
        for (WrkMast wrkMast : wrkMasts) {
            if (isOutboundTargetStationTaskLimitReached(wrkMast)) {
                continue;
            }
            if (!allowBatchOutboundExecute(wrkMast)) {
                continue;
            }
            for (StationObjModel stationObjModel : outStationList) {
                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
                if (stationThread == null) {
@@ -312,8 +382,8 @@
                    continue;
                }
                if (!stationProtocol.isOutEnable()) {
                    News.info("放货站点:{} 没有可出信号", stationObjModel.getStationId());
                if (isRequireOutboundStationOutEnable() && !stationProtocol.isOutEnable()) {
                    News.taskInfo(wrkMast.getWrkNo(), "放货站点:{} 没有可出信号", stationObjModel.getStationId());
                    continue;
                }
@@ -340,11 +410,14 @@
                CrnCommand command = crnThread.getPickAndPutCommand(wrkMast.getSourceLocNo(), targetLocNo, wrkMast.getWrkNo(), crnNo);
                Date now = new Date();
                wrkMast.setWrkSts(WrkStsType.OUTBOUND_RUN.sts);
                wrkMast.setCrnNo(crnNo);
                wrkMast.setSystemMsg("");
                wrkMast.setIoTime(new Date());
                wrkMast.setIoTime(now);
                wrkMast.setModiTime(now);
                if (wrkMastService.updateById(wrkMast)) {
                    wrkAnalysisService.markCraneStart(wrkMast, now);
                    MessageQueue.offer(SlaveType.Crn, crnNo, new Task(2, command));
                    notifyUtils.notify(String.valueOf(SlaveType.Crn), crnNo, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_OUT_TASK_RUN, null);
                    News.info("堆垛机命令下发成功,堆垛机号={},任务数据={}", crnNo, JSON.toJSON(command));
@@ -407,7 +480,7 @@
                continue;
            }
            if (wrkMast.getWrkSts() != WrkStsType.INBOUND_DEVICE_RUN.sts) {
            if (wrkMast.getWrkSts() != WrkStsType.INBOUND_STATION_RUN_COMPLETE.sts) {
                continue;
            }
@@ -434,11 +507,14 @@
            CrnCommand command = crnThread.getPickAndPutCommand(sourceLocNo, wrkMast.getLocNo(), wrkMast.getWrkNo(), crnNo);
            Date now = new Date();
            wrkMast.setWrkSts(WrkStsType.INBOUND_RUN.sts);
            wrkMast.setCrnNo(crnNo);
            wrkMast.setSystemMsg("");
            wrkMast.setIoTime(new Date());
            wrkMast.setIoTime(now);
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                wrkAnalysisService.markCraneStart(wrkMast, now);
                MessageQueue.offer(SlaveType.Crn, crnNo, new Task(2, command));
                notifyUtils.notify(String.valueOf(SlaveType.Crn), crnNo, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_IN_TASK_RUN, null);
                News.info("堆垛机命令下发成功,堆垛机号={},任务数据={}", crnNo, JSON.toJSON(command));
@@ -465,7 +541,19 @@
            return false;
        }
        if (isOutboundStationTaskLimitReached()) {
            return false;
        }
        Integer crnNo = basCrnp.getCrnNo();
        if (isOutboundTargetStationTaskLimitReached(wrkMast)) {
            return false;
        }
        if (!allowBatchOutboundExecute(wrkMast)) {
            return false;
        }
        for (StationObjModel stationObjModel : outStationList) {
            StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
@@ -491,8 +579,8 @@
                continue;
            }
            if (!stationProtocol.isOutEnable()) {
                News.info("放货站点:{} 没有可出信号", stationObjModel.getStationId());
            if (isRequireOutboundStationOutEnable() && !stationProtocol.isOutEnable()) {
                News.taskInfo(wrkMast.getWrkNo(), "放货站点:{} 没有可出信号", stationObjModel.getStationId());
                continue;
            }
@@ -519,11 +607,14 @@
            CrnCommand command = crnThread.getPickAndPutCommand(wrkMast.getSourceLocNo(), targetLocNo, wrkMast.getWrkNo(), crnNo);
            Date now = new Date();
            wrkMast.setWrkSts(WrkStsType.OUTBOUND_RUN.sts);
            wrkMast.setCrnNo(crnNo);
            wrkMast.setSystemMsg("");
            wrkMast.setIoTime(new Date());
            wrkMast.setIoTime(now);
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                wrkAnalysisService.markCraneStart(wrkMast, now);
                MessageQueue.offer(SlaveType.Crn, crnNo, new Task(2, command));
                notifyUtils.notify(String.valueOf(SlaveType.Crn), crnNo, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_OUT_TASK_RUN, null);
                News.info("堆垛机命令下发成功,堆垛机号={},任务数据={}", crnNo, JSON.toJSON(command));
@@ -531,6 +622,190 @@
            }
        }
        return false;
    }
    private boolean allowBatchOutboundExecute(WrkMast wrkMast) {
        if (wrkMast == null || Cools.isEmpty(wrkMast.getBatch())) {
            return true;
        }
        if (Cools.isEmpty(wrkMast.getBatchSeq())) {
            News.taskInfo(wrkMast.getWrkNo(), "批次:{} 缺少批次序号,暂不允许堆垛机出库", wrkMast.getBatch());
            return false;
        }
        WrkMast firstBatchWrkMast = wrkMastService.getOne(new QueryWrapper<WrkMast>()
                .eq("io_type", WrkIoType.OUT.id)
                .eq("batch", wrkMast.getBatch())
                .orderByAsc("batch_seq")
                .orderByAsc("wrk_no")
                .last("limit 1"));
        if (firstBatchWrkMast == null) {
            return true;
        }
        if (Cools.isEmpty(firstBatchWrkMast.getBatchSeq())) {
            News.taskInfo(wrkMast.getWrkNo(), "批次:{} 存在未配置批次序号的任务,暂不允许堆垛机出库", wrkMast.getBatch());
            return false;
        }
        boolean currentIsFirstBatchTask = wrkMast.getWrkNo().equals(firstBatchWrkMast.getWrkNo());
        boolean firstBatchTaskExecuted = firstBatchWrkMast.getWrkSts() != null
                && !firstBatchWrkMast.getWrkSts().equals(WrkStsType.NEW_OUTBOUND.sts);
        if (!currentIsFirstBatchTask && !firstBatchTaskExecuted) {
            News.taskInfo(wrkMast.getWrkNo(), "批次:{} 首个序号任务:{} 尚未执行,当前任务暂不允许出库", wrkMast.getBatch(), firstBatchWrkMast.getWrkNo());
            return false;
        }
        int batchRunningLimit = getSystemConfigInt("crnOutBatchRunningLimit", 5);
        if (batchRunningLimit <= 0) {
            return true;
        }
        List<WrkMast> unfinishedBatchWrkMasts = listUnfinishedBatchWrkMasts(wrkMast.getBatch());
        if (hasMissingBatchSeq(unfinishedBatchWrkMasts)) {
            News.taskInfo(wrkMast.getWrkNo(), "批次:{} 存在未配置批次序号的未完成任务,暂不允许堆垛机出库", wrkMast.getBatch());
            return false;
        }
        if (!isWithinBatchExecuteWindow(wrkMast, unfinishedBatchWrkMasts, batchRunningLimit)) {
            Integer windowStartSeq = unfinishedBatchWrkMasts.get(0).getBatchSeq();
            Integer windowEndSeq = unfinishedBatchWrkMasts.get(Math.min(batchRunningLimit, unfinishedBatchWrkMasts.size()) - 1).getBatchSeq();
            News.taskInfo(wrkMast.getWrkNo(),
                    "批次:{} 当前严格执行窗口序号为[{}-{}],当前序号={},暂不允许堆垛机出库",
                    wrkMast.getBatch(),
                    windowStartSeq,
                    windowEndSeq,
                    wrkMast.getBatchSeq());
            return false;
        }
        long batchRunningCount = wrkMastService.count(new QueryWrapper<WrkMast>()
                .eq("io_type", WrkIoType.OUT.id)
                .eq("batch", wrkMast.getBatch())
                .notIn("wrk_sts",
                        WrkStsType.NEW_OUTBOUND.sts,
                        WrkStsType.COMPLETE_OUTBOUND.sts,
                        WrkStsType.SETTLE_OUTBOUND.sts));
        if (batchRunningCount >= batchRunningLimit) {
            News.taskInfo(wrkMast.getWrkNo(), "批次:{} 执行中任务数达到上限,当前={},上限={}", wrkMast.getBatch(), batchRunningCount, batchRunningLimit);
            return false;
        }
        return true;
    }
    private List<WrkMast> listUnfinishedBatchWrkMasts(String batch) {
        if (Cools.isEmpty(batch)) {
            return new ArrayList<>();
        }
        return wrkMastService.list(new QueryWrapper<WrkMast>()
                .eq("io_type", WrkIoType.OUT.id)
                .eq("batch", batch)
                .notIn("wrk_sts",
                        WrkStsType.COMPLETE_OUTBOUND.sts,
                        WrkStsType.SETTLE_OUTBOUND.sts)
                .orderByAsc("batch_seq")
                .orderByAsc("wrk_no"));
    }
    private boolean hasMissingBatchSeq(List<WrkMast> wrkMasts) {
        if (wrkMasts == null || wrkMasts.isEmpty()) {
            return false;
        }
        for (WrkMast item : wrkMasts) {
            if (item == null || Cools.isEmpty(item.getBatchSeq())) {
                return true;
            }
        }
        return false;
    }
    private boolean isWithinBatchExecuteWindow(WrkMast wrkMast, List<WrkMast> unfinishedBatchWrkMasts, int batchRunningLimit) {
        if (wrkMast == null || unfinishedBatchWrkMasts == null || unfinishedBatchWrkMasts.isEmpty()) {
            return true;
        }
        int windowSize = Math.min(batchRunningLimit, unfinishedBatchWrkMasts.size());
        for (int i = 0; i < windowSize; i++) {
            WrkMast current = unfinishedBatchWrkMasts.get(i);
            if (current != null && wrkMast.getWrkNo().equals(current.getWrkNo())) {
                return true;
            }
        }
        return false;
    }
    private boolean isOutboundStationTaskLimitReached() {
        int stationMaxTaskCount = getSystemConfigInt("stationMaxTaskCountLimit", 30);
        if (stationMaxTaskCount <= 0) {
            return false;
        }
        int currentStationTaskCount = stationOperateProcessUtils.getCurrentStationTaskCount();
        if (currentStationTaskCount >= stationMaxTaskCount) {
            News.warn("输送站点任务数量达到上限,已停止任务下发。当前任务数={},上限={}", currentStationTaskCount, stationMaxTaskCount);
            return true;
        }
        return false;
    }
    private boolean isOutboundTargetStationTaskLimitReached(WrkMast wrkMast) {
        if (wrkMast == null || wrkMast.getStaNo() == null) {
            return false;
        }
        BasStation basStation = basStationService.getById(wrkMast.getStaNo());
        if (basStation == null || basStation.getOutTaskLimit() == null || basStation.getOutTaskLimit() < 0) {
            return false;
        }
        int currentStationTaskCount = stationOperateProcessUtils.getCurrentOutboundTaskCountByTargetStation(wrkMast.getStaNo());
        if (currentStationTaskCount >= basStation.getOutTaskLimit()) {
            News.taskInfo(wrkMast.getWrkNo(),
                    "目标出库站:{} 已达出库任务上限,当前={},上限={}",
                    wrkMast.getStaNo(),
                    currentStationTaskCount,
                    basStation.getOutTaskLimit());
            return true;
        }
        return false;
    }
    private int getSystemConfigInt(String code, int defaultValue) {
        Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
        if (systemConfigMapObj == null) {
            return defaultValue;
        }
        try {
            HashMap<String, String> systemConfigMap = (HashMap<String, String>) systemConfigMapObj;
            return Integer.parseInt(systemConfigMap.getOrDefault(code, String.valueOf(defaultValue)));
        } catch (Exception ignore) {
            return defaultValue;
        }
    }
    private boolean isRequireOutboundStationOutEnable() {
        return getSystemConfigBoolean(CRN_OUT_REQUIRE_STATION_OUT_ENABLE_CONFIG, true);
    }
    private boolean getSystemConfigBoolean(String code, boolean defaultValue) {
        Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
        if (!(systemConfigMapObj instanceof Map)) {
            return defaultValue;
        }
        try {
            Object value = ((Map<?, ?>) systemConfigMapObj).get(code);
            if (value == null) {
                return defaultValue;
            }
            String text = String.valueOf(value).trim();
            if ("Y".equalsIgnoreCase(text) || "true".equalsIgnoreCase(text) || "1".equals(text)) {
                return true;
            }
            if ("N".equalsIgnoreCase(text) || "false".equalsIgnoreCase(text) || "0".equals(text)) {
                return false;
            }
        } catch (Exception ignore) {
        }
        return defaultValue;
    }
    private synchronized boolean crnExecuteLocTransfer(BasCrnp basCrnp, CrnThread crnThread) {
@@ -573,11 +848,14 @@
            CrnCommand command = crnThread.getPickAndPutCommand(wrkMast.getSourceLocNo(), wrkMast.getLocNo(), wrkMast.getWrkNo(), crnNo);
            Date now = new Date();
            wrkMast.setWrkSts(WrkStsType.LOC_MOVE_RUN.sts);
            wrkMast.setCrnNo(crnNo);
            wrkMast.setSystemMsg("");
            wrkMast.setIoTime(new Date());
            wrkMast.setIoTime(now);
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                wrkAnalysisService.markCraneStart(wrkMast, now);
                MessageQueue.offer(SlaveType.Crn, crnNo, new Task(2, command));
                notifyUtils.notify(String.valueOf(SlaveType.Crn), crnNo, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_TRANSFER_TASK_RUN, null);
                News.info("堆垛机命令下发成功,堆垛机号={},任务数据={}", crnNo, JSON.toJSON(command));
@@ -618,6 +896,7 @@
                }
                Long updateWrkSts = null;
                Date now = new Date();
                if(wrkMast.getWrkSts() == WrkStsType.INBOUND_RUN.sts){
                    updateWrkSts = WrkStsType.COMPLETE_INBOUND.sts;
                    notifyUtils.notify(String.valueOf(SlaveType.Crn), crnProtocol.getCrnNo(), String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_IN_TASK_COMPLETE, null);
@@ -649,8 +928,10 @@
                wrkMast.setWrkSts(updateWrkSts);
                wrkMast.setSystemMsg("");
                wrkMast.setIoTime(new Date());
                wrkMast.setIoTime(now);
                wrkMast.setModiTime(now);
                if (wrkMastService.updateById(wrkMast)) {
                    wrkAnalysisService.markCraneComplete(wrkMast, now, updateWrkSts);
                    CrnCommand resetCommand = crnThread.getResetCommand(crnProtocol.getTaskNo(), crnProtocol.getCrnNo());
                    MessageQueue.offer(SlaveType.Crn, crnProtocol.getCrnNo(), new Task(2, resetCommand));
                    News.info("堆垛机任务状态更新成功,堆垛机号={},工作号={}", basCrnp.getCrnNo(), crnProtocol.getTaskNo());
@@ -796,11 +1077,14 @@
        CrnCommand command = crnThread.getPickAndPutCommand(wrkMast.getSourceLocNo(), wrkMast.getLocNo(), wrkMast.getWrkNo(), crnNo);
        Date now = new Date();
        wrkMast.setWrkSts(WrkStsType.LOC_MOVE_RUN.sts);
        wrkMast.setCrnNo(crnNo);
        wrkMast.setSystemMsg("");
        wrkMast.setIoTime(new Date());
        wrkMast.setIoTime(now);
        wrkMast.setModiTime(now);
        if (wrkMastService.updateById(wrkMast)) {
            wrkAnalysisService.markCraneStart(wrkMast, now);
            MessageQueue.offer(SlaveType.Crn, crnNo, new Task(2, command));
            notifyUtils.notify(String.valueOf(SlaveType.Crn), crnNo, String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(), NotifyMsgType.CRN_TRANSFER_TASK_RUN, null);
            News.info("堆垛机命令下发成功,堆垛机号={},任务数据={}", crnNo, JSON.toJSON(command));