diff --git a/src/main/java/com/wms/constants/enums/VehicleStatus.java b/src/main/java/com/wms/constants/enums/VehicleStatus.java index 4118d14..e0f10a0 100644 --- a/src/main/java/com/wms/constants/enums/VehicleStatus.java +++ b/src/main/java/com/wms/constants/enums/VehicleStatus.java @@ -1,8 +1,11 @@ package com.wms.constants.enums; +import lombok.Getter; + /** * 载具状态 */ +@Getter public enum VehicleStatus { IN(1, "入库中"), ON(2, "在库中"), @@ -19,11 +22,4 @@ public enum VehicleStatus { this.value = value; } - public Integer getCode() { - return code; - } - - public String getValue() { - return value; - } } diff --git a/src/main/java/com/wms/controller/TaskController.java b/src/main/java/com/wms/controller/TaskController.java index f441f83..2a534eb 100644 --- a/src/main/java/com/wms/controller/TaskController.java +++ b/src/main/java/com/wms/controller/TaskController.java @@ -11,6 +11,7 @@ import com.wms.entity.app.*; import com.wms.entity.app.dto.PageDto; import com.wms.entity.app.dto.StockOfGoodsDto; import com.wms.entity.app.dto.extend.StockDetailInfo; +import com.wms.entity.app.dto.extend.VehicleDetailInfo; import com.wms.entity.app.request.*; import com.wms.entity.app.vo.*; import com.wms.entity.app.wcs.*; @@ -188,7 +189,7 @@ public class TaskController { response.setMessage("入库请求验证错误!" + validationInfo); return convertJsonString(response); } - // 查找当前箱子是否有其他等待入库的箱子 + // 查找当前箱子是否有其他等待入库的任务 Task sameVehicleTempTask = taskService.getOne(new LambdaQueryWrapper() .eq(Task::getVehicleId, taskInRequest.getVehicleId()) .eq(Task::getTaskStatus, WmsTaskStatus.TEMP.getCode()) @@ -356,6 +357,7 @@ public class TaskController { newStock.setIsInventory(0); newStock.setCreateTime(LocalDateTime.now()); newStock.setWeight(inTask.getWeight()); + newStock.setGoodsType(inTask.getGoodsRelated().getGoodsType()); StockDetailInfo detailInfo = new StockDetailInfo(); detailInfo.setGoodsId(inTask.getGoodsRelated().getGoodsId()); detailInfo.setGoodsName(inTask.getGoodsRelated().getGoodsName()); @@ -433,6 +435,16 @@ public class TaskController { } else { newVehicle.setIsEmpty(1); } + // 设置当前料箱的类型 + if (inTask.getGoodsRelated() != null && inTask.getGoodsRelated().getGoodsType() != null && inTask.getGoodsRelated().getGoodsId() != null) { + newVehicle.setVehicleType(inTask.getGoodsRelated().getGoodsType()); + if (Objects.equals(newVehicle.getVehicleType(), "间接物料")) { + // 如果是间接物料,则设置配对物料 + List vehicleDetailInfos = new ArrayList<>(); + vehicleDetailInfos.add(new VehicleDetailInfo(inTask.getGoodsRelated().getGoodsId())); + newVehicle.setDetails(vehicleDetailInfos); + } + } newVehicle.setLastInTime(LocalDateTime.now()); vehicleService.save(newVehicle); } else { @@ -449,6 +461,17 @@ public class TaskController { } else { currentVehicle.setIsEmpty(1); } + if (inTask.getGoodsRelated() != null && inTask.getGoodsRelated().getGoodsType() != null && inTask.getGoodsRelated().getGoodsId() != null) { + currentVehicle.setVehicleType(inTask.getGoodsRelated().getGoodsType()); + if (Objects.equals(currentVehicle.getVehicleType(), "间接物料")) { + // 如果是间接物料,则设置配对物料 + List vehicleDetailInfos = currentVehicle.getDetails() == null ? new ArrayList<>() : currentVehicle.getDetails(); + if (!vehicleDetailInfos.stream().map(VehicleDetailInfo::getGoodsId).toList().contains(inTask.getGoodsRelated().getGoodsId())) { + vehicleDetailInfos.add(new VehicleDetailInfo(inTask.getGoodsRelated().getGoodsId())); + currentVehicle.setDetails(vehicleDetailInfos); + } + } + } currentVehicle.setLastInTime(LocalDateTime.now()); vehicleService.update(currentVehicle, new LambdaUpdateWrapper().eq(Vehicle::getVehicleId, currentVehicle.getVehicleId())); } @@ -472,6 +495,8 @@ public class TaskController { // 非出库任务跳过 continue; } + // 查询到当前料箱 + Vehicle outVehicle = vehicleService.getOne(new LambdaQueryWrapper().eq(Vehicle::getVehicleId, outTask.getVehicleId())); if (outTask.getIsPicking() == 1) { // 当前载具设置为出库中状态 vehicleService.update(new LambdaUpdateWrapper() @@ -513,10 +538,12 @@ public class TaskController { // 删除出库任务 taskService.remove(new LambdaQueryWrapper().eq(Task::getTaskId, outTask.getTaskId())); // 释放原来的库位 - locationService.update(new LambdaUpdateWrapper() - .set(Location::getLocationStatus, LocationStatus.EMPTY.getCode()) - .set(Location::getVehicleId, "") - .eq(Location::getLocationId, outTask.getOrigin())); + if (outVehicle == null || !Objects.equals(outVehicle.getVehicleType(), "间接物料")) { + locationService.update(new LambdaUpdateWrapper() + .set(Location::getLocationStatus, LocationStatus.EMPTY.getCode()) + .set(Location::getVehicleId, "") + .eq(Location::getLocationId, outTask.getOrigin())); + } } } // 移库任务完成 @@ -608,7 +635,7 @@ public class TaskController { // 请求可用库位 String nextLocationId = ""; for (int i = 0; i < locationService.count(new LambdaQueryWrapper().eq(Location::getLocationStatus, LocationStatus.EMPTY.getCode())); i++) { - Map resultMap = locationService.getOneLocation("", ""); + Map resultMap = locationService.getOneLocation("", wcsVehicleInRequest.getVehicleNo(), ""); if (resultMap.isEmpty() || !resultMap.containsKey("nextLocationId")) { logger.error("暂无可用库位"); response.setCode(ResponseCode.ERROR.getCode()); @@ -616,6 +643,10 @@ public class TaskController { return convertJsonString(response); } else { Location nextLocation = locationService.getOne(new LambdaQueryWrapper().eq(Location::getLocationId, resultMap.get("nextLocationId")).last("limit 1")); + if (Objects.equals(nextLocation.getLocationStatus(), LocationStatus.OCCUPY.getCode()) && nextLocation.getVehicleId().equals(wcsVehicleInRequest.getVehicleNo())) { + nextLocationId = resultMap.get("nextLocationId"); + break; + } LambdaUpdateWrapper updateLocationWrapper = new LambdaUpdateWrapper() .set(Location::getLocationStatus, LocationStatus.OCCUPY.getCode()) .set(Location::getVehicleId, wcsVehicleInRequest.getVehicleNo()) @@ -695,7 +726,7 @@ public class TaskController { // 请求可用库位 String nextLocationId = ""; for (int i = 0; i < locationService.count(new LambdaQueryWrapper().eq(Location::getLocationStatus, LocationStatus.EMPTY.getCode())); i++) { - Map resultMap = locationService.getOneLocation("", ""); + Map resultMap = locationService.getOneLocation("", duplicateLocationRequest.getVehicleId(), ""); if (resultMap.isEmpty() || !resultMap.containsKey("nextLocationId")) { logger.error("暂无可用库位"); response.setCode(ResponseCode.ERROR.getCode()); @@ -703,6 +734,10 @@ public class TaskController { return convertJsonString(response); } else { Location nextLocation = locationService.getOne(new LambdaQueryWrapper().eq(Location::getLocationId, resultMap.get("nextLocationId")).last("limit 1")); + if (Objects.equals(nextLocation.getLocationStatus(), LocationStatus.OCCUPY.getCode()) && nextLocation.getVehicleId().equals(duplicateLocationRequest.getVehicleId())) { + nextLocationId = resultMap.get("nextLocationId"); + break; + } LambdaUpdateWrapper updateLocationWrapper = new LambdaUpdateWrapper() .set(Location::getLocationStatus, LocationStatus.OCCUPY.getCode()) .set(Location::getVehicleId, duplicateLocationRequest.getVehicleId()) @@ -2289,11 +2324,15 @@ public class TaskController { String nextLocationId = ""; int emptyLocationSize = (int) locationService.count(new LambdaQueryWrapper().eq(Location::getLocationStatus, LocationStatus.EMPTY.getCode())); for (int i = 0; i < emptyLocationSize; i++) { - Map resultMap = locationService.getOneLocation("", ""); + Map resultMap = locationService.getOneLocation("", vehicleId, ""); if (resultMap.isEmpty() || !resultMap.containsKey("nextLocationId")) { return ""; } else { Location nextLocation = locationService.getOne(new LambdaQueryWrapper().eq(Location::getLocationId, resultMap.get("nextLocationId")).last("limit 1")); + if (Objects.equals(nextLocation.getLocationStatus(), LocationStatus.OCCUPY.getCode()) && nextLocation.getVehicleId().equals(vehicleId)) { + nextLocationId = resultMap.get("nextLocationId"); + break; + } LambdaUpdateWrapper updateLocationWrapper = new LambdaUpdateWrapper() .set(Location::getLocationStatus, LocationStatus.OCCUPY.getCode()) .set(Location::getVehicleId, vehicleId) diff --git a/src/main/java/com/wms/entity/app/dto/extend/TaskDetailInfo.java b/src/main/java/com/wms/entity/app/dto/extend/TaskDetailInfo.java index 20a63c6..3611b30 100644 --- a/src/main/java/com/wms/entity/app/dto/extend/TaskDetailInfo.java +++ b/src/main/java/com/wms/entity/app/dto/extend/TaskDetailInfo.java @@ -22,4 +22,8 @@ public class TaskDetailInfo { * 原库存剩余数量 */ private BigDecimal originNum; + /** + * 物料类型 + */ + private String goodsType; } diff --git a/src/main/java/com/wms/entity/app/dto/extend/VehicleDetailInfo.java b/src/main/java/com/wms/entity/app/dto/extend/VehicleDetailInfo.java index 6869970..09ad0d8 100644 --- a/src/main/java/com/wms/entity/app/dto/extend/VehicleDetailInfo.java +++ b/src/main/java/com/wms/entity/app/dto/extend/VehicleDetailInfo.java @@ -1,18 +1,14 @@ package com.wms.entity.app.dto.extend; +import lombok.AllArgsConstructor; import lombok.Data; /** * 料箱详细信息 */ @Data +@AllArgsConstructor public class VehicleDetailInfo { - /// 上 - private String up; - /// 下 - private String down; - /// 左右 - private String left; - /// 右 - private String right; + /// 料号 + private String goodsId; } diff --git a/src/main/java/com/wms/entity/app/vo/StockVo.java b/src/main/java/com/wms/entity/app/vo/StockVo.java index 9d9e44c..1cf72a9 100644 --- a/src/main/java/com/wms/entity/app/vo/StockVo.java +++ b/src/main/java/com/wms/entity/app/vo/StockVo.java @@ -98,6 +98,11 @@ public class StockVo { */ @JsonProperty("totalNum") private BigDecimal totalNum; + /** + * 物料类型 + */ + @JsonProperty("goodsType") + private String goodsType; /** * 从数据库实体转换为前端显示 @@ -122,6 +127,7 @@ public class StockVo { stockVo.setGoodsStatus(stockPo.getGoodsRelated().getGoodsStatus()); stockVo.setRemainNum(stockPo.getGoodsRelated().getRemainNum()); stockVo.setTotalNum(stockPo.getGoodsRelated().getTotalNum()); + stockVo.setGoodsType(stockPo.getGoodsType()); return stockVo; } } diff --git a/src/main/java/com/wms/entity/app/vo/VehicleVO.java b/src/main/java/com/wms/entity/app/vo/VehicleVO.java index 3551d05..76de863 100644 --- a/src/main/java/com/wms/entity/app/vo/VehicleVO.java +++ b/src/main/java/com/wms/entity/app/vo/VehicleVO.java @@ -6,6 +6,7 @@ import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; +import java.util.List; /** * 载具VO @@ -35,7 +36,7 @@ public class VehicleVO { /** * 额外信息 */ - private VehicleDetailInfo details; + private List details; /** * 上次入库时间 */ diff --git a/src/main/java/com/wms/entity/table/Location.java b/src/main/java/com/wms/entity/table/Location.java index de77a10..7e472bd 100644 --- a/src/main/java/com/wms/entity/table/Location.java +++ b/src/main/java/com/wms/entity/table/Location.java @@ -66,4 +66,9 @@ public class Location { */ @TableField("vehicle_id") private String vehicleId; + /** + * 物料类型 + */ + @TableField("goods_type") + private String goodsType; } diff --git a/src/main/java/com/wms/entity/table/Stock.java b/src/main/java/com/wms/entity/table/Stock.java index ff8e9ac..275d40b 100644 --- a/src/main/java/com/wms/entity/table/Stock.java +++ b/src/main/java/com/wms/entity/table/Stock.java @@ -77,4 +77,9 @@ public class Stock { */ @TableField(value = "goods_related", typeHandler = Fastjson2TypeHandler.class) private StockDetailInfo goodsRelated; + /** + * 物料类型 + */ + @TableField("goods_type") + private String goodsType; } diff --git a/src/main/java/com/wms/entity/table/Vehicle.java b/src/main/java/com/wms/entity/table/Vehicle.java index 979e318..9bab7b9 100644 --- a/src/main/java/com/wms/entity/table/Vehicle.java +++ b/src/main/java/com/wms/entity/table/Vehicle.java @@ -8,6 +8,7 @@ import com.wms.entity.app.dto.extend.VehicleDetailInfo; import lombok.Data; import java.time.LocalDateTime; +import java.util.List; /** * 载具 @@ -44,7 +45,7 @@ public class Vehicle { * 额外信息 */ @TableField(value = "details", typeHandler = Fastjson2TypeHandler.class) - private VehicleDetailInfo details; + private List details; /** * 上次入库时间 */ diff --git a/src/main/java/com/wms/service/LocationService.java b/src/main/java/com/wms/service/LocationService.java index 177448f..7dc5e48 100644 --- a/src/main/java/com/wms/service/LocationService.java +++ b/src/main/java/com/wms/service/LocationService.java @@ -12,8 +12,9 @@ public interface LocationService extends IService { /** * 查找一个可用库位 * @param inPoint 入库站点 + * @param vehicleId 箱号 * @param goodsId 物料编号--可选 * @return 结果 nextLocationId, preTaskId */ - Map getOneLocation(String inPoint, String goodsId); + Map getOneLocation(String inPoint, String vehicleId, String goodsId); } diff --git a/src/main/java/com/wms/service/business/serviceImplements/ValidateServiceImplements.java b/src/main/java/com/wms/service/business/serviceImplements/ValidateServiceImplements.java index c29962c..1b4cc41 100644 --- a/src/main/java/com/wms/service/business/serviceImplements/ValidateServiceImplements.java +++ b/src/main/java/com/wms/service/business/serviceImplements/ValidateServiceImplements.java @@ -2,6 +2,7 @@ package com.wms.service.business.serviceImplements; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.wms.constants.enums.*; +import com.wms.entity.app.dto.extend.VehicleDetailInfo; import com.wms.entity.app.request.GoodsInRequest; import com.wms.entity.app.request.TaskInRequest; import com.wms.entity.app.request.TaskOutRequest; @@ -20,6 +21,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import static com.wms.constants.WmsConstants.MYSQL_JSON_CI; @@ -54,8 +57,8 @@ public class ValidateServiceImplements implements IValidateService { return TaskInValidationEnum.NO_VEHICLE_ID.getErrorMessage(); } // 验证载具号是否重复入库 - if (vehicleService.exists(new LambdaQueryWrapper().eq(Vehicle::getVehicleId, taskInRequest.getVehicleId()) - .and(wrapper -> wrapper.eq(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode())))) { + Vehicle existVehicle = vehicleService.getOne(new LambdaQueryWrapper().eq(Vehicle::getVehicleId, taskInRequest.getVehicleId()).last("limit 1")); + if (existVehicle != null && Objects.equals(existVehicle.getVehicleStatus(), VehicleStatus.ON.getCode())) { return TaskInValidationEnum.DUPLICATE_VEHICLE_ID.getErrorMessage(); } // 如果这个箱子还有拣选任务,不允许操作 @@ -71,15 +74,41 @@ public class ValidateServiceImplements implements IValidateService { } // 验证物料信息 if (taskInRequest.getGoodsList() != null && !taskInRequest.getGoodsList().isEmpty()) { + // 判断当前入库的箱子是什么类型 + int goodsType = 0; + List canInGoodsIdList = new ArrayList<>(); + if (existVehicle != null) { + if (!Objects.equals(existVehicle.getVehicleType(), "间接物料")) { + goodsType = 1; + } else { + goodsType = 2; + if (existVehicle.getDetails() != null) { + canInGoodsIdList = existVehicle.getDetails().stream().map(VehicleDetailInfo::getGoodsId).toList(); + } + } + } for (GoodsInRequest goodsInRequest : taskInRequest.getGoodsList()) { // 验证物料编号 if (StringUtils.isEmpty(goodsInRequest.getGoodsId())) { return TaskInValidationEnum.NO_GOODS_ID.getErrorMessage(); } else { + if (!canInGoodsIdList.isEmpty() && !canInGoodsIdList.contains(goodsInRequest.getGoodsId())) { + return "当前料箱是间接物料料箱,当前物料不在绑定物料内。"; + } Goods goods = goodsService.getOne(new LambdaQueryWrapper().eq(Goods::getGoodsId, goodsInRequest.getGoodsId())); if (goods == null) { return TaskInValidationEnum.ERROR_GOODS_ID.getErrorMessage(); } + if (goodsType == 0) { + goodsType = Objects.equals(goods.getGoodsType(), "间接物料") ? 2 : 1; + } else { + if (goodsType == 1 && Objects.equals(goods.getGoodsType(), "间接物料")) { + return "间接物料和直接物料无法一起入库。"; + } + if (goodsType == 2 && !Objects.equals(goods.getGoodsType(), "间接物料")) { + return "直接物料和间接物料无法一起入库。"; + } + } // TODO 超重验证 // // 验证重量 // BigDecimal max_weight = BigDecimal.valueOf(10000000); diff --git a/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java b/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java index 0d09fc9..f18e57e 100644 --- a/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java +++ b/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java @@ -113,6 +113,7 @@ public class WmsTaskServiceImplements implements IWmsTaskService { goodsRelatedInfo.setGoodsName(goods.getGoodsName()); goodsRelatedInfo.setOpNum(goodsInRequest.getGoodsNum()); goodsRelatedInfo.setOriginNum(BigDecimal.ZERO); + goodsRelatedInfo.setGoodsType(goods.getGoodsType()); tempInTask.setGoodsRelated(goodsRelatedInfo); tempTasks.add(tempInTask); diff --git a/src/main/java/com/wms/service/serviceImplements/LocationServiceImplements.java b/src/main/java/com/wms/service/serviceImplements/LocationServiceImplements.java index d6385de..d8471e5 100644 --- a/src/main/java/com/wms/service/serviceImplements/LocationServiceImplements.java +++ b/src/main/java/com/wms/service/serviceImplements/LocationServiceImplements.java @@ -6,14 +6,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.wms.constants.enums.StockStatus; import com.wms.constants.enums.TaskType; import com.wms.constants.enums.WmsTaskStatus; -import com.wms.entity.table.Location; -import com.wms.entity.table.Stand; -import com.wms.entity.table.Stock; -import com.wms.entity.table.Task; -import com.wms.mapper.LocationMapper; -import com.wms.mapper.StandMapper; -import com.wms.mapper.StockMapper; -import com.wms.mapper.TaskMapper; +import com.wms.entity.table.*; +import com.wms.mapper.*; import com.wms.service.LocationService; import com.wms.utils.StringUtils; import lombok.RequiredArgsConstructor; @@ -45,17 +39,22 @@ public class LocationServiceImplements extends ServiceImpl getOneLocation(String inPoint, String goodsId) { + public Map getOneLocation(String inPoint, String vehicleId, String goodsId) { Map resultMap = new HashMap<>(); // 添加对应设备的查询条件 int equipmentId = -1; @@ -71,7 +70,7 @@ public class LocationServiceImplements extends ServiceImpl stackerList = standMapper.selectList(new LambdaQueryWrapper() @@ -109,13 +108,8 @@ public class LocationServiceImplements extends ServiceImpl() - .set(Stand::getLastUseTime, LocalDateTime.now()) - .eq(Stand::getEquipmentId, mostEmptyStackerId) - .eq(Stand::getStandType, 3)); break; } runningTaskNumToEquipmentMap.remove(mostEmptyStackerId); @@ -159,8 +153,61 @@ public class LocationServiceImplements extends ServiceImpl getOneLocationByEquipmentId(Map resultMap, int equipmentId) { + private Map getOneLocationByEquipmentId(Map resultMap, int equipmentId, String vehicleId) { resultMap.clear(); + // 查询当前的料箱是否存在 + if (StringUtils.isNotEmpty(vehicleId)) { + Vehicle exsitVehicle = vehicleMapper.selectOne(new LambdaQueryWrapper() + .eq(Vehicle::getVehicleId, vehicleId).last("limit 1")); + if (exsitVehicle != null) { + if (Objects.equals(exsitVehicle.getVehicleType(), "间接物料")) { + LambdaQueryWrapper locationQueryWrapper = new LambdaQueryWrapper().eq(Location::getLocationId, exsitVehicle.getCurrentLocation()); + List availableLocations = locationMapper.selectList(locationQueryWrapper); + for (Location oneAvailableLocation : availableLocations) { + resultMap.put("nextLocationId", oneAvailableLocation.getLocationId()); + standMapper.update(new LambdaUpdateWrapper() + .set(Stand::getLastUseTime, LocalDateTime.now()) + .eq(Stand::getEquipmentId, equipmentId) + .eq(Stand::getStandType, 3)); + break; + } + return resultMap; + } + } else { + // 判断当前料箱是不是承载的是间接物料的任务 + List tasks = taskMapper.selectList(new LambdaQueryWrapper() + .eq(Task::getVehicleId, vehicleId) + .eq(Task::getTaskType, TaskType.IN.getCode())); + boolean isIndirect = false; + for (Task task : tasks) { + if (Objects.equals(task.getGoodsRelated().getGoodsType(), "间接物料")) { + isIndirect = true; + break; + } + } + if (isIndirect) { + LambdaQueryWrapper locationQueryWrapper = new LambdaQueryWrapper() + .eq(Location::getGoodsType, "间接物料") + .eq(Location::getAreaId, 1) + .eq(Location::getLocationStatus, 0) + .eq(Location::getLocationType, 1) + .eq(Location::getIsLock, 0) + .eq(Location::getEquipmentId, equipmentId) + .orderByDesc(Location::getWDepth) + .orderByAsc(List.of(Location::getWCol, Location::getWLayer, Location::getWRow)); + List availableLocations = locationMapper.selectList(locationQueryWrapper); + for (Location oneAvailableLocation : availableLocations) { + resultMap.put("nextLocationId", oneAvailableLocation.getLocationId()); + standMapper.update(new LambdaUpdateWrapper() + .set(Stand::getLastUseTime, LocalDateTime.now()) + .eq(Stand::getEquipmentId, equipmentId) + .eq(Stand::getStandType, 3)); + break; + } + return resultMap; + } + } + } LambdaQueryWrapper locationQueryWrapper = new LambdaQueryWrapper() .eq(Location::getAreaId, 1) .eq(Location::getLocationStatus, 0)