#
Junjie
9 天以前 dc3f9cc91759823ce59486f19b138be4b296a0f1
src/main/java/com/zy/common/service/CommonService.java
@@ -33,6 +33,11 @@
public class CommonService {
    private static final long OUT_STATION_ROUTE_CACHE_SECONDS = 60 * 60 * 24 * 7;
    /**
     * 入库目标站的拓扑变化频率很低,允许使用 24h 缓存减少重复可达路径搜索。
     */
    private static final long IN_STATION_ROUTE_CACHE_SECONDS = 60 * 60 * 24;
    private static final long IN_STATION_ROUTE_SLOW_LOG_THRESHOLD_MS = 200L;
    @Autowired
    private WrkMastService wrkMastService;
@@ -59,36 +64,10 @@
     * 生成工作号
     * @return workNo(工作号)
     */
    public synchronized int getWorkNo(Integer wrkMk) {
        WrkLastno wrkLastno = wrkLastnoService.getById(wrkMk);
        if (Cools.isEmpty(wrkLastno)) {
            throw new CoolException("数据异常,请联系管理员");
        }
        int workNo = wrkLastno.getWrkNo();
        int sNo = wrkLastno.getsNo();
        int eNo = wrkLastno.geteNo();
        workNo = workNo>=eNo ? sNo : workNo+1;
        while (true) {
            WrkMast wrkMast = wrkMastService.selectByWorkNo(workNo);
            if (null != wrkMast) {
                workNo = workNo>=eNo ? sNo : workNo+1;
            } else {
                break;
            }
        }
        // 修改序号记录
        if (workNo > 0){
            wrkLastno.setWrkNo(workNo);
            wrkLastnoService.updateById(wrkLastno);
        }
        // 检验
        if (workNo == 0) {
    public int getWorkNo(Integer wrkMk) {
        int workNo = wrkLastnoService.allocateNextWorkNo(wrkMk);
        if (workNo <= 0) {
            throw new CoolException("生成工作号失败,请联系管理员");
        } else {
            if (wrkMastService.selectByWorkNo(workNo)!=null) {
                throw new CoolException("生成工作号" + workNo + "在工作档中已存在");
            }
        }
        return workNo;
    }
@@ -110,18 +89,29 @@
            throw new CoolException("任务不存在");
        }
        Long currentWrkSts = wrkMast.getWrkSts();
        Long targetWrkSts;
        if (wrkMast.getIoType() == WrkIoType.IN.id) {
            wrkMast.setWrkSts(WrkStsType.COMPLETE_INBOUND.sts);
            targetWrkSts = WrkStsType.COMPLETE_INBOUND.sts;
        }else if (wrkMast.getIoType() == WrkIoType.OUT.id) {
            wrkMast.setWrkSts(WrkStsType.COMPLETE_OUTBOUND.sts);
            targetWrkSts = WrkStsType.COMPLETE_OUTBOUND.sts;
        } else if (wrkMast.getIoType() == WrkIoType.LOC_MOVE.id) {
            wrkMast.setWrkSts(WrkStsType.COMPLETE_LOC_MOVE.sts);
            targetWrkSts = WrkStsType.COMPLETE_LOC_MOVE.sts;
        } else if (wrkMast.getIoType() == WrkIoType.CRN_MOVE.id) {
            wrkMast.setWrkSts(WrkStsType.COMPLETE_CRN_MOVE.sts);
            targetWrkSts = WrkStsType.COMPLETE_CRN_MOVE.sts;
        } else {
            throw new CoolException("任务类型不支持完成");
        }
        wrkMast.setModiTime(new Date());
        wrkMastService.updateById(wrkMast);
        boolean updated = wrkMastService.update(null, new UpdateWrapper<WrkMast>()
                .set("wrk_sts", targetWrkSts)
                .set("modi_time", new Date())
                .set("memo", "手动完成")
                .eq("wrk_no", wrkMast.getWrkNo())
                .eq("wrk_sts", currentWrkSts));
        if (!updated) {
            throw new CoolException("任务状态已变化,完成失败");
        }
        return true;
    }
@@ -164,6 +154,7 @@
                .eq("wrk_no", wrkMast.getWrkNo())
                .eq("wrk_sts", expectedWrkSts)
                .set("mk", "taskCancel")
                .set("memo", "手动取消")
                .set("modi_time", new Date()));
        if (!updated) {
            throw new CoolException("任务状态已变化,取消失败");
@@ -192,6 +183,7 @@
        boolean updated = wrkMastService.update(null, new UpdateWrapper<WrkMast>()
                .eq("wrk_no", wrkMast.getWrkNo())
                .set("mk", "taskForceCancel")
                .set("memo", "手动完成")
                .set("modi_time", new Date()));
        if (!updated) {
            throw new CoolException("任务强制取消失败");
@@ -677,27 +669,42 @@
    }
    public Integer findInStationId(FindCrnNoResult findCrnNoResult, Integer sourceStationId) {
        return resolveInStationId(findCrnNoResult, sourceStationId).getTargetStationId();
    }
    public InStationResolveResult resolveInStationId(FindCrnNoResult findCrnNoResult, Integer sourceStationId) {
        long resolveStartNs = System.nanoTime();
        if (findCrnNoResult == null || findCrnNoResult.getCrnType() == null
                || findCrnNoResult.getCrnNo() == null || sourceStationId == null) {
            return InStationResolveResult.empty(false, nanosToMillis(resolveStartNs));
        }
        List<StationObjModel> stationList = new ArrayList<>();
        Integer crnNo = findCrnNoResult.getCrnNo();
        if (findCrnNoResult.getCrnType().equals(SlaveType.Crn)) {
            BasCrnp basCrnp = basCrnpService.getOne(new QueryWrapper<BasCrnp>().eq("crn_no", crnNo));
            if(basCrnp == null) {
                return null;
                return InStationResolveResult.empty(false, nanosToMillis(resolveStartNs));
            }
            stationList = basCrnp.getInStationList$();
        } else if (findCrnNoResult.getCrnType().equals(SlaveType.DualCrn)) {
            BasDualCrnp basDualCrnp = basDualCrnpService.getOne(new QueryWrapper<BasDualCrnp>().eq("crn_no", crnNo));
            if(basDualCrnp == null) {
                return null;
                return InStationResolveResult.empty(false, nanosToMillis(resolveStartNs));
            }
            stationList = basDualCrnp.getInStationList$();
        }
        Integer cachedTargetStationId = resolveCachedInStationId(findCrnNoResult, sourceStationId, stationList);
        if (cachedTargetStationId != null) {
            return cachedTargetStationId;
            long totalCostMs = nanosToMillis(resolveStartNs);
            if (totalCostMs >= IN_STATION_ROUTE_SLOW_LOG_THRESHOLD_MS) {
                log.info("入库目标站缓存命中耗时较长,sourceStationId={},crnNo={},targetStationId={},totalCost={}ms",
                        sourceStationId, crnNo, cachedTargetStationId, totalCostMs);
            }
            return InStationResolveResult.cacheHit(cachedTargetStationId, totalCostMs);
        }
        long searchStartNs = System.nanoTime();
        Integer targetStationId = null;
        for (StationObjModel stationObjModel : stationList) {
            try {
@@ -711,7 +718,11 @@
//                e.printStackTrace();
            }
        }
        return targetStationId;
        long searchCostMs = nanosToMillis(searchStartNs);
        long totalCostMs = nanosToMillis(resolveStartNs);
        log.info("入库目标站缓存未命中,sourceStationId={},crnNo={},targetStationId={},searchCost={}ms,totalCost={}ms",
                sourceStationId, crnNo, targetStationId, searchCostMs, totalCostMs);
        return InStationResolveResult.searchResult(targetStationId, totalCostMs, searchCostMs);
    }
    public Integer findOutStationId(FindCrnNoResult findCrnNoResult, Integer targetStationId) {
@@ -792,7 +803,7 @@
        }
        redisUtil.set(buildInStationRouteCacheKey(findCrnNoResult, sourceStationId),
                targetStationId,
                OUT_STATION_ROUTE_CACHE_SECONDS);
                IN_STATION_ROUTE_CACHE_SECONDS);
    }
    private String buildInStationRouteCacheKey(FindCrnNoResult findCrnNoResult, Integer sourceStationId) {
@@ -873,4 +884,54 @@
        }
    }
    private long nanosToMillis(long startNs) {
        long elapsedNs = System.nanoTime() - startNs;
        return elapsedNs <= 0L ? 0L : elapsedNs / 1_000_000L;
    }
    public static class InStationResolveResult {
        private final Integer targetStationId;
        private final boolean cacheHit;
        private final long totalCostMs;
        private final long searchCostMs;
        private InStationResolveResult(Integer targetStationId,
                                       boolean cacheHit,
                                       long totalCostMs,
                                       long searchCostMs) {
            this.targetStationId = targetStationId;
            this.cacheHit = cacheHit;
            this.totalCostMs = totalCostMs;
            this.searchCostMs = searchCostMs;
        }
        public static InStationResolveResult cacheHit(Integer targetStationId, long totalCostMs) {
            return new InStationResolveResult(targetStationId, true, totalCostMs, 0L);
        }
        public static InStationResolveResult searchResult(Integer targetStationId, long totalCostMs, long searchCostMs) {
            return new InStationResolveResult(targetStationId, false, totalCostMs, searchCostMs);
        }
        public static InStationResolveResult empty(boolean cacheHit, long totalCostMs) {
            return new InStationResolveResult(null, cacheHit, totalCostMs, 0L);
        }
        public Integer getTargetStationId() {
            return targetStationId;
        }
        public boolean isCacheHit() {
            return cacheHit;
        }
        public long getTotalCostMs() {
            return totalCostMs;
        }
        public long getSearchCostMs() {
            return searchCostMs;
        }
    }
}