diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Point.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Point.java index 5d7afbd..760f27f 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Point.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/entity/Point.java @@ -93,6 +93,22 @@ public class Point implements Serializable { @Schema(description = "位置坐标y") private java.lang.Integer positionY; + + /** + * 位置坐标x + */ + @Excel(name = "第二层坐标X", width = 15) + @Schema(description = "位置坐标x") + private java.lang.Integer positionTwoX; + + /** + * 位置坐标y + */ + @Excel(name = "第二层坐标Y", width = 15) + @Schema(description = "第二层坐标Y") + private java.lang.Integer positionTwoY; + + /** * 是否双通道 * 0-单通道 1-双通道 diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/mapper/PointMapper.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/mapper/PointMapper.java index 7a8552e..ea4bd2f 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/mapper/PointMapper.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/mapper/PointMapper.java @@ -48,4 +48,5 @@ public interface PointMapper extends BaseMapper { @Select("SELECT * FROM base_point WHERE col_num = #{colNum} AND layer_num = #{layerNum} ORDER BY row_num ASC") List findByColAndLayer(@Param("colNum") String colNum, @Param("layerNum") String layerNum); + } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/processor/BatchProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/processor/BatchProcessor.java index 51a0f12..f45cb15 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/processor/BatchProcessor.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/base/service/processor/BatchProcessor.java @@ -7,6 +7,8 @@ import org.cpte.modules.base.entity.Point; import org.cpte.modules.base.entity.Stock; import org.cpte.modules.base.mapper.PointMapper; import org.cpte.modules.base.mapper.StockMapper; +import org.cpte.modules.constant.enums.CommonStatusEnum; +import org.cpte.modules.constant.enums.TaskTypeEnum; import org.cpte.modules.inventory.entity.Inventory; import org.cpte.modules.inventory.mapper.InventoryMapper; import org.cpte.modules.inventoryLog.entity.InventoryLog; @@ -142,6 +144,7 @@ public class BatchProcessor { if (CollectionUtils.isNotEmpty(updateToPickDetail)) { batchUtil.updateBatchPickDetail(updateToPickDetail); } + if (CollectionUtils.isNotEmpty(deleteToTask)) { taskMapper.deleteByIds(deleteToTask); } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/CommonStatusEnum.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/CommonStatusEnum.java index 1d2fca5..aa34fd2 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/CommonStatusEnum.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/constant/enums/CommonStatusEnum.java @@ -14,6 +14,10 @@ public enum CommonStatusEnum { USED(1, "占用"), + ONE(1, "一层"), + + TWO(2, "二层"), + ; /** * 值 diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/service/processor/ScanTrayProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/service/processor/ScanTrayProcessor.java index c33d0b9..beaaa23 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/service/processor/ScanTrayProcessor.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/service/processor/ScanTrayProcessor.java @@ -17,6 +17,7 @@ import org.cpte.modules.constant.enums.*; import org.cpte.modules.conveyorLine.request.ScanTrayRequest; import org.cpte.modules.conveyorLine.vo.PointScore; import org.cpte.modules.conveyorLine.vo.ScanTrayData; +import org.cpte.modules.conveyorLine.vo.Station; import org.cpte.modules.inventory.entity.Inventory; import org.cpte.modules.inventory.mapper.InventoryMapper; import org.cpte.modules.receive.entity.Asn; @@ -28,6 +29,7 @@ import org.springframework.stereotype.Service; import java.util.*; import java.util.stream.Collectors; +import java.util.stream.Stream; /** * 扫描托盘处理 @@ -78,7 +80,7 @@ public class ScanTrayProcessor { // 4.智能分配库位 String areaCode = getAreaCode(data.getAsn().getOrderType()); - Point dstPoint = allocatePoint(data.getItemKeys(), data.getStation(), areaCode); + Point dstPoint = allocatePoint(data.getItemKeys(), data.getStation(), areaCode, BusinessTypeEnum.INBOUND.getValue()); // 5.生成TES任务 agvTaskService.processAgvTask(data, dstPoint); @@ -192,21 +194,63 @@ public class ScanTrayProcessor { * * @param itemKeys 物料属性 * @param station 工作站 + * @param areaCode 库区 + * @param type 业务类型 * @return 目标库位 */ - public Point allocatePoint(List itemKeys, Point station, String areaCode) { - //1.优先寻找同物料/同仓库/同项目号/同任务号/同批次/同外部库存状态 + public Point allocatePoint(List itemKeys, Point station, String areaCode, String type) { + //1.优先寻找同物料/同仓库/同项目号/同任务号/同批次/同外部库存状态的库位 List itemKeyIds = itemKeys.stream().map(ItemKey::getId).toList(); List availablePoints = pointService.findClusterPoint(itemKeyIds, areaCode); if (CollectionUtils.isEmpty(availablePoints)) { //2.获取所有可用库位 availablePoints = pointMapper.queryPoints(null, CommonStatusEnum.FREE.getValue(), areaCode); } - //根据巷到分组,得到每个巷道有多个库位,<巷道编号,库位个数> + //根据巷道分组,得到每个巷道有多个库位,<巷道编号,库位个数> Map colMap = getColMap(areaCode); - List scoredPoints = availablePoints.stream() - .map(point -> clusterPointScore(point, station, itemKeys, colMap)) + //根据layerNum层来分组 + Map> layerMap = availablePoints.stream().collect(Collectors.groupingBy(Point::getLayerNum)); + + List firstScoredPoints = new ArrayList<>(); + List secondScoredPoints = new ArrayList<>(); + + //移位选择最优库位 + if (type.equals(BusinessTypeEnum.MOVE.getValue())) { + String layerNum = station.getLayerNum(); + Station currentStation = new Station(station.getPositionX(), station.getPositionY()); + List firstLevelPoints = layerMap.get(layerNum); + if (CollectionUtils.isNotEmpty(firstLevelPoints)) { + firstScoredPoints = firstLevelPoints.stream() + .map(point -> clusterPointScore(point, currentStation, itemKeys, colMap)) + .toList(); + } + } else { + //入库选择最优库位 + //计算第一层的库位分数 + Station firstStation = new Station(station.getPositionX(), station.getPositionY()); + List firstLevelPoints = layerMap.get(String.valueOf(CommonStatusEnum.ONE.getValue())); + if (CollectionUtils.isNotEmpty(firstLevelPoints)) { + firstScoredPoints = firstLevelPoints.stream() + .map(point -> clusterPointScore(point, firstStation, itemKeys, colMap)) + .toList(); + } + + //计算第二层的库位分数 + Station secondStation = new Station(station.getPositionTwoX(), station.getPositionTwoY()); + List secondLevelPoints = layerMap.get(String.valueOf(CommonStatusEnum.TWO.getValue())); + if (CollectionUtils.isNotEmpty(secondLevelPoints)) { + secondScoredPoints = secondLevelPoints.stream() + .map(point -> clusterPointScore(point, secondStation, itemKeys, colMap)) + .toList(); + } + } + + //合并获取最优库位 + List scoredPoints = Stream.concat( + firstScoredPoints.stream(), + secondScoredPoints.stream() + ) .sorted(Comparator.comparing(PointScore::getScore).reversed()) .toList(); @@ -221,7 +265,7 @@ public class ScanTrayProcessor { /** * 库位评分计算 */ - private PointScore clusterPointScore(Point point, Point station, List itemKeys, Map colMap) { + private PointScore clusterPointScore(Point point, Station station, List itemKeys, Map colMap) { double totalScore; // 1. 距离评分 - 考虑从入库口到库位的距离 @@ -241,6 +285,7 @@ public class ScanTrayProcessor { totalScore = distanceScore + channelDepthScore + channelScore; log.info("【{}】库位总分:{} - 距离评分: {} - 通道深度策略评分: {} - 通道类型评分: {} - 均衡评分: {} - 物料聚集评分: {}", point.getPointCode(), totalScore, distanceScore, channelDepthScore, channelScore, 0, 0); + return new PointScore(point, totalScore); } @@ -406,11 +451,13 @@ public class ScanTrayProcessor { * 计算距离评分 * 基于入库口位置和库位坐标计算最短路径距离 */ - private double calculateClusterDistanceCost(Point point, Point station) { + + private double calculateClusterDistanceCost(Point point, Station station) { // 计算曼哈顿距离 double distance = Math.abs(point.getPositionX() - station.getPositionX()) + Math.abs(point.getPositionY() - station.getPositionY()); + // 使用更大的标准化参数(根据实际坐标范围) - double normalizationFactor = 250000.0; // 或使用动态计算的最大距离值 + double normalizationFactor = 300000.0; // 距离越小分数越高 return Math.max(0, 100 - (distance / normalizationFactor) * 100); } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/vo/Station.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/vo/Station.java new file mode 100644 index 0000000..65752f5 --- /dev/null +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/conveyorLine/vo/Station.java @@ -0,0 +1,13 @@ +package org.cpte.modules.conveyorLine.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import org.cpte.modules.base.entity.Point; +@Data +@AllArgsConstructor +public class Station { + // X坐标 + private Integer positionX; + // Y坐标 + private Integer positionY; +} diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/controller/InventoryController.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/controller/InventoryController.java index 84de44a..72e5165 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/controller/InventoryController.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/controller/InventoryController.java @@ -12,7 +12,12 @@ import java.net.URLDecoder; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.cpte.modules.base.entity.ItemKey; +import org.cpte.modules.base.entity.Point; +import org.cpte.modules.base.entity.Stock; +import org.cpte.modules.base.mapper.PointMapper; +import org.cpte.modules.base.mapper.StockMapper; import org.cpte.modules.base.service.IItemKeyService; +import org.cpte.modules.constant.enums.CommonStatusEnum; import org.jeecg.common.api.vo.Result; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.query.QueryRuleEnum; @@ -53,12 +58,19 @@ import org.apache.shiro.authz.annotation.RequiresPermissions; @RequestMapping("/inventory") @Slf4j public class InventoryController extends JeecgController { + @Autowired + private StockMapper stockMapper; + + @Autowired + private PointMapper pointMapper; + @Autowired private IInventoryService inventoryService; @Autowired private IItemKeyService itemKeyService; + /** * 分页列表查询 * @@ -125,6 +137,15 @@ public class InventoryController extends JeecgController edit(@RequestBody Inventory inventory) { + Inventory oldInventory = inventoryService.getById(inventory.getId()); + Point oldPoint = pointMapper.selectById(oldInventory.getPointId()); + Point newPoint = pointMapper.selectById(inventory.getPointId()); + if(!oldPoint.getId().equals(newPoint.getId())){ + oldPoint.setStatus(CommonStatusEnum.FREE.getValue()); + pointMapper.updateById(oldPoint); + newPoint.setStatus(CommonStatusEnum.USED.getValue()); + pointMapper.updateById(newPoint); + } ItemKey itemKey = itemKeyService.createItemKey(inventory.getItemId(), inventory.getWhCode(), inventory.getProject(), inventory.getTaskNo(), inventory.getPropC1(), inventory.getPropC3()); inventory.setItemKeyId(itemKey.getId()); inventoryService.updateById(inventory); @@ -142,6 +163,17 @@ public class InventoryController extends JeecgController delete(@RequestParam(name = "id", required = true) String id) { + Inventory inventory = inventoryService.getById(id); + Stock stock = stockMapper.selectById(inventory.getStockId()); + if (stock != null) { + stock.setStatus(CommonStatusEnum.FREE.getValue()); + stockMapper.updateById(stock); + } + Point point = pointMapper.selectById(inventory.getPointId()); + if (point != null) { + point.setStatus(CommonStatusEnum.FREE.getValue()); + pointMapper.updateById(point); + } inventoryService.removeById(id); return Result.OK("删除成功!"); } @@ -157,7 +189,21 @@ public class InventoryController extends JeecgController deleteBatch(@RequestParam(name = "ids", required = true) String ids) { - this.inventoryService.removeByIds(Arrays.asList(ids.split(","))); + List invIds = Arrays.stream(ids.split(",")).map(Long::parseLong).toList(); + List inventories = inventoryService.listByIds(invIds); + for (Inventory inventory : inventories) { + Stock stock = stockMapper.selectById(inventory.getStockId()); + if (stock != null) { + stock.setStatus(CommonStatusEnum.FREE.getValue()); + stockMapper.updateById(stock); + } + Point point = pointMapper.selectById(inventory.getPointId()); + if (point != null) { + point.setStatus(CommonStatusEnum.FREE.getValue()); + pointMapper.updateById(point); + } + } + this.inventoryService.removeByIds(invIds); return Result.OK("批量删除成功!"); } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/IInventoryService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/IInventoryService.java index 03bfbd1..2267dae 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/IInventoryService.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/IInventoryService.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import org.cpte.modules.receive.entity.Asn; import org.cpte.modules.receive.entity.AsnDetail; import org.cpte.modules.receive.entity.ReceiveRecord; +import org.cpte.modules.shipping.entity.Task; import java.math.BigDecimal; import java.util.List; @@ -53,4 +54,10 @@ public interface IInventoryService extends IService { * @param stockIds 容器ID */ void deleteByStockIds(List stockIds); + + /** + * 移动库存 + * @param tasks 移位任务 + */ + void moveInventory(List tasks); } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/impl/InventoryServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/impl/InventoryServiceImpl.java index c5b14e9..df88e15 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/impl/InventoryServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/inventory/service/impl/InventoryServiceImpl.java @@ -2,12 +2,17 @@ package org.cpte.modules.inventory.service.impl; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import org.apache.commons.collections4.CollectionUtils; +import org.cpte.modules.base.entity.Point; +import org.cpte.modules.base.mapper.PointMapper; +import org.cpte.modules.constant.enums.CommonStatusEnum; import org.cpte.modules.constant.enums.InventoryStatusEnum; import org.cpte.modules.inventory.entity.Inventory; import org.cpte.modules.inventory.mapper.InventoryMapper; import org.cpte.modules.inventory.service.IInventoryService; import org.cpte.modules.receive.entity.Asn; import org.cpte.modules.receive.entity.ReceiveRecord; +import org.cpte.modules.shipping.entity.Task; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.transaction.annotation.Transactional; @@ -23,6 +28,9 @@ import java.util.*; */ @Service public class InventoryServiceImpl extends ServiceImpl implements IInventoryService { + @Autowired + private PointMapper pointMapper; + @Override public Inventory buildInventory(Long stockId, BigDecimal receivedQty, Asn asn, ReceiveRecord receiveRecord) { return Inventory.builder() @@ -82,5 +90,30 @@ public class InventoryServiceImpl extends ServiceImpl tasks) { + List updateToInventoryList = new ArrayList<>(); + List updateToPointList = new ArrayList<>(); + for (Task task : tasks) { + Inventory inventory = this.baseMapper.selectById(task.getInventoryId()); + inventory.setPointId(task.getToPointId()); + inventory.setStatus(InventoryStatusEnum.AVAILABLE.getValue()); + updateToInventoryList.add(inventory); + } + List srcPointIds = tasks.stream().map(Task::getFromPointId).distinct().toList(); + List srcPoints = pointMapper.selectByIds(srcPointIds); + for (Point point : srcPoints) { + point.setStatus(CommonStatusEnum.FREE.getValue()); + updateToPointList.add(point); + } + if (CollectionUtils.isNotEmpty(updateToInventoryList)) { + this.baseMapper.updateById(updateToInventoryList); + } + if (CollectionUtils.isNotEmpty(updateToPointList)) { + pointMapper.updateById(updateToPointList); + } + } + } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/mapper/AsnDetailMapper.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/mapper/AsnDetailMapper.java index 20b792f..211039b 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/mapper/AsnDetailMapper.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/mapper/AsnDetailMapper.java @@ -40,7 +40,6 @@ public interface AsnDetailMapper extends BaseMapper { * @param status 状态 * @return AsnDetail */ - @Select("select * from data_asn_detail where stock_id = #{stockId} and status = #{status} ") List queryByStockCode(@Param("stockId") Long stockId, @Param("status") Integer status); } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/mapper/xml/AsnDetailMapper.xml b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/mapper/xml/AsnDetailMapper.xml index 1b1af92..f33ca4f 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/mapper/xml/AsnDetailMapper.xml +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/receive/mapper/xml/AsnDetailMapper.xml @@ -15,4 +15,14 @@ WHERE asn_id = #{mainId} + + diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/InBoundTaskProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/InBoundTaskProcessor.java index 0c232d7..aedcbec 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/InBoundTaskProcessor.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/saiWms/service/processor/InBoundTaskProcessor.java @@ -11,13 +11,11 @@ import org.cpte.modules.base.service.IItemService; import org.cpte.modules.base.service.IPointService; import org.cpte.modules.base.service.IStockService; import org.cpte.modules.constant.GeneralConstant; -import org.cpte.modules.constant.enums.AgvVendorEnum; -import org.cpte.modules.constant.enums.AreaTypeEnum; -import org.cpte.modules.constant.enums.AsnOrderTypeEnum; -import org.cpte.modules.constant.enums.BusinessTypeEnum; +import org.cpte.modules.constant.enums.*; import org.cpte.modules.inventory.mapper.InventoryMapper; import org.cpte.modules.receive.entity.Asn; import org.cpte.modules.receive.entity.AsnDetail; +import org.cpte.modules.receive.mapper.AsnDetailMapper; import org.cpte.modules.receive.mapper.AsnMapper; import org.cpte.modules.receive.service.IAsnDetailService; import org.cpte.modules.receive.service.IAsnService; @@ -42,6 +40,9 @@ public class InBoundTaskProcessor { @Autowired private AsnMapper asnMapper; + @Autowired + private AsnDetailMapper asnDetailMapper; + @Autowired private InventoryMapper inventoryMapper; @@ -148,11 +149,24 @@ public class InBoundTaskProcessor { String lpn = lpns.iterator().next(); Stock stock = stockService.validateStock(lpn); if (inventoryMapper.exitsStockInventory(stock.getId()) != null) { - throw new RuntimeException("【" + lpn + "】托盘已入库"); + throw new RuntimeException("【" + lpn + "】托盘已入库,请勿下发"); + } + + //验证托盘未完成,不能继续下发当前托盘的任务 + List asnDetail = asnDetailMapper.queryByStockCode(stock.getId(), null); + boolean hasUnfinishedTask = asnDetail.stream().anyMatch(ad -> !isAsnCompleted(ad)); + if (hasUnfinishedTask) { + throw new RuntimeException("【" + lpn + "】托盘任务未完成,请勿下发"); } return stock; } + // 辅助方法 - 判断 ASN 是否已完成 + private boolean isAsnCompleted(AsnDetail asnDetail) { + return AsnStatusEnum.CLOSED.getValue().equals(asnDetail.getStatus()) + || AsnStatusEnum.CANCELED.getValue().equals(asnDetail.getStatus()); + } + /** * 验证任务号 * diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/TaskMapper.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/TaskMapper.java index f35ef33..a44ece8 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/TaskMapper.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/TaskMapper.java @@ -31,4 +31,6 @@ public interface TaskMapper extends BaseMapper { @Select("SELECT * FROM data_task WHERE pick_id = #{pickId} ") List queryTaskByMainId(@Param("pickId")Long pickId); + + List queryByInventoryIds(@Param("inventoryIds") List inventoryIds); } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/xml/TaskMapper.xml b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/xml/TaskMapper.xml index a3d938c..f589ed6 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/xml/TaskMapper.xml +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/mapper/xml/TaskMapper.xml @@ -8,4 +8,12 @@ #{pickId} + + \ No newline at end of file diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/ITaskService.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/ITaskService.java index 69b23f2..b68c574 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/ITaskService.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/ITaskService.java @@ -64,4 +64,6 @@ public interface ITaskService extends IService { * @return List */ List queryTaskByMainId(Long id); + + } diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/AllocateProcessor.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/AllocateProcessor.java index 243bc01..50895f5 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/AllocateProcessor.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/shipping/service/processor/AllocateProcessor.java @@ -6,6 +6,7 @@ import org.apache.commons.lang3.StringUtils; import org.cpte.modules.base.entity.*; import org.cpte.modules.base.mapper.AreaMapper; import org.cpte.modules.base.mapper.ItemKeyMapper; +import org.cpte.modules.base.mapper.PointMapper; import org.cpte.modules.base.service.IItemKeyService; import org.cpte.modules.base.service.IItemService; import org.cpte.modules.base.service.IPointService; @@ -22,6 +23,7 @@ import org.cpte.modules.shipping.entity.Pick; import org.cpte.modules.shipping.entity.PickDetail; import org.cpte.modules.shipping.entity.Task; import org.cpte.modules.shipping.mapper.PickDetailMapper; +import org.cpte.modules.shipping.mapper.TaskMapper; import org.cpte.modules.shipping.service.IPickDetailService; import org.cpte.modules.shipping.service.ITaskService; import org.cpte.modules.shipping.vo.AllocationData; @@ -46,12 +48,17 @@ public class AllocateProcessor { @Autowired private AreaMapper areaMapper; + @Autowired + private PointMapper pointMapper; + @Autowired private PickDetailMapper pickDetailMapper; @Autowired private ItemKeyMapper itemKeyMapper; + + @Autowired private InventoryMapper inventoryMapper; @@ -391,18 +398,6 @@ public class AllocateProcessor { .toList(); Map pointMap = pointService.queryByPointIdsToMap(pointIds); - // 按巷道和层分组 - Map> colLayerPointsMap = new HashMap<>(); - - for (Point point : pointMap.values()) { - String key = point.getColNum() + "-" + point.getLayerNum(); - if (colLayerPointsMap.containsKey(key)) { - continue; - } - List points = pointService.findByColAndLayer(point.getColNum(), point.getLayerNum()); - colLayerPointsMap.put(key, points); - } - //获取出库口的库位 List outPoints = pointService.queryPoints(null, null, AreaTypeEnum.CK_DOCK.getValue()); @@ -410,9 +405,7 @@ public class AllocateProcessor { return matchedInventories.stream() .map(inventory -> { Point currPoint = pointMap.get(inventory.getPointId()); - String key = currPoint.getColNum() + "-" + currPoint.getLayerNum(); - List points = colLayerPointsMap.get(key); - return calculateMoveCount(inventory, currPoint, points, outPoints); + return calculateMoveCount(inventory, currPoint, outPoints); }) //按分数倒序排序、移动次数升序排序 .sorted(Comparator.comparing(InventoryScore::getScore).reversed() @@ -426,10 +419,9 @@ public class AllocateProcessor { * * @param inventory 库存 * @param currPoint 当前库位 - * @param points 当前库位巷道的库位集合 * @return 库位位移次数 */ - private InventoryScore calculateMoveCount(Inventory inventory, Point currPoint, List points, List outPoints) { + private InventoryScore calculateMoveCount(Inventory inventory, Point currPoint, List outPoints) { // 位移分数 double moveScore; //移位库位 @@ -439,6 +431,9 @@ public class AllocateProcessor { Point bestPoint = getBestOutboundPoint(currPoint, outPoints); double distanceScore = calculateClusterDistanceCost(currPoint, bestPoint) * 0.3; + //当前巷道的库位数 + List points= pointMapper.findByColAndLayer(currPoint.getColNum(), currPoint.getLayerNum()); + // 目标库位的深度位转换为索引 int targetIndex = Integer.parseInt(currPoint.getRowNum()) - 1; @@ -729,6 +724,7 @@ public class AllocateProcessor { Point toPoint = allocatePoint(fromPoint, itemKeyMap.get(inv.getItemKeyId())); Task moveTask = taskService.bulidTask(taskNo, TaskTypeEnum.MOVE.getValue(), moveItem, fromPoint, toPoint, stock, null, null, inv.getItemKeyId(), inv.getId(), inv.getQuantity(), 0); moveList.add(moveTask); + pointService.bindPoint(toPoint); log.info("生成移位任务:{}- 容器:{} - 库位:{} - 库存数量:{}", taskNo, stock.getStockCode(), fromPoint.getPointCode(), inv.getQuantity()); } return moveList; @@ -744,7 +740,7 @@ public class AllocateProcessor { Area area = areaMapper.selectById(currentPoint.getAreaId()); String areaCode = area.getAreaCode(); List itemKeyIds = Collections.singletonList(itemKey); - return scanTrayProcessor.allocatePoint(itemKeyIds, currentPoint, areaCode); + return scanTrayProcessor.allocatePoint(itemKeyIds, currentPoint, areaCode,BusinessTypeEnum.MOVE.getValue()); } /** diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/service/impl/ITesAgvServiceImpl.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/service/impl/ITesAgvServiceImpl.java index 3bddf89..802c95f 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/service/impl/ITesAgvServiceImpl.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/tesAgv/service/impl/ITesAgvServiceImpl.java @@ -11,6 +11,8 @@ import org.cpte.modules.constant.GeneralConstant; import org.cpte.modules.constant.enums.AgvStatusEnum; import org.cpte.modules.constant.enums.AgvVendorEnum; import org.cpte.modules.constant.enums.BusinessTypeEnum; +import org.cpte.modules.inventory.service.IInventoryService; +import org.cpte.modules.inventory.service.impl.InventoryServiceImpl; import org.cpte.modules.receive.service.IAsnService; import org.cpte.modules.shipping.entity.Task; import org.cpte.modules.shipping.mapper.TaskMapper; @@ -55,6 +57,9 @@ public class ITesAgvServiceImpl implements ITesAgvService { @Autowired private IAgvTaskService agvTaskService; + @Autowired + private IInventoryService inventoryService; + @Override public String generateTesAgvTaskJson(AgvTask agvTask) { NewMovePodTaskRequest newMovePodTaskRequest = new NewMovePodTaskRequest(); @@ -214,6 +219,9 @@ public class ITesAgvServiceImpl implements ITesAgvService { String endCode = pointService.getElevatorPoint(agvTask.getEndCode(), GeneralConstant.CK_ELEVATOR_TASK_INDEX); agvTaskService.createAgvTask(null, agvTask.getCarrierCode(), agvTask.getEndCode(), endCode, null, BusinessTypeEnum.OUTBOUND.getValue(), 0, AgvVendorEnum.HIK.getValue()); }*/ + }else if(BusinessTypeEnum.MOVE.getValue().equals(agvTask.getType())){ + List tasks = taskMapper.queryByAgvTask(agvTask.getId()); + inventoryService.moveInventory(tasks); } agvTask.setStatus(AgvStatusEnum.COMPLETED.getValue()); diff --git a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/BatchUtil.java b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/BatchUtil.java index b139529..a737127 100644 --- a/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/BatchUtil.java +++ b/cpte-boot-module/cpte-module-wms/src/main/java/org/cpte/modules/utils/BatchUtil.java @@ -299,8 +299,8 @@ public class BatchUtil { ps.setString(8, task.getToPointCode()); ps.setLong(9, task.getStockId()); ps.setString(10, task.getStockCode()); - ps.setLong(11, task.getPickId()); - ps.setLong(12, task.getPickDetailId()); + ps.setObject(11, task.getPickId()); + ps.setObject(12, task.getPickDetailId()); ps.setLong(13, task.getItemKeyId()); ps.setLong(14, task.getInventoryId()); ps.setBigDecimal(15, task.getPlanQty());