增加新方式,首选工作机型优先分完,剩余站台可做次选机型
This commit is contained in:
parent
c0f4471b8f
commit
9baf971e3d
|
|
@ -67,7 +67,7 @@ public class KateWorkExecutor implements Job {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// 分配工作
|
// 分配工作
|
||||||
workService.distributeWorks();
|
workService.distributeWorksMethod2();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("分配工作时发生错误:{}", e.getMessage());
|
log.error("分配工作时发生错误:{}", e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,4 +28,6 @@ public interface IWorkService {
|
||||||
* 分配工作
|
* 分配工作
|
||||||
*/
|
*/
|
||||||
void distributeWorks();
|
void distributeWorks();
|
||||||
|
|
||||||
|
void distributeWorksMethod2();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1119,6 +1119,460 @@ public class WorkServiceImplements implements IWorkService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分配工作的第二种方法
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void distributeWorksMethod2() {
|
||||||
|
try {
|
||||||
|
// 查询所有的拣选站台
|
||||||
|
List<Stand> allPickStands = standService.list(new LambdaQueryWrapper<Stand>()
|
||||||
|
.eq(Stand::getStandType, 2).eq(Stand::getIsLock, 0)
|
||||||
|
.orderByAsc(Stand::getStandId));
|
||||||
|
// 找出可用的站台
|
||||||
|
List<Stand> usablePickStands = allPickStands.stream().filter(stand -> stand.getStandStatus() == 0).toList();
|
||||||
|
if (usablePickStands.size() != allPickStands.size()) {
|
||||||
|
logger.info("站台未全部释放,不执行分配。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 映射出站台号
|
||||||
|
List<String> standIds = usablePickStands.stream().map(Stand::getStandId).distinct().toList();
|
||||||
|
if (standIds.isEmpty()) {
|
||||||
|
logger.info("没有站台能够分配,不执行分配。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 查询出所有的工作流
|
||||||
|
List<WorkFlow> allCurrentWorks = workFlowService.list();
|
||||||
|
// 查询这些站台是否已经分配了工作
|
||||||
|
boolean haveDistributedWorks = false;
|
||||||
|
for (String standId : standIds) {
|
||||||
|
List<WorkFlow> distributedWorks = allCurrentWorks.stream().filter(workFlow -> workFlow.getWorkStation().equals(standId)).toList();
|
||||||
|
if (!distributedWorks.isEmpty()) {
|
||||||
|
haveDistributedWorks = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (haveDistributedWorks) {
|
||||||
|
logger.info("有站台进行过分配,不执行分配。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 获取工作优先级
|
||||||
|
String workPriority = configMap.get(ConfigMapKeyEnum.WORK_PRIORITY.getConfigKey());
|
||||||
|
// 获取优先的工作类型
|
||||||
|
int firstWorkType;// 1为装载机,2为平地机
|
||||||
|
if (!StringUtils.isEmpty(workPriority) && workPriority.equals("1")) {
|
||||||
|
firstWorkType = 2;
|
||||||
|
} else {
|
||||||
|
firstWorkType = 1;
|
||||||
|
}
|
||||||
|
// 需要分配的平地机工作流
|
||||||
|
List<WorkFlow> needDistributeMgWorks = allCurrentWorks.stream().filter(workFlow -> workFlow.getMachineType() == 2 && workFlow.getWorkStatus() == -1).toList();
|
||||||
|
// 需要分配的装载机工作流
|
||||||
|
List<WorkFlow> needDistributeMwlWorks = allCurrentWorks.stream().filter(workFlow -> workFlow.getMachineType() == 1 && workFlow.getWorkStatus() == -1).toList();
|
||||||
|
// 方案1:装载机与平地机分开分配,且优先分配的工作的物料类对次选工作存在影响
|
||||||
|
List<WorkFlow> needDistributeWorksOfFirst = new ArrayList<>();
|
||||||
|
List<WorkFlow> needDistributeWorksOfNext = new ArrayList<>();
|
||||||
|
if (firstWorkType == 1) {
|
||||||
|
needDistributeWorksOfFirst.addAll(needDistributeMwlWorks);
|
||||||
|
needDistributeWorksOfNext.addAll(needDistributeMgWorks);
|
||||||
|
} else {
|
||||||
|
needDistributeWorksOfFirst.addAll(needDistributeMgWorks);
|
||||||
|
needDistributeWorksOfNext.addAll(needDistributeMwlWorks);
|
||||||
|
}
|
||||||
|
// 获取所有可用的电子标签位
|
||||||
|
List<ETagLocation> allELocations = eTagLocationService.list(new LambdaQueryWrapper<ETagLocation>()
|
||||||
|
.eq(ETagLocation::getELocationStatus, 0)
|
||||||
|
.orderByAsc(ETagLocation::getSequenceId));
|
||||||
|
// 获取已经添加的电子标签库位分配
|
||||||
|
List<ELocationConfig> oldELocationConfigs = eLocationConfigService.list(new LambdaQueryWrapper<ELocationConfig>()
|
||||||
|
.in(ELocationConfig::getWorkStation, standIds));
|
||||||
|
if (oldELocationConfigs != null && !oldELocationConfigs.isEmpty()) {
|
||||||
|
logger.info("存在旧的标签配置,不执行分配。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 本次分配的工作
|
||||||
|
List<WorkFlow> thisTimeDistributeWorkFlows = new ArrayList<>();
|
||||||
|
// 查询出所有的工站配置
|
||||||
|
List<WorkStationConfig> workStationConfigs = workStationConfigService.list();
|
||||||
|
// 根据小盒子号生成map
|
||||||
|
Map<String, String> smallBoxToBigBoxConfigMap = workStationConfigs.stream().collect(Collectors.toMap(WorkStationConfig::getSmallBox, WorkStationConfig::getBigBox));
|
||||||
|
// 首选工作存储的信息
|
||||||
|
List<GoodsToStation> finalGoodsToStationsOfFirst = new ArrayList<>();// 物料分配
|
||||||
|
List<ELocationConfig> finalELocationConfigsOfFirst = new ArrayList<>();// 标签库位分配
|
||||||
|
// 每个站台的剩余电子标签
|
||||||
|
Map<String, List<String>> stationToRemainELocationMap = new HashMap<>();
|
||||||
|
for (String standId : standIds) {
|
||||||
|
List<ETagLocation> thisStandELocations = allELocations.stream().filter(eTagLocation -> eTagLocation.getWorkStation().equals(standId)).toList();
|
||||||
|
if (thisStandELocations.isEmpty()) {
|
||||||
|
// 当前站台没有可用电子标签位
|
||||||
|
stationToRemainELocationMap.put(standId, Collections.emptyList());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 排序
|
||||||
|
List<String> thisStandELocationIds = thisStandELocations.stream().sorted(Comparator.comparingInt(ETagLocation::getSequenceId)).map(ETagLocation::getELocationId).toList();
|
||||||
|
stationToRemainELocationMap.put(standId, thisStandELocationIds);
|
||||||
|
}
|
||||||
|
// 每个站台做的机型
|
||||||
|
Map<String, Integer> standToMachineTypeMap = new HashMap<>();
|
||||||
|
// 下面开始分配首选工作
|
||||||
|
if (!needDistributeWorksOfFirst.isEmpty()) {
|
||||||
|
logger.info("开始分配首选机型。");
|
||||||
|
// 获取大盒子-订单的map
|
||||||
|
Map<String, List<WorkFlow>> workFlowsByBigBoxMapOfFirst = new HashMap<>();
|
||||||
|
for (WorkFlow workFlow : needDistributeWorksOfFirst) {
|
||||||
|
if (smallBoxToBigBoxConfigMap.containsKey(workFlow.getWorkCenter())) {
|
||||||
|
String bigBox = smallBoxToBigBoxConfigMap.get(workFlow.getWorkCenter());
|
||||||
|
workFlowsByBigBoxMapOfFirst.computeIfAbsent(bigBox, k -> new ArrayList<>())
|
||||||
|
.add(workFlow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 根据订单量,对大盒子号进行一个排序
|
||||||
|
List<String> bigBoxes = workFlowsByBigBoxMapOfFirst.keySet().stream().sorted(Comparator.comparingInt(o -> workFlowsByBigBoxMapOfFirst.get(o).size())).toList();
|
||||||
|
// 每个站台分配的电子标签
|
||||||
|
Map<String, List<ELocationConfig>> stationToELocationConfigsMap = new HashMap<>();
|
||||||
|
// 每个站台的物料需求
|
||||||
|
Map<String, List<GoodsToStation>> stationToGoodsToStationsMap = new HashMap<>();
|
||||||
|
// 决定每个大盒子的站台分配
|
||||||
|
Map<String, String> bigBoxToStandIdMap = new HashMap<>();
|
||||||
|
// 查询出需要分配的工单的dbs
|
||||||
|
List<KateDBS> kateDBSS = kateDBSService.list(new LambdaQueryWrapper<KateDBS>()
|
||||||
|
.in(KateDBS::getWorkOrder, needDistributeWorksOfFirst.stream().map(WorkFlow::getWorkOrder).distinct().toList()));
|
||||||
|
// 将这个工单的顺序号进行一个map
|
||||||
|
Map<String, Integer> workOrderToSequenceMap = kateDBSS.stream().collect(Collectors.toMap(KateDBS::getWorkOrder, KateDBS::getWorkSequence));
|
||||||
|
// 轮询站台
|
||||||
|
for (String targetStandId : standIds) {
|
||||||
|
if (stationToRemainELocationMap.get(targetStandId) == null || stationToRemainELocationMap.get(targetStandId).isEmpty()) {
|
||||||
|
// 当前站台没有可用的电子标签库位
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 轮询大盒子,找到可以分配的
|
||||||
|
for (String bigBox : bigBoxes) {
|
||||||
|
if (bigBoxToStandIdMap.containsKey(bigBox)) {
|
||||||
|
// 当前大盒子已经被分配过站台
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 找出这个大盒子下的工作流
|
||||||
|
List<WorkFlow> thisBoxWorkFlows = workFlowsByBigBoxMapOfFirst.get(bigBox);
|
||||||
|
if (thisBoxWorkFlows.isEmpty()) {
|
||||||
|
// 当前大盒子没有工作流,跳过
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 未分配的工作流,按照boxNo分组
|
||||||
|
Map<String, List<WorkFlow>> notDistributeYetWorksByBoxMap = new HashMap<>();
|
||||||
|
for (WorkFlow workFlow : thisBoxWorkFlows) {
|
||||||
|
String boxNo = workFlow.getWorkOrder() + "@" + workFlow.getWorkCenter();
|
||||||
|
notDistributeYetWorksByBoxMap.computeIfAbsent(boxNo, k -> new ArrayList<>())
|
||||||
|
.add(workFlow);
|
||||||
|
}
|
||||||
|
if (notDistributeYetWorksByBoxMap.isEmpty()) {
|
||||||
|
// 当前大盒子全部分配完毕
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (notDistributeYetWorksByBoxMap.size() > stationToRemainELocationMap.get(targetStandId).size()) {
|
||||||
|
// 标签个数不够
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 判断这个站台是否还包含剩余标签位
|
||||||
|
List<String> thisStandRemainELocationIds = new ArrayList<>(stationToRemainELocationMap.get(targetStandId));
|
||||||
|
if (thisStandRemainELocationIds.size() < notDistributeYetWorksByBoxMap.size()) {
|
||||||
|
// 标签不够,此处的判断主要用于装载机
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 排序后的key
|
||||||
|
List<String> sortedKeyString = notDistributeYetWorksByBoxMap.keySet().stream()
|
||||||
|
.sorted(
|
||||||
|
Comparator.comparing((String o) -> workOrderToSequenceMap.get(o.split("@")[0]))
|
||||||
|
.thenComparing(o -> o.split("@")[1])
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
// 本次生成的电子标签配置
|
||||||
|
List<ELocationConfig> thisStandELocationConfigs = stationToELocationConfigsMap.getOrDefault(targetStandId, new ArrayList<>());
|
||||||
|
for (String boxNo : sortedKeyString) {
|
||||||
|
// 获取一个电子标签库位
|
||||||
|
String eLocationId = thisStandRemainELocationIds.get(0);
|
||||||
|
ELocationConfig eLocationConfig = new ELocationConfig();
|
||||||
|
eLocationConfig.setWorkOrder(boxNo.split("@")[0]);
|
||||||
|
eLocationConfig.setWorkCenter(boxNo.split("@")[1]);
|
||||||
|
eLocationConfig.setWorkStation(targetStandId);
|
||||||
|
eLocationConfig.setELocationId(eLocationId);
|
||||||
|
eLocationConfig.setOrderBoxNo(boxNo);
|
||||||
|
// 添加配置
|
||||||
|
thisStandELocationConfigs.add(eLocationConfig);
|
||||||
|
// 移除这个库位
|
||||||
|
thisStandRemainELocationIds.remove(eLocationId);
|
||||||
|
}
|
||||||
|
// 更新电子标签剩余库位
|
||||||
|
stationToRemainELocationMap.replace(targetStandId, thisStandRemainELocationIds);
|
||||||
|
// 更新电子标签配置
|
||||||
|
stationToELocationConfigsMap.put(targetStandId, thisStandELocationConfigs);
|
||||||
|
// 已经分配完的大盒子
|
||||||
|
bigBoxToStandIdMap.put(bigBox, targetStandId);
|
||||||
|
// 制定当前站台已经在做的工作类型
|
||||||
|
standToMachineTypeMap.put(targetStandId, firstWorkType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 处理分配
|
||||||
|
List<GoodsToStation> oldGoodsStations = goodsToStationService.list();
|
||||||
|
if (oldGoodsStations != null && !oldGoodsStations.isEmpty()) {
|
||||||
|
// 按照站台分组
|
||||||
|
stationToGoodsToStationsMap = oldGoodsStations.stream().collect(Collectors.groupingBy(GoodsToStation::getWorkStation));
|
||||||
|
}
|
||||||
|
// 更新数据
|
||||||
|
for (String bigBox : bigBoxToStandIdMap.keySet()) {
|
||||||
|
String thisStandId = bigBoxToStandIdMap.get(bigBox);
|
||||||
|
// 当前站台的旧的goodsToStation
|
||||||
|
List<GoodsToStation> thisStandOldGoodsToStationList = stationToGoodsToStationsMap.getOrDefault(thisStandId, new ArrayList<>());
|
||||||
|
// 根据料号Map一下
|
||||||
|
Map<String, GoodsToStation> oldGoodsStationsMap = thisStandOldGoodsToStationList.stream().collect(Collectors.toMap(GoodsToStation::getGoodsId, goodsToStation -> goodsToStation));
|
||||||
|
List<WorkFlow> thisBigBoxWorks = workFlowsByBigBoxMapOfFirst.get(bigBox);
|
||||||
|
for (WorkFlow workFlow : thisBigBoxWorks) {
|
||||||
|
if (oldGoodsStationsMap.containsKey(workFlow.getGoodsId())) {
|
||||||
|
// 更新totalNum,并把状态改成分配中
|
||||||
|
GoodsToStation goodsToStation = oldGoodsStationsMap.get(workFlow.getGoodsId());
|
||||||
|
goodsToStation.setTotalNum(goodsToStation.getTotalNum().add(workFlow.getNeedNum()));
|
||||||
|
oldGoodsStationsMap.replace(workFlow.getGoodsId(), goodsToStation);
|
||||||
|
} else {
|
||||||
|
GoodsToStation newGoodsToStation = new GoodsToStation();
|
||||||
|
newGoodsToStation.setConfigId(generateId(""));
|
||||||
|
newGoodsToStation.setGoodsId(workFlow.getGoodsId());
|
||||||
|
newGoodsToStation.setWorkStation(thisStandId);
|
||||||
|
newGoodsToStation.setDistributeStatus(0);
|
||||||
|
newGoodsToStation.setDistributedNum(BigDecimal.ZERO);
|
||||||
|
newGoodsToStation.setTotalNum(workFlow.getNeedNum());
|
||||||
|
oldGoodsStationsMap.put(workFlow.getGoodsId(), newGoodsToStation);
|
||||||
|
}
|
||||||
|
WorkFlow onlyForUpdateTemp = new WorkFlow();
|
||||||
|
onlyForUpdateTemp.setWorkFlowId(workFlow.getWorkFlowId());
|
||||||
|
onlyForUpdateTemp.setWorkStatus(0);
|
||||||
|
onlyForUpdateTemp.setWorkStation(thisStandId);
|
||||||
|
thisTimeDistributeWorkFlows.add(onlyForUpdateTemp);
|
||||||
|
}
|
||||||
|
// 替换
|
||||||
|
stationToGoodsToStationsMap.put(thisStandId, oldGoodsStationsMap.values().stream().toList());
|
||||||
|
}
|
||||||
|
// 以下更新物料需求
|
||||||
|
for (String standId : stationToGoodsToStationsMap.keySet()) {
|
||||||
|
finalGoodsToStationsOfFirst.addAll(stationToGoodsToStationsMap.get(standId));
|
||||||
|
}
|
||||||
|
// 以下更新电子标签配置
|
||||||
|
for (String standId : stationToELocationConfigsMap.keySet()) {
|
||||||
|
finalELocationConfigsOfFirst.addAll(stationToELocationConfigsMap.get(standId));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.info("无法分配首选机型,可能是没有工作流或可用站台。");
|
||||||
|
}
|
||||||
|
// 筛选次选工作还有哪些站台可用
|
||||||
|
List<String> nextWorkStandIds = new ArrayList<>();
|
||||||
|
for (String standId : standIds) {
|
||||||
|
if (standToMachineTypeMap.containsKey(standId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
nextWorkStandIds.add(standId);
|
||||||
|
}
|
||||||
|
// 次选工作存储的信息
|
||||||
|
List<GoodsToStation> finalGoodsToStationsOfNext = new ArrayList<>();// 物料分配
|
||||||
|
List<ELocationConfig> finalELocationConfigsOfNext = new ArrayList<>();// 标签库位分配
|
||||||
|
// 处理次选工作 TODO 需要考虑一下优先分配和首选工作存在相同物料种类的大盒子
|
||||||
|
if (!needDistributeWorksOfNext.isEmpty() && !nextWorkStandIds.isEmpty()) {
|
||||||
|
logger.info("开始分配次选机型。");
|
||||||
|
// 获取大盒子-订单的map
|
||||||
|
Map<String, List<WorkFlow>> workFlowsByBigBoxMapOfNext = new HashMap<>();
|
||||||
|
for (WorkFlow workFlow : needDistributeWorksOfNext) {
|
||||||
|
if (smallBoxToBigBoxConfigMap.containsKey(workFlow.getWorkCenter())) {
|
||||||
|
String bigBox = smallBoxToBigBoxConfigMap.get(workFlow.getWorkCenter());
|
||||||
|
workFlowsByBigBoxMapOfNext.computeIfAbsent(bigBox, k -> new ArrayList<>())
|
||||||
|
.add(workFlow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 生成每个大盒子的物料种类map
|
||||||
|
Map<String, Integer> bigBoxToGoodsTypeQtyMap = new HashMap<>();
|
||||||
|
for (String bigBox : workFlowsByBigBoxMapOfNext.keySet()) {
|
||||||
|
List<WorkFlow> thisBoxWorkFlows = workFlowsByBigBoxMapOfNext.get(bigBox);
|
||||||
|
int goodsTypeQty = thisBoxWorkFlows.stream().map(WorkFlow::getGoodsId).distinct().toList().size();
|
||||||
|
bigBoxToGoodsTypeQtyMap.put(bigBox, goodsTypeQty);
|
||||||
|
}
|
||||||
|
// 根据物料种类数量对大盒子进行排序
|
||||||
|
List<String> sortedBoxesByGoodsTypeQty = bigBoxToGoodsTypeQtyMap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).map(Map.Entry::getKey).toList();
|
||||||
|
// 每个站台包含的物料种类数量
|
||||||
|
Map<String, List<String>> stationToGoodsTypeQtyMap = new HashMap<>();
|
||||||
|
for (String standId : nextWorkStandIds) {
|
||||||
|
// 每个站台物料分配种类
|
||||||
|
stationToGoodsTypeQtyMap.put(standId, new ArrayList<>());
|
||||||
|
}
|
||||||
|
// 每个站台分配的电子标签
|
||||||
|
Map<String, List<ELocationConfig>> stationToELocationConfigsMap = new HashMap<>();
|
||||||
|
// 每个站台的物料需求
|
||||||
|
Map<String, List<GoodsToStation>> stationToGoodsToStationsMap = new HashMap<>();
|
||||||
|
// 决定每个大盒子的站台分配
|
||||||
|
Map<String, String> bigBoxToStandIdMap = new HashMap<>();
|
||||||
|
// 物料种类总数---这里存在一个分歧,大盒子之间的共通物料种类是否需要重复计算---CONFUSION
|
||||||
|
int totalGoodsTypeQty = needDistributeWorksOfNext.stream().map(WorkFlow::getGoodsId).distinct().toList().size();
|
||||||
|
// 物料种类数量平均值
|
||||||
|
int goodsTypeQtyAverage = (int) Math.ceil(totalGoodsTypeQty / (double) nextWorkStandIds.size());
|
||||||
|
// 查询出需要分配的工单的dbs
|
||||||
|
List<KateDBS> kateDBSS = kateDBSService.list(new LambdaQueryWrapper<KateDBS>()
|
||||||
|
.in(KateDBS::getWorkOrder, needDistributeWorksOfNext.stream().map(WorkFlow::getWorkOrder).distinct().toList()));
|
||||||
|
// 将这个工单的顺序号进行一个map
|
||||||
|
Map<String, Integer> workOrderToSequenceMap = kateDBSS.stream().collect(Collectors.toMap(KateDBS::getWorkOrder, KateDBS::getWorkSequence));
|
||||||
|
for (String bigBox : sortedBoxesByGoodsTypeQty) {
|
||||||
|
// 找出这个大盒子下的工作流
|
||||||
|
List<WorkFlow> thisBoxWorkFlows = workFlowsByBigBoxMapOfNext.get(bigBox);
|
||||||
|
if (thisBoxWorkFlows.isEmpty()) {
|
||||||
|
// 当前大盒子没有工作流,跳过
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 获取这个大盒子下面的物料列表
|
||||||
|
List<String> goodsIds = thisBoxWorkFlows.stream().map(WorkFlow::getGoodsId).distinct().toList();
|
||||||
|
// 未分配的工作流,按照boxNo分组
|
||||||
|
Map<String, List<WorkFlow>> notDistributeYetWorksByBoxMap = new HashMap<>();
|
||||||
|
for (WorkFlow workFlow : thisBoxWorkFlows) {
|
||||||
|
String boxNo = workFlow.getWorkOrder() + "@" + workFlow.getWorkCenter();
|
||||||
|
notDistributeYetWorksByBoxMap.computeIfAbsent(boxNo, k -> new ArrayList<>())
|
||||||
|
.add(workFlow);
|
||||||
|
}
|
||||||
|
if (notDistributeYetWorksByBoxMap.isEmpty()) {
|
||||||
|
// 当前大盒子全部分配完毕
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String targetStandId = "";
|
||||||
|
targetStandId = getMinGapStandToAvgAfterAddABox(stationToGoodsTypeQtyMap, goodsIds, goodsTypeQtyAverage, notDistributeYetWorksByBoxMap.size(), stationToRemainELocationMap);
|
||||||
|
if (StringUtils.isEmpty(targetStandId)) {
|
||||||
|
// 没有站台能够分配
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 判断这个站台是否还包含剩余标签位
|
||||||
|
List<String> thisStandRemainELocationIds = new ArrayList<>(stationToRemainELocationMap.get(targetStandId));
|
||||||
|
if (thisStandRemainELocationIds.size() < notDistributeYetWorksByBoxMap.size()) {
|
||||||
|
// 标签不够,此处的判断主要用于装载机
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 排序后的key
|
||||||
|
List<String> sortedKeyString = notDistributeYetWorksByBoxMap.keySet().stream()
|
||||||
|
.sorted(
|
||||||
|
Comparator.comparing((String o) -> workOrderToSequenceMap.get(o.split("@")[0]))
|
||||||
|
.thenComparing(o -> o.split("@")[1])
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
// 本次生成的电子标签配置
|
||||||
|
List<ELocationConfig> thisStandELocationConfigs = stationToELocationConfigsMap.getOrDefault(targetStandId, new ArrayList<>());
|
||||||
|
for (String boxNo : sortedKeyString) {
|
||||||
|
// 获取一个电子标签库位
|
||||||
|
String eLocationId = thisStandRemainELocationIds.get(0);
|
||||||
|
ELocationConfig eLocationConfig = new ELocationConfig();
|
||||||
|
eLocationConfig.setWorkOrder(boxNo.split("@")[0]);
|
||||||
|
eLocationConfig.setWorkCenter(boxNo.split("@")[1]);
|
||||||
|
eLocationConfig.setWorkStation(targetStandId);
|
||||||
|
eLocationConfig.setELocationId(eLocationId);
|
||||||
|
eLocationConfig.setOrderBoxNo(boxNo);
|
||||||
|
// 添加配置
|
||||||
|
thisStandELocationConfigs.add(eLocationConfig);
|
||||||
|
// 移除这个库位
|
||||||
|
thisStandRemainELocationIds.remove(eLocationId);
|
||||||
|
}
|
||||||
|
// 更新电子标签剩余库位
|
||||||
|
stationToRemainELocationMap.replace(targetStandId, thisStandRemainELocationIds);
|
||||||
|
// 更新电子标签配置
|
||||||
|
stationToELocationConfigsMap.put(targetStandId, thisStandELocationConfigs);
|
||||||
|
// 已经分配完的大盒子
|
||||||
|
bigBoxToStandIdMap.put(bigBox, targetStandId);
|
||||||
|
}
|
||||||
|
// 处理分配
|
||||||
|
List<GoodsToStation> oldGoodsStations = goodsToStationService.list();
|
||||||
|
if (oldGoodsStations != null && !oldGoodsStations.isEmpty()) {
|
||||||
|
// 按照站台分组
|
||||||
|
stationToGoodsToStationsMap = oldGoodsStations.stream().collect(Collectors.groupingBy(GoodsToStation::getWorkStation));
|
||||||
|
}
|
||||||
|
// 更新数据
|
||||||
|
for (String bigBox : bigBoxToStandIdMap.keySet()) {
|
||||||
|
String thisStandId = bigBoxToStandIdMap.get(bigBox);
|
||||||
|
// 当前站台的旧的goodsToStation
|
||||||
|
List<GoodsToStation> thisStandOldGoodsToStationList = stationToGoodsToStationsMap.getOrDefault(thisStandId, new ArrayList<>());
|
||||||
|
// 根据料号Map一下
|
||||||
|
Map<String, GoodsToStation> oldGoodsStationsMap = thisStandOldGoodsToStationList.stream().collect(Collectors.toMap(GoodsToStation::getGoodsId, goodsToStation -> goodsToStation));
|
||||||
|
List<WorkFlow> thisBigBoxWorks = workFlowsByBigBoxMapOfNext.get(bigBox);
|
||||||
|
for (WorkFlow workFlow : thisBigBoxWorks) {
|
||||||
|
if (oldGoodsStationsMap.containsKey(workFlow.getGoodsId())) {
|
||||||
|
// 更新totalNum,并把状态改成分配中
|
||||||
|
GoodsToStation goodsToStation = oldGoodsStationsMap.get(workFlow.getGoodsId());
|
||||||
|
goodsToStation.setTotalNum(goodsToStation.getTotalNum().add(workFlow.getNeedNum()));
|
||||||
|
oldGoodsStationsMap.replace(workFlow.getGoodsId(), goodsToStation);
|
||||||
|
} else {
|
||||||
|
GoodsToStation newGoodsToStation = new GoodsToStation();
|
||||||
|
newGoodsToStation.setConfigId(generateId(""));
|
||||||
|
newGoodsToStation.setGoodsId(workFlow.getGoodsId());
|
||||||
|
newGoodsToStation.setWorkStation(thisStandId);
|
||||||
|
newGoodsToStation.setDistributeStatus(0);
|
||||||
|
newGoodsToStation.setDistributedNum(BigDecimal.ZERO);
|
||||||
|
newGoodsToStation.setTotalNum(workFlow.getNeedNum());
|
||||||
|
oldGoodsStationsMap.put(workFlow.getGoodsId(), newGoodsToStation);
|
||||||
|
}
|
||||||
|
WorkFlow onlyForUpdateTemp = new WorkFlow();
|
||||||
|
onlyForUpdateTemp.setWorkFlowId(workFlow.getWorkFlowId());
|
||||||
|
onlyForUpdateTemp.setWorkStatus(0);
|
||||||
|
onlyForUpdateTemp.setWorkStation(thisStandId);
|
||||||
|
thisTimeDistributeWorkFlows.add(onlyForUpdateTemp);
|
||||||
|
}
|
||||||
|
// 替换
|
||||||
|
stationToGoodsToStationsMap.put(thisStandId, oldGoodsStationsMap.values().stream().toList());
|
||||||
|
}
|
||||||
|
// 以下更新物料需求
|
||||||
|
for (String standId : stationToGoodsToStationsMap.keySet()) {
|
||||||
|
finalGoodsToStationsOfNext.addAll(stationToGoodsToStationsMap.get(standId));
|
||||||
|
}
|
||||||
|
// 以下更新电子标签配置
|
||||||
|
for (String standId : stationToELocationConfigsMap.keySet()) {
|
||||||
|
finalELocationConfigsOfNext.addAll(stationToELocationConfigsMap.get(standId));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.info("无法分配次选机型,可能是没有工作流或可用站台。");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最终存储数据
|
||||||
|
List<GoodsToStation> finalGoodsToStations = new ArrayList<>();// 物料分配
|
||||||
|
List<ELocationConfig> finalELocationConfigs = new ArrayList<>();// 标签库位分配
|
||||||
|
// 物料需求
|
||||||
|
if (!finalGoodsToStationsOfFirst.isEmpty()) {
|
||||||
|
finalGoodsToStations.addAll(finalGoodsToStationsOfFirst);
|
||||||
|
}
|
||||||
|
if (!finalGoodsToStationsOfNext.isEmpty()) {
|
||||||
|
finalGoodsToStations.addAll(finalGoodsToStationsOfNext);
|
||||||
|
}
|
||||||
|
// 更新物料需求数据库
|
||||||
|
if (!finalGoodsToStations.isEmpty()) {
|
||||||
|
goodsToStationService.saveOrUpdateBatch(finalGoodsToStations);
|
||||||
|
logger.info("添加新的站台物料需求成功。");
|
||||||
|
} else {
|
||||||
|
logger.info("没有新的站台物料需求。");
|
||||||
|
}
|
||||||
|
// 电子标签配置
|
||||||
|
if (!finalELocationConfigsOfFirst.isEmpty()) {
|
||||||
|
finalELocationConfigs.addAll(finalELocationConfigsOfFirst);
|
||||||
|
}
|
||||||
|
if (!finalELocationConfigsOfNext.isEmpty()) {
|
||||||
|
finalELocationConfigs.addAll(finalELocationConfigsOfNext);
|
||||||
|
}
|
||||||
|
// 添加标签配置数据库
|
||||||
|
if (!finalELocationConfigs.isEmpty()) {
|
||||||
|
eLocationConfigService.saveBatch(finalELocationConfigs);
|
||||||
|
logger.info("添加新的灯光配置成功。");
|
||||||
|
} else {
|
||||||
|
logger.info("没有新的灯光配置。");
|
||||||
|
}
|
||||||
|
// 更新工作流数据
|
||||||
|
if (!thisTimeDistributeWorkFlows.isEmpty()) {
|
||||||
|
workFlowService.updateBatchById(thisTimeDistributeWorkFlows);
|
||||||
|
logger.info("分配工作完成,此次分配{}条。", thisTimeDistributeWorkFlows.size());
|
||||||
|
} else {
|
||||||
|
logger.info("此次未执行分配。");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("分配工作发生异常:{}", JSON.toJSONString(e));
|
||||||
|
// 回滚事务
|
||||||
|
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取最小差距的站台(加上新数量后离平均值)
|
* 获取最小差距的站台(加上新数量后离平均值)
|
||||||
*
|
*
|
||||||
|
|
@ -1145,7 +1599,8 @@ public class WorkServiceImplements implements IWorkService {
|
||||||
// 筛选新增加的物料数量
|
// 筛选新增加的物料数量
|
||||||
List<String> thisTimeAddGoodsIdsOfThisStand = new ArrayList<>();
|
List<String> thisTimeAddGoodsIdsOfThisStand = new ArrayList<>();
|
||||||
for (String goodsId : goodsIdsThisTime) {
|
for (String goodsId : goodsIdsThisTime) {
|
||||||
if (thisStandGoodsId.stream().filter(goodsId1 -> goodsId1.equals(goodsId)).toList().isEmpty()) thisTimeAddGoodsIdsOfThisStand.add(goodsId);
|
if (thisStandGoodsId.stream().filter(goodsId1 -> goodsId1.equals(goodsId)).toList().isEmpty())
|
||||||
|
thisTimeAddGoodsIdsOfThisStand.add(goodsId);
|
||||||
}
|
}
|
||||||
// 判断偏差值
|
// 判断偏差值
|
||||||
int gap = thisStandGoodsId.size() + thisTimeAddGoodsIdsOfThisStand.size() - avgQty;
|
int gap = thisStandGoodsId.size() + thisTimeAddGoodsIdsOfThisStand.size() - avgQty;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user