diff --git a/src/main/java/com/wms/service/business/IWmsTaskService.java b/src/main/java/com/wms/service/business/IWmsTaskService.java index 7063ff0..d776de0 100644 --- a/src/main/java/com/wms/service/business/IWmsTaskService.java +++ b/src/main/java/com/wms/service/business/IWmsTaskService.java @@ -5,6 +5,7 @@ import com.wms.entity.app.request.TaskOutRequest; import com.wms.entity.table.Task; import java.math.BigDecimal; +import java.util.Map; /** * WMS任务服务接口 @@ -41,5 +42,5 @@ public interface IWmsTaskService { BigDecimal callGoods(String goodsId, BigDecimal needNum, String workStation); - BigDecimal callStocks(String goodsId, BigDecimal needNum, String workStation); + BigDecimal callStocks(String goodsId, BigDecimal needNum, String workStation, Map runningTaskNumToEquipmentMap); } 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 77127be..361f7df 100644 --- a/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java +++ b/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java @@ -27,6 +27,7 @@ import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; +import static com.wms.config.InitLocalConfig.instantLocationMap; import static com.wms.constants.WmsConstants.MYSQL_JSON_CI; import static com.wms.utils.StringUtils.convertJsonString; import static com.wms.utils.WmsUtils.generateId; @@ -366,7 +367,7 @@ public class WmsTaskServiceImplements implements IWmsTaskService { @Override @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) - public BigDecimal callStocks(String goodsId, BigDecimal needNum, String workStation) { + public BigDecimal callStocks(String goodsId, BigDecimal needNum, String workStation, Map runningTaskNumToEquipmentMap) { BigDecimal originNum = needNum;// 原始数量 try { // 判断当前这个料是否已经有outsideVehicles @@ -392,12 +393,38 @@ public class WmsTaskServiceImplements implements IWmsTaskService { .apply("goods_related ->> '$.remainNum' > 0") .orderByAsc(Stock::getCreateTime)); if (stockList != null && !stockList.isEmpty()) { + // 要生成的出库任务列表 List waitForOutStockList = new ArrayList<>(); + // 找出最空闲的那台堆垛机 + Integer mostEmptyStackerId = runningTaskNumToEquipmentMap.entrySet().stream() + .min(Comparator.comparingInt(Map.Entry::getValue)) + .map(Map.Entry::getKey) + .orElse(null); + // 那台堆垛机的库存id + String selectedStockId = ""; + if (mostEmptyStackerId != null) { + // 判断这些里面有没有当前堆垛机/巷道的库存--- + Stock mostEmptyStock = stockList.stream().filter(stock -> instantLocationMap.get(stock.getLocationId()).getEquipmentId().equals(mostEmptyStackerId)).findFirst().orElse(null); + if (mostEmptyStock != null) { + selectedStockId = mostEmptyStock.getStockId(); + } + } // 尝试生成出库任务 for (Stock tempStock : stockList) { if (needNum.compareTo(BigDecimal.ZERO) <= 0) {// 需求数量小于等于0 break; } + if (StringUtils.isNotEmpty(selectedStockId)) { + if (!Objects.equals(tempStock.getStockId(), selectedStockId)) { + continue; + } + } + // 当前库位设备号 + int equipmentId = instantLocationMap.get(tempStock.getLocationId()).getEquipmentId(); + if (!runningTaskNumToEquipmentMap.containsKey(equipmentId)) { + // 设备应该处于不可用状态,就不生成任务了 + continue; + } if (tempStock.getGoodsRelated().getRemainNum().compareTo(needNum) > 0) { // 当前箱子剩余物料数量多于需求数量 needNum = BigDecimal.ZERO; @@ -414,9 +441,14 @@ public class WmsTaskServiceImplements implements IWmsTaskService { tempStock.setGoodsRelated(goodsRelated); } waitForOutStockList.add(tempStock); + // 将堆垛机任务数量更新 + runningTaskNumToEquipmentMap.put(equipmentId, runningTaskNumToEquipmentMap.get(equipmentId) + 1); break; } - createVehicleOutTaskAndPickTask(waitForOutStockList, workStation); + if (!waitForOutStockList.isEmpty()) { + // 创建任务 + createVehicleOutTaskAndPickTask(waitForOutStockList, workStation); + } } return needNum; } catch (Exception ex) { diff --git a/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java b/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java index a10676c..81f2233 100644 --- a/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java +++ b/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java @@ -3,6 +3,8 @@ package com.wms.service.business.serviceImplements; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.wms.constants.enums.ConfigMapKeyEnum; +import com.wms.constants.enums.TaskType; +import com.wms.constants.enums.WmsTaskStatus; import com.wms.entity.app.dto.WorkCenterAndOrderDto; import com.wms.entity.table.*; import com.wms.service.*; @@ -50,6 +52,8 @@ public class WorkServiceImplements implements IWorkService { private final IWmsTaskService wmsTaskService;// 任务服务 private final PickTaskService pickTaskService;// 拣选任务服务 private final OutsideVehiclesService outsideVehiclesService;// 外部流转箱服务 + private final StandService standService;// 站台服务 + private final TaskService taskService;// 任务服务 private final List workCreatingStations = new ArrayList<>();// 当前正在创建任务的站台 private final List workDoingStations = new ArrayList<>();// 当前正在执行任务的站台 private final List workFinishingStations = new ArrayList<>();// 当前正在完成任务的站台 @@ -295,6 +299,33 @@ public class WorkServiceImplements implements IWorkService { } return; } + // 轮询堆垛机状态 + List stackerList = standService.list(new LambdaQueryWrapper() + .eq(Stand::getIsLock, 0).eq(Stand::getStandStatus, 0) + .eq(Stand::getStandType, 3)); + // 查出所有的正在执行的拣选出库的任务 + List stackRunningTasks = taskService.list(new LambdaQueryWrapper() + .eq(Task::getTaskType, TaskType.OUT.getCode()) + .eq(Task::getIsPicking, 1)); + Map runningTaskNumToEquipmentMap = new HashMap<>(); + for (Stand stacker : stackerList) { + // 找这台堆垛机正在执行的拣选出库任务数量 + runningTaskNumToEquipmentMap.put(stacker.getEquipmentId(), 0); + } + // 生成堆垛机的任务数量映射 + for (Task tempStackRunningTask : stackRunningTasks) { + if (instantLocationMap.containsKey(tempStackRunningTask.getOrigin())) { + int key = instantLocationMap.get(tempStackRunningTask.getOrigin()).getEquipmentId(); + if (runningTaskNumToEquipmentMap.isEmpty()) { + // 没有可用堆垛机 + break; + } + if (runningTaskNumToEquipmentMap.containsKey(key)) { + runningTaskNumToEquipmentMap.replace(key, runningTaskNumToEquipmentMap.get(key) + 1); + } + } + } + for (GoodsToStation goodsToStation : notFinishedGoodsList) { // 当前物料当前站台需求数量 BigDecimal needNum = goodsToStation.getTotalNum().subtract(goodsToStation.getDistributedNum()); @@ -317,7 +348,7 @@ public class WorkServiceImplements implements IWorkService { // 分配完成 goodsToStation.setDistributeStatus(2); } else { - needNum = wmsTaskService.callStocks(goodsToStation.getGoodsId(), needNum, workStation); + needNum = wmsTaskService.callStocks(goodsToStation.getGoodsId(), needNum, workStation, runningTaskNumToEquipmentMap); if (needNum.compareTo(BigDecimal.ZERO) > 0) { // 已分配但未完全分配 goodsToStation.setDistributeStatus(1); diff --git a/src/main/java/com/wms/service/serviceImplements/LocationServiceImplements.java b/src/main/java/com/wms/service/serviceImplements/LocationServiceImplements.java index 1da48b2..70cc749 100644 --- a/src/main/java/com/wms/service/serviceImplements/LocationServiceImplements.java +++ b/src/main/java/com/wms/service/serviceImplements/LocationServiceImplements.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.wms.constants.enums.StockStatus; +import com.wms.constants.enums.TaskType; import com.wms.entity.table.Location; import com.wms.entity.table.Stand; import com.wms.entity.table.Stock; @@ -21,6 +22,7 @@ import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.util.*; +import static com.wms.config.InitLocalConfig.instantLocationMap; import static com.wms.constants.WmsConstants.MYSQL_JSON_CI; @Service @@ -70,33 +72,80 @@ public class LocationServiceImplements extends ServiceImpl LRUStandQueryWrapper = new LambdaQueryWrapper() - .select(Stand::getStandId, Stand::getEquipmentId) - .eq(Stand::getStandStatus, 0) - .eq(Stand::getIsLock, 0) - .eq(Stand::getStandType, 3) - .orderByAsc(Stand::getLastUseTime); - List LRUStands = standMapper.selectList(LRUStandQueryWrapper); - if (!LRUStands.isEmpty()) { - if (StringUtils.isNotEmpty(goodsId)) {// 需要根据物料编号做出区分 - equipmentId = selectEquipmentByLRUAndGoods(LRUStands, goodsId); - if (equipmentId != -1) { - getOneLocationByEquipmentId(resultMap, equipmentId); + // 轮询堆垛机状态 + List stackerList = standMapper.selectList(new LambdaQueryWrapper() + .eq(Stand::getIsLock, 0).eq(Stand::getStandStatus, 0) + .eq(Stand::getStandType, 3)); + // 查出所有的正在执行的拣选出库的任务 + List stackRunningTasks = taskMapper.selectList(new LambdaQueryWrapper() + .eq(Task::getTaskType, TaskType.IN.getCode())); + Map runningTaskNumToEquipmentMap = new HashMap<>(); + for (Stand stacker : stackerList) { + // 找这台堆垛机正在执行的拣选出库任务数量 + runningTaskNumToEquipmentMap.put(stacker.getEquipmentId(), 0); + } + // 生成堆垛机的任务数量映射 + for (Task tempStackRunningTask : stackRunningTasks) { + if (instantLocationMap.containsKey(tempStackRunningTask.getOrigin())) { + int key = instantLocationMap.get(tempStackRunningTask.getOrigin()).getEquipmentId(); + if (runningTaskNumToEquipmentMap.isEmpty()) { + // 没有可用堆垛机 + break; } - } - if (resultMap.isEmpty()) {// 结果集为空 - for (Stand lruStand : LRUStands) { - getOneLocationByEquipmentId(resultMap, lruStand.getEquipmentId()); - if (!resultMap.isEmpty()) { - // 更新最近使用时间 - lruStand.setLastUseTime(LocalDateTime.now()); - standMapper.updateById(lruStand); - break; - } + if (runningTaskNumToEquipmentMap.containsKey(key)) { + runningTaskNumToEquipmentMap.replace(key, runningTaskNumToEquipmentMap.get(key) + 1); } } } + // 查找库位 + while (!runningTaskNumToEquipmentMap.isEmpty()) { + Integer mostEmptyStackerId = runningTaskNumToEquipmentMap.entrySet().stream() + .min(Comparator.comparingInt(Map.Entry::getValue)) + .map(Map.Entry::getKey) + .orElse(null); + if (mostEmptyStackerId == null) { + // 跳出循环 + break; + } + getOneLocationByEquipmentId(resultMap, mostEmptyStackerId); + if (!resultMap.isEmpty()) { + // 更新最近使用时间 + standMapper.update(new LambdaUpdateWrapper() + .set(Stand::getLastUseTime, LocalDateTime.now()) + .eq(Stand::getEquipmentId, mostEmptyStackerId) + .eq(Stand::getStandType, 3)); + break; + } + runningTaskNumToEquipmentMap.remove(mostEmptyStackerId); + } + + // 选择最近未使用的设备 +// LambdaQueryWrapper LRUStandQueryWrapper = new LambdaQueryWrapper() +// .select(Stand::getStandId, Stand::getEquipmentId) +// .eq(Stand::getStandStatus, 0) +// .eq(Stand::getIsLock, 0) +// .eq(Stand::getStandType, 3) +// .orderByAsc(Stand::getLastUseTime); +// List LRUStands = standMapper.selectList(LRUStandQueryWrapper); +// if (!LRUStands.isEmpty()) { +// if (StringUtils.isNotEmpty(goodsId)) {// 需要根据物料编号做出区分 +// equipmentId = selectEquipmentByLRUAndGoods(LRUStands, goodsId); +// if (equipmentId != -1) { +// getOneLocationByEquipmentId(resultMap, equipmentId); +// } +// } +// if (resultMap.isEmpty()) {// 结果集为空 +// for (Stand lruStand : LRUStands) { +// getOneLocationByEquipmentId(resultMap, lruStand.getEquipmentId()); +// if (!resultMap.isEmpty()) { +// // 更新最近使用时间 +// lruStand.setLastUseTime(LocalDateTime.now()); +// standMapper.updateById(lruStand); +// break; +// } +// } +// } +// } return resultMap; } }