From b71ca6faa130dbd9baed68d1402365ccc63e79c2 Mon Sep 17 00:00:00 2001
From: 1 <1@123>
Date: 星期三, 15 四月 2026 16:38:26 +0800
Subject: [PATCH] lsh#

---
 rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/LocManageUtil.java |  131 ++++++++++++++++++++++++++++++++++---------
 1 files changed, 103 insertions(+), 28 deletions(-)

diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/LocManageUtil.java b/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/LocManageUtil.java
index d999743..9bcebaa 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/LocManageUtil.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/LocManageUtil.java
@@ -5,6 +5,7 @@
 import com.vincent.rsf.framework.common.SpringUtils;
 import com.vincent.rsf.framework.exception.CoolException;
 import com.vincent.rsf.server.api.utils.LocUtils;
+import com.vincent.rsf.server.common.redis.RedisKeys;
 import com.vincent.rsf.server.manager.controller.dto.ExistDto;
 import com.vincent.rsf.server.manager.controller.dto.OrderOutItemDto;
 import com.vincent.rsf.server.manager.controller.params.WaveToLocParams;
@@ -12,14 +13,20 @@
 import com.vincent.rsf.server.manager.enums.TaskType;
 import com.vincent.rsf.server.manager.enums.WaveRuleType;
 import com.vincent.rsf.server.manager.service.*;
+import com.vincent.rsf.server.manager.service.impl.WmsRedisLuaService;
 import com.vincent.rsf.server.manager.enums.LocStsType;
 import org.apache.commons.lang3.StringUtils;
 
 import java.math.BigDecimal;
+import java.time.Duration;
 import java.util.*;
 import java.util.stream.Collectors;
 
 public class LocManageUtil {
+
+    private static final int TARGET_LOC_QUERY_LIMIT = 10;
+    private static final String TARGET_LOC_LOCK_KEY_PREFIX = "wms:loc:claim:";
+    private static final Duration TARGET_LOC_LOCK_TTL = Duration.ofMinutes(1);
 
     /**
      * @param
@@ -39,7 +46,7 @@
         Long locType = containerType;
         //TODO 搴撲綅绛栫暐鍚庣画鎺掓湡
         LocService locService = SpringUtils.getBean(LocService.class);
-        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>()
+        List<Loc> locList = locService.list(new LambdaQueryWrapper<Loc>()
                 .eq(!Objects.isNull(locType), Loc::getType, locType)
                 .eq(Loc::getAreaId, areaId)
                 .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
@@ -47,45 +54,44 @@
                 .orderByAsc(Loc::getLev)
                 .orderByAsc(Loc::getCol)
                 .orderByAsc(Loc::getRow)
-                .last("LIMIT 1")
+                .last("LIMIT " + TARGET_LOC_QUERY_LIMIT)
         );
 
-        return !Objects.isNull(loc) ? loc.getCode() : null;
+        return claimTargetLoc(locList);
     }
 
     public static String getTargetLoc(Long areaId, Long containerType) {
         Long locType = containerType;
-//        if (!Objects.isNull(containerType)) {
-//            LocTypeService locService = SpringUtils.getBean(LocTypeService.class);
-//            if (containerType.equals(ContainerType.CONTAINER_TYPE_NORMAL.val)) {
-//                LocType low = locService.getOne(new LambdaQueryWrapper<LocType>()
-//                        .eq(LocType::getCode, "L"));
-//                if (Objects.isNull(low)) {
-//                    throw new CoolException("搴綅椤炲瀷涓嶅瓨鍦紒锛�");
-//                }
-//                locType = low.getId();
-//            } else {
-//                LocType low = locService.getOne(new LambdaQueryWrapper<LocType>()
-//                        .eq(LocType::getCode, "H"));
-//                if (Objects.isNull(low)) {
-//                    throw new CoolException("搴綅椤炲瀷涓嶅瓨鍦紒锛�");
-//                }
-//                locType = low.getId();
-//            }
-//        }
         //TODO 搴撲綅绛栫暐鍚庣画鎺掓湡
         LocService locService = SpringUtils.getBean(LocService.class);
-        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>()
+        List<Loc> locList = locService.list(new LambdaQueryWrapper<Loc>()
                 .eq(!Objects.isNull(locType), Loc::getType, locType)
                 .eq(Loc::getAreaId, areaId)
                 .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
                 .orderByAsc(Loc::getLev)
                 .orderByAsc(Loc::getCol)
                 .orderByAsc(Loc::getRow)
-                .last("LIMIT 1")
+                .last("LIMIT " + TARGET_LOC_QUERY_LIMIT)
         );
 
-        return !Objects.isNull(loc) ? loc.getCode() : null;
+        return claimTargetLoc(locList);
+    }
+
+    private static String claimTargetLoc(List<Loc> locList) {
+        if (Cools.isEmpty(locList)) {
+            return null;
+        }
+        WmsRedisLuaService wmsRedisLuaService = SpringUtils.getBean(WmsRedisLuaService.class);
+        for (Loc loc : locList) {
+            if (Objects.isNull(loc) || Cools.isEmpty(loc.getCode())) {
+                continue;
+            }
+            boolean claimed = wmsRedisLuaService.claimLocation(RedisKeys.locationOccupy(loc.getCode()), loc.getCode(), TARGET_LOC_LOCK_TTL);
+            if (claimed) {
+                return loc.getCode();
+            }
+        }
+        return null;
     }
 
     /**
@@ -99,6 +105,39 @@
     public static List<LocItem> getEfficiencyFirstItemList(String matnrCode, String splrBatch, Double anfme) {
         LambdaQueryWrapper<LocItem> locItemQueryWrapper = new LambdaQueryWrapper<>();
         locItemQueryWrapper.eq(LocItem::getMatnrCode, matnrCode);
+        locItemQueryWrapper.eq(StringUtils.isNotBlank(splrBatch), LocItem::getBatch, splrBatch);
+        String applySql = String.format(
+                "EXISTS (SELECT 1 FROM man_loc ml " +
+                        "WHERE ml.use_status = '%s'" +
+                        "AND ml.id = man_loc_item.loc_id " +
+                        ")",
+                LocStsType.LOC_STS_TYPE_F.type
+        );
+        locItemQueryWrapper.apply(applySql);
+        LocItemService locItemService = SpringUtils.getBean(LocItemService.class);
+        List<LocItem> locItems = locItemService.list(locItemQueryWrapper);
+        locItems.sort(Comparator.comparing((LocItem item) -> !LocUtils.isShallowLoc(item.getLocCode())));
+        List<LocItem> locsSet = locItems.stream().filter(locItem -> locItem.getAnfme().compareTo(anfme) == 0.0).collect(Collectors.toList());
+        if (!locsSet.isEmpty()) {
+            return locsSet;
+        }
+        return locItems;
+    }
+
+    /**
+     * 鍑哄簱绛栫暐锛�--銆堟晥鐜囦紭鍖栥��
+     *
+     * @param matnrCode
+     * @param splrBatch
+     * @param anfme
+     * @return
+     */
+    public static List<LocItem> getEfficiencyFirstItemList(String matnrCode, String splrBatch, Double anfme,String locCode) {
+        LambdaQueryWrapper<LocItem> locItemQueryWrapper = new LambdaQueryWrapper<>();
+        locItemQueryWrapper.eq(LocItem::getMatnrCode, matnrCode);
+        if (!Cools.isEmpty(locCode)){
+            locItemQueryWrapper.eq(LocItem::getLocCode, locCode);
+        }
         locItemQueryWrapper.eq(StringUtils.isNotBlank(splrBatch), LocItem::getBatch, splrBatch);
         String applySql = String.format(
                 "EXISTS (SELECT 1 FROM man_loc ml " +
@@ -150,6 +189,41 @@
         return locItems;
     }
 
+
+    /**
+     * 鍑哄簱绛栫暐锛�--<鍏堣繘鍏堝嚭>
+     *
+     * @param matnrCode
+     * @param splrBatch
+     * @param anfme
+     * @return
+     */
+    public static List<LocItem> getFirstInFirstOutItemList(String matnrCode, String splrBatch, Double anfme,String locCode) {
+        LambdaQueryWrapper<LocItem> locItemQueryWrapper = new LambdaQueryWrapper<>();
+        locItemQueryWrapper.eq(LocItem::getMatnrCode, matnrCode);
+        if (!Cools.isEmpty(locCode)){
+            locItemQueryWrapper.eq(LocItem::getLocCode, locCode);
+        }
+        locItemQueryWrapper.eq(StringUtils.isNotEmpty(splrBatch), LocItem::getBatch, splrBatch);
+        //濡傛灉鎵规涓嶄负绌猴紝鎸夋壒娆″厛鍚庡嚭搴�
+        if (StringUtils.isNotBlank(splrBatch)) {
+            locItemQueryWrapper.orderByAsc(LocItem::getBatch);
+        } else {
+            locItemQueryWrapper.orderByAsc(LocItem::getCreateTime);
+        }
+        String applySql = String.format(
+                "EXISTS (SELECT 1 FROM man_loc ml " +
+                        "WHERE ml.use_status = '%s'" +
+                        "AND ml.id = man_loc_item.loc_id " +
+                        ")",
+                LocStsType.LOC_STS_TYPE_F.type
+        );
+        locItemQueryWrapper.apply(applySql);
+        LocItemService locItemService = SpringUtils.getBean(LocItemService.class);
+        List<LocItem> locItems = locItemService.list(locItemQueryWrapper);
+        return locItems;
+    }
+
     /**
      * 鑾峰彇鍑哄簱搴撲綅淇℃伅
      *
@@ -174,14 +248,14 @@
             }
             List<LocItem> locItems;
             if (Objects.isNull(waveRule)) {
-                locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme());
+                locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme(),locCode);
             } else {
                 if (WaveRuleType.Efficiency_First.type.equals(waveRule.getType())) {
-                    locItems = LocManageUtil.getEfficiencyFirstItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme());
+                    locItems = LocManageUtil.getEfficiencyFirstItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme(),locCode);
                 } else if (WaveRuleType.First_In_First_Out.type.equals(waveRule.getType())) {
-                    locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme());
+                    locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme(),locCode);
                 } else {
-                    locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme());
+                    locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme(),locCode);
                 }
             }
             for (LocItem locItem : locItems) {
@@ -227,6 +301,7 @@
                                 .apply("cross_zone_area != '[]'")  // 涓嶆槸绌烘暟缁�
                                 .apply("container_type != '[]'")
                                 .apply("station_alias != '[]'")
+                                .apply("station_alias_sta_no != '[]'")
                                 .apply("JSON_CONTAINS(cross_zone_area, {0}) = 1", loc.getAreaId().toString())//鍙墽琛屽簱鍖哄尯鍖哄煙id
                                 .apply("JSON_CONTAINS(container_type, {0}) = 1", containerType.getContainerType().toString())//瀹瑰櫒绫诲瀷
                                 .eq(BasStationArea::getDeleted, 0));

--
Gitblit v1.9.1