#
Junjie
14 小时以前 bf4e43c1fd1a361029e7cb51daac378fa5ee3617
src/main/java/com/zy/core/utils/StationOperateProcessUtils.java
@@ -7,6 +7,7 @@
import com.core.common.Cools;
import com.core.exception.CoolException;
import com.zy.asrs.domain.enums.NotifyMsgType;
import com.zy.asrs.domain.path.StationPathResolvedPolicy;
import com.zy.asrs.domain.vo.StationCycleCapacityVo;
import com.zy.asrs.domain.vo.StationCycleLoopVo;
import com.zy.asrs.entity.*;
@@ -35,6 +36,7 @@
@Component
public class StationOperateProcessUtils {
    private static final int LOOP_LOAD_RESERVE_EXPIRE_SECONDS = 120;
    private static final int OUT_ORDER_DISPATCH_LIMIT_SECONDS = 10;
    @Autowired
    private BasDevpService basDevpService;
@@ -56,13 +58,15 @@
    private BasStationService basStationService;
    @Autowired
    private StationCycleCapacityService stationCycleCapacityService;
    @Autowired
    private StationPathPolicyService stationPathPolicyService;
    //执行输送站点入库任务
    public synchronized void stationInExecute() {
        try {
            DispatchLimitConfig limitConfig = getDispatchLimitConfig();
            DispatchLimitConfig baseLimitConfig = getDispatchLimitConfig(null, null);
            int[] currentStationTaskCountRef = new int[]{countCurrentStationTask()};
            LoadGuardState loadGuardState = buildLoadGuardState(limitConfig);
            LoadGuardState loadGuardState = buildLoadGuardState(baseLimitConfig);
            List<BasDevp> basDevps = basDevpService.list(new QueryWrapper<>());
            for (BasDevp basDevp : basDevps) {
@@ -118,6 +122,7 @@
                            continue;
                        }
                        DispatchLimitConfig limitConfig = getDispatchLimitConfig(stationProtocol.getStationId(), targetStationId);
                        LoopHitResult loopHitResult = findPathLoopHit(limitConfig, stationProtocol.getStationId(), targetStationId, loadGuardState);
                        if (isDispatchBlocked(limitConfig, currentStationTaskCountRef[0], loadGuardState, loopHitResult.isThroughLoop())) {
@@ -153,9 +158,9 @@
    //执行堆垛机输送站点出库任务
    public synchronized void crnStationOutExecute() {
        try {
            DispatchLimitConfig limitConfig = getDispatchLimitConfig();
            DispatchLimitConfig baseLimitConfig = getDispatchLimitConfig(null, null);
            int[] currentStationTaskCountRef = new int[]{countCurrentStationTask()};
            LoadGuardState loadGuardState = buildLoadGuardState(limitConfig);
            LoadGuardState loadGuardState = buildLoadGuardState(baseLimitConfig);
            List<WrkMast> wrkMasts = wrkMastService.list(new QueryWrapper<WrkMast>()
                    .eq("wrk_sts", WrkStsType.OUTBOUND_RUN_COMPLETE.sts)
@@ -199,6 +204,7 @@
                            true
                    );
                    DispatchLimitConfig limitConfig = getDispatchLimitConfig(stationProtocol.getStationId(), moveStaNo);
                    LoopHitResult loopHitResult = findPathLoopHit(limitConfig, stationProtocol.getStationId(), moveStaNo, loadGuardState);
                    if (isDispatchBlocked(limitConfig, currentStationTaskCountRef[0], loadGuardState, loopHitResult.isThroughLoop())) {
@@ -556,6 +562,10 @@
                    continue;
                }
                if (isWatchingCircleArrival(wrkMast.getWrkNo(), stationProtocol.getStationId())) {
                    continue;
                }
                if (Cools.isEmpty(wrkMast.getBatch())) {
                    continue;
                }
@@ -600,6 +610,10 @@
                        News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败");
                        continue;
                    }
                    if (!tryAcquireOutOrderDispatchLock(wrkMast.getWrkNo(), stationProtocol.getStationId())) {
                        continue;
                    }
                    clearWatchCircleCommand(wrkMast.getWrkNo());
                    MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command));
                    News.info("{}任务直接去目标点", wrkMast.getWrkNo());
                } else if (commandType.equals("toCircle")) {
@@ -615,8 +629,11 @@
                        News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败");
                        continue;
                    }
                    if (!tryAcquireOutOrderDispatchLock(wrkMast.getWrkNo(), stationProtocol.getStationId())) {
                        continue;
                    }
                    MessageQueue.offer(SlaveType.Devp, stationObjModel.getDeviceNo(), new Task(2, command));
                    redisUtil.set(RedisKeyType.WATCH_CIRCLE_STATION_.key + wrkMast.getWrkNo(), JSON.toJSONString(command, SerializerFeature.DisableCircularReferenceDetect), 60 * 60 * 24);
                    saveWatchCircleCommand(wrkMast.getWrkNo(), command);
                    News.info("{}任务进行绕圈", wrkMast.getWrkNo());
                }
            }
@@ -647,12 +664,10 @@
                    continue;
                }
                Object circleObj = redisUtil.get(RedisKeyType.WATCH_CIRCLE_STATION_.key + stationProtocol.getTaskNo());
                if (circleObj == null) {
                StationCommand circleCommand = getWatchCircleCommand(stationProtocol.getTaskNo());
                if (circleCommand == null) {
                    continue;
                }
                StationCommand circleCommand = JSON.parseObject(circleObj.toString(), StationCommand.class);
                if (!stationProtocol.getStationId().equals(circleCommand.getTargetStaNo())) {
                    continue;
                }
@@ -673,6 +688,14 @@
                if (command == null) {
                    News.taskInfo(wrkMast.getWrkNo(), "获取输送线命令失败");
                    continue;
                }
                if (!tryAcquireOutOrderDispatchLock(wrkMast.getWrkNo(), stationProtocol.getStationId())) {
                    continue;
                }
                if (Objects.equals(moveStaNo, wrkMast.getStaNo())) {
                    clearWatchCircleCommand(wrkMast.getWrkNo());
                } else {
                    saveWatchCircleCommand(wrkMast.getWrkNo(), command);
                }
                MessageQueue.offer(SlaveType.Devp, basDevp.getDevpNo(), new Task(2, command));
            }
@@ -739,6 +762,54 @@
            } catch (Exception ignore) {}
        }
        return null;
    }
    private boolean tryAcquireOutOrderDispatchLock(Integer wrkNo, Integer stationId) {
        if (wrkNo == null || wrkNo <= 0 || stationId == null) {
            return true;
        }
        String key = RedisKeyType.STATION_OUT_ORDER_DISPATCH_LIMIT_.key + wrkNo + "_" + stationId;
        Object lock = redisUtil.get(key);
        if (lock != null) {
            return false;
        }
        redisUtil.set(key, "lock", OUT_ORDER_DISPATCH_LIMIT_SECONDS);
        return true;
    }
    private boolean isWatchingCircleArrival(Integer wrkNo, Integer stationId) {
        StationCommand command = getWatchCircleCommand(wrkNo);
        return command != null && stationId != null && stationId.equals(command.getTargetStaNo());
    }
    private StationCommand getWatchCircleCommand(Integer wrkNo) {
        if (wrkNo == null || wrkNo <= 0) {
            return null;
        }
        Object circleObj = redisUtil.get(RedisKeyType.WATCH_CIRCLE_STATION_.key + wrkNo);
        if (circleObj == null) {
            return null;
        }
        try {
            return JSON.parseObject(circleObj.toString(), StationCommand.class);
        } catch (Exception ignore) {
            return null;
        }
    }
    private void saveWatchCircleCommand(Integer wrkNo, StationCommand command) {
        if (wrkNo == null || wrkNo <= 0 || command == null) {
            return;
        }
        redisUtil.set(RedisKeyType.WATCH_CIRCLE_STATION_.key + wrkNo,
                JSON.toJSONString(command, SerializerFeature.DisableCircularReferenceDetect), 60 * 60 * 24);
    }
    private void clearWatchCircleCommand(Integer wrkNo) {
        if (wrkNo == null || wrkNo <= 0) {
            return;
        }
        redisUtil.del(RedisKeyType.WATCH_CIRCLE_STATION_.key + wrkNo);
    }
    public Integer getOutStationBatchSeq(List<NavigateNode> pathList, Integer searchStationId, String searchBatch) {
@@ -840,7 +911,8 @@
        }
        state.totalStationCount = toNonNegative(capacityVo.getTotalStationCount());
        state.projectedTaskStationCount = toNonNegative(capacityVo.getTaskStationCount());
        Integer occupiedStationCount = capacityVo.getOccupiedStationCount();
        state.projectedTaskStationCount = toNonNegative(occupiedStationCount != null ? occupiedStationCount : capacityVo.getTaskStationCount());
        List<StationCycleLoopVo> loopList = capacityVo.getLoopList();
        if (loopList != null) {
@@ -933,23 +1005,31 @@
        redisUtil.expire(RedisKeyType.STATION_CYCLE_LOAD_RESERVE.key, LOOP_LOAD_RESERVE_EXPIRE_SECONDS);
    }
    private DispatchLimitConfig getDispatchLimitConfig() {
    private DispatchLimitConfig getDispatchLimitConfig(Integer startStationId, Integer endStationId) {
        DispatchLimitConfig config = new DispatchLimitConfig();
        Object systemConfigMapObj = redisUtil.get(RedisKeyType.SYSTEM_CONFIG_MAP.key);
        if (!(systemConfigMapObj instanceof Map)) {
            return config;
        if (systemConfigMapObj instanceof Map) {
            Map<?, ?> systemConfigMap = (Map<?, ?>) systemConfigMapObj;
            config.circleMaxLoadLimit = parseLoadLimit(getConfigValue(systemConfigMap, "circleMaxLoadLimit"), config.circleMaxLoadLimit);
            String loopModeValue = getConfigValue(systemConfigMap, "circleLoopModeEnable");
            if (isBlank(loopModeValue)) {
                loopModeValue = getConfigValue(systemConfigMap, "circleModeEnable");
            }
            if (isBlank(loopModeValue)) {
                loopModeValue = getConfigValue(systemConfigMap, "isCircleMode");
            }
            config.loopModeEnable = parseBoolean(loopModeValue, config.loopModeEnable);
        }
        Map<?, ?> systemConfigMap = (Map<?, ?>) systemConfigMapObj;
        config.circleMaxLoadLimit = parseLoadLimit(getConfigValue(systemConfigMap, "circleMaxLoadLimit"), config.circleMaxLoadLimit);
        String loopModeValue = getConfigValue(systemConfigMap, "circleLoopModeEnable");
        if (isBlank(loopModeValue)) {
            loopModeValue = getConfigValue(systemConfigMap, "circleModeEnable");
        if (stationPathPolicyService != null && startStationId != null && endStationId != null) {
            try {
                StationPathResolvedPolicy resolvedPolicy = stationPathPolicyService.resolvePolicy(startStationId, endStationId);
                if (resolvedPolicy != null && resolvedPolicy.getProfileConfig() != null) {
                    config.circleMaxLoadLimit = parseLoadLimit(String.valueOf(resolvedPolicy.getProfileConfig().getCircleMaxLoadLimit()), config.circleMaxLoadLimit);
                }
            } catch (Exception ignore) {
            }
        }
        if (isBlank(loopModeValue)) {
            loopModeValue = getConfigValue(systemConfigMap, "isCircleMode");
        }
        config.loopModeEnable = parseBoolean(loopModeValue, config.loopModeEnable);
        return config;
    }