diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/LocationAllocationService.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/LocationAllocationService.java index 42d05a8..8182016 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/LocationAllocationService.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/LocationAllocationService.java @@ -4,7 +4,43 @@ import java.util.List; public interface LocationAllocationService { + /** + * 获得库位分配的库位 + */ String allocation(int locationRule, List<String> locationTypeCodeList, int high, String zoneCode, List<Integer> raodWays, String warehouseCode, String containerCode, String materialAreaCode); + String doubleRk(String zoneCode, List<Integer> roadWays, int high, String warehouseCode, List<String> locationTypeCodeList, String materialAreaCode); + + String singleRk(String zoneCode, List<Integer> roadWays, int high, String warehouseCode, List<String> locationTypeCodeList, String materialAreaCode); + + /** + * 获取可用巷道 + * @param roadWays + * @return + */ + Integer getRoadWay(List<Integer> roadWays, String warehouseCode); + + /** + * 获取巷道,选取空闲库位最多作为巷道 + * @param roadWays + * @return + */ + Integer getRoadWayByMaxFreeLocation(List<Integer> roadWays, String warehouseCode); + + /** + * 排除巷道,如果这个巷道分配了超过2个库位,那么就不往这边分库位了,避免堵死的情况 + * @param roadWays + * @param warehouseCode + * @return + */ + List<Integer> removeRoadWaysByPreLocations(List<Integer> roadWays, String warehouseCode); + +// /** +// * 获取巷道,根据入库物料均分原则,选取物料最少的巷道 +// * @param roadWays +// * @return +// */ +// Integer getRoadWayByMinMaterial(List<Integer> roadWays, String warehouseCode); + } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/LocationAllocationServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/LocationAllocationServiceImpl.java index daaf64f..fca4232 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/LocationAllocationServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/LocationAllocationServiceImpl.java @@ -1,8 +1,14 @@ package org.jeecg.modules.wms.api.wcs.service; +import static java.util.stream.Collectors.toList; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.annotation.Resource; + import org.jeecg.common.exception.JeecgBootException; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; import org.jeecg.modules.wms.config.container.entity.Container; import org.jeecg.modules.wms.config.container.service.IContainerService; import org.jeecg.modules.wms.config.containerType.entity.ContainerType; @@ -11,10 +17,9 @@ import org.jeecg.modules.wms.config.location.entity.Location; import org.jeecg.modules.wms.config.location.service.ILocationService; import org.jeecg.modules.wms.config.locationType.entity.LocationType; import org.jeecg.modules.wms.config.locationType.service.ILocationTypeService; -import org.jeecg.modules.wms.config.parameterConfiguration.entity.ParameterConfiguration; import org.jeecg.modules.wms.config.parameterConfiguration.service.IParameterConfigurationService; -import org.jeecg.modules.wms.config.zone.entity.Zone; import org.jeecg.modules.wms.config.zone.service.IZoneService; +import org.jeecg.modules.wms.task.taskHeader.entity.TaskHeader; import org.jeecg.modules.wms.task.taskHeader.service.ITaskHeaderService; import org.jeecg.utils.StringUtils; import org.jeecg.utils.constant.QuantityConstant; @@ -22,12 +27,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StopWatch; -import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import static java.util.stream.Collectors.toList; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; /** * @author 游杰 @@ -49,6 +50,8 @@ public class LocationAllocationServiceImpl implements LocationAllocationService private IZoneService zoneService; @Resource private IParameterConfigurationService parameterConfigurationService; + @Resource + private LocationAllocationService locationAllocationService; @Override @Transactional(rollbackFor = Exception.class) @@ -76,9 +79,9 @@ public class LocationAllocationServiceImpl implements LocationAllocationService List<String> mergelocationTypeCodeList = locationTypeCodeList.stream().filter(item -> locationTypeCodes.contains(item)).collect(toList()); switch (locationRule) { case QuantityConstant.DOUBLE_FORK: - return doubleRk(zoneCode, raodWays, high, warehouseCode, mergelocationTypeCodeList, materialAreaCode); + return locationAllocationService.doubleRk(zoneCode, raodWays, high, warehouseCode, mergelocationTypeCodeList, materialAreaCode); case QuantityConstant.SINGLE_FORK: - return singleRk(zoneCode, raodWays, high, warehouseCode, mergelocationTypeCodeList, materialAreaCode); + return locationAllocationService.singleRk(zoneCode, raodWays, high, warehouseCode, mergelocationTypeCodeList, materialAreaCode); } return null; } @@ -86,7 +89,9 @@ public class LocationAllocationServiceImpl implements LocationAllocationService /** * 双伸位库位入库分配库位 */ - private String doubleRk(String zoneCode, List<Integer> roadWays, int high, String warehouseCode, List<String> locationTypeCodeList, String materialAreaCode) { + @Override + @Transactional(rollbackFor = Exception.class) + public String doubleRk(String zoneCode, List<Integer> roadWays, int high, String warehouseCode, List<String> locationTypeCodeList, String materialAreaCode) { if (roadWays == null || roadWays.size() < 1) { List<Location> locationList = locationService.getLocationListByZoneCode(zoneCode, warehouseCode); roadWays = locationList.stream().map(Location::getRoadWay).distinct().collect(toList()); @@ -121,15 +126,14 @@ public class LocationAllocationServiceImpl implements LocationAllocationService System.out.println("waste aa:" + stopWatch.getLastTaskTimeMillis()); stopWatch.start("bbb"); roadWays.removeAll(removeRoadWays); - Collections.shuffle(roadWays); if (roadWays == null || roadWays.size() == 0) { throw new JeecgBootException("分配库位时, 巷道为空"); } - Integer roadWay = roadWays.get(0); + Integer roadWay = locationAllocationService.getRoadWay(roadWays, warehouseCode); // 优先找外侧库位 LambdaQueryWrapper<Location> locationLambda = Wrappers.lambdaQuery(); locationLambda.eq(Location::getZoneCode, zoneCode).eq(Location::getWarehouseCode, warehouseCode).eq(Location::getRoadWay, roadWay) - .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY).eq(Location::getHigh, high) + .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY).ge(Location::getHigh, high) .eq(StringUtils.isNotEmpty(materialAreaCode), Location::getMaterialAreaCode, materialAreaCode).eq(Location::getRowFlag, QuantityConstant.ROW_OUT) .in(Location::getLocationTypeCode, locationTypeCodeList).eq(Location::getContainerCode, QuantityConstant.EMPTY_STRING).last(lastString); List<Location> locationList = locationService.list(locationLambda); @@ -148,7 +152,7 @@ public class LocationAllocationServiceImpl implements LocationAllocationService if (locationList.size() == 0) { locationLambda = Wrappers.lambdaQuery(); locationLambda.eq(Location::getZoneCode, zoneCode).eq(Location::getWarehouseCode, warehouseCode).eq(Location::getRoadWay, roadWay) - .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY).eq(Location::getHigh, high) + .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY).ge(Location::getHigh, high) .eq(StringUtils.isNotEmpty(materialAreaCode), Location::getMaterialAreaCode, materialAreaCode).eq(Location::getRowFlag, QuantityConstant.ROW_IN) .in(Location::getLocationTypeCode, locationTypeCodeList).eq(Location::getContainerCode, QuantityConstant.EMPTY_STRING).last(lastString); locationList = locationService.list(locationLambda); @@ -173,16 +177,17 @@ public class LocationAllocationServiceImpl implements LocationAllocationService /** * 单伸位库位入库分配库位 */ - private String singleRk(String zoneCode, List<Integer> roadWays, int high, String warehouseCode, List<String> locationTypeCodeList, String materialAreaCode) { + @Override + @Transactional(rollbackFor = Exception.class) + public String singleRk(String zoneCode, List<Integer> roadWays, int high, String warehouseCode, List<String> locationTypeCodeList, String materialAreaCode) { if (roadWays == null || roadWays.size() < 1) { List<Location> locationList = locationService.getLocationListByZoneCode(zoneCode, warehouseCode); roadWays = locationList.stream().map(Location::getRoadWay).distinct().collect(toList()); } - Collections.shuffle(roadWays); - Integer roadWay = roadWays.get(0); + Integer roadWay = locationAllocationService.getRoadWay(roadWays, warehouseCode); LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery(); locationLambdaQueryWrapper.eq(Location::getZoneCode, zoneCode).eq(Location::getWarehouseCode, warehouseCode).eq(Location::getRoadWay, roadWay) - .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY).eq(Location::getHigh, high) + .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY).ge(Location::getHigh, high) .eq(StringUtils.isNotEmpty(materialAreaCode), Location::getMaterialAreaCode, materialAreaCode).in(Location::getLocationTypeCode, locationTypeCodeList) .eq(Location::getContainerCode, QuantityConstant.EMPTY_STRING).last("ORDER BY layer asc, id asc limit 1"); // 单伸位逻辑简单,只需要找到一个空闲库位 @@ -194,4 +199,67 @@ public class LocationAllocationServiceImpl implements LocationAllocationService return locationCode; } + @Override + @Transactional(rollbackFor = Exception.class) + public Integer getRoadWay(List<Integer> roadWays, String warehouseCode) { + if (roadWays.size() == 1) { + return roadWays.get(0); + } + roadWays = locationAllocationService.removeRoadWaysByPreLocations(roadWays, warehouseCode); + int roadWay = getRoadWayByMaxFreeLocation(roadWays, warehouseCode); + return roadWay; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Integer getRoadWayByMaxFreeLocation(List<Integer> roadWays, String warehouseCode) { + List<Integer> locationSizeList = new ArrayList<Integer>(); + int max = 0; + // 最多空闲库位的巷道索引 + int index = 0; + // 获取每个巷道的可用空闲库位数 + for (Integer roadWay : roadWays) { + int size = locationService.getEmptyLocationSizeByRoadWay(roadWay, warehouseCode); + locationSizeList.add(size); + } + // 通过比较每个巷道的库位数,最终找到最大库位数的索引,这个索引是roadWays的第几个。 + for (int i = 0; i < locationSizeList.size(); i++) { + int locationSize = locationSizeList.get(i);; + if (max == 0) { + max = locationSize; + index = i; + } else { + if (max < locationSize) { + max = locationSize; + index = i; + } + } + } + // 获得空闲库位数 + int maxRoadWay = roadWays.get(index); + return maxRoadWay; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public List<Integer> removeRoadWaysByPreLocations(List<Integer> roadWays, String warehouseCode) { + // 同巷道分配的库位大于等于2时,这个巷道就不能再分了 + LambdaQueryWrapper<TaskHeader> taskHeaderLambdaQueryWrapper = Wrappers.lambdaQuery(); + taskHeaderLambdaQueryWrapper.lt(TaskHeader::getStatus, QuantityConstant.TASK_STATUS_COMPLETED).ne(TaskHeader::getToLocationCode, + QuantityConstant.EMPTY_STRING); + List<TaskHeader> taskHeaderList = taskHeaderService.list(taskHeaderLambdaQueryWrapper); + if (taskHeaderList.size() != 0) { + List<Integer> roadWayList = taskHeaderList.stream().map(TaskHeader::getRoadWay).collect(toList()); + List<Integer> removeRoadWayList = new ArrayList<>(); + for (Integer roadWay : roadWays) { + int i = Collections.frequency(roadWayList, roadWay); + if (i >= 2) { + removeRoadWayList.add(roadWay); + } + } + roadWays.removeAll(removeRoadWayList); + } + return roadWays; + } + } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java index 8617447..1c2a7b2 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/api/wcs/service/WcsServiceImpl.java @@ -241,6 +241,7 @@ public class WcsServiceImpl implements WcsService { taskHeader = new TaskHeader(); taskHeader.setId(Integer.parseInt(taskNo)); taskHeader.setZoneCode(location.getZoneCode()); + taskHeader.setRoadWay(location.getRoadWay()); taskHeader.setPreTaskNo(preTaskNo); taskHeader.setWeight(Integer.parseInt(warecellDomain.getWeight())); taskHeader.setToLocationCode(locationCode); diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/container/service/impl/ContainerServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/container/service/impl/ContainerServiceImpl.java index 72bd349..6a54168 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/container/service/impl/ContainerServiceImpl.java +++ b/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<ContainerMapper, Container @Override public Container getContainerByCode(String containCode, String warehouseCode) { + if (StringUtils.havaLowerCase(containCode)) { + throw new JeecgBootException("容器不能有小字母" + containCode); + } LambdaQueryWrapper<Container> containerLambdaQueryWrapper = Wrappers.lambdaQuery(); containerLambdaQueryWrapper.eq(Container::getCode, containCode).eq(Container::getWarehouseCode, warehouseCode); Container container = this.getOne(containerLambdaQueryWrapper); diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/ILocationService.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/ILocationService.java index c734189..3cf52be 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/ILocationService.java +++ b/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; import java.util.List; import org.jeecg.common.api.vo.Result; -import org.jeecg.modules.wms.config.location.dto.CompareContainerTaskDto; -import org.jeecg.modules.wms.config.location.dto.CompareLocationDto; -import org.jeecg.modules.wms.config.location.dto.CompareLocationTaskDto; -import org.jeecg.modules.wms.config.location.dto.QueryCompareContainerTaskDto; -import org.jeecg.modules.wms.config.location.dto.QueryCompareLocationDto; -import org.jeecg.modules.wms.config.location.dto.QueryCompareLocationTaskDto; +import org.jeecg.modules.wms.config.location.dto.*; import org.jeecg.modules.wms.config.location.entity.BatchLocation; import org.jeecg.modules.wms.config.location.entity.Location; import org.jeecg.modules.wms.config.location.entity.LocationInfo; @@ -44,6 +39,8 @@ public interface ILocationService extends IService<Location> { Location getEmptyLocation(Location location); + int getEmptyLocationSizeByRoadWay(Integer roadWay, String warehouseCode); + Location getEmptyInsideLocation(Location location); Location getEmptyOutSideLocation(Location location); @@ -66,8 +63,7 @@ public interface ILocationService extends IService<Location> { PageUtil<CompareLocationDto> compareWcsLocation(QueryCompareLocationDto queryCompareLocationDto); PageUtil<CompareLocationTaskDto> compareWcsLocationTask(QueryCompareLocationTaskDto queryCompareLocationTaskDto); - - PageUtil<CompareContainerTaskDto> compareWcsContainerTask(QueryCompareContainerTaskDto queryCompareLocationTaskDto); + PageUtil<CompareContainerTaskDto> compareWcsContainerTask(QueryCompareContainerTaskDto queryCompareLocationTaskDto); } diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java index cfec542..dc2a9cf 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/config/location/service/impl/LocationServiceImpl.java +++ b/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<LocationMapper, Location> i @Override public Location getLocationByCode(String locationCode, String warehouseCode) { + if (StringUtils.havaLowerCase(locationCode)) { + throw new JeecgBootException("库位不能有小字母" + locationCode); + } LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery(); locationLambdaQueryWrapper.eq(Location::getCode, locationCode).eq(Location::getEnable, QuantityConstant.STATUS_ENABLE).eq(Location::getWarehouseCode, warehouseCode); @@ -187,6 +190,15 @@ public class LocationServiceImpl extends ServiceImpl<LocationMapper, Location> i } @Override + public int getEmptyLocationSizeByRoadWay(Integer roadWay, String warehouseCode) { + LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery(); + locationLambdaQueryWrapper.eq(Location::getRoadWay, roadWay).eq(Location::getWarehouseCode, warehouseCode) + .eq(Location::getStatus, QuantityConstant.STATUS_LOCATION_EMPTY).eq(Location::getContainerCode, QuantityConstant.EMPTY_STRING); + int count = count(locationLambdaQueryWrapper); + return count; + } + + @Override public Location getEmptyInsideLocation(Location location) { LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery(); locationLambdaQueryWrapper.eq(Location::getWarehouseCode, location.getWarehouseCode()).eq(Location::getRoadWay, location.getRoadWay()) diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/entity/TaskHeader.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/entity/TaskHeader.java index 2695f52..29a5aec 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/entity/TaskHeader.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/task/taskHeader/entity/TaskHeader.java @@ -142,6 +142,8 @@ public class TaskHeader implements Serializable { private String exceptionName; @ApiModelProperty(value = "异常状态") private Integer exceptionState; + @ApiModelProperty(value = "巷道") + private Integer roadWay; /** 备用字段1 */ @Excel(name = "备用字段1", width = 15) @ApiModelProperty(value = "备用字段1") diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/StringUtils.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/StringUtils.java index cf3b904..06510c3 100644 --- a/huaheng-wms-core/src/main/java/org/jeecg/utils/StringUtils.java +++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/StringUtils.java @@ -327,6 +327,24 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils { } /** + * 字符串有小写 + */ + public static boolean havaLowerCase(String str) { + int strLen; + boolean have = false; + if (str == null || (strLen = str.length()) == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + char charAt = str.charAt(i); + if (Character.isLowerCase(charAt)) { + return true; + } + } + return false; + } + + /** * 驼峰式命名法 例如:user_name->userName */ public static String toCamelCase(String s) {