Commit b63d003e839192d219bc141d7b72469eb2108e8c

Authored by 肖超群
1 parent b9a2d4b9

选择巷道, 首选排除任务多余2个的巷道,选择空闲库位多的库位,

huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/LocationAllocationService.java
... ... @@ -4,7 +4,43 @@ import java.util.List;
4 4  
5 5 public interface LocationAllocationService {
6 6  
  7 + /**
  8 + * 获得库位分配的库位
  9 + */
7 10 String allocation(int locationRule, List<String> locationTypeCodeList, int high, String zoneCode, List<Integer> raodWays, String warehouseCode,
8 11 String containerCode, String materialAreaCode);
9 12  
  13 + String doubleRk(String zoneCode, List<Integer> roadWays, int high, String warehouseCode, List<String> locationTypeCodeList, String materialAreaCode);
  14 +
  15 + String singleRk(String zoneCode, List<Integer> roadWays, int high, String warehouseCode, List<String> locationTypeCodeList, String materialAreaCode);
  16 +
  17 + /**
  18 + * 获取可用巷道
  19 + * @param roadWays
  20 + * @return
  21 + */
  22 + Integer getRoadWay(List<Integer> roadWays, String warehouseCode);
  23 +
  24 + /**
  25 + * 获取巷道,选取空闲库位最多作为巷道
  26 + * @param roadWays
  27 + * @return
  28 + */
  29 + Integer getRoadWayByMaxFreeLocation(List<Integer> roadWays, String warehouseCode);
  30 +
  31 + /**
  32 + * 排除巷道,如果这个巷道分配了超过2个库位,那么就不往这边分库位了,避免堵死的情况
  33 + * @param roadWays
  34 + * @param warehouseCode
  35 + * @return
  36 + */
  37 + List<Integer> removeRoadWaysByPreLocations(List<Integer> roadWays, String warehouseCode);
  38 +
  39 +// /**
  40 +// * 获取巷道,根据入库物料均分原则,选取物料最少的巷道
  41 +// * @param roadWays
  42 +// * @return
  43 +// */
  44 +// Integer getRoadWayByMinMaterial(List<Integer> roadWays, String warehouseCode);
  45 +
10 46 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/LocationAllocationServiceImpl.java
1 1 package org.jeecg.modules.wms.api.wcs.service;
2 2  
  3 +import static java.util.stream.Collectors.toList;
  4 +
  5 +import java.util.ArrayList;
  6 +import java.util.Collections;
  7 +import java.util.List;
  8 +
  9 +import javax.annotation.Resource;
  10 +
3 11 import org.jeecg.common.exception.JeecgBootException;
4   -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
5   -import com.baomidou.mybatisplus.core.toolkit.Wrappers;
6 12 import org.jeecg.modules.wms.config.container.entity.Container;
7 13 import org.jeecg.modules.wms.config.container.service.IContainerService;
8 14 import org.jeecg.modules.wms.config.containerType.entity.ContainerType;
... ... @@ -11,10 +17,9 @@ import org.jeecg.modules.wms.config.location.entity.Location;
11 17 import org.jeecg.modules.wms.config.location.service.ILocationService;
12 18 import org.jeecg.modules.wms.config.locationType.entity.LocationType;
13 19 import org.jeecg.modules.wms.config.locationType.service.ILocationTypeService;
14   -import org.jeecg.modules.wms.config.parameterConfiguration.entity.ParameterConfiguration;
15 20 import org.jeecg.modules.wms.config.parameterConfiguration.service.IParameterConfigurationService;
16   -import org.jeecg.modules.wms.config.zone.entity.Zone;
17 21 import org.jeecg.modules.wms.config.zone.service.IZoneService;
  22 +import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader;
18 23 import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService;
19 24 import org.jeecg.utils.StringUtils;
20 25 import org.jeecg.utils.constant.QuantityConstant;
... ... @@ -22,12 +27,8 @@ import org.springframework.stereotype.Service;
22 27 import org.springframework.transaction.annotation.Transactional;
23 28 import org.springframework.util.StopWatch;
24 29  
25   -import javax.annotation.Resource;
26   -import java.util.ArrayList;
27   -import java.util.Collections;
28   -import java.util.List;
29   -
30   -import static java.util.stream.Collectors.toList;
  30 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  31 +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
31 32  
32 33 /**
33 34 * @author 游杰
... ... @@ -49,6 +50,8 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
49 50 private IZoneService zoneService;
50 51 @Resource
51 52 private IParameterConfigurationService parameterConfigurationService;
  53 + @Resource
  54 + private LocationAllocationService locationAllocationService;
52 55  
53 56 @Override
54 57 @Transactional(rollbackFor = Exception.class)
... ... @@ -76,9 +79,9 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
76 79 List<String> mergelocationTypeCodeList = locationTypeCodeList.stream().filter(item -> locationTypeCodes.contains(item)).collect(toList());
77 80 switch (locationRule) {
78 81 case QuantityConstant.DOUBLE_FORK:
79   - return doubleRk(zoneCode, raodWays, high, warehouseCode, mergelocationTypeCodeList, materialAreaCode);
  82 + return locationAllocationService.doubleRk(zoneCode, raodWays, high, warehouseCode, mergelocationTypeCodeList, materialAreaCode);
80 83 case QuantityConstant.SINGLE_FORK:
81   - return singleRk(zoneCode, raodWays, high, warehouseCode, mergelocationTypeCodeList, materialAreaCode);
  84 + return locationAllocationService.singleRk(zoneCode, raodWays, high, warehouseCode, mergelocationTypeCodeList, materialAreaCode);
82 85 }
83 86 return null;
84 87 }
... ... @@ -86,7 +89,9 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
86 89 /**
87 90 * 双伸位库位入库分配库位
88 91 */
89   - private String doubleRk(String zoneCode, List<Integer> roadWays, int high, String warehouseCode, List<String> locationTypeCodeList, String materialAreaCode) {
  92 + @Override
  93 + @Transactional(rollbackFor = Exception.class)
  94 + public String doubleRk(String zoneCode, List<Integer> roadWays, int high, String warehouseCode, List<String> locationTypeCodeList, String materialAreaCode) {
90 95 if (roadWays == null || roadWays.size() < 1) {
91 96 List<Location> locationList = locationService.getLocationListByZoneCode(zoneCode, warehouseCode);
92 97 roadWays = locationList.stream().map(Location::getRoadWay).distinct().collect(toList());
... ... @@ -121,15 +126,14 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
121 126 System.out.println("waste aa:" + stopWatch.getLastTaskTimeMillis());
122 127 stopWatch.start("bbb");
123 128 roadWays.removeAll(removeRoadWays);
124   - Collections.shuffle(roadWays);
125 129 if (roadWays == null || roadWays.size() == 0) {
126 130 throw new JeecgBootException("分配库位时, 巷道为空");
127 131 }
128   - Integer roadWay = roadWays.get(0);
  132 + Integer roadWay = locationAllocationService.getRoadWay(roadWays, warehouseCode);
129 133 // 优先找外侧库位
130 134 LambdaQueryWrapper<Location> locationLambda = Wrappers.lambdaQuery();
131 135 locationLambda.eq(Location::getZoneCode, zoneCode).eq(Location::getWarehouseCode, warehouseCode).eq(Location::getRoadWay, roadWay)
132   - .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY).eq(Location::getHigh, high)
  136 + .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY).ge(Location::getHigh, high)
133 137 .eq(StringUtils.isNotEmpty(materialAreaCode), Location::getMaterialAreaCode, materialAreaCode).eq(Location::getRowFlag, QuantityConstant.ROW_OUT)
134 138 .in(Location::getLocationTypeCode, locationTypeCodeList).eq(Location::getContainerCode, QuantityConstant.EMPTY_STRING).last(lastString);
135 139 List<Location> locationList = locationService.list(locationLambda);
... ... @@ -148,7 +152,7 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
148 152 if (locationList.size() == 0) {
149 153 locationLambda = Wrappers.lambdaQuery();
150 154 locationLambda.eq(Location::getZoneCode, zoneCode).eq(Location::getWarehouseCode, warehouseCode).eq(Location::getRoadWay, roadWay)
151   - .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY).eq(Location::getHigh, high)
  155 + .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY).ge(Location::getHigh, high)
152 156 .eq(StringUtils.isNotEmpty(materialAreaCode), Location::getMaterialAreaCode, materialAreaCode).eq(Location::getRowFlag, QuantityConstant.ROW_IN)
153 157 .in(Location::getLocationTypeCode, locationTypeCodeList).eq(Location::getContainerCode, QuantityConstant.EMPTY_STRING).last(lastString);
154 158 locationList = locationService.list(locationLambda);
... ... @@ -173,16 +177,17 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
173 177 /**
174 178 * 单伸位库位入库分配库位
175 179 */
176   - private String singleRk(String zoneCode, List<Integer> roadWays, int high, String warehouseCode, List<String> locationTypeCodeList, String materialAreaCode) {
  180 + @Override
  181 + @Transactional(rollbackFor = Exception.class)
  182 + public String singleRk(String zoneCode, List<Integer> roadWays, int high, String warehouseCode, List<String> locationTypeCodeList, String materialAreaCode) {
177 183 if (roadWays == null || roadWays.size() < 1) {
178 184 List<Location> locationList = locationService.getLocationListByZoneCode(zoneCode, warehouseCode);
179 185 roadWays = locationList.stream().map(Location::getRoadWay).distinct().collect(toList());
180 186 }
181   - Collections.shuffle(roadWays);
182   - Integer roadWay = roadWays.get(0);
  187 + Integer roadWay = locationAllocationService.getRoadWay(roadWays, warehouseCode);
183 188 LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
184 189 locationLambdaQueryWrapper.eq(Location::getZoneCode, zoneCode).eq(Location::getWarehouseCode, warehouseCode).eq(Location::getRoadWay, roadWay)
185   - .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY).eq(Location::getHigh, high)
  190 + .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY).ge(Location::getHigh, high)
186 191 .eq(StringUtils.isNotEmpty(materialAreaCode), Location::getMaterialAreaCode, materialAreaCode).in(Location::getLocationTypeCode, locationTypeCodeList)
187 192 .eq(Location::getContainerCode, QuantityConstant.EMPTY_STRING).last("ORDER BY layer asc, id asc limit 1");
188 193 // 单伸位逻辑简单,只需要找到一个空闲库位
... ... @@ -194,4 +199,67 @@ public class LocationAllocationServiceImpl implements LocationAllocationService
194 199 return locationCode;
195 200 }
196 201  
  202 + @Override
  203 + @Transactional(rollbackFor = Exception.class)
  204 + public Integer getRoadWay(List<Integer> roadWays, String warehouseCode) {
  205 + if (roadWays.size() == 1) {
  206 + return roadWays.get(0);
  207 + }
  208 + roadWays = locationAllocationService.removeRoadWaysByPreLocations(roadWays, warehouseCode);
  209 + int roadWay = getRoadWayByMaxFreeLocation(roadWays, warehouseCode);
  210 + return roadWay;
  211 + }
  212 +
  213 + @Override
  214 + @Transactional(rollbackFor = Exception.class)
  215 + public Integer getRoadWayByMaxFreeLocation(List<Integer> roadWays, String warehouseCode) {
  216 + List<Integer> locationSizeList = new ArrayList<Integer>();
  217 + int max = 0;
  218 + // 最多空闲库位的巷道索引
  219 + int index = 0;
  220 + // 获取每个巷道的可用空闲库位数
  221 + for (Integer roadWay : roadWays) {
  222 + int size = locationService.getEmptyLocationSizeByRoadWay(roadWay, warehouseCode);
  223 + locationSizeList.add(size);
  224 + }
  225 + // 通过比较每个巷道的库位数,最终找到最大库位数的索引,这个索引是roadWays的第几个。
  226 + for (int i = 0; i < locationSizeList.size(); i++) {
  227 + int locationSize = locationSizeList.get(i);;
  228 + if (max == 0) {
  229 + max = locationSize;
  230 + index = i;
  231 + } else {
  232 + if (max < locationSize) {
  233 + max = locationSize;
  234 + index = i;
  235 + }
  236 + }
  237 + }
  238 + // 获得空闲库位数
  239 + int maxRoadWay = roadWays.get(index);
  240 + return maxRoadWay;
  241 + }
  242 +
  243 + @Override
  244 + @Transactional(rollbackFor = Exception.class)
  245 + public List<Integer> removeRoadWaysByPreLocations(List<Integer> roadWays, String warehouseCode) {
  246 + // 同巷道分配的库位大于等于2时,这个巷道就不能再分了
  247 + LambdaQueryWrapper<TaskHeader> taskHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
  248 + taskHeaderLambdaQueryWrapper.lt(TaskHeader::getStatus, QuantityConstant.TASK_STATUS_COMPLETED).ne(TaskHeader::getToLocationCode,
  249 + QuantityConstant.EMPTY_STRING);
  250 + List<TaskHeader> taskHeaderList = taskHeaderService.list(taskHeaderLambdaQueryWrapper);
  251 + if (taskHeaderList.size() != 0) {
  252 + List<Integer> roadWayList = taskHeaderList.stream().map(TaskHeader::getRoadWay).collect(toList());
  253 + List<Integer> removeRoadWayList = new ArrayList<>();
  254 + for (Integer roadWay : roadWays) {
  255 + int i = Collections.frequency(roadWayList, roadWay);
  256 + if (i >= 2) {
  257 + removeRoadWayList.add(roadWay);
  258 + }
  259 + }
  260 + roadWays.removeAll(removeRoadWayList);
  261 + }
  262 + return roadWays;
  263 + }
  264 +
197 265 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java
... ... @@ -241,6 +241,7 @@ public class WcsServiceImpl implements WcsService {
241 241 taskHeader = new TaskHeader();
242 242 taskHeader.setId(Integer.parseInt(taskNo));
243 243 taskHeader.setZoneCode(location.getZoneCode());
  244 + taskHeader.setRoadWay(location.getRoadWay());
244 245 taskHeader.setPreTaskNo(preTaskNo);
245 246 taskHeader.setWeight(Integer.parseInt(warecellDomain.getWeight()));
246 247 taskHeader.setToLocationCode(locationCode);
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/container/service/impl/ContainerServiceImpl.java
... ... @@ -62,6 +62,9 @@ public class ContainerServiceImpl extends ServiceImpl&lt;ContainerMapper, Container
62 62  
63 63 @Override
64 64 public Container getContainerByCode(String containCode, String warehouseCode) {
  65 + if (StringUtils.havaLowerCase(containCode)) {
  66 + throw new JeecgBootException("容器不能有小字母" + containCode);
  67 + }
65 68 LambdaQueryWrapper<Container> containerLambdaQueryWrapper = Wrappers.lambdaQuery();
66 69 containerLambdaQueryWrapper.eq(Container::getCode, containCode).eq(Container::getWarehouseCode, warehouseCode);
67 70 Container container = this.getOne(containerLambdaQueryWrapper);
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/ILocationService.java
... ... @@ -3,12 +3,7 @@ package org.jeecg.modules.wms.config.location.service;
3 3 import java.util.List;
4 4  
5 5 import org.jeecg.common.api.vo.Result;
6   -import org.jeecg.modules.wms.config.location.dto.CompareContainerTaskDto;
7   -import org.jeecg.modules.wms.config.location.dto.CompareLocationDto;
8   -import org.jeecg.modules.wms.config.location.dto.CompareLocationTaskDto;
9   -import org.jeecg.modules.wms.config.location.dto.QueryCompareContainerTaskDto;
10   -import org.jeecg.modules.wms.config.location.dto.QueryCompareLocationDto;
11   -import org.jeecg.modules.wms.config.location.dto.QueryCompareLocationTaskDto;
  6 +import org.jeecg.modules.wms.config.location.dto.*;
12 7 import org.jeecg.modules.wms.config.location.entity.BatchLocation;
13 8 import org.jeecg.modules.wms.config.location.entity.Location;
14 9 import org.jeecg.modules.wms.config.location.entity.LocationInfo;
... ... @@ -44,6 +39,8 @@ public interface ILocationService extends IService&lt;Location&gt; {
44 39  
45 40 Location getEmptyLocation(Location location);
46 41  
  42 + int getEmptyLocationSizeByRoadWay(Integer roadWay, String warehouseCode);
  43 +
47 44 Location getEmptyInsideLocation(Location location);
48 45  
49 46 Location getEmptyOutSideLocation(Location location);
... ... @@ -66,8 +63,7 @@ public interface ILocationService extends IService&lt;Location&gt; {
66 63 PageUtil<CompareLocationDto> compareWcsLocation(QueryCompareLocationDto queryCompareLocationDto);
67 64  
68 65 PageUtil<CompareLocationTaskDto> compareWcsLocationTask(QueryCompareLocationTaskDto queryCompareLocationTaskDto);
69   -
70   - PageUtil<CompareContainerTaskDto> compareWcsContainerTask(QueryCompareContainerTaskDto queryCompareLocationTaskDto);
71 66  
  67 + PageUtil<CompareContainerTaskDto> compareWcsContainerTask(QueryCompareContainerTaskDto queryCompareLocationTaskDto);
72 68  
73 69 }
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java
... ... @@ -79,6 +79,9 @@ public class LocationServiceImpl extends ServiceImpl&lt;LocationMapper, Location&gt; i
79 79  
80 80 @Override
81 81 public Location getLocationByCode(String locationCode, String warehouseCode) {
  82 + if (StringUtils.havaLowerCase(locationCode)) {
  83 + throw new JeecgBootException("库位不能有小字母" + locationCode);
  84 + }
82 85 LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
83 86 locationLambdaQueryWrapper.eq(Location::getCode, locationCode).eq(Location::getEnable, QuantityConstant.STATUS_ENABLE).eq(Location::getWarehouseCode,
84 87 warehouseCode);
... ... @@ -187,6 +190,15 @@ public class LocationServiceImpl extends ServiceImpl&lt;LocationMapper, Location&gt; i
187 190 }
188 191  
189 192 @Override
  193 + public int getEmptyLocationSizeByRoadWay(Integer roadWay, String warehouseCode) {
  194 + LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
  195 + locationLambdaQueryWrapper.eq(Location::getRoadWay, roadWay).eq(Location::getWarehouseCode, warehouseCode)
  196 + .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY).eq(Location::getContainerCode, QuantityConstant.EMPTY_STRING);
  197 + int count = count(locationLambdaQueryWrapper);
  198 + return count;
  199 + }
  200 +
  201 + @Override
190 202 public Location getEmptyInsideLocation(Location location) {
191 203 LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
192 204 locationLambdaQueryWrapper.eq(Location::getWarehouseCode, location.getWarehouseCode()).eq(Location::getRoadWay, location.getRoadWay())
... ...
huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/entity/TaskHeader.java
... ... @@ -142,6 +142,8 @@ public class TaskHeader implements Serializable {
142 142 private String exceptionName;
143 143 @ApiModelProperty(value = "异常状态")
144 144 private Integer exceptionState;
  145 + @ApiModelProperty(value = "巷道")
  146 + private Integer roadWay;
145 147 /** 备用字段1 */
146 148 @Excel(name = "备用字段1", width = 15)
147 149 @ApiModelProperty(value = "备用字段1")
... ...
huaheng-wms-core/src/main/java/org/jeecg/utils/StringUtils.java
... ... @@ -327,6 +327,24 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
327 327 }
328 328  
329 329 /**
  330 + * 字符串有小写
  331 + */
  332 + public static boolean havaLowerCase(String str) {
  333 + int strLen;
  334 + boolean have = false;
  335 + if (str == null || (strLen = str.length()) == 0) {
  336 + return true;
  337 + }
  338 + for (int i = 0; i < strLen; i++) {
  339 + char charAt = str.charAt(i);
  340 + if (Character.isLowerCase(charAt)) {
  341 + return true;
  342 + }
  343 + }
  344 + return false;
  345 + }
  346 +
  347 + /**
330 348 * 驼峰式命名法 例如:user_name->userName
331 349 */
332 350 public static String toCamelCase(String s) {
... ...