Junjie
21 小时以前 eeca5bc061d3f74e76658a5ae339fa9e5eff0d57
src/main/java/com/zy/core/utils/station/StationOutboundDispatchProcessor.java
@@ -2,8 +2,10 @@
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zy.asrs.entity.BasStation;
import com.zy.asrs.domain.enums.NotifyMsgType;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.BasStationService;
import com.zy.asrs.service.WrkAnalysisService;
import com.zy.asrs.service.WrkMastService;
import com.zy.asrs.utils.NotifyUtils;
@@ -30,12 +32,17 @@
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@Component
public class StationOutboundDispatchProcessor {
    private static final int PENDING_DISPATCH_EXPIRE_SECONDS = 60 * 10;
    @Autowired
    private WrkMastService wrkMastService;
    @Autowired
    private BasStationService basStationService;
    @Autowired
    private WrkAnalysisService wrkAnalysisService;
    @Autowired
@@ -69,14 +76,57 @@
            if (wrkMast == null || wrkMast.getWrkNo() == null) {
                return;
            }
            Object pendingObj = redisUtil.get(RedisKeyType.STATION_OUT_PENDING_DISPATCH_.key + wrkMast.getWrkNo());
            if (pendingObj != null) {
                if (!Objects.equals(wrkMast.getWrkSts(), WrkStsType.OUTBOUND_RUN_COMPLETE.sts)) {
                    clearPendingDispatch(wrkMast.getWrkNo());
                    return;
                }
            Object infoObj = redisUtil.get(RedisKeyType.CRN_OUT_TASK_COMPLETE_STATION_INFO.key + wrkMast.getWrkNo());
            if (infoObj == null) {
                News.info("出库任务{}数据缓存不存在", wrkMast.getWrkNo());
                return;
                StationObjModel pendingStationObjModel = getOutboundSourceStation(wrkMast);
                if (pendingStationObjModel == null
                        || pendingStationObjModel.getDeviceNo() == null
                        || pendingStationObjModel.getStationId() == null) {
                    clearPendingDispatch(wrkMast.getWrkNo());
                    return;
                }
                StationThread pendingStationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, pendingStationObjModel.getDeviceNo());
                if (pendingStationThread != null) {
                    List<Integer> taskNoList = pendingStationThread.getAllTaskNoList();
                    if (taskNoList != null && taskNoList.contains(wrkMast.getWrkNo())) {
                        Date now = new Date();
                        wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts);
                        wrkMast.setSystemMsg("");
                        wrkMast.setIoTime(now);
                        wrkMast.setModiTime(now);
                        if (wrkMastService.updateById(wrkMast)) {
                            wrkAnalysisService.markOutboundStationStart(wrkMast, now);
                            notifyUtils.notify(String.valueOf(SlaveType.Devp), pendingStationObjModel.getDeviceNo(),
                                    String.valueOf(wrkMast.getWrkNo()), wrkMast.getWmsWrkNo(),
                                    NotifyMsgType.STATION_OUT_TASK_RUN, null);
                            clearPendingDispatch(wrkMast.getWrkNo());
                            News.info("输送设备已发现任务号,任务转运行中。deviceNo={},源站={},工作号={}",
                                    pendingStationObjModel.getDeviceNo(), pendingStationObjModel.getStationId(), wrkMast.getWrkNo());
                        }
                        return;
                    }
                }
                long createdAt;
                try {
                    createdAt = Long.parseLong(String.valueOf(pendingObj));
                } catch (Exception ignore) {
                    createdAt = System.currentTimeMillis();
                }
                if (System.currentTimeMillis() - createdAt < 15_000L) {
                    return;
                }
                clearPendingDispatch(wrkMast.getWrkNo());
                News.warn("输送站点执行超时,已释放重试资格。工作号={}", wrkMast.getWrkNo());
            }
            StationObjModel stationObjModel = JSON.parseObject(infoObj.toString(), StationObjModel.class);
            StationObjModel stationObjModel = getOutboundSourceStation(wrkMast);
            if (stationObjModel == null || stationObjModel.getDeviceNo() == null || stationObjModel.getStationId() == null) {
                return;
            }
@@ -150,30 +200,25 @@
                return;
            }
            Date now = new Date();
            wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts);
            wrkMast.setSystemMsg("");
            wrkMast.setIoTime(now);
            wrkMast.setModiTime(now);
            if (wrkMastService.updateById(wrkMast)) {
                wrkAnalysisService.markOutboundStationStart(wrkMast, now);
                boolean offered = offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "crnStationOutExecute");
                if (offered && stationMoveCoordinator != null) {
                    stationMoveCoordinator.recordDispatch(
                            wrkMast.getWrkNo(),
                            stationProtocol.getStationId(),
                            "crnStationOutExecute",
                            command,
                            false
                    );
                }
                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());
                loadGuardState.reserveLoopTask(loopHitResult.getLoopNo());
                stationDispatchLoadSupport.saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult);
            boolean offered = offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "crnStationOutExecute");
            if (!offered) {
                return;
            }
            if (stationMoveCoordinator != null) {
                stationMoveCoordinator.recordDispatch(
                        wrkMast.getWrkNo(),
                        stationProtocol.getStationId(),
                        "crnStationOutExecute",
                        command,
                        false
                );
            }
            markPendingDispatch(wrkMast.getWrkNo());
            News.info("输送站点出库命令已入设备执行链路,等待源站执行。站点号={},工作号={},命令数据={}",
                    stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
            redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5);
            loadGuardState.reserveLoopTask(loopHitResult.getLoopNo());
            stationDispatchLoadSupport.saveLoopLoadReserve(wrkMast.getWrkNo(), loopHitResult);
        } catch (Exception e) {
            e.printStackTrace();
        }
@@ -185,13 +230,13 @@
                    .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());
                if (hasPendingDispatch(wrkMast.getWrkNo())) {
                    continue;
                }
                StationObjModel stationObjModel = JSON.parseObject(infoObj.toString(), StationObjModel.class);
                StationObjModel stationObjModel = getOutboundSourceStation(wrkMast);
                if (stationObjModel == null || stationObjModel.getDeviceNo() == null || stationObjModel.getStationId() == null) {
                    continue;
                }
                StationThread stationThread = (StationThread) SlaveConnection.get(SlaveType.Devp, stationObjModel.getDeviceNo());
                if (stationThread == null) {
                    continue;
@@ -224,28 +269,23 @@
                        continue;
                    }
                    wrkMast.setWrkSts(WrkStsType.STATION_RUN.sts);
                    wrkMast.setSystemMsg("");
                    wrkMast.setIoTime(new Date());
                    if (wrkMastService.updateById(wrkMast)) {
                        boolean offered = offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "dualCrnStationOutExecute");
                        if (offered && stationMoveCoordinator != null) {
                            stationMoveCoordinator.recordDispatch(
                                    wrkMast.getWrkNo(),
                                    stationProtocol.getStationId(),
                                    "dualCrnStationOutExecute",
                                    command,
                                    false
                            );
                        }
                        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());
                    boolean offered = offerDevpCommandWithDedup(stationObjModel.getDeviceNo(), command, "dualCrnStationOutExecute");
                    if (!offered) {
                        continue;
                    }
                    if (stationMoveCoordinator != null) {
                        stationMoveCoordinator.recordDispatch(
                                wrkMast.getWrkNo(),
                                stationProtocol.getStationId(),
                                "dualCrnStationOutExecute",
                                command,
                                false
                        );
                    }
                    markPendingDispatch(wrkMast.getWrkNo());
                    News.info("输送站点出库命令已入设备执行链路,等待源站接单。站点号={},工作号={},命令数据={}",
                            stationProtocol.getStationId(), wrkMast.getWrkNo(), JSON.toJSONString(command));
                    redisUtil.set(RedisKeyType.STATION_OUT_EXECUTE_LIMIT.key + stationProtocol.getStationId(), "lock", 5);
                }
            }
        } catch (Exception e) {
@@ -258,4 +298,36 @@
                .dispatch(deviceNo, command, "station-operate-process", scene);
        return dispatchResult.isAccepted();
    }
    private StationObjModel getOutboundSourceStation(WrkMast wrkMast) {
        if (wrkMast == null || wrkMast.getSourceStaNo() == null) {
            return null;
        }
        BasStation basStation = basStationService.getById(wrkMast.getSourceStaNo());
        if (basStation == null || basStation.getDeviceNo() == null) {
            return null;
        }
        StationObjModel stationObjModel = new StationObjModel();
        stationObjModel.setStationId(wrkMast.getSourceStaNo());
        stationObjModel.setDeviceNo(basStation.getDeviceNo());
        return stationObjModel;
    }
    private boolean hasPendingDispatch(Integer wrkNo) {
        return wrkNo != null && redisUtil.get(RedisKeyType.STATION_OUT_PENDING_DISPATCH_.key + wrkNo) != null;
    }
    private void markPendingDispatch(Integer wrkNo) {
        if (wrkNo == null) {
            return;
        }
        redisUtil.set(RedisKeyType.STATION_OUT_PENDING_DISPATCH_.key + wrkNo, String.valueOf(System.currentTimeMillis()), PENDING_DISPATCH_EXPIRE_SECONDS);
    }
    private void clearPendingDispatch(Integer wrkNo) {
        if (wrkNo == null) {
            return;
        }
        redisUtil.del(RedisKeyType.STATION_OUT_PENDING_DISPATCH_.key + wrkNo);
    }
}