新的创建与分配工作流方法
This commit is contained in:
parent
b80ed591c9
commit
9618fa8782
|
|
@ -8,7 +8,6 @@ import com.wms.annotation.MyLog;
|
|||
import com.wms.constants.enums.ResponseCode;
|
||||
import com.wms.entity.app.ResponseEntity;
|
||||
import com.wms.entity.app.dto.PageDto;
|
||||
import com.wms.entity.app.dto.StandDto;
|
||||
import com.wms.entity.app.request.StandQuery;
|
||||
import com.wms.entity.app.vo.StandVo;
|
||||
import com.wms.entity.app.wcs.DdjStatusChangeRequest;
|
||||
|
|
@ -66,7 +65,9 @@ public class StandController {
|
|||
.like(StringUtils.isNotEmpty(standQuery.getStandId()), Stand::getStandId, standQuery.getStandId())
|
||||
.eq(standQuery.getStandStatus() != null, Stand::getStandStatus, standQuery.getStandStatus())
|
||||
.eq(standQuery.getIsLock() != null, Stand::getIsLock, standQuery.getIsLock())
|
||||
.eq(standQuery.getStandType() != null, Stand::getStandType, standQuery.getStandType());
|
||||
.eq(standQuery.getStandType() != null, Stand::getStandType, standQuery.getStandType())
|
||||
.eq(standQuery.getAllowMwl() != null, Stand::getAllowMwl, standQuery.getAllowMwl())
|
||||
.eq(standQuery.getAllowMg() != null, Stand::getAllowMg, standQuery.getAllowMg());
|
||||
Page<Stand> standPage = standService.page(page, lambdaQueryWrapper);
|
||||
|
||||
PageDto<StandVo> pageDto = PageDto.of(standPage, stand -> BeanUtil.copyProperties(stand, StandVo.class));
|
||||
|
|
@ -112,6 +113,8 @@ public class StandController {
|
|||
.set(request.getLastUseTime() != null, Stand::getLastUseTime, request.getLastUseTime())
|
||||
.set(request.getPickVehicleCount() != null, Stand::getPickVehicleCount, request.getPickVehicleCount())
|
||||
.set(request.getAllowNoPlan() != null, Stand::getAllowNoPlan, request.getAllowNoPlan())
|
||||
.set(request.getAllowMwl() != null, Stand::getAllowMwl, request.getAllowMwl())
|
||||
.set(request.getAllowMg() != null, Stand::getAllowMg, request.getAllowMg())
|
||||
.eq(Stand::getStandId, request.getStandId());
|
||||
if (standService.update(lambdaUpdateWrapper)) {
|
||||
logger.info("更新站台信息成功。");
|
||||
|
|
|
|||
|
|
@ -99,4 +99,14 @@ public class StandQuery extends PageQuery {
|
|||
*/
|
||||
@JsonProperty("allowNoPlan")
|
||||
private Integer allowNoPlan;
|
||||
/**
|
||||
* 允许做装载机
|
||||
*/
|
||||
@JsonProperty("allowMwl")
|
||||
private Integer allowMwl;
|
||||
/**
|
||||
* 允许做平地机
|
||||
*/
|
||||
@JsonProperty("allowMg")
|
||||
private Integer allowMg;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,4 +97,14 @@ public class StandVo {
|
|||
*/
|
||||
@JsonProperty("allowNoPlan")
|
||||
private Integer allowNoPlan;
|
||||
/**
|
||||
* 允许做装载机
|
||||
*/
|
||||
@JsonProperty("allowMwl")
|
||||
private Integer allowMwl;
|
||||
/**
|
||||
* 允许做平地机
|
||||
*/
|
||||
@JsonProperty("allowMg")
|
||||
private Integer allowMg;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,4 +96,14 @@ public class Stand {
|
|||
*/
|
||||
@TableField("allow_no_plan")
|
||||
private Integer allowNoPlan;
|
||||
/**
|
||||
* 允许做装载机
|
||||
*/
|
||||
@TableField("allow_mwl")
|
||||
private Integer allowMwl;
|
||||
/**
|
||||
* 允许做平地机
|
||||
*/
|
||||
@TableField("allow_mg")
|
||||
private Integer allowMg;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.wms.service.business.serviceImplements;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.wms.constants.enums.*;
|
||||
|
|
@ -539,6 +540,16 @@ public class WorkServiceImplements implements IWorkService {
|
|||
if (!localWorkDateList.contains(currentWorkDate)) {
|
||||
return;
|
||||
}
|
||||
// 查找所有未锁定的拣选站台
|
||||
List<Stand> usableStands = standService.list(new LambdaQueryWrapper<Stand>()
|
||||
.eq(Stand::getStandType, 2)
|
||||
.eq(Stand::getIsLock, 0));
|
||||
for (Stand stand : usableStands) {
|
||||
if (stand.getStandStatus() == 0) {
|
||||
// 存在站台处于可用状态,不创建工作流
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 添加进总汇总数据
|
||||
List<WorkFlow> allFlows = new ArrayList<>();
|
||||
// 获取当天所有的装载机工作
|
||||
|
|
@ -547,98 +558,28 @@ public class WorkServiceImplements implements IWorkService {
|
|||
List<WorkFlow> thisDayMGWorks = new ArrayList<>();
|
||||
// 需要合并第二天的平地机工作
|
||||
List<WorkFlow> nextDayMGWorks = new ArrayList<>();
|
||||
// 获取工作优先级
|
||||
String workPriority = configMap.get(ConfigMapKeyEnum.WORK_PRIORITY.getConfigKey());
|
||||
// 获取目前已经存在的工作流
|
||||
List<WorkFlow> allOldWorkFlows = workFlowService.list();
|
||||
if (!StringUtils.isEmpty(workPriority) && workPriority.equals("1")) {
|
||||
List<WorkFlow> oldMwlWorkFlows = allOldWorkFlows.stream().filter(workFlow -> workFlow.getMachineType() == 1).toList();
|
||||
if (oldMwlWorkFlows.isEmpty()) {
|
||||
// 先平地机再装载机
|
||||
findWorks("", thisDayMGWorks, "NOT_MWL", currentWorkDate);
|
||||
if (!thisDayMGWorks.isEmpty()) {
|
||||
allFlows.addAll(thisDayMGWorks);
|
||||
// 查询配置是否需要合并第二天的配置
|
||||
String ifMergeTomorrow = configMap.get(ConfigMapKeyEnum.IF_MERGE_TOMORROW.getConfigKey());
|
||||
if (!StringUtils.isEmpty(ifMergeTomorrow) && ifMergeTomorrow.equals("1")) {
|
||||
// 获取下一个工作日
|
||||
LocalDate nextWorkDate = nextWorkDate(currentWorkDate);
|
||||
if (nextWorkDate != null && nextWorkDate.isAfter(currentWorkDate)) {
|
||||
findWorks("", nextDayMGWorks, "NOT_MWL", nextWorkDate);
|
||||
}
|
||||
if (!nextDayMGWorks.isEmpty()) {
|
||||
// 添加第二天的平地机工作进汇总
|
||||
allFlows.addAll(nextDayMGWorks);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<WorkFlow> oldMgWorkFlows = allOldWorkFlows.stream().filter(workFlow -> workFlow.getMachineType() == 2).toList();
|
||||
if (oldMgWorkFlows.isEmpty()) {
|
||||
// 装载机
|
||||
findWorks("", thisDayMWLWorks, "MWL", currentWorkDate);
|
||||
if (!thisDayMWLWorks.isEmpty()) {
|
||||
allFlows.addAll(thisDayMWLWorks);
|
||||
}
|
||||
}
|
||||
// 生成装载机工作流
|
||||
findWorks("", thisDayMWLWorks, "MWL", currentWorkDate);
|
||||
if (!thisDayMWLWorks.isEmpty()) {
|
||||
allFlows.addAll(thisDayMWLWorks);
|
||||
}
|
||||
// 生成当天平地机工作流
|
||||
findWorks("", thisDayMGWorks, "NOT_MWL", currentWorkDate);
|
||||
if (!thisDayMGWorks.isEmpty()) {
|
||||
allFlows.addAll(thisDayMGWorks);
|
||||
// 查询配置是否需要合并第二天的配置
|
||||
String ifMergeTomorrow = configMap.get(ConfigMapKeyEnum.IF_MERGE_TOMORROW.getConfigKey());
|
||||
if (!StringUtils.isEmpty(ifMergeTomorrow) && ifMergeTomorrow.equals("1")) {
|
||||
// 获取下一个工作日
|
||||
LocalDate nextWorkDate = nextWorkDate(currentWorkDate);
|
||||
if (nextWorkDate != null && nextWorkDate.isAfter(currentWorkDate)) {
|
||||
findWorks("", nextDayMGWorks, "NOT_MWL", nextWorkDate);
|
||||
}
|
||||
} else {
|
||||
// 装载机
|
||||
findWorks("", thisDayMWLWorks, "MWL", currentWorkDate);
|
||||
if (!thisDayMWLWorks.isEmpty()) {
|
||||
allFlows.addAll(thisDayMWLWorks);
|
||||
if (!nextDayMGWorks.isEmpty()) {
|
||||
// 添加第二天的平地机工作进汇总
|
||||
allFlows.addAll(nextDayMGWorks);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<WorkFlow> oldMgWorkFlows = allOldWorkFlows.stream().filter(workFlow -> workFlow.getMachineType() == 2).toList();
|
||||
if (oldMgWorkFlows.isEmpty()) {
|
||||
// 先装载机再平地机
|
||||
findWorks("", thisDayMWLWorks, "MWL", currentWorkDate);
|
||||
if (!thisDayMWLWorks.isEmpty()) {
|
||||
allFlows.addAll(thisDayMWLWorks);
|
||||
} else {
|
||||
List<WorkFlow> oldMwlWorkFlows = allOldWorkFlows.stream().filter(workFlow -> workFlow.getMachineType() == 1).toList();
|
||||
if (oldMwlWorkFlows.isEmpty()) {
|
||||
// 平地机
|
||||
findWorks("", thisDayMGWorks, "NOT_MWL", currentWorkDate);
|
||||
if (!thisDayMGWorks.isEmpty()) {
|
||||
allFlows.addAll(thisDayMGWorks);
|
||||
// 查询配置是否需要合并第二天的配置
|
||||
String ifMergeTomorrow = configMap.get(ConfigMapKeyEnum.IF_MERGE_TOMORROW.getConfigKey());
|
||||
if (!StringUtils.isEmpty(ifMergeTomorrow) && ifMergeTomorrow.equals("1")) {
|
||||
// 获取下一个工作日
|
||||
LocalDate nextWorkDate = nextWorkDate(currentWorkDate);
|
||||
if (nextWorkDate != null && nextWorkDate.isAfter(currentWorkDate)) {
|
||||
findWorks("", nextDayMGWorks, "NOT_MWL", nextWorkDate);
|
||||
}
|
||||
if (!nextDayMGWorks.isEmpty()) {
|
||||
// 添加第二天的平地机工作进汇总
|
||||
allFlows.addAll(nextDayMGWorks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 平地机
|
||||
findWorks("", thisDayMGWorks, "NOT_MWL", currentWorkDate);
|
||||
if (!thisDayMGWorks.isEmpty()) {
|
||||
allFlows.addAll(thisDayMGWorks);
|
||||
// 查询配置是否需要合并第二天的配置
|
||||
String ifMergeTomorrow = configMap.get(ConfigMapKeyEnum.IF_MERGE_TOMORROW.getConfigKey());
|
||||
if (!StringUtils.isEmpty(ifMergeTomorrow) && ifMergeTomorrow.equals("1")) {
|
||||
// 获取下一个工作日
|
||||
LocalDate nextWorkDate = nextWorkDate(currentWorkDate);
|
||||
if (nextWorkDate != null && nextWorkDate.isAfter(currentWorkDate)) {
|
||||
findWorks("", nextDayMGWorks, "NOT_MWL", nextWorkDate);
|
||||
}
|
||||
if (!nextDayMGWorks.isEmpty()) {
|
||||
// 添加第二天的平地机工作进汇总
|
||||
allFlows.addAll(nextDayMGWorks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (!allFlows.isEmpty()) {
|
||||
// 处理这些工作流
|
||||
|
|
@ -725,44 +666,56 @@ public class WorkServiceImplements implements IWorkService {
|
|||
}
|
||||
// 获取工作优先级
|
||||
String workPriority = configMap.get(ConfigMapKeyEnum.WORK_PRIORITY.getConfigKey());
|
||||
List<WorkFlow> needDistributeWorks = new ArrayList<>();
|
||||
int currentWorkType;
|
||||
// 获取优先的工作类型
|
||||
int firstWorkType;// 1为装载机,2为平地机
|
||||
if (!StringUtils.isEmpty(workPriority) && workPriority.equals("1")) {
|
||||
// 当前工作优先级为先平地机后装载机
|
||||
List<WorkFlow> needDistributeMgWorks = allCurrentWorks.stream().filter(workFlow -> workFlow.getMachineType() == 2 && workFlow.getWorkStatus() == -1).toList();
|
||||
if (!needDistributeMgWorks.isEmpty()) {
|
||||
needDistributeWorks.addAll(needDistributeMgWorks);
|
||||
currentWorkType = 2;// 平地机
|
||||
} else {
|
||||
List<WorkFlow> needDistributeMwlWorks = allCurrentWorks.stream().filter(workFlow -> workFlow.getMachineType() == 1 && workFlow.getWorkStatus() == -1).toList();
|
||||
if (!needDistributeMwlWorks.isEmpty()) {
|
||||
needDistributeWorks.addAll(needDistributeMwlWorks);
|
||||
currentWorkType = 1;// 装载机
|
||||
} else {
|
||||
logger.info("当前没有未分配的工作,优先级:平地机优先。");
|
||||
return;
|
||||
}
|
||||
}
|
||||
firstWorkType = 2;
|
||||
} else {
|
||||
// 默认优先级为先装载机后平地机
|
||||
List<WorkFlow> needDistributeMwlWorks = allCurrentWorks.stream().filter(workFlow -> workFlow.getMachineType() == 1 && workFlow.getWorkStatus() == -1).toList();
|
||||
if (!needDistributeMwlWorks.isEmpty()) {
|
||||
needDistributeWorks.addAll(needDistributeMwlWorks);
|
||||
currentWorkType = 1;// 装载机
|
||||
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<String> firstWorkStandIds = new ArrayList<>();
|
||||
// 次选工作的站台
|
||||
List<String> nextWorkStandIds = new ArrayList<>();
|
||||
for (Stand stand : usablePickStands) {
|
||||
if (firstWorkType == 2) {
|
||||
// 优先做平地机
|
||||
if (!needDistributeMgWorks.isEmpty() && stand.getAllowMg() == 1) {
|
||||
// 当前站台做平地机
|
||||
firstWorkStandIds.add(stand.getStandId());
|
||||
continue;
|
||||
}
|
||||
if (!needDistributeMwlWorks.isEmpty() && stand.getAllowMwl() == 1) {
|
||||
// 当前站台可以继续做装载机
|
||||
nextWorkStandIds.add(stand.getStandId());
|
||||
}
|
||||
} else {
|
||||
List<WorkFlow> needDistributeMgWorks = allCurrentWorks.stream().filter(workFlow -> workFlow.getMachineType() == 2 && workFlow.getWorkStatus() == -1).toList();
|
||||
if (!needDistributeMgWorks.isEmpty()) {
|
||||
needDistributeWorks.addAll(needDistributeMgWorks);
|
||||
currentWorkType = 2;// 平地机
|
||||
} else {
|
||||
logger.info("当前没有未分配的工作,优先级:装载机优先。");
|
||||
return;
|
||||
// 优先做装载机
|
||||
if (!needDistributeMwlWorks.isEmpty() && stand.getAllowMwl() == 1) {
|
||||
// 当前站台做装载机
|
||||
firstWorkStandIds.add(stand.getStandId());
|
||||
continue;
|
||||
}
|
||||
if (!needDistributeMgWorks.isEmpty() && stand.getAllowMg() == 1) {
|
||||
// 当前站台可以继续做平地机
|
||||
nextWorkStandIds.add(stand.getStandId());
|
||||
}
|
||||
}
|
||||
}
|
||||
// 最终需要存储的数据
|
||||
List<GoodsToStation> finalGoodsToStations = new ArrayList<>();// 物料分配
|
||||
List<ELocationConfig> finalELocationConfigs = new ArrayList<>();// 标签库位分配
|
||||
// 获取所有可用的电子标签位
|
||||
List<ETagLocation> allELocations = eTagLocationService.list(new LambdaQueryWrapper<ETagLocation>()
|
||||
.eq(ETagLocation::getELocationStatus, 0)
|
||||
|
|
@ -774,203 +727,366 @@ public class WorkServiceImplements implements IWorkService {
|
|||
logger.info("存在旧的标签配置,不执行分配。");
|
||||
return;
|
||||
}
|
||||
// 获取工站配置
|
||||
LambdaQueryWrapper<WorkStationConfig> wsConfigQueryWrapper = new LambdaQueryWrapper<>();
|
||||
if (currentWorkType == 1) {
|
||||
// 当前是装载机工作,装载机要区分站台
|
||||
wsConfigQueryWrapper
|
||||
.eq(WorkStationConfig::getModel, "MWL");
|
||||
} else {
|
||||
// 当前是平地机工作
|
||||
wsConfigQueryWrapper.ne(WorkStationConfig::getModel, "MWL");
|
||||
}
|
||||
List<WorkStationConfig> workStationConfigs = workStationConfigService.list(wsConfigQueryWrapper);
|
||||
// 然后获取大盒子-订单的map
|
||||
Map<String, List<WorkFlow>> workFlowsByBigBoxMap = new HashMap<>();
|
||||
// 本次分配的工作
|
||||
List<WorkFlow> thisTimeDistributeWorkFlows = new ArrayList<>();
|
||||
// 查询出所有的工站配置
|
||||
List<WorkStationConfig> workStationConfigs = workStationConfigService.list();
|
||||
// 根据小盒子号生成map
|
||||
Map<String, String> smallBoxToBigBoxConfigMap = workStationConfigs.stream().collect(Collectors.toMap(WorkStationConfig::getSmallBox, WorkStationConfig::getBigBox));
|
||||
for (WorkFlow workFlow : needDistributeWorks) {
|
||||
if (smallBoxToBigBoxConfigMap.containsKey(workFlow.getWorkCenter())) {
|
||||
String bigbox = smallBoxToBigBoxConfigMap.get(workFlow.getWorkCenter());
|
||||
workFlowsByBigBoxMap.computeIfAbsent(bigbox, k -> new ArrayList<>())
|
||||
.add(workFlow);
|
||||
}
|
||||
}
|
||||
// 生成每个大盒子的物料种类map
|
||||
Map<String, Integer> bigBoxToGoodsTypeQtyMap = new HashMap<>();
|
||||
for (String bigBox : workFlowsByBigBoxMap.keySet()) {
|
||||
List<WorkFlow> thisBoxWorkFlows = workFlowsByBigBoxMap.get(bigBox);
|
||||
int goodsTypeQty = thisBoxWorkFlows.stream().map(WorkFlow::getGoodsId).distinct().toList().size();
|
||||
bigBoxToGoodsTypeQtyMap.put(bigBox, goodsTypeQty);
|
||||
}
|
||||
// 根据物料种类数量对大盒子进行排序
|
||||
List<String> sortedBoxedByGoodsTypeQty = bigBoxToGoodsTypeQtyMap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).map(Map.Entry::getKey).toList();
|
||||
// 每个站台包含的物料种类数量
|
||||
Map<String, List<String>> stationToGoodsTypeQtyMap = new HashMap<>();
|
||||
// 每个站台分配的电子标签
|
||||
Map<String, List<ELocationConfig>> stationToELocationConfigsMap = new HashMap<>();
|
||||
// 每个站台的物料需求
|
||||
Map<String, List<GoodsToStation>> stationToGoodsToStationsMap = new HashMap<>();
|
||||
// 每个站台的剩余电子标签
|
||||
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);
|
||||
// 每个站台物料分配种类
|
||||
stationToGoodsTypeQtyMap.put(standId, new ArrayList<>());
|
||||
}
|
||||
// 决定每个大盒子的站台分配
|
||||
Map<String, String> bigBoxToStandIdMap = new HashMap<>();
|
||||
// 物料种类总数---这里存在一个分歧,大盒子之间的共通物料种类是否需要重复计算---CONFUSION
|
||||
int totalGoodsTypeQty = needDistributeWorks.stream().map(WorkFlow::getGoodsId).distinct().toList().size();
|
||||
// 物料种类数量平均值
|
||||
int goodsTypeQtyAverage = (int) Math.ceil(totalGoodsTypeQty / (double) standIds.size());
|
||||
// 查询出需要分配的工单的dbs
|
||||
List<KateDBS> kateDBSS = kateDBSService.list(new LambdaQueryWrapper<KateDBS>()
|
||||
.in(KateDBS::getWorkOrder, needDistributeWorks.stream().map(WorkFlow::getWorkOrder).distinct().toList()));
|
||||
// 将这个工单的顺序号进行一个map
|
||||
Map<String, Integer> workOrderToSequenceMap = kateDBSS.stream().collect(Collectors.toMap(KateDBS::getWorkOrder, KateDBS::getWorkSequence));
|
||||
for (String bigBox : sortedBoxedByGoodsTypeQty) {
|
||||
// 找出这个站台下的工作流
|
||||
List<WorkFlow> thisBoxWorkFlows = workFlowsByBigBoxMap.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.containsKey(boxNo)) {
|
||||
// List<WorkFlow> thisBoxNotDistributeYetWorks = new ArrayList<>(notDistributeYetWorksByBoxMap.get(boxNo));
|
||||
// thisBoxNotDistributeYetWorks.add(workFlow);
|
||||
// notDistributeYetWorksByBoxMap.replace(boxNo, thisBoxNotDistributeYetWorks);
|
||||
// } else {
|
||||
// notDistributeYetWorksByBoxMap.put(boxNo, List.of(workFlow));
|
||||
// }
|
||||
}
|
||||
if (notDistributeYetWorksByBoxMap.isEmpty()) {
|
||||
// 当前大盒子全部分配完毕
|
||||
continue;
|
||||
}
|
||||
String targetStandId = "";
|
||||
if (currentWorkType == 1) {
|
||||
// 装载机使用固定配置
|
||||
List<WorkStationConfig> thisBigBoxConfigs = workStationConfigs.stream().filter(workStationConfig -> workStationConfig.getBigBox().equals(bigBox)).toList();
|
||||
if (!thisBigBoxConfigs.isEmpty()) {
|
||||
targetStandId = thisBigBoxConfigs.get(0).getWorkStation();
|
||||
// 首选工作存储的信息
|
||||
List<GoodsToStation> finalGoodsToStationsOfFirst = new ArrayList<>();// 物料分配
|
||||
List<ELocationConfig> finalELocationConfigsOfFirst = new ArrayList<>();// 标签库位分配
|
||||
// 下面开始分配首选工作
|
||||
if (!needDistributeWorksOfFirst.isEmpty() && !firstWorkStandIds.isEmpty()) {
|
||||
// 获取大盒子-订单的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);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
// 生成每个大盒子的物料种类map
|
||||
Map<String, Integer> bigBoxToGoodsTypeQtyMap = new HashMap<>();
|
||||
for (String bigBox : workFlowsByBigBoxMapOfFirst.keySet()) {
|
||||
List<WorkFlow> thisBoxWorkFlows = workFlowsByBigBoxMapOfFirst.get(bigBox);
|
||||
int goodsTypeQty = thisBoxWorkFlows.stream().map(WorkFlow::getGoodsId).distinct().toList().size();
|
||||
bigBoxToGoodsTypeQtyMap.put(bigBox, goodsTypeQty);
|
||||
}
|
||||
// 根据物料种类数量对大盒子进行排序
|
||||
List<String> sortedBoxedByGoodsTypeQty = bigBoxToGoodsTypeQtyMap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).map(Map.Entry::getKey).toList();
|
||||
// 每个站台包含的物料种类数量
|
||||
Map<String, List<String>> stationToGoodsTypeQtyMap = new HashMap<>();
|
||||
// 每个站台分配的电子标签
|
||||
Map<String, List<ELocationConfig>> stationToELocationConfigsMap = new HashMap<>();
|
||||
// 每个站台的物料需求
|
||||
Map<String, List<GoodsToStation>> stationToGoodsToStationsMap = new HashMap<>();
|
||||
// 每个站台的剩余电子标签
|
||||
Map<String, List<String>> stationToRemainELocationMap = new HashMap<>();
|
||||
for (String standId : firstWorkStandIds) {
|
||||
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);
|
||||
// 每个站台物料分配种类
|
||||
stationToGoodsTypeQtyMap.put(standId, new ArrayList<>());
|
||||
}
|
||||
// 决定每个大盒子的站台分配
|
||||
Map<String, String> bigBoxToStandIdMap = new HashMap<>();
|
||||
// 物料种类总数---这里存在一个分歧,大盒子之间的共通物料种类是否需要重复计算---CONFUSION
|
||||
int totalGoodsTypeQty = needDistributeWorksOfFirst.stream().map(WorkFlow::getGoodsId).distinct().toList().size();
|
||||
// 物料种类数量平均值
|
||||
int goodsTypeQtyAverage = (int) Math.ceil(totalGoodsTypeQty / (double) standIds.size());
|
||||
// 查询出需要分配的工单的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 bigBox : sortedBoxedByGoodsTypeQty) {
|
||||
// 找出这个站台下的工作流
|
||||
List<WorkFlow> thisBoxWorkFlows = workFlowsByBigBoxMapOfFirst.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(o -> workOrderToSequenceMap.get(o.split("@")[0])))
|
||||
// .sorted(Comparator.comparing(o -> o.split("@")[1]))
|
||||
// .toList();
|
||||
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));
|
||||
}
|
||||
// 处理物料的需求分配
|
||||
List<WorkFlow> thisTimeDistributeWorkFlows = new ArrayList<>();
|
||||
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 = workFlowsByBigBoxMap.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);
|
||||
if (StringUtils.isEmpty(targetStandId)) {
|
||||
// 没有站台能够分配
|
||||
continue;
|
||||
}
|
||||
WorkFlow onlyForUpdateTemp = new WorkFlow();
|
||||
onlyForUpdateTemp.setWorkFlowId(workFlow.getWorkFlowId());
|
||||
onlyForUpdateTemp.setWorkStatus(0);
|
||||
onlyForUpdateTemp.setWorkStation(thisStandId);
|
||||
thisTimeDistributeWorkFlows.add(onlyForUpdateTemp);
|
||||
// 判断这个站台是否还包含剩余标签位
|
||||
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 = 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));
|
||||
}
|
||||
// 替换
|
||||
stationToGoodsToStationsMap.put(thisStandId, oldGoodsStationsMap.values().stream().toList());
|
||||
}
|
||||
// 以下更新物料需求
|
||||
for (String standId : stationToGoodsToStationsMap.keySet()) {
|
||||
finalGoodsToStations.addAll(stationToGoodsToStationsMap.get(standId));
|
||||
// 首选工作存储的信息
|
||||
List<GoodsToStation> finalGoodsToStationsOfNext = new ArrayList<>();// 物料分配
|
||||
List<ELocationConfig> finalELocationConfigsOfNext = new ArrayList<>();// 标签库位分配
|
||||
// 处理次选工作 TODO 需要考虑一下优先分配和首选工作存在相同物料种类的大盒子
|
||||
if (!needDistributeWorksOfNext.isEmpty() && !nextWorkStandIds.isEmpty()) {
|
||||
// 获取大盒子-订单的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> sortedBoxedByGoodsTypeQty = bigBoxToGoodsTypeQtyMap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).map(Map.Entry::getKey).toList();
|
||||
// 每个站台包含的物料种类数量
|
||||
Map<String, List<String>> stationToGoodsTypeQtyMap = new HashMap<>();
|
||||
// 每个站台分配的电子标签
|
||||
Map<String, List<ELocationConfig>> stationToELocationConfigsMap = new HashMap<>();
|
||||
// 每个站台的物料需求
|
||||
Map<String, List<GoodsToStation>> stationToGoodsToStationsMap = new HashMap<>();
|
||||
// 每个站台的剩余电子标签
|
||||
Map<String, List<String>> stationToRemainELocationMap = new HashMap<>();
|
||||
for (String standId : nextWorkStandIds) {
|
||||
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);
|
||||
// 每个站台物料分配种类
|
||||
stationToGoodsTypeQtyMap.put(standId, new ArrayList<>());
|
||||
}
|
||||
// 决定每个大盒子的站台分配
|
||||
Map<String, String> bigBoxToStandIdMap = new HashMap<>();
|
||||
// 物料种类总数---这里存在一个分歧,大盒子之间的共通物料种类是否需要重复计算---CONFUSION
|
||||
int totalGoodsTypeQty = needDistributeWorksOfNext.stream().map(WorkFlow::getGoodsId).distinct().toList().size();
|
||||
// 物料种类数量平均值
|
||||
int goodsTypeQtyAverage = (int) Math.ceil(totalGoodsTypeQty / (double) standIds.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 : sortedBoxedByGoodsTypeQty) {
|
||||
// 找出这个站台下的工作流
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 最终存储数据
|
||||
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);
|
||||
}
|
||||
// 以下更新电子标签配置
|
||||
for (String standId : stationToELocationConfigsMap.keySet()) {
|
||||
finalELocationConfigs.addAll(stationToELocationConfigsMap.get(standId));
|
||||
// 电子标签配置
|
||||
if (!finalELocationConfigsOfFirst.isEmpty()) {
|
||||
finalELocationConfigs.addAll(finalELocationConfigsOfFirst);
|
||||
}
|
||||
if (!finalELocationConfigsOfNext.isEmpty()) {
|
||||
finalELocationConfigs.addAll(finalELocationConfigsOfNext);
|
||||
}
|
||||
// 添加标签配置数据库
|
||||
if (!finalELocationConfigs.isEmpty()) {
|
||||
// 添加电子标签库位配置
|
||||
eLocationConfigService.saveBatch(finalELocationConfigs);
|
||||
}
|
||||
// 更新工作流数据
|
||||
|
|
@ -979,8 +1095,7 @@ public class WorkServiceImplements implements IWorkService {
|
|||
}
|
||||
logger.info("分配工作完成");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
logger.error("分配工作发生异常:{}", e.getMessage());
|
||||
logger.error("分配工作发生异常:{}", JSON.toJSONString(e));
|
||||
// 回滚事务
|
||||
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user