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 | 335 +++++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 284 insertions(+), 51 deletions(-)
diff --git a/src/main/java/com/zy/common/service/CommonService.java b/src/main/java/com/zy/common/service/CommonService.java
index f03a253..2870463 100644
--- a/src/main/java/com/zy/common/service/CommonService.java
+++ b/src/main/java/com/zy/common/service/CommonService.java
@@ -20,6 +20,7 @@
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;
@@ -30,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;
@@ -56,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;
}
@@ -107,21 +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) {
- 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;
}
+ @Transactional
public boolean cancelTask(CancelTaskParam param) {
WrkMast wrkMast = null;
Integer wrkNo = param.getWrkNo();
@@ -139,24 +133,61 @@
throw new CoolException("浠诲姟涓嶅瓨鍦�");
}
- boolean cancelSuccess = false;
- if (wrkMast.getIoType().equals(WrkIoType.IN.id) && !wrkMast.getWrkSts().equals(WrkStsType.NEW_INBOUND.sts)) {
- cancelSuccess = true;
- } else if (wrkMast.getIoType().equals(WrkIoType.OUT.id) && !wrkMast.getWrkSts().equals(WrkStsType.NEW_OUTBOUND.sts)) {
- cancelSuccess = true;
- } else if (wrkMast.getIoType().equals(WrkIoType.LOC_MOVE.id) && !wrkMast.getWrkSts().equals(WrkStsType.NEW_LOC_MOVE.sts)) {
- cancelSuccess = true;
- } else if (wrkMast.getIoType().equals(WrkIoType.CRN_MOVE.id) && !wrkMast.getWrkSts().equals(WrkStsType.NEW_CRN_MOVE.sts)) {
- cancelSuccess = true;
+ 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 (cancelSuccess) {
+ if (!expectedWrkSts.equals(wrkMast.getWrkSts())) {
throw new CoolException("浠诲姟宸叉墽琛岋紝鍙栨秷澶辫触");
}
- wrkMast.setMk("taskCancel");
- wrkMast.setModiTime(new Date());
- wrkMastService.updateById(wrkMast);
+ 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;
}
@@ -638,35 +669,60 @@
}
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) {
+ 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.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) {
@@ -686,12 +742,18 @@
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.calcReachablePathByStationId(stationObjModel.getStationId(), targetStationId);
if(!navigateNodes.isEmpty()) {
finalSourceStationId = stationObjModel.getStationId();
+ cacheOutStationId(findCrnNoResult, targetStationId, finalSourceStationId);
break;
}
} catch (Exception e) {
@@ -701,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