From 73e42333948a8143c54218cd26435c2233daf279 Mon Sep 17 00:00:00 2001
From: chen.llin <1442464845@qq.comm>
Date: 星期五, 16 一月 2026 14:13:14 +0800
Subject: [PATCH] agv出入库逻辑
---
src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java | 158 +++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 137 insertions(+), 21 deletions(-)
diff --git a/src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java
index 21c7923..173cf0c 100644
--- a/src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java
+++ b/src/main/java/com/zy/asrs/service/impl/MobileServiceImpl.java
@@ -23,6 +23,7 @@
import com.zy.common.model.DetlDto;
import com.zy.common.model.MesCombParam;
import com.zy.common.model.enums.WorkNoType;
+import com.zy.common.properties.AgvProperties;
import com.zy.common.service.CommonService;
import com.zy.common.utils.HttpHandler;
import lombok.extern.slf4j.Slf4j;
@@ -36,6 +37,8 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
@@ -122,13 +125,25 @@
@Resource
private BasDevpMapper basDevpMapper;
+ @Resource
+ private AgvProperties agvProperties;
+
+ /**
+ * 绔欑偣杞璁℃暟鍣紝鐢ㄤ簬骞冲潎鍒嗛厤绔欑偣
+ * Key: 绔欑偣缁勬爣璇嗭紙濡� "east" 鎴� "west"锛夛紝Value: 褰撳墠杞绱㈠紩
+ */
+ private final Map<String, AtomicInteger> siteRoundRobinCounters = new ConcurrentHashMap<>();
+
@Override
public R inLocCallAgv(CallAgvParam param,Long userId) {
int type = param.getType();
String sourceSite = param.getSourceSite();
String barcode = param.getBarcode();
int ioType;
-
+ LocCache locCache = locCacheService.selectOne(new EntityWrapper<LocCache>().eq("loc_no", sourceSite));
+ if (null == locCache) {
+ throw new CoolException("绔欑偣涓嶅瓨鍦細" + sourceSite);
+ }
switch (type) {
case 1:
// 鍒ゆ柇鏈夋病鏈夌粍鎵�
@@ -136,7 +151,10 @@
if (count == 0) {
throw new CoolException("鏉$爜鏈粍鎵橈細" + barcode);
}
- ioType = 1;
+ ioType = 101;
+
+ locCache.setLocSts(LocStsType.LOC_STS_TYPE_R.type);
+ locCacheService.updateById(locCache);
break;
case 2:
// 鍒ゆ柇鏄嫞閫夊洖搴撴墭鐩�
@@ -148,25 +166,38 @@
throw new CoolException("鏉$爜涓嶉渶瑕佸洖搴擄細" + barcode);
}
ioType = wrkMast.getIoType() - 50;
+
+ locCache.setLocSts(LocStsType.LOC_STS_TYPE_R.type);
+ locCacheService.updateById(locCache);
break;
case 3:
- // 鍒ゆ柇鏉$爜鍦╳ms涓嶅瓨鍦紝鏄┖鎵樼洏
- // 宸茬粍鎵�
+ // 鍒ゆ柇鏄惁涓虹┖鎵樺叆搴擄細妫�鏌ユ潯鐮佸湪wms涓笉瀛樺湪锛岀‘璁や负绌烘墭鐩�
+ log.info("寮�濮嬪垽鏂槸鍚︿负绌烘墭鍏ュ簱锛屾潯鐮侊細{}", barcode);
+
+ // 妫�鏌ユ槸鍚﹀凡缁勬墭
int waitPakInCount = waitPakinService.selectCount(new EntityWrapper<WaitPakin>().eq("zpallet", barcode));
if (waitPakInCount != 0) {
+ log.warn("鏉$爜缁勬墭妗e凡瀛樺湪锛屼笉鏄┖鎵樼洏锛歿}", barcode);
throw new CoolException("鏉$爜缁勬墭妗e凡瀛樺湪锛�" + barcode);
}
- // 鏈変换鍔�
+
+ // 妫�鏌ユ槸鍚︽湁浠诲姟
int wrkMastCount = wrkMastService.selectCount(new EntityWrapper<WrkMast>().eq("barcode", barcode));
if (wrkMastCount != 0) {
+ log.warn("鏉$爜浠诲姟妗e凡瀛樺湪锛屼笉鏄┖鎵樼洏锛歿}", barcode);
throw new CoolException("鏉$爜浠诲姟妗e凡瀛樺湪锛�" + barcode);
}
- // 鏈夊簱瀛�
+
+ // 妫�鏌ユ槸鍚︽湁搴撳瓨
int locDetlCount = locDetlService.selectCount(new EntityWrapper<LocDetl>().eq("zpallet", barcode));
if (locDetlCount != 0) {
+ log.warn("鏉$爜搴撳瓨宸插瓨鍦紝涓嶆槸绌烘墭鐩橈細{}", barcode);
throw new CoolException("鏉$爜搴撳瓨宸插瓨鍦細" + barcode);
}
+
+ // 閫氳繃鎵�鏈夋鏌ワ紝纭涓虹┖鎵樼洏锛岃缃负绌烘墭鍏ュ簱
ioType = 10;
+ log.info("纭涓虹┖鎵樼洏锛岃缃负绌烘墭鍏ュ簱锛屾潯鐮侊細{}锛宨oType锛歿}", barcode, ioType);
break;
default:
throw new CoolException("鍏ュ簱绫诲瀷閿欒,type锛�" + type);
@@ -177,15 +208,47 @@
throw new CoolException(barcode+ "锛氭潯鐮佸瓨鍦╝gv鎼繍浠诲姟!");
}
- // 鍒ゆ柇鑳藉叆绔欑偣
+ // 鏍规嵁whs_type閫夋嫨绔欑偣鍜屾満鍣ㄤ汉缁�
+ Long whsType = locCache.getWhsType();
+ List<String> targetStations;
+ String robotGroup;
+
+ if (whsType != null && whsType.equals(agvProperties.getWhsTypeMapping().getInboundArea())) {
+ // whs_type = 1: 鍏ュ簱鍖猴紝浣跨敤涓滀晶绔欑偣鍜孏roup-001
+ targetStations = agvProperties.getEastStations();
+ robotGroup = agvProperties.getRobotGroupEast();
+ log.info("搴撲綅whs_type={}锛屼娇鐢ㄥ叆搴撳尯閰嶇疆锛堜笢渚х珯鐐瑰拰Group-001锛�", whsType);
+ } else if (whsType != null && whsType.equals(agvProperties.getWhsTypeMapping().getCacheArea())) {
+ // whs_type = 2: 缂撳瓨鍖猴紝浣跨敤瑗夸晶绔欑偣鍜孏roup-002
+ targetStations = agvProperties.getWestStations();
+ robotGroup = agvProperties.getRobotGroupWest();
+ log.info("搴撲綅whs_type={}锛屼娇鐢ㄧ紦瀛樺尯閰嶇疆锛堣タ渚х珯鐐瑰拰Group-002锛�", whsType);
+ } else {
+ // whs_type涓虹┖鎴栧叾浠栧�硷紝鏍规嵁type鍒ゆ柇锛堝吋瀹规棫閫昏緫锛�
+ if (type == 1) {
+ targetStations = agvProperties.getEastStations();
+ robotGroup = agvProperties.getRobotGroupEast();
+ } else {
+ targetStations = agvProperties.getWestStations();
+ robotGroup = agvProperties.getRobotGroupWest();
+ }
+ log.warn("搴撲綅whs_type={}鏈厤缃垨涓嶅湪鏄犲皠鑼冨洿鍐咃紝浣跨敤type={}鐨勯粯璁ら�昏緫", whsType, type);
+ }
+
+ // 灏嗙珯鐐瑰瓧绗︿覆鍒楄〃杞崲涓烘暣鏁板垪琛�
+ List<Integer> siteIntList = targetStations.stream()
+ .map(Integer::parseInt)
+ .collect(Collectors.toList());
+
+ // 鍒ゆ柇鑳藉叆绔欑偣锛坕n_enable="Y"琛ㄧず鑳藉叆锛�
List<Integer> sites = basDevpMapper.selectList(
new EntityWrapper<BasDevp>()
- .eq("canining", "Y")
- .in("dev_no", type == 1 ? Arrays.asList(1003, 1005, 1007) : Arrays.asList(1044, 1046, 1048))
+ .eq("in_enable", "Y") // in_enable鏄兘鍏�
+ .in("dev_no", siteIntList)
).stream().map(BasDevp::getDevNo).collect(Collectors.toList());
if (sites.isEmpty()) {
- throw new CoolException("娌℃湁鑳藉叆绔欑偣,type锛�" + type);
+ throw new CoolException("娌℃湁鑳藉叆绔欑偣,whs_type锛�" + whsType + ",type锛�" + type);
}
// 鑾峰彇娌℃湁鍑哄簱浠诲姟鐨勭珯鐐�
@@ -194,17 +257,68 @@
throw new CoolException("璇风瓑寰呭嚭搴撳畬鎴�,type:" + type);
}
- // 瀵绘壘鍏ュ簱浠诲姟鏈�灏戠殑绔欑偣
- List<BasDevp> devList = basDevpMapper.selectList(new EntityWrapper<BasDevp>().in("dev_no", canInSites));
- // 鍏ュ簱浠诲姟鏁版帓搴�
- devList.sort(Comparator.comparing(BasDevp::getInQty));
+ // 瀵绘壘鍏ュ簱浠诲姟鏈�灏戠殑绔欑偣锛堜笖蹇呴』in_enable="Y"鑳藉叆 鍜� canining="Y"鍙叆锛�
+ // 娉ㄦ剰锛氫笉鍦ㄦ澶勬鏌ユ湭瀹屾垚鐨凙GV浠诲姟锛屽厑璁窹DA鎸佺画鐢宠涓嬪崟
+ // 鏈畬鎴愪换鍔$殑妫�鏌ュ皢鍦ㄥ彂閫丄GV璇锋眰鏃惰繘琛岋紙AgvHandler.callAgv锛�
+ List<BasDevp> devList = basDevpMapper.selectList(new EntityWrapper<BasDevp>()
+ .in("dev_no", canInSites)
+ .eq("in_enable", "Y") // in_enable鏄兘鍏�
+ .eq("canining", "Y") // canining鏄彲鍏�
+ );
+
+ // 閫夋嫨绔欑偣锛堝鏋滃彲鍏ョ珯鐐逛负绌猴紝鍒欎笉鍦ㄥ垱寤轰换鍔℃椂鍒嗛厤绔欑偣锛岀敱瀹氭椂浠诲姟鍒嗛厤锛�
+ Integer endSite = null;
+ if (!devList.isEmpty()) {
+ // 鍏ュ簱浠诲姟鏁版帓搴�
+ devList.sort(Comparator.comparing(BasDevp::getInQty));
- // 鍙栧叆搴撲换鍔℃渶灏戠珯鐐�
- BasDevp basDevp = devList.get(0);
- int endSite = basDevp.getDevNo();
+ // 閫夋嫨绔欑偣
+ BasDevp basDevp;
+
+ // 鑾峰彇鏈�灏戜换鍔℃暟
+ int minInQty = devList.get(0).getInQty();
+
+ // 绛涢�夊嚭浠诲姟鏁版渶灏戠殑绔欑偣鍒楄〃
+ List<BasDevp> minTaskSites = devList.stream()
+ .filter(dev -> dev.getInQty() == minInQty)
+ .collect(Collectors.toList());
+
+ // 鏍规嵁閰嶇疆閫夋嫨鍒嗛厤绛栫暐
+ String strategy = agvProperties.getSiteAllocation().getStrategy();
+ boolean enableRoundRobin = agvProperties.getSiteAllocation().isEnableRoundRobin();
+
+ if (minTaskSites.size() > 1 && enableRoundRobin && "round-robin".equals(strategy)) {
+ // 杞鍒嗛厤锛氬綋澶氫釜绔欑偣浠诲姟鏁扮浉鍚屾椂锛屼娇鐢ㄨ疆璇�
+ String groupKey = (whsType != null && whsType.equals(agvProperties.getWhsTypeMapping().getInboundArea()))
+ ? "east" : "west";
+ AtomicInteger counter = siteRoundRobinCounters.computeIfAbsent(groupKey, k -> new AtomicInteger(0));
+ int index = counter.getAndIncrement() % minTaskSites.size();
+ basDevp = minTaskSites.get(index);
+ log.info("浣跨敤杞鍒嗛厤绛栫暐锛岀珯鐐圭粍锛歿}锛岃疆璇㈢储寮曪細{}锛岄�変腑绔欑偣锛歿}", groupKey, index, basDevp.getDevNo());
+ } else if (minTaskSites.size() > 1 && enableRoundRobin && "random".equals(strategy)) {
+ // 闅忔満鍒嗛厤
+ Random random = new Random();
+ int index = random.nextInt(minTaskSites.size());
+ basDevp = minTaskSites.get(index);
+ log.info("浣跨敤闅忔満鍒嗛厤绛栫暐锛岄�変腑绔欑偣锛歿}", basDevp.getDevNo());
+ } else {
+ // 榛樿锛氶�夋嫨绗竴涓紙浠诲姟鏈�灏戠殑锛�
+ basDevp = devList.get(0);
+ if (minTaskSites.size() > 1) {
+ log.info("澶氫釜绔欑偣浠诲姟鏁扮浉鍚岋紙{}锛夛紝浣嗘湭鍚敤杞锛岄�夋嫨绗竴涓珯鐐癸細{}", minInQty, basDevp.getDevNo());
+ }
+ }
+
+ endSite = basDevp.getDevNo();
- // 鍏ュ簱鏆傚瓨+1
- basDevpMapper.incrementInQty(endSite);
+ // 鍏ュ簱鏆傚瓨+1
+ basDevpMapper.incrementInQty(endSite);
+ } else {
+ // 娌℃湁鍙叆绔欑偣锛岃褰曟棩蹇椾絾涓嶉樆姝笅鍗曪紝绔欑偣鍒嗛厤灏嗗湪瀹氭椂浠诲姟涓鐞�
+ String groupName = (whsType != null && whsType.equals(agvProperties.getWhsTypeMapping().getInboundArea()))
+ ? "涓滀晶" : "瑗夸晶";
+ log.warn("{}鍙敤绔欑偣锛坽}锛変腑娌℃湁鍙叆绔欑偣锛坕n_enable='Y'涓攃anining='Y'锛夛紝鏆備笉鍒嗛厤绔欑偣锛屽皢鍦ㄥ畾鏃朵换鍔′腑鍒嗛厤", groupName, canInSites);
+ }
// 鑾峰彇宸ヤ綔鍙�
@@ -218,11 +332,13 @@
.setIoType(ioType) // 鍏ュ嚭搴撶姸鎬侊細 1.鍏ュ簱
.setTaskType("agv")
.setIoPri(10D)
- .setStaNo(String.valueOf(endSite))
+ .setStaNo(endSite != null ? String.valueOf(endSite) : null) // 濡傛灉鍒嗛厤浜嗙珯鐐瑰垯璁剧疆锛屽惁鍒欎负null锛岀敱瀹氭椂浠诲姟鍒嗛厤
+ .setSourceStaNo(sourceSite) // 璁剧疆婧愮珯鐐�
+ .setInvWh(robotGroup) // 鏍规嵁whs_type璁剧疆鏈哄櫒浜虹粍
.setFullPlt(ioType != 10 ? "N" : "Y")// 婊℃澘锛歒
.setPicking("N") // 鎷f枡
.setExitMk("N")// 閫�鍑�
- .setSourceLocNo(sourceSite)
+ .setSourceLocNo(locCache.getLocNo()) // 璁剧疆婧愬簱浣嶇紪鍙凤紝鐢ㄤ簬AGV fromBin
.setEmptyMk(ioType == 10 ? "Y" : "N")// 绌烘澘
.setBarcode(barcode)// 鎵樼洏鐮�
.setLinkMis("N")
--
Gitblit v1.9.1