Quellcode durchsuchen

库位建模和库位推荐mdc日志跟踪

ChenYang vor 1 Jahr
Ursprung
Commit
86203f22da
16 geänderte Dateien mit 602 neuen und 82 gelöschten Zeilen
  1. 9 15
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/wms/box/WmsBoxInfoController.java
  2. 2 3
      ruoyi-admin/src/main/java/com/ruoyi/xuankuang/controller/WcsToWmsApiController.java
  3. 19 44
      ruoyi-admin/src/test/java/com/ruoyi/admin/test/base/ProcessLocationTest.java
  4. 117 5
      ruoyi-admin/src/test/java/com/ruoyi/admin/test/base/WarehouseTest.java
  5. 29 0
      ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
  6. 3 0
      ruoyi-common/src/main/java/com/ruoyi/common/constant/SceneConstants.java
  7. 4 0
      ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java
  8. 37 0
      ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/mdc/GlobalLogInterceptor.java
  9. 11 0
      ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/mdc/MdcIDGenerator.java
  10. 7 0
      warewms-ams/src/main/java/com/ruoyi/ams/inv/service/IInvLotLocIdService.java
  11. 6 0
      warewms-ams/src/main/java/com/ruoyi/ams/inv/service/impl/InvLotLocIdServiceImpl.java
  12. 143 0
      warewms-ams/src/main/java/com/ruoyi/ams/runner/LocationInitRunner.java
  13. 180 15
      warewms-ams/src/main/java/com/ruoyi/ams/xuankuang/service/WmsDocOrderSubService.java
  14. 3 0
      warewms-base/src/main/java/com/ruoyi/base/constant/Constant.java
  15. 14 0
      warewms-base/src/main/java/com/ruoyi/base/service/IBaseLocationInfoService.java
  16. 18 0
      warewms-base/src/main/java/com/ruoyi/base/service/impl/BaseLocationInfoServiceImpl.java

+ 9 - 15
ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/wms/box/WmsBoxInfoController.java

@@ -1,25 +1,19 @@
 package com.ruoyi.web.controller.warewms.wms.box;
 
-import java.util.List;
-import javax.servlet.http.HttpServletResponse;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.ams.box.domain.WmsBoxInfo;
+import com.ruoyi.ams.box.service.IWmsBoxInfoService;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.enums.BusinessType;
-import com.ruoyi.ams.box.domain.WmsBoxInfo;
-import com.ruoyi.ams.box.service.IWmsBoxInfoService;
 import com.ruoyi.common.utils.poi.ExcelUtil;
-import com.ruoyi.common.core.page.TableDataInfo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
 
 /**
  * 容器管理Controller

+ 2 - 3
ruoyi-admin/src/main/java/com/ruoyi/xuankuang/controller/WcsToWmsApiController.java

@@ -5,7 +5,6 @@ import com.ruoyi.ams.xuankuang.domain.form.*;
 import com.ruoyi.ams.xuankuang.service.WcsToWmsApiService;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.utils.DateUtils;
-import com.ruoyi.common.utils.StringUtils;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -107,8 +106,8 @@ public class WcsToWmsApiController {
     @PostMapping("/errorStatusResponse")
     public AjaxResult errorStatusResponse(@RequestBody ErrorStatusForm errorStatusForm) {
         log.info("WcsToWmsApiController - errorStatusResponse request errorStatusForm is :{}, time is :{}", JSONObject.toJSONString(errorStatusForm), DateUtils.getTime());
-        log.info("WcsToWmsApiController - errorStatusResponse response ajaxResult is :{}, time is :{}", StringUtils.EMPTY, DateUtils.getTime());
-        return AjaxResult.success(StringUtils.EMPTY);
+
+        return AjaxResult.success();
     }
 
     /**

+ 19 - 44
ruoyi-admin/src/test/java/com/ruoyi/admin/test/base/ProcessLocationTest.java

@@ -10,6 +10,7 @@ import com.ruoyi.RuoYiApplication;
 import com.ruoyi.ams.inv.domain.InvLotLocId;
 import com.ruoyi.ams.inv.service.IInvLotAttService;
 import com.ruoyi.ams.inv.service.IInvLotLocIdService;
+import com.ruoyi.ams.xuankuang.service.WmsDocOrderSubService;
 import com.ruoyi.base.domain.BaseLocationInfo;
 import com.ruoyi.base.domain.BaseSku;
 import com.ruoyi.base.service.IBaseLocationInfoService;
@@ -130,9 +131,9 @@ public class ProcessLocationTest {
 
         //查出原先的库存情况,如果当前库存SKU不符合,则生成新的批次记录
         List<InvLotLocId> invLotLocList = invLotLocIdService.getInvLotLocList(baseLocationInfo.getId());
-        if(CollectionUtil.isEmpty(invLotLocList)) return;
         //此时数据是错的都要重新生成库存
-        List<String> skuList = invLotLocList.stream().map(item -> item.getSku()).collect(Collectors.toList());
+        List<String> skuList = CollectionUtil.isNotEmpty(invLotLocList)
+                ? invLotLocList.stream().map(item -> item.getSku()).collect(Collectors.toList()) : Lists.newArrayList();
         if(CollectionUtil.isEmpty(skuList) || skuList.size() > 1 || !StringUtils.equals(skuList.get(0), bindSku)){
             //生成新的批次记录
             String lotnum = invLotAttService.insertInvLotAtt(bindSku, palletNo);
@@ -181,49 +182,15 @@ public class ProcessLocationTest {
 //        System.out.println(handleLocationNo("STAGE01"));
 
 
+        boolean condition = true;
+        Boolean notFail = null;
+        process(condition, notFail);
 
-        LinkedList<String> linkedList = Lists.newLinkedList();
-        ArrayList<String> arrayList = Lists.newArrayList();
-        linkedList.add("10");
-        linkedList.add("20");
-        linkedList.add("30");
-        linkedList.add("40");
-        linkedList.add("50");
-        linkedList.add("60");
-        linkedList.add("70");
-        linkedList.add("80");
-        System.out.println("queue.element():"+linkedList.element()); //读取第一个
-        System.out.println("queue.remove():"+linkedList.remove()); //删掉第一个
-
-        System.out.println("queue:"+linkedList);
-        System.out.println("queue.poll():" + linkedList.poll()); //读取且拿取==出队列
-        System.out.println("queue.poll():" + linkedList.poll()); //读取且拿取==出队列
-        System.out.println("queue.poll():" + linkedList.poll()); //读取且拿取==出队列
-        System.out.println("queue.poll():" + linkedList.poll()); //读取且拿取==出队列
-        System.out.println("queue.poll():" + linkedList.poll()); //读取且拿取==出队列
-        System.out.println("queue.poll():" + linkedList.poll()); //读取且拿取==出队列
-        System.out.println("queue.poll():" + linkedList.poll()); //读取且拿取==出队列
-        System.out.println("queue.poll():" + linkedList.poll()); //读取且拿取==出队列
-        System.out.println("queue.poll():" + linkedList.poll()); //读取且拿取==出队列
-        System.out.println("queue:"+linkedList);
-
-        linkedList.clear();
-
-        linkedList.push("10");
-        linkedList.push("20");
-        linkedList.push("30");
-        linkedList.push("40");
-        linkedList.push("50");
-        linkedList.push("60");
-        linkedList.push("70");
-        linkedList.push("80");
-
-        System.out.println("stack.element():"+linkedList.element()); //读取第一个
-        System.out.println("stack.remove():"+linkedList.remove()); //删掉第一个
-
-        System.out.println("stack:"+linkedList);
-        System.out.println("stack.peek():"+linkedList.peek()); //拿取栈顶==出栈
-        System.out.println("stack:"+linkedList);
+    }
+
+    private static void process(boolean condition, Boolean notFail) {
+        boolean fail = false;
+        System.out.println(condition ? notFail : fail);
     }
 
 
@@ -249,5 +216,13 @@ public class ProcessLocationTest {
         invLotLocIdService.updateInvLotLocId(invLotLocId);
     }
 
+    @Autowired
+    private WmsDocOrderSubService wmsDocOrderSubService;
+
+    @Test
+    public void initOrderDetails(){
+        wmsDocOrderSubService.initOrderDetails("SO202309070001");
+    }
+
 
 }

+ 117 - 5
ruoyi-admin/src/test/java/com/ruoyi/admin/test/base/WarehouseTest.java

@@ -1,6 +1,11 @@
 package com.ruoyi.admin.test.base;
 
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Lists;
 import com.ruoyi.RuoYiApplication;
 import com.ruoyi.ams.agv.ndc.domain.AmsHexdefineDetail;
 import com.ruoyi.ams.agv.ndc.domain.AmsTask;
@@ -21,6 +26,7 @@ import com.ruoyi.ams.config.service.IFlowConfigHeaderService;
 import com.ruoyi.ams.config.service.LocationAllocationStrategy;
 import com.ruoyi.ams.inv.domain.InvLotLocId;
 import com.ruoyi.ams.inv.mapper.InvLotLocIdMapper;
+import com.ruoyi.ams.inv.service.IInvLotLocIdService;
 import com.ruoyi.ams.locationView.domain.form.LocationViewForm;
 import com.ruoyi.ams.locationView.domain.vo.LocationViewVO;
 import com.ruoyi.ams.locationView.service.LocationViewService;
@@ -42,17 +48,25 @@ import com.ruoyi.base.service.IBaseIdsequenceService;
 import com.ruoyi.base.service.IBaseLocationInfoService;
 import com.ruoyi.base.service.IBaseWarehouseService;
 import com.ruoyi.base.utils.IdSequenceUtils;
+import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.constant.SceneConstants;
+import com.ruoyi.common.core.domain.BaseEntity;
+import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.system.service.ISysConfigService;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.util.Assert;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Created by IntelliJ IDEA.
@@ -334,17 +348,17 @@ public class WarehouseTest {
     private RedisTemplate redisTemplate;
 
 
-    @Test
+    /*@Test
     public void stackTest(){
-        /*redisTemplate.opsForList().leftPush("1", "Pallet01");
+        *//*redisTemplate.opsForList().leftPush("1", "Pallet01");
         redisTemplate.opsForList().leftPush("1", "Pallet02");
         redisTemplate.opsForList().leftPush("1", "Pallet03");
         redisTemplate.opsForList().leftPush("1", "Pallet04");
         redisTemplate.opsForList().leftPush("1", "Pallet05");
-        *//*redisTemplate.opsForList().leftPop("1");
+        *//**//*redisTemplate.opsForList().leftPop("1");
         redisTemplate.opsForList().leftPop("1");
         redisTemplate.opsForList().leftPop("1");
-        redisTemplate.opsForList().leftPop("1");*//*
+        redisTemplate.opsForList().leftPop("1");*//**//*
         System.out.println(redisTemplate.opsForList().leftPop("1"));
         System.out.println(redisTemplate.opsForList().leftPop("1"));
         System.out.println(redisTemplate.opsForList().leftPop("1"));
@@ -358,7 +372,7 @@ public class WarehouseTest {
         System.out.println(redisTemplate.opsForList().leftPop("1"));
         System.out.println(redisTemplate.opsForList().leftPop("1"));
         System.out.println(redisTemplate.opsForList().leftPop("1"));
-        */
+        *//*
 
         redisTemplate.boundListOps("2").leftPush("Pallet01");
         redisTemplate.boundListOps("2").leftPush("Pallet02");
@@ -374,13 +388,111 @@ public class WarehouseTest {
 
 
 
+    }*/
+
+
+    @Autowired
+    private IInvLotLocIdService invLotLocIdService;
+
+    @Autowired
+    private RedisCache redisCache;
+
+
+    @Autowired
+    private ISysConfigService sysConfigService;
+
+    @Test
+    public void selectInvLotLocIdList(){
+        String floorAppendRowKey = "2_8";
+        Map<String, List<Long>> partitionRowNoListMapper = redisCache.getCacheObject(floorAppendRowKey);
+        Map<String, Object> warehouseAttrMapper = getWarehouseAttrConfig();
+        List<Integer> wayRowNoList = (List<Integer>) warehouseAttrMapper.get(Constants.WAY_ROW_NO_LIST);
+        //获取到这个库位命中的子列在两边还是中间
+        String partitionRowKey = Constants.MIDDLE;
+        List<Long> partitionLocationIdList = partitionRowNoListMapper.get(partitionRowKey);
+        int locationIndex = partitionLocationIdList.indexOf(101212L);
+
+    }
+
+
+    /**
+     * 获取库位的配置
+     * @return
+     */
+    private Map<String, Object> getWarehouseAttrConfig() {
+        String warehouseAttrInfo = sysConfigService.selectConfigByKey(SceneConstants.WAREHOUSE_ATTRIBUTE_SCENE_CONFIG);
+        Assert.isTrue(com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(warehouseAttrInfo), "baseLocationInfoList is empty");
+        return JSONObject.parseObject(warehouseAttrInfo);
     }
 
 
+
     @Autowired
     private WmsDocAsnSubService wmsDocAsnSubService;
 
 
+    public static void main(String[] args) {
+        List<String>  idList = Lists.newArrayList("1","2","3","4");
+        List<String>  anotherIdList = idList;
+        idList.add("5");
+        System.out.println(JSONUtil.toJsonStr(idList)); //idList: ["1","2","3","4","5"]
+        System.out.println(JSONUtil.toJsonStr(anotherIdList));  // anotherIdList: ["1","2","3","4","5"]
+
+        StringBuffer stringBuffer = new StringBuffer("2222");
+        stringBuffer.append("1111");
+        StringBuffer anotherStringBuffer = stringBuffer;
+        System.out.println(stringBuffer);   //stringBuffer: 22221111
+        System.out.println(anotherStringBuffer);   //anotherStringBuffer:22221111
+
+
+        BaseEntity baseEntity = new BaseEntity();
+        baseEntity.setRemark("111");
+        BaseEntity anotherBaseEntity = baseEntity;
+        anotherBaseEntity.setRemark("2222");
+        System.out.println(JSONUtil.toJsonStr(baseEntity)); // baseEntity.getRemark(): 2222
+        System.out.println(JSONUtil.toJsonStr(anotherBaseEntity)); //anotherBaseEntity.getRemark():2222
+
+        int a = 5;
+        process(a);
+        System.out.println(a); //a: 5
+
+
+        Integer b = 5;
+        process(b);
+        System.out.println(b); //b: 5
+
+
+        String str = "lilei";
+        process(str);
+        System.out.println(str); //str: lilei
+
+        process(idList);
+        System.out.println(JSONUtil.toJsonStr(idList));// idList: ["1","2","3","4","5","6"]
+
+        process(baseEntity);
+        System.out.println(JSONUtil.toJsonStr(baseEntity)); //baseEntity.getRemark(): 333333
+    }
+
+
+    private static void process(BaseEntity baseEntity) {
+        baseEntity.setRemark("333333");
+    }
+
+    private static void process(List<String> idList) {
+        idList.add("6");
+    }
+
+    private static void process(String str) {
+        str = new String("hanmeimei");
+    }
+
+    private static void process(int a) {
+        a++;
+    }
+
+    private static void process(Integer b) {
+        b++;
+    }
 
 
 }

+ 29 - 0
ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java

@@ -1,7 +1,11 @@
 package com.ruoyi.common.constant;
 
+
+import com.google.common.collect.Lists;
 import io.jsonwebtoken.Claims;
 
+import java.util.List;
+
 /**
  * 通用常量信息
  * 
@@ -229,4 +233,29 @@ public class Constants
      * 空托盘库位排序的子场景
      */
     public static final String EMPTY_PALLET_INV_SORT = "emptyPalletInvSort";
+
+
+    public static final String TRACE_ID = "mdcId";
+
+    public static final String ROW = "row";
+    public static final String COLUMN = "column";
+    public static final String WAY_ROW_NO_LIST = "wayRowNoList";
+
+    public static final String FIRST = "first";
+
+    public static final String MIDDLE = "middle";
+
+    public static final String LAST = "last";
+
+    public static final int START_VALUE = 0;
+
+    private static final Integer FIRST_FLOOR = 1;
+
+    private static final Integer SECOND_FLOOR = 2;
+
+    private static final Integer THIRD_FLOOR = 3;
+
+    public static final Integer DEFAULT_WAREHOUSE_ID = 1;
+
+    public static final List<Integer> FLOOR_LIST = Lists.newArrayList(FIRST_FLOOR, SECOND_FLOOR, THIRD_FLOOR);
 }

+ 3 - 0
ruoyi-common/src/main/java/com/ruoyi/common/constant/SceneConstants.java

@@ -6,4 +6,7 @@ public interface SceneConstants {
      * 桶装物料的业务场景配置
      */
     String STORAGE_BUCKET_SCENE = "storage.bucket.scene.config";
+
+
+    String WAREHOUSE_ATTRIBUTE_SCENE_CONFIG = "warehouse.attribute.scene.config";
 }

+ 4 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java

@@ -1,5 +1,6 @@
 package com.ruoyi.framework.config;
 
+import com.ruoyi.framework.interceptor.mdc.GlobalLogInterceptor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -23,6 +24,8 @@ public class ResourcesConfig implements WebMvcConfigurer
 {
     @Autowired
     private RepeatSubmitInterceptor repeatSubmitInterceptor;
+    @Autowired
+    private GlobalLogInterceptor globalLogInterceptor;
 
     @Override
     public void addResourceHandlers(ResourceHandlerRegistry registry)
@@ -44,6 +47,7 @@ public class ResourcesConfig implements WebMvcConfigurer
     @Override
     public void addInterceptors(InterceptorRegistry registry)
     {
+        registry.addInterceptor(globalLogInterceptor).addPathPatterns("/**");
         registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
     }
 

+ 37 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/mdc/GlobalLogInterceptor.java

@@ -0,0 +1,37 @@
+package com.ruoyi.framework.interceptor.mdc;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.utils.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.lang.invoke.MethodHandle;
+
+@Component
+@Slf4j
+public class GlobalLogInterceptor implements HandlerInterceptor {
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+
+        String traceId = request.getHeader(Constants.TRACE_ID);
+        traceId = ObjectUtil.isNotNull(traceId) ? traceId : MdcIDGenerator.generateId();
+        MDC.put(Constants.TRACE_ID, traceId);
+        if(handler instanceof HandlerMethod)
+            log.info("current method is {}, mdcId is {}", handler, MDC.get(Constants.TRACE_ID));
+
+        return StringUtils.isNotBlank(MDC.get(Constants.TRACE_ID));
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
+        MDC.remove(Constants.TRACE_ID);
+    }
+}

+ 11 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/mdc/MdcIDGenerator.java

@@ -0,0 +1,11 @@
+package com.ruoyi.framework.interceptor.mdc;
+
+import cn.hutool.core.util.NumberUtil;
+
+public class MdcIDGenerator {
+
+
+    public static String generateId() {
+        return NumberUtil.toStr(System.nanoTime(), NumberUtil.toStr(Thread.currentThread().getId()));
+    }
+}

+ 7 - 0
warewms-ams/src/main/java/com/ruoyi/ams/inv/service/IInvLotLocIdService.java

@@ -330,4 +330,11 @@ public interface IInvLotLocIdService {
      * @return
      */
     Boolean operateTraceIdByLocationId(String locationId, String traceId);
+
+    /**
+     * 根据库位ID列表查询库存列表,按照创建时间正序排列
+     * @param locationIdList
+     * @return
+     */
+    List<InvLotLocId> selectInvLotLocIdList(List<String> locationIdList);
 }

+ 6 - 0
warewms-ams/src/main/java/com/ruoyi/ams/inv/service/impl/InvLotLocIdServiceImpl.java

@@ -737,5 +737,11 @@ public class InvLotLocIdServiceImpl implements IInvLotLocIdService {
                 .set(InvLotLocId::getTraceid, traceId).eq(InvLotLocId::getLocationId, locationId)) > 0;
     }
 
+    @Override
+    public List<InvLotLocId> selectInvLotLocIdList(List<String> locationIdList) {
+        return invLotLocIdMapper.selectList(Wrappers.<InvLotLocId>lambdaQuery()
+                .in(InvLotLocId::getLocationId, locationIdList).orderByAsc(InvLotLocId::getCreateTime));
+    }
+
 
 }

+ 143 - 0
warewms-ams/src/main/java/com/ruoyi/ams/runner/LocationInitRunner.java

@@ -0,0 +1,143 @@
+package com.ruoyi.ams.runner;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.comparator.CompareUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.ruoyi.base.domain.BaseLocationInfo;
+import com.ruoyi.base.service.IBaseLocationInfoService;
+import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.constant.SceneConstants;
+import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.system.service.ISysConfigService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Assert;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Component
+@Slf4j
+public class LocationInitRunner implements CommandLineRunner {
+
+    @Autowired
+    private RedisCache redisCache;
+
+    @Autowired
+    private IBaseLocationInfoService iBaseLocationInfoService;
+
+    @Autowired
+    private ISysConfigService sysConfigService;
+
+    @Override
+    public void run(String... args) {
+        //1.获取当前所有的立体库库位列表列表
+        List<BaseLocationInfo> baseLocationInfoList = iBaseLocationInfoService.selectLocationInfoList();
+        Assert.isTrue(CollectionUtil.isNotEmpty(baseLocationInfoList), "baseLocationInfoList is empty");
+
+        //2.获取当前库位的行列属性配置
+        Map<String, Object> warehouseAttrMapper = getWarehouseAttrConfig();
+        int rowNum = (int) warehouseAttrMapper.get(Constants.ROW);//14
+        int columnNum = (int)warehouseAttrMapper.get(Constants.COLUMN); //10
+        List<Integer> wayRowNoList = (List<Integer>) warehouseAttrMapper.get(Constants.WAY_ROW_NO_LIST);
+
+        List<Integer> floorList = Constants.FLOOR_LIST;
+
+        //3.遍历库位,分割列表,用适合的数据结构进行存储
+        for(int currentfloor = 0; currentfloor < floorList.size(); currentfloor++ ){
+            final int currentfloorNum = currentfloor + 1;
+            //层号对应的当列库位号列表的映射
+            Map<String, List<BaseLocationInfo>> locationInfoListByRowNo = baseLocationInfoList.stream().filter(ObjectUtil::isNotNull)
+                    .filter(item -> ObjectUtil.isNotNull(item.getRowIndex())
+                            && StringUtils.equals(String.valueOf(currentfloorNum), item.getShiftNo())
+                            && CompareUtil.compare(Integer.parseInt(item.getRowIndex()), rowNum) <= 0 )
+                    .sorted(Comparator.comparing(item -> Integer.parseInt(item.getRowNo())))
+                    .collect(Collectors.groupingBy(BaseLocationInfo::getRowIndex,
+                            () -> new TreeMap<>((before, after) -> CompareUtil.compare(NumberUtil.parseInt(before), NumberUtil.parseInt(after))), Collectors.toList()));
+            if(CollectionUtil.isEmpty(locationInfoListByRowNo)) continue;
+            //当列库位号列表的映射处理,分层处理 key:列号
+            for(Map.Entry<String, List<BaseLocationInfo>> locationInfoListEntry : locationInfoListByRowNo.entrySet()){
+                List<BaseLocationInfo> locationInfoList = locationInfoListEntry.getValue();
+                BaseLocationInfo firstLocation = CollectionUtil.getFirst(locationInfoList);
+                BaseLocationInfo lastLocation = CollectionUtil.getLast(locationInfoList);
+                if(ObjectUtil.isNull(firstLocation) || ObjectUtil.isNull(lastLocation)) continue;
+
+                Integer firstRowNo = NumberUtil.parseInt(firstLocation.getRowNo());
+                Integer lastRowNo = NumberUtil.parseInt(lastLocation.getRowNo());
+                if(ObjectUtil.isNull(firstRowNo) || firstRowNo <= 0
+                        || ObjectUtil.isNull(lastRowNo) || lastRowNo <= 0) continue;
+                lastRowNo = CompareUtil.compare(lastRowNo, columnNum) > 0 ? columnNum : lastRowNo;
+                //result:[1,2,3,5,6,7,8,10] or [5,6,7,8,10]
+                List<Integer> rowNoList = locationInfoList.stream()
+                        .map(item -> Integer.parseInt(item.getRowNo())).collect(Collectors.toList());
+                //根据过道的列号进行分区
+                Map<String, List<Long>> partitionRowNoListMapper = partitionProcess(rowNoList, wayRowNoList, locationInfoList);
+                String floorAppendRowKey = currentfloorNum + "_" + locationInfoListEntry.getKey();
+                redisCache.setCacheObject(floorAppendRowKey, partitionRowNoListMapper);
+                //TODO  张馨
+                System.out.println(floorAppendRowKey + "==================================" + partitionRowNoListMapper);
+            }
+        }
+
+
+    }
+
+    /**
+     * 把当前的列分区,按照过道切分,获取列号对应的库位
+     * @param rowNoList 当前列对应的行号信息
+     * @param wayRowNoList 过道的行号信息
+     * @param locationInfoList 库位信息
+     * @return
+     */
+    private Map<String, List<Long>> partitionProcess(List<Integer> rowNoList, List<Integer> wayRowNoList, List<BaseLocationInfo> locationInfoList) {
+        Integer first = CollectionUtil.getFirst(wayRowNoList);
+        Integer last = CollectionUtil.getLast(wayRowNoList);
+        Map<String, List<Long>> partitionRowNoListMapper = Maps.newLinkedHashMap();
+
+        List<Integer> firstRowNoList = rowNoList.stream()
+                .filter(item -> CompareUtil.compare(item, first) < 0 ).collect(Collectors.toCollection(Lists::newLinkedList));
+        if(CollectionUtil.isNotEmpty(firstRowNoList)){
+            LinkedList<Long> firstSubRowLocationIdList = locationInfoList.stream()
+                    .filter(item -> firstRowNoList.contains(Integer.parseInt(item.getRowNo())))
+                    .map(item -> item.getId()).collect(Collectors.toCollection(Lists::newLinkedList));
+            partitionRowNoListMapper.put("first", firstSubRowLocationIdList);
+        }
+
+        List<Integer> middleRowNoList = rowNoList.stream()
+                .filter(item -> CompareUtil.compare(item, first) > 0 && CompareUtil.compare(item, last) < 0)
+                .collect(Collectors.toCollection(Lists::newLinkedList));
+        if(CollectionUtil.isNotEmpty(middleRowNoList)){
+            LinkedList<Long> middleSubRowLocationIdList = locationInfoList.stream()
+                    .filter(item -> middleRowNoList.contains(Integer.parseInt(item.getRowNo())))
+                    .map(item -> item.getId()).collect(Collectors.toCollection(Lists::newLinkedList));
+            partitionRowNoListMapper.put("middle", middleSubRowLocationIdList);
+        }
+
+        List<Integer> lastRowNoList = rowNoList.stream().filter(item -> CompareUtil.compare(item, last) > 0)
+                .collect(Collectors.toCollection(Lists::newLinkedList));
+        if(CollectionUtil.isNotEmpty(lastRowNoList)){
+            LinkedList<Long> lastSubRowLocationIdList = locationInfoList.stream()
+                    .filter(item -> lastRowNoList.contains(Integer.parseInt(item.getRowNo())))
+                    .map(item -> item.getId()).collect(Collectors.toCollection(Lists::newLinkedList));
+            partitionRowNoListMapper.put("last", lastSubRowLocationIdList);
+        }
+        return partitionRowNoListMapper;
+    }
+
+    /**
+     * 获取库位的大小
+     * @return
+     */
+    private Map<String, Object> getWarehouseAttrConfig() {
+        String warehouseAttrInfo = sysConfigService.selectConfigByKey(SceneConstants.WAREHOUSE_ATTRIBUTE_SCENE_CONFIG);
+        Assert.isTrue(StringUtils.isNotBlank(warehouseAttrInfo), "baseLocationInfoList is empty");
+        return JSONObject.parseObject(warehouseAttrInfo);
+    }
+}

+ 180 - 15
warewms-ams/src/main/java/com/ruoyi/ams/xuankuang/service/WmsDocOrderSubService.java

@@ -1,11 +1,17 @@
 package com.ruoyi.ams.xuankuang.service;
 
 import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.comparator.CompareUtil;
+import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.google.common.collect.Lists;
 import com.ruoyi.ams.asn.domain.WmsDocAsnDetails;
 import com.ruoyi.ams.asn.service.IWmsDocAsnHeaderService;
 import com.ruoyi.ams.config.domain.dto.LotattDTO;
+import com.ruoyi.ams.inv.domain.InvLotLocId;
 import com.ruoyi.ams.inv.service.IInvLotLocIdService;
 import com.ruoyi.ams.order.domain.WmsDocOrderDetails;
 import com.ruoyi.ams.order.domain.WmsDocOrderHeader;
@@ -15,13 +21,19 @@ import com.ruoyi.ams.order.service.IWmsDocOrderHeaderService;
 import com.ruoyi.ams.xuankuang.domain.form.OutTaskForm;
 import com.ruoyi.ams.xuankuang.domain.vo.WcsResponseVo;
 import com.ruoyi.base.constant.Constant;
+import com.ruoyi.base.domain.BaseLocationInfo;
 import com.ruoyi.base.domain.BaseSku;
 import com.ruoyi.base.domain.vo.BaseLocationLotattDTO;
 import com.ruoyi.base.service.IBaseLocationInfoService;
 import com.ruoyi.base.service.IBaseSkuService;
 import com.ruoyi.base.utils.IdSequenceUtils;
+import com.ruoyi.common.constant.Constants;
+import com.ruoyi.common.constant.SceneConstants;
 import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.system.service.ISysConfigService;
+import com.sun.xml.internal.ws.api.model.CheckedException;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -30,9 +42,8 @@ import org.springframework.util.Assert;
 import org.springframework.web.bind.annotation.PathVariable;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
 
 import static com.ruoyi.ams.xuankuang.service.BaseLocationInfoSubService.OUT_ZONES;
 
@@ -69,39 +80,44 @@ public class WmsDocOrderSubService {
     private WmsToWcsApiService wmsToWcsApiService;
     @Autowired
     private IInvLotLocIdService invLotLocIdService;
+    @Autowired
+    private RedisCache redisCache;
+    @Autowired
+    private ISysConfigService sysConfigService;
+
+
 
 
     @Transactional
     public AjaxResult initOrderDetails(@PathVariable("orderNo") String orderNo) {
-
         //  根据单号,和创建状态为00
         WmsDocOrderDetails wmsDocOrderDetails = new WmsDocOrderDetails();
         wmsDocOrderDetails.setOrderNo(orderNo);
         wmsDocOrderDetails.setLineStatus(Constant.ORDER_STS.STS00.getValue());
         List<WmsDocOrderDetails> list = iWmsDocOrderDetailsService.selectWmsDocOrderDetailsList(wmsDocOrderDetails);
-
+        //IllegalArgumentException NPE RuntimeException;
         // 查询出库单头
         WmsDocOrderHeader wmsDocOrderHeader = iWmsDocOrderHeaderService.selectWmsDocOrderHeaderByOrderNo(orderNo);
 
         // 匹配库存(先进先出)
-        List<BaseLocationLotattDTO> baseLocationLotattVOS = addConfirmAllocationAuto(orderNo);
-
-        //筛选库存
-        List<BaseLocationLotattDTO> baseLocationLotattVOS1 = filterInv(baseLocationLotattVOS, orderNo);
+        List<BaseLocationLotattDTO> baseLocationLotattList = addConfirmAllocationAuto(orderNo);
 
+        //筛选库存 由于选矿项目出库单头只对应一个
+        List<BaseLocationLotattDTO> filteredLocationLotattList = selectInventoriesByLocation(baseLocationLotattList, list.get(0));
         // 匹配库存(撇开先进先出)
 //        baseLocationLotattVOS = addConfirmAllocationAuto(orderNo);
 
         //重新筛选库存
 //        baseLocationLotattVOS1 = filterInv(baseLocationLotattVOS, orderNo);
-
+        //TODO  张馨
+        if(0==0) throw new RuntimeException("test");
 
         boolean con = true;
         //机械手应拆袋数
         int allocateQuantities = 0;
         //出库单对应袋数
         int orderNum = list.get(0).getQtyOrderedEach().intValue();
-        for (BaseLocationLotattDTO baseLocationLotatt : baseLocationLotattVOS1) {
+        for (BaseLocationLotattDTO baseLocationLotatt : filteredLocationLotattList) {
 
 
             BaseSku baseSku = iBaseSkuService.selectBaseSkuByCustomerId(Constant.CUSTOMER_ID, list.get(0).getSku());
@@ -175,9 +191,158 @@ public class WmsDocOrderSubService {
             wmsDocOrderHeader.setOrderStatus(Constant.ORDER_STS.STS10.getValue());
             iWmsDocOrderHeaderService.updateWmsDocOrderHeader(wmsDocOrderHeader);
         }
-        return AjaxResult.success("", baseLocationLotattVOS1);
+        return AjaxResult.success("", filteredLocationLotattList);
     }
 
+    public List<BaseLocationLotattDTO> selectInventoriesByLocation(List<BaseLocationLotattDTO> baseLocationLotattList, WmsDocOrderDetails docOrderDetail) {
+        if( CollectionUtil.isEmpty(baseLocationLotattList) || ObjectUtil.isNull(docOrderDetail)) return Lists.newArrayList();
+
+        List<String> locationIdList = baseLocationLotattList.stream()
+                .filter(ObjectUtil::isNotNull).map(item -> NumberUtil.toStr(item.getId())).collect(Collectors.toList());
+
+        List<InvLotLocId> sourceInvLotLocIdList = invLotLocIdService.selectInvLotLocIdList(locationIdList);
+        BigDecimal quantity = docOrderDetail.getQtyOrdered();
+        //从最老的库存开始,计算库存所在的列是否符合要求
+        List<Long> selectedLocationIdList = Lists.newArrayList();
+        for (InvLotLocId invLotLocId : sourceInvLotLocIdList){
+            BaseLocationInfo locationInfo = baseLocationLotattList.stream()
+                    .filter(item -> StringUtils.equals(NumberUtil.toStr(item.getId()), invLotLocId.getLocationId())).findFirst().orElse(null);
+            if(ObjectUtil.isNull(locationInfo)) continue;
+
+            String floorAppendRowKey = locationInfo.getShiftNo() + "_" + locationInfo.getRowIndex();
+            Map<String, List<Long>> partitionRowNoListMapper = redisCache.getCacheObject(floorAppendRowKey);
+            Map<String, Object> warehouseAttrMapper = getWarehouseAttrConfig();
+            List<Integer> wayRowNoList = (List<Integer>) warehouseAttrMapper.get(Constants.WAY_ROW_NO_LIST);
+            //获取到这个库位命中的子列在两边还是中间
+            Integer firstWayNo = CollectionUtil.getFirst(wayRowNoList);
+            Integer lastWayNo = CollectionUtil.getLast(wayRowNoList);
+            String partitionRowKey = getPartitionRowKey(firstWayNo, lastWayNo, locationInfo.getRowIndex());
+            List<Long> partitionLocationIdList = partitionRowNoListMapper.get(partitionRowKey);
+            int locationIndex = partitionLocationIdList.indexOf(locationInfo.getId());
+            if(StringUtils.equals(partitionRowKey, Constants.FIRST)) {
+                //TODO  张馨
+                List<Long> firstRightSubList = ListUtil.sub(partitionLocationIdList, locationIndex, partitionLocationIdList.size());
+                List<Long> resultLocationIdList = checkLocationIdList(locationInfo.getId(), sourceInvLotLocIdList, firstRightSubList,
+                        baseLocationLotattList, quantity);
+                if(CollectionUtil.isEmpty(resultLocationIdList)) continue;
+                BigDecimal firstRightCount = sourceInvLotLocIdList.stream()
+                        .filter(item -> CollectionUtil.contains(resultLocationIdList, Long.parseLong(item.getLocationId()))
+                                && ObjectUtil.isNotNull(item.getQty()))
+                        .map(item -> item.getQty()).reduce(BigDecimal.ZERO, BigDecimal::add);
+                quantity = NumberUtil.sub(quantity, firstRightCount);
+                baseLocationLotattList = baseLocationLotattList.stream()
+                        .filter(item -> !CollectionUtil.contains(resultLocationIdList, item.getId())).collect(Collectors.toList());
+                selectedLocationIdList.addAll(resultLocationIdList);
+                if(CompareUtil.compare(quantity, BigDecimal.ZERO) <= 0) break;
+            }
+
+            if(StringUtils.equals(partitionRowKey, Constants.MIDDLE)){
+                //TODO  张馨
+                List<Long> middleLeftSubList = ListUtil.sub(partitionLocationIdList, Constants.START_VALUE, locationIndex + 1);
+                List<Long> middleLeftLocationIdList = checkLocationIdList(locationInfo.getId(), sourceInvLotLocIdList, middleLeftSubList,
+                        baseLocationLotattList, quantity);
+                if(CollectionUtil.isEmpty(middleLeftLocationIdList)) continue;
+                BigDecimal middleLeftCount = sourceInvLotLocIdList.stream()
+                        .filter(item -> CollectionUtil.contains(middleLeftLocationIdList, Long.parseLong(item.getLocationId()))
+                                && ObjectUtil.isNotNull(item.getQty()))
+                        .map(item -> item.getQty()).reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                List<Long> middleRightSubList = ListUtil.sub(partitionLocationIdList, locationIndex, partitionLocationIdList.size());
+                List<Long> middleRightLocationIdList = checkLocationIdList(locationInfo.getId(), sourceInvLotLocIdList, middleRightSubList,
+                        baseLocationLotattList, quantity);
+                if(CollectionUtil.isEmpty(middleRightLocationIdList)) continue;
+                BigDecimal middleRightCount = sourceInvLotLocIdList.stream()
+                        .filter(item -> CollectionUtil.contains(middleRightLocationIdList, Long.parseLong(item.getLocationId()))
+                                && ObjectUtil.isNotNull(item.getQty()))
+                        .map(item -> item.getQty()).reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                BigDecimal singleRowInvCount = CompareUtil.compare(middleLeftCount, middleRightCount) > 0 ? middleLeftCount : middleRightCount;
+                quantity = NumberUtil.sub(quantity, singleRowInvCount);
+
+                selectedLocationIdList.addAll(CompareUtil.compare(middleLeftCount, middleRightCount) > 0
+                        ? middleLeftLocationIdList : middleRightLocationIdList);
+                if(CompareUtil.compare(quantity, BigDecimal.ZERO) <= 0) break;
+            }
+
+            if(StringUtils.equals(partitionRowKey, Constants.LAST)) {
+                //TODO  张馨
+                List<Long> lastLeftSubList = ListUtil.sub(partitionLocationIdList, Constants.START_VALUE, locationIndex + 1);
+                List<Long> lastLeftLocationIdList = checkLocationIdList(locationInfo.getId(), sourceInvLotLocIdList, lastLeftSubList,
+                        baseLocationLotattList, quantity);
+                if(CollectionUtil.isEmpty(lastLeftLocationIdList)) continue;
+                BigDecimal lastLeftCount = sourceInvLotLocIdList.stream()
+                        .filter(item -> CollectionUtil.contains(lastLeftLocationIdList, Long.parseLong(item.getLocationId()))
+                                && ObjectUtil.isNotNull(item.getQty()))
+                        .map(item -> item.getQty()).reduce(BigDecimal.ZERO, BigDecimal::add);
+
+                quantity = NumberUtil.sub(quantity, lastLeftCount);
+                baseLocationLotattList = baseLocationLotattList.stream()
+                        .filter(item -> !CollectionUtil.contains(lastLeftLocationIdList, item.getId())).collect(Collectors.toList());
+                selectedLocationIdList.addAll(lastLeftLocationIdList);
+               if(CompareUtil.compare(quantity, BigDecimal.ZERO) <= 0) break;
+            }
+        }
+
+        //TODO  张馨 加过滤 删掉注释
+        System.err.println(JSONObject.toJSONString(selectedLocationIdList));
+        return null;
+    }
+
+
+    private List<Long> checkLocationIdList(Long locationId, List<InvLotLocId> sourceInvLotLocIdList, List<Long> subList,
+                                           List<BaseLocationLotattDTO> baseLocationLotattList, BigDecimal quantity) {
+        //要过滤掉已经推荐的库存
+        List<Long> locationIdList = baseLocationLotattList.stream().map(item -> item.getId()).collect(Collectors.toList());
+        //证明这一列只有这一个
+        List<Long> filteredList = subList.stream()
+                .filter(item -> !ObjectUtil.equal(item, locationId)
+                        && CollectionUtil.contains(locationIdList, item)).collect(Collectors.toList());
+        if(CollectionUtil.isEmpty(filteredList)) return Lists.newArrayList(locationId);
+
+        //查有没有入库任务,存在入库任务,此列不能出库
+        List<BaseLocationInfo> locationInfoList = baseLocationInfoService.selectLocationInfoList(filteredList);
+        List<BaseLocationInfo> asnTaskCheckList = locationInfoList.stream()
+                .filter(item -> StringUtils.equals(item.getStockStatus(), Constant.STOCK_STATUS.STOCK10.getValue())
+                        && StringUtils.equals(item.getIsEmpty(), Constants.YES)).collect(Collectors.toList());
+        if(CollectionUtil.isNotEmpty(asnTaskCheckList)) return Lists.newArrayList();
+
+        //证明外侧都是空的
+        List<BaseLocationLotattDTO> locationLotattList = baseLocationLotattList.stream()
+                .filter(item -> CollectionUtil.contains(filteredList, item.getId())
+                        && CollectionUtil.contains(locationIdList, item.getId())).collect(Collectors.toList());
+        if(CollectionUtil.isEmpty(locationLotattList)) return Lists.newArrayList(locationId);
+
+        //要过滤掉已经推荐的库存
+        List<InvLotLocId> invLocIdList = sourceInvLotLocIdList.stream()
+                .filter(item -> CollectionUtil.contains(locationIdList, Long.parseLong(item.getLocationId())))
+                .filter(item -> CollectionUtil.contains(subList, Long.parseLong(item.getLocationId()))).collect(Collectors.toList());
+        BigDecimal singleRowInvCount = invLocIdList.stream().filter(item -> ObjectUtil.isNotNull(item.getQty()))
+                .map(item -> item.getQty()).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
+        return CompareUtil.compare(singleRowInvCount, quantity) < 0
+                ? invLocIdList.stream().map(item -> Long.parseLong(item.getLocationId())).collect(Collectors.toList())
+                : Lists.newArrayList();
+    }
+
+
+    private String getPartitionRowKey(Integer first, Integer last, String rowIndex) {
+        if(CompareUtil.compare(Integer.parseInt(rowIndex), first) < 0) return Constants.FIRST;
+        if(CompareUtil.compare(Integer.parseInt(rowIndex), first) > 0
+                && CompareUtil.compare(Integer.parseInt(rowIndex), last) < 0) return Constants.MIDDLE;
+        if(CompareUtil.compare(Integer.parseInt(rowIndex), last) > 0) return Constants.LAST;
+        return StringUtils.EMPTY;
+    }
+
+    /**
+     * 获取库位的配置
+     * @return
+     */
+    private Map<String, Object> getWarehouseAttrConfig() {
+        String warehouseAttrInfo = sysConfigService.selectConfigByKey(SceneConstants.WAREHOUSE_ATTRIBUTE_SCENE_CONFIG);
+        Assert.isTrue(com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(warehouseAttrInfo), "baseLocationInfoList is empty");
+        return JSONObject.parseObject(warehouseAttrInfo);
+    }
+
+
     /**
      * 匹配库存
      *
@@ -197,11 +362,11 @@ public class WmsDocOrderSubService {
         //List<String> skuList = detailslist.stream().map(item -> item.getSku()).collect(Collectors.toList());
         String sku = detailslist.get(0).getSku();
         Assert.isTrue(StringUtils.isNotNull(sku),"存在无物料号的出库单");
-        List<BaseLocationLotattDTO> baseLocationLotattVOS
+        List<BaseLocationLotattDTO> baseLocationLotattList
                 = baseLocationInfoSubService.selectAllocatingInventoryAccordingConditionsOrderBy(OUT_ZONES,  new LotattDTO(), sku, null);
-        Assert.isTrue(CollectionUtil.isNotEmpty(baseLocationLotattVOS),"仓库中无库存");
+        Assert.isTrue(CollectionUtil.isNotEmpty(baseLocationLotattList),"仓库中无库存");
 
-        return baseLocationLotattVOS;
+        return baseLocationLotattList;
     }
 
     /**

+ 3 - 0
warewms-base/src/main/java/com/ruoyi/base/constant/Constant.java

@@ -2,9 +2,12 @@ package com.ruoyi.base.constant;
 
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.ruoyi.base.domain.BaseLocationZone;
+import com.ruoyi.base.domain.vo.BaseLocationLotattDTO;
 import com.ruoyi.common.utils.StringUtils;
 import io.netty.util.internal.ObjectUtil;
 
+import java.util.List;
+
 /**
  * Created by IntelliJ IDEA.
  * User: andy.qu

+ 14 - 0
warewms-base/src/main/java/com/ruoyi/base/service/IBaseLocationInfoService.java

@@ -350,4 +350,18 @@ public interface IBaseLocationInfoService {
      * @return
      */
     List<BaseLocationInfo> selectLocationInfoList(Long zoneId, String bindSku, Boolean isEmpty, String stockStatus);
+
+
+    /**
+     * 选取所有四向车立体库的库位
+     * @return 四向车库位列表
+     */
+    List<BaseLocationInfo> selectLocationInfoList();
+
+    /**
+     * 查询库ID列表库位信息列表
+     * @param locationIdList
+     * @return
+     */
+    List<BaseLocationInfo> selectLocationInfoList(List<Long> locationIdList);
 }

+ 18 - 0
warewms-base/src/main/java/com/ruoyi/base/service/impl/BaseLocationInfoServiceImpl.java

@@ -1,6 +1,7 @@
 package com.ruoyi.base.service.impl;
 
 import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.ruoyi.base.constant.Constant;
@@ -537,4 +538,21 @@ public class BaseLocationInfoServiceImpl implements IBaseLocationInfoService {
                 .eq(BaseLocationInfo::getIsEmpty, isEmpty? Constants.YES : Constants.NO)
                 .eq(BaseLocationInfo::getStockStatus, stockStatus));
     }
+
+    @Override
+    public List<BaseLocationInfo> selectLocationInfoList() {
+        LambdaQueryWrapper<BaseLocationInfo> queryWrapper = Wrappers.<BaseLocationInfo>lambdaQuery()
+                .eq(BaseLocationInfo::getWarehouseId, Constants.DEFAULT_WAREHOUSE_ID)
+                .in(BaseLocationInfo::getZoneId, Constants.FLOOR_LIST);
+        return baseLocationInfoMapper.selectList(queryWrapper);
+    }
+
+    @Override
+    public List<BaseLocationInfo> selectLocationInfoList(List<Long> locationIdList) {
+        LambdaQueryWrapper<BaseLocationInfo> queryWrapper = Wrappers.<BaseLocationInfo>lambdaQuery()
+                .eq(BaseLocationInfo::getWarehouseId, Constants.DEFAULT_WAREHOUSE_ID)
+                .in(BaseLocationInfo::getId, locationIdList);
+        return baseLocationInfoMapper.selectList(queryWrapper);
+    }
+
 }