From dc3f9cc91759823ce59486f19b138be4b296a0f1 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期二, 28 四月 2026 09:43:28 +0800
Subject: [PATCH] #
---
src/main/java/com/zy/common/service/CommonService.java | 563 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 504 insertions(+), 59 deletions(-)
diff --git a/src/main/java/com/zy/common/service/CommonService.java b/src/main/java/com/zy/common/service/CommonService.java
index 43408b8..2870463 100644
--- a/src/main/java/com/zy/common/service/CommonService.java
+++ b/src/main/java/com/zy/common/service/CommonService.java
@@ -1,8 +1,10 @@
package com.zy.common.service;
-import com.baomidou.mybatisplus.mapper.EntityWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.core.common.Cools;
import com.core.exception.CoolException;
+import com.zy.asrs.domain.Result.CancelTaskBatchResult;
import com.zy.asrs.domain.param.*;
import com.zy.asrs.entity.*;
import com.zy.asrs.service.*;
@@ -12,13 +14,16 @@
import com.zy.common.utils.NavigateUtils;
import com.zy.common.utils.RedisUtil;
import com.zy.core.News;
+import com.zy.core.service.WrkCommandRollbackService;
import com.zy.core.enums.*;
import com.zy.core.model.StationObjModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Random;
@@ -26,6 +31,13 @@
@Slf4j
@Service
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;
@@ -43,41 +55,19 @@
private RedisUtil redisUtil;
@Autowired
private BasOutStationAreaService basOutStationAreaService;
+ @Autowired
+ private WrkCommandRollbackService wrkCommandRollbackService;
+ @Autowired
+ private WrkAnalysisService wrkAnalysisService;
/**
* 鐢熸垚宸ヤ綔鍙�
* @return workNo(宸ヤ綔鍙�)
*/
- public synchronized int getWorkNo(Integer wrkMk) {
- WrkLastno wrkLastno = wrkLastnoService.selectById(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;
}
@@ -89,7 +79,7 @@
if(wrkNo == null) {
if (!Cools.isEmpty(taskNo)) {
- wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wms_wrk_no", taskNo));
+ wrkMast = wrkMastService.getOne(new QueryWrapper<WrkMast>().eq("wms_wrk_no", taskNo));
}
}else {
wrkMast = wrkMastService.selectByWorkNo(wrkNo);
@@ -99,19 +89,33 @@
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) {
+ 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;
}
+ @Transactional
public boolean cancelTask(CancelTaskParam param) {
WrkMast wrkMast = null;
Integer wrkNo = param.getWrkNo();
@@ -119,7 +123,7 @@
if(wrkNo == null) {
if (!Cools.isEmpty(taskNo)) {
- wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wms_wrk_no", taskNo));
+ wrkMast = wrkMastService.getOne(new QueryWrapper<WrkMast>().eq("wms_wrk_no", taskNo));
}
}else {
wrkMast = wrkMastService.selectByWorkNo(wrkNo);
@@ -129,10 +133,204 @@
throw new CoolException("浠诲姟涓嶅瓨鍦�");
}
- wrkMast.setMk("taskCancel");
+ Long expectedWrkSts;
+ if (wrkMast.getIoType().equals(WrkIoType.IN.id)) {
+ expectedWrkSts = WrkStsType.NEW_INBOUND.sts;
+ } else if (wrkMast.getIoType().equals(WrkIoType.OUT.id)) {
+ expectedWrkSts = WrkStsType.NEW_OUTBOUND.sts;
+ } else if (wrkMast.getIoType().equals(WrkIoType.LOC_MOVE.id)) {
+ expectedWrkSts = WrkStsType.NEW_LOC_MOVE.sts;
+ } else if (wrkMast.getIoType().equals(WrkIoType.CRN_MOVE.id)) {
+ expectedWrkSts = WrkStsType.NEW_CRN_MOVE.sts;
+ } else {
+ throw new CoolException("浠诲姟绫诲瀷涓嶆敮鎸佸彇娑�");
+ }
+
+ if (!expectedWrkSts.equals(wrkMast.getWrkSts())) {
+ throw new CoolException("浠诲姟宸叉墽琛岋紝鍙栨秷澶辫触");
+ }
+
+ boolean updated = wrkMastService.update(null, new UpdateWrapper<WrkMast>()
+ .eq("wrk_no", wrkMast.getWrkNo())
+ .eq("wrk_sts", expectedWrkSts)
+ .set("mk", "taskCancel")
+ .set("memo", "鎵嬪姩鍙栨秷")
+ .set("modi_time", new Date()));
+ if (!updated) {
+ throw new CoolException("浠诲姟鐘舵�佸凡鍙樺寲锛屽彇娑堝け璐�");
+ }
+ return true;
+ }
+
+ @Transactional
+ public boolean forceCancelTask(CancelTaskParam param) {
+ WrkMast wrkMast = null;
+ Integer wrkNo = param.getWrkNo();
+ String taskNo = param.getTaskNo();//wms浠诲姟鍙�
+
+ if (wrkNo == null) {
+ if (!Cools.isEmpty(taskNo)) {
+ wrkMast = wrkMastService.getOne(new QueryWrapper<WrkMast>().eq("wms_wrk_no", taskNo));
+ }
+ } else {
+ wrkMast = wrkMastService.selectByWorkNo(wrkNo);
+ }
+
+ if (wrkMast == null) {
+ throw new CoolException("浠诲姟涓嶅瓨鍦�");
+ }
+
+ 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("浠诲姟寮哄埗鍙栨秷澶辫触");
+ }
+ return true;
+ }
+
+ public boolean updateTaskPriorityAndBatchSeq(UpdateTaskPriorityAndBatchSeqParam param) {
+ if (param == null) {
+ throw new CoolException("鍙傛暟涓嶈兘涓虹┖");
+ }
+ if (Cools.isEmpty(param.getTaskNo())) {
+ throw new CoolException("WMS浠诲姟鍙蜂笉鑳戒负绌�");
+ }
+ if (param.getTaskPri() == null && param.getBatchSeq() == null) {
+ throw new CoolException("浠诲姟浼樺厛绾у拰鎵规搴忓彿涓嶈兘鍚屾椂涓虹┖");
+ }
+
+ WrkMast wrkMast = wrkMastService.getOne(new QueryWrapper<WrkMast>().eq("wms_wrk_no", param.getTaskNo()));
+ if (wrkMast == null) {
+ throw new CoolException("浠诲姟涓嶅瓨鍦�");
+ }
+
+ if (param.getTaskPri() != null) {
+ wrkMast.setIoPri(param.getTaskPri().doubleValue());
+ }
+ if (param.getBatchSeq() != null) {
+ wrkMast.setBatchSeq(param.getBatchSeq());
+ }
wrkMast.setModiTime(new Date());
wrkMastService.updateById(wrkMast);
return true;
+ }
+
+ public CancelTaskBatchResult cancelOutTaskBatchInfo(CancelTaskBatchParam param) {
+ if (param == null) {
+ throw new CoolException("鍙傛暟涓嶈兘涓虹┖");
+ }
+ List<CancelTaskParam> taskList = param.getTaskList();
+ if (taskList == null || taskList.isEmpty()) {
+ throw new CoolException("浠诲姟鍙傛暟鍒楄〃涓虹┖");
+ }
+
+ List<String> successList = new ArrayList<>();
+ List<String> failList = new ArrayList<>();
+ for (CancelTaskParam taskParam : taskList) {
+ if (taskParam == null) {
+ throw new CoolException("浠诲姟鍙傛暟涓嶈兘涓虹┖");
+ }
+ boolean cancelStatus = false;
+ try {
+ cancelStatus = cancelSingleOutTaskBatchInfo(taskParam);
+ } catch (Exception e) {
+ }
+
+ if (cancelStatus) {
+ successList.add(resolveTaskIdentifier(taskParam));
+ } else {
+ failList.add(resolveTaskIdentifier(taskParam));
+ }
+ }
+
+ CancelTaskBatchResult result = new CancelTaskBatchResult();
+ result.setSuccessList(successList);
+ result.setFailList(failList);
+ return result;
+ }
+
+ private boolean cancelSingleOutTaskBatchInfo(CancelTaskParam param) {
+ WrkMast wrkMast = null;
+ Integer wrkNo = param.getWrkNo();
+ String taskNo = param.getTaskNo();
+ if (wrkNo == null) {
+ if (Cools.isEmpty(taskNo)) {
+ throw new CoolException("WMS浠诲姟鍙蜂笉鑳戒负绌�");
+ }
+ wrkMast = wrkMastService.getOne(new QueryWrapper<WrkMast>().eq("wms_wrk_no", taskNo));
+ } else {
+ wrkMast = wrkMastService.selectByWorkNo(wrkNo);
+ }
+ if (wrkMast == null) {
+ throw new CoolException("浠诲姟涓嶅瓨鍦�");
+ }
+ if (!wrkMast.getIoType().equals(WrkIoType.OUT.id)) {
+ throw new CoolException("浠呮敮鎸佸嚭搴撲换鍔�");
+ }
+
+ boolean updated = wrkMast.getWrkNo() != null && wrkMastService.update(null, new UpdateWrapper<WrkMast>()
+ .eq("wrk_no", wrkMast.getWrkNo())
+ .set("batch", null)
+ .set("batch_seq", null)
+ .set("modi_time", new Date()));
+ if (!updated) {
+ throw new CoolException("鍙栨秷鍑哄簱浠诲姟鎵规鍜屾壒娆″簭鍙峰け璐�");
+ }
+ return true;
+ }
+
+ private String resolveTaskIdentifier(CancelTaskParam param) {
+ if (!Cools.isEmpty(param.getTaskNo())) {
+ return param.getTaskNo();
+ }
+ if (param.getWrkNo() != null) {
+ return String.valueOf(param.getWrkNo());
+ }
+ return "";
+ }
+
+ public CancelTaskBatchResult cancelTaskBatch(CancelTaskBatchParam param) {
+ if (param == null) {
+ throw new CoolException("鍙傛暟涓嶈兘涓虹┖");
+ }
+
+ List<CancelTaskParam> taskList = param.getTaskList();
+ if (taskList == null || taskList.isEmpty()) {
+ throw new CoolException("浠诲姟鍙傛暟鍒楄〃涓虹┖");
+ }
+
+ List<String> successList = new ArrayList<>();
+ List<String> failList = new ArrayList<>();
+
+ for (CancelTaskParam cancelTaskParam : taskList) {
+ if (cancelTaskParam == null) {
+ throw new CoolException("浠诲姟鍙傛暟涓嶈兘涓虹┖");
+ }
+
+ boolean cancelStatus = false;
+ try {
+ cancelStatus = cancelTask(cancelTaskParam);
+ } catch (Exception e) {
+ }
+
+ if (cancelStatus) {
+ successList.add(cancelTaskParam.getTaskNo());
+ }else {
+ failList.add(cancelTaskParam.getTaskNo());
+ }
+ }
+
+ CancelTaskBatchResult result = new CancelTaskBatchResult();
+ result.setSuccessList(successList);
+ result.setFailList(failList);
+ return result;
+ }
+
+ public boolean manualRollbackTask(ManualRollbackTaskParam param) {
+ return wrkCommandRollbackService.manualRollbackTask(param);
}
//绉诲簱浠诲姟
@@ -199,11 +397,12 @@
throw new CoolException("鏈煡璁惧绫诲瀷");
}
- boolean res = wrkMastService.insert(wrkMast);
+ boolean res = wrkMastService.save(wrkMast);
if (!res) {
News.error("绉诲簱浠诲姟 --- 淇濆瓨宸ヤ綔妗eけ璐ワ紒");
throw new CoolException("淇濆瓨宸ヤ綔妗eけ璐�");
}
+ wrkAnalysisService.initForTask(wrkMast);
sourceLocMast.setLocSts("R");
sourceLocMast.setModiTime(new Date());
@@ -267,11 +466,12 @@
throw new CoolException("鏈煡璁惧绫诲瀷");
}
- boolean res = wrkMastService.insert(wrkMast);
+ boolean res = wrkMastService.save(wrkMast);
if (!res) {
News.error("鍏ュ簱浠诲姟 --- 淇濆瓨宸ヤ綔妗eけ璐ワ紒");
throw new CoolException("淇濆瓨宸ヤ綔妗eけ璐�");
}
+ wrkAnalysisService.initForTask(wrkMast);
locMast.setLocSts("S");
locMast.setModiTime(new Date());
@@ -309,7 +509,7 @@
}
if(Cools.isEmpty(staNo)) {
- List<BasOutStationArea> areaList = basOutStationAreaService.selectList(new EntityWrapper<BasOutStationArea>().eq("area_code", outArea));
+ List<BasOutStationArea> areaList = basOutStationAreaService.list(new QueryWrapper<BasOutStationArea>().eq("area_code", outArea));
if (areaList.isEmpty()) {
throw new CoolException("鍑哄簱鍖哄煙涓嶅瓨鍦�");
}
@@ -349,11 +549,11 @@
}
if (findCrnResult.getCrnType().equals(SlaveType.Crn)) {
- BasCrnp basCrnp = basCrnpService.selectOne(new EntityWrapper<BasCrnp>().eq("crn_no", crnNo));
+ BasCrnp basCrnp = basCrnpService.getOne(new QueryWrapper<BasCrnp>().eq("crn_no", crnNo));
if(basCrnp == null) {
throw new CoolException("鏈壘鍒板搴斿爢鍨涙満鏁版嵁");
}
- List<WrkMast> outWrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+ List<WrkMast> outWrkMasts = wrkMastService.list(new QueryWrapper<WrkMast>()
.eq("crn_no", crnNo)
.eq("io_type", WrkIoType.OUT.id)
);
@@ -365,11 +565,11 @@
wrkMast.setCrnNo(findCrnResult.getCrnNo());
} else if (findCrnResult.getCrnType().equals(SlaveType.DualCrn)) {
- BasDualCrnp basDualCrnp = basDualCrnpService.selectOne(new EntityWrapper<BasDualCrnp>().eq("crn_no", crnNo));
+ BasDualCrnp basDualCrnp = basDualCrnpService.getOne(new QueryWrapper<BasDualCrnp>().eq("crn_no", crnNo));
if(basDualCrnp == null) {
throw new CoolException("鏈壘鍒板搴斿弻宸ヤ綅鍫嗗灈鏈烘暟鎹�");
}
- List<WrkMast> outWrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>()
+ List<WrkMast> outWrkMasts = wrkMastService.list(new QueryWrapper<WrkMast>()
.eq("dual_crn_no", crnNo)
.eq("io_type", WrkIoType.OUT.id)
);
@@ -384,11 +584,12 @@
throw new CoolException("鏈煡璁惧绫诲瀷");
}
- boolean res = wrkMastService.insert(wrkMast);
+ boolean res = wrkMastService.save(wrkMast);
if (!res) {
News.error("鍑哄簱浠诲姟 --- 淇濆瓨宸ヤ綔妗eけ璐ワ紒");
throw new CoolException("淇濆瓨宸ヤ綔妗eけ璐�");
}
+ wrkAnalysisService.initForTask(wrkMast);
locMast.setLocSts("R");
locMast.setModiTime(new Date());
@@ -396,8 +597,50 @@
return true;
}
+ public boolean createOutTaskBatch(CreateOutTaskBatchParam param) {
+ if (param == null) {
+ throw new CoolException("鍙傛暟涓嶈兘涓虹┖");
+ }
+
+ List<CreateOutTaskParam> taskList = param.getTaskList();
+ if (taskList == null || taskList.isEmpty()) {
+ throw new CoolException("浠诲姟鍒楄〃涓嶈兘涓虹┖");
+ }
+
+ List<CreateOutTaskParam> sortedTaskList = new ArrayList<>(taskList);
+ sortedTaskList.sort(Comparator.nullsLast(Comparator
+ .comparing(this::getSortableBatch, Comparator.nullsLast(String::compareTo))
+ .thenComparing(this::getSortableBatchSeq, Comparator.nullsLast(Integer::compareTo))));
+
+ for (CreateOutTaskParam createOutTaskParam : sortedTaskList) {
+ if (createOutTaskParam == null) {
+ throw new CoolException("浠诲姟鍙傛暟涓嶈兘涓虹┖");
+ }
+ createOutTask(createOutTaskParam);
+ }
+ return true;
+ }
+
+ private String getSortableBatch(CreateOutTaskParam param) {
+ if (param == null) {
+ return null;
+ }
+ String batch = param.getBatch();
+ if (batch == null || batch.trim().isEmpty()) {
+ return null;
+ }
+ return batch;
+ }
+
+ private Integer getSortableBatchSeq(CreateOutTaskParam param) {
+ if (param == null) {
+ return null;
+ }
+ return param.getBatchSeq();
+ }
+
public FindCrnNoResult findCrnNoByLocNo(String locNo) {
- List<BasCrnp> basCrnps = basCrnpService.selectList(new EntityWrapper<>());
+ List<BasCrnp> basCrnps = basCrnpService.list(new QueryWrapper<>());
for (BasCrnp basCrnp : basCrnps) {
List<List<Integer>> rowList = basCrnp.getControlRows$();
for (List<Integer> rows : rowList) {
@@ -410,7 +653,7 @@
}
}
- List<BasDualCrnp> basDualCrnps = basDualCrnpService.selectList(new EntityWrapper<>());
+ List<BasDualCrnp> basDualCrnps = basDualCrnpService.list(new QueryWrapper<>());
for (BasDualCrnp basDualCrnp : basDualCrnps) {
List<List<Integer>> rowList = basDualCrnp.getControlRows$();
for (List<Integer> rows : rowList) {
@@ -426,60 +669,91 @@
}
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.selectOne(new EntityWrapper<BasCrnp>().eq("crn_no", crnNo));
+ 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.selectOne(new EntityWrapper<BasDualCrnp>().eq("crn_no", crnNo));
+ 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) {
+ long totalCostMs = nanosToMillis(resolveStartNs);
+ if (totalCostMs >= IN_STATION_ROUTE_SLOW_LOG_THRESHOLD_MS) {
+ log.info("鍏ュ簱鐩爣绔欑紦瀛樺懡涓�楁椂杈冮暱锛宻ourceStationId={}锛宑rnNo={}锛宼argetStationId={}锛宼otalCost={}ms",
+ sourceStationId, crnNo, cachedTargetStationId, totalCostMs);
+ }
+ return InStationResolveResult.cacheHit(cachedTargetStationId, totalCostMs);
+ }
+
+ long searchStartNs = System.nanoTime();
Integer targetStationId = null;
for (StationObjModel stationObjModel : stationList) {
try {
- List<NavigateNode> navigateNodes = navigateUtils.calcByStationId(sourceStationId, stationObjModel.getStationId());
- if(navigateNodes != null) {
+ List<NavigateNode> navigateNodes = navigateUtils.calcReachablePathByStationId(sourceStationId, stationObjModel.getStationId());
+ if(!navigateNodes.isEmpty()) {
targetStationId = stationObjModel.getStationId();
+ cacheInStationId(findCrnNoResult, sourceStationId, targetStationId);
break;
}
} catch (Exception e) {
// e.printStackTrace();
}
}
- return targetStationId;
+ long searchCostMs = nanosToMillis(searchStartNs);
+ long totalCostMs = nanosToMillis(resolveStartNs);
+ log.info("鍏ュ簱鐩爣绔欑紦瀛樻湭鍛戒腑锛宻ourceStationId={}锛宑rnNo={}锛宼argetStationId={}锛宻earchCost={}ms锛宼otalCost={}ms",
+ sourceStationId, crnNo, targetStationId, searchCostMs, totalCostMs);
+ return InStationResolveResult.searchResult(targetStationId, totalCostMs, searchCostMs);
}
public Integer findOutStationId(FindCrnNoResult findCrnNoResult, Integer targetStationId) {
List<StationObjModel> stationList = new ArrayList<>();
Integer crnNo = findCrnNoResult.getCrnNo();
if (findCrnNoResult.getCrnType().equals(SlaveType.Crn)) {
- BasCrnp basCrnp = basCrnpService.selectOne(new EntityWrapper<BasCrnp>().eq("crn_no", crnNo));
+ BasCrnp basCrnp = basCrnpService.getOne(new QueryWrapper<BasCrnp>().eq("crn_no", crnNo));
if(basCrnp == null) {
return null;
}
stationList = basCrnp.getOutStationList$();
} else if (findCrnNoResult.getCrnType().equals(SlaveType.DualCrn)) {
- BasDualCrnp basDualCrnp = basDualCrnpService.selectOne(new EntityWrapper<BasDualCrnp>().eq("crn_no", crnNo));
+ BasDualCrnp basDualCrnp = basDualCrnpService.getOne(new QueryWrapper<BasDualCrnp>().eq("crn_no", crnNo));
if(basDualCrnp == null) {
return null;
}
stationList = basDualCrnp.getOutStationList$();
}
+ Integer cachedSourceStationId = resolveCachedOutStationId(findCrnNoResult, targetStationId, stationList);
+ if (cachedSourceStationId != null) {
+ return cachedSourceStationId;
+ }
+
Integer finalSourceStationId = null;
for (StationObjModel stationObjModel : stationList) {
try {
- List<NavigateNode> navigateNodes = navigateUtils.calcByStationId(stationObjModel.getStationId(), targetStationId);
- if(navigateNodes != null) {
+ List<NavigateNode> navigateNodes = navigateUtils.calcReachablePathByStationId(stationObjModel.getStationId(), targetStationId);
+ if(!navigateNodes.isEmpty()) {
finalSourceStationId = stationObjModel.getStationId();
+ cacheOutStationId(findCrnNoResult, targetStationId, finalSourceStationId);
break;
}
} catch (Exception e) {
@@ -489,4 +763,175 @@
return finalSourceStationId;
}
+ /**
+ * 鍏ュ簱璺緞鎼滅储鍚屾牱浠d环杈冮珮锛屽彧缂撳瓨宸茬‘璁ゅ彲杈剧殑鐩爣绔欑偣缁撴灉锛屽苟閫氳繃 TTL 闄愬埗闄堟棫椋庨櫓銆�
+ */
+ private Integer resolveCachedInStationId(FindCrnNoResult findCrnNoResult,
+ Integer sourceStationId,
+ List<StationObjModel> stationList) {
+ if (findCrnNoResult == null || findCrnNoResult.getCrnType() == null
+ || findCrnNoResult.getCrnNo() == null || sourceStationId == null
+ || stationList == null || stationList.isEmpty()) {
+ return null;
+ }
+
+ Object cacheValue = redisUtil.get(buildInStationRouteCacheKey(findCrnNoResult, sourceStationId));
+ if (cacheValue == null) {
+ return null;
+ }
+
+ Integer cachedStationId = parseInteger(cacheValue);
+ if (cachedStationId == null) {
+ return null;
+ }
+
+ for (StationObjModel stationObjModel : stationList) {
+ if (stationObjModel != null && cachedStationId.equals(stationObjModel.getStationId())) {
+ return cachedStationId;
+ }
+ }
+ return null;
+ }
+
+ private void cacheInStationId(FindCrnNoResult findCrnNoResult,
+ Integer sourceStationId,
+ Integer targetStationId) {
+ if (findCrnNoResult == null || findCrnNoResult.getCrnType() == null
+ || findCrnNoResult.getCrnNo() == null || sourceStationId == null
+ || targetStationId == null) {
+ return;
+ }
+ redisUtil.set(buildInStationRouteCacheKey(findCrnNoResult, sourceStationId),
+ targetStationId,
+ IN_STATION_ROUTE_CACHE_SECONDS);
+ }
+
+ private String buildInStationRouteCacheKey(FindCrnNoResult findCrnNoResult, Integer sourceStationId) {
+ return RedisKeyType.IN_STATION_ROUTE_CACHE.key
+ + findCrnNoResult.getCrnType().name()
+ + "_"
+ + findCrnNoResult.getCrnNo()
+ + "_"
+ + sourceStationId;
+ }
+
+ /**
+ * 鍑哄簱璺緞鎼滅储浠d环杈冮珮锛屽彧缂撳瓨宸茬‘璁ゅ彲杈剧殑绔欑偣缁撴灉锛屽苟閫氳繃 TTL 鎺у埗闄堟棫椋庨櫓銆�
+ */
+ private Integer resolveCachedOutStationId(FindCrnNoResult findCrnNoResult,
+ Integer targetStationId,
+ List<StationObjModel> stationList) {
+ if (findCrnNoResult == null || findCrnNoResult.getCrnType() == null
+ || findCrnNoResult.getCrnNo() == null || targetStationId == null
+ || stationList == null || stationList.isEmpty()) {
+ return null;
+ }
+
+ Object cacheValue = redisUtil.get(buildOutStationRouteCacheKey(findCrnNoResult, targetStationId));
+ if (cacheValue == null) {
+ return null;
+ }
+
+ Integer cachedStationId = parseInteger(cacheValue);
+ if (cachedStationId == null) {
+ return null;
+ }
+
+ for (StationObjModel stationObjModel : stationList) {
+ if (stationObjModel != null && cachedStationId.equals(stationObjModel.getStationId())) {
+ return cachedStationId;
+ }
+ }
+ return null;
+ }
+
+ private void cacheOutStationId(FindCrnNoResult findCrnNoResult,
+ Integer targetStationId,
+ Integer sourceStationId) {
+ if (findCrnNoResult == null || findCrnNoResult.getCrnType() == null
+ || findCrnNoResult.getCrnNo() == null || targetStationId == null
+ || sourceStationId == null) {
+ return;
+ }
+ redisUtil.set(buildOutStationRouteCacheKey(findCrnNoResult, targetStationId),
+ sourceStationId,
+ OUT_STATION_ROUTE_CACHE_SECONDS);
+ }
+
+ private String buildOutStationRouteCacheKey(FindCrnNoResult findCrnNoResult, Integer targetStationId) {
+ return RedisKeyType.OUT_STATION_ROUTE_CACHE.key
+ + findCrnNoResult.getCrnType().name()
+ + "_"
+ + findCrnNoResult.getCrnNo()
+ + "_"
+ + targetStationId;
+ }
+
+ private Integer parseInteger(Object value) {
+ if (value == null) {
+ return null;
+ }
+ if (value instanceof Integer) {
+ return (Integer) value;
+ }
+ if (value instanceof Number) {
+ return ((Number) value).intValue();
+ }
+ try {
+ return Integer.parseInt(String.valueOf(value));
+ } catch (Exception ignore) {
+ return null;
+ }
+ }
+
+ 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;
+ }
+ }
+
}
--
Gitblit v1.9.1