代码更新:

1. 物料表信息维护
2. 工站配置信息维护
3. 发送任务功能优化
4. 开始工作和请求回库时,冲突防止。
This commit is contained in:
梁州 2024-09-23 19:04:52 +08:00
parent fc1d0ef3b4
commit 8095c40e60
15 changed files with 167 additions and 29 deletions

View File

@ -369,10 +369,10 @@ public class ExcelController {
// 目标数量 // 目标数量
BigDecimal targetNum = stockOfGoodsDto.getNumOfKanban().multiply(stockOfGoodsDto.getNumOfPerKanban()); BigDecimal targetNum = stockOfGoodsDto.getNumOfKanban().multiply(stockOfGoodsDto.getNumOfPerKanban());
// 计算需要多少个看板 // 计算需要多少个看板
BigDecimal needKanbanQuantity = targetNum.subtract(stockOfGoodsDto.getRemainNumSum()).divide(stockOfGoodsDto.getNumOfPerKanban(), 2, RoundingMode.CEILING); BigDecimal needKanbanQuantity = targetNum.subtract(stockOfGoodsDto.getRemainNumSum()).divide(stockOfGoodsDto.getNumOfPerKanban(), 0, RoundingMode.CEILING);
// 设定物流数据 // 设定物流数据
tempClcKanbanRequirementExcelVo.setGoodsId(stockOfGoodsDto.getGoodsId()); tempClcKanbanRequirementExcelVo.setGoodsId(stockOfGoodsDto.getGoodsId());
tempClcKanbanRequirementExcelVo.setRequireNum(needKanbanQuantity.multiply(stockOfGoodsDto.getNumOfPerKanban())); tempClcKanbanRequirementExcelVo.setReleasePoint(stockOfGoodsDto.getReleasePoint());
// 设定看板 // 设定看板
List<KanbanEntity> needKanbanList = new ArrayList<>(); List<KanbanEntity> needKanbanList = new ArrayList<>();
for (KanbanEntity kanbanEntity : stockOfGoodsDto.getKanbanList()) { for (KanbanEntity kanbanEntity : stockOfGoodsDto.getKanbanList()) {

View File

@ -487,7 +487,7 @@ public class KateWorkQueryController {
TotalNumOfType = TotalNumOfType.add(BigDecimal.ONE); TotalNumOfType = TotalNumOfType.add(BigDecimal.ONE);
BigDecimal targetNum = stockOfGoodsDto.getNumOfKanban().multiply(stockOfGoodsDto.getNumOfPerKanban()); BigDecimal targetNum = stockOfGoodsDto.getNumOfKanban().multiply(stockOfGoodsDto.getNumOfPerKanban());
// 计算需要多少个看板 // 计算需要多少个看板
BigDecimal needKanbanQuantity = targetNum.subtract(stockOfGoodsDto.getRemainNumSum()).divide(stockOfGoodsDto.getNumOfPerKanban(), 2, RoundingMode.CEILING); BigDecimal needKanbanQuantity = targetNum.subtract(stockOfGoodsDto.getRemainNumSum()).divide(stockOfGoodsDto.getNumOfPerKanban(), 0, RoundingMode.CEILING);
TotalNumOfPc = TotalNumOfPc.add(needKanbanQuantity.multiply(stockOfGoodsDto.getNumOfPerKanban())); TotalNumOfPc = TotalNumOfPc.add(needKanbanQuantity.multiply(stockOfGoodsDto.getNumOfPerKanban()));
TotalNumOfBox = TotalNumOfBox.add(needKanbanQuantity); TotalNumOfBox = TotalNumOfBox.add(needKanbanQuantity);
if (stockOfGoodsDto.getBoxType().contains("810")) { if (stockOfGoodsDto.getBoxType().contains("810")) {

View File

@ -2030,6 +2030,12 @@ public class TaskController {
} }
} }
} }
boolean hasPickTasksAgain = pickTaskService.exists(new LambdaQueryWrapper<PickTask>()
.eq(PickTask::getVehicleId, requestBackQuery.getVehicleId()));
if (hasPickTasksAgain) {
// 防止生成回库任务时正好又生成拣选任务
throw new Exception("生成新的拣选任务,不可回库。");
}
response.setCode(ResponseCode.OK.getCode()); response.setCode(ResponseCode.OK.getCode());
response.setMessage("可以回库。"); response.setMessage("可以回库。");
} else { } else {
@ -2042,7 +2048,7 @@ public class TaskController {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
logger.error("处理回库请求异常,{}", convertJsonString(e)); logger.error("处理回库请求异常,{}", convertJsonString(e));
response.setCode(ResponseCode.ERROR.getCode()); response.setCode(ResponseCode.ERROR.getCode());
response.setMessage("处理回库请求异常"); response.setMessage("处理回库请求异常" + e.getMessage());
return convertJsonString(response); return convertJsonString(response);
} }
} }
@ -2185,16 +2191,6 @@ public class TaskController {
response.setMessage("请求参数缺少站台号。"); response.setMessage("请求参数缺少站台号。");
return convertJsonString(response); return convertJsonString(response);
} }
// 判断大盒子号是否正确
List<WorkStationConfig> stationConfigs = workStationConfigService.list(new LambdaQueryWrapper<WorkStationConfig>()
.eq(WorkStationConfig::getBigBox, sortBoxRequest.getBigBoxNo())
.eq(WorkStationConfig::getWorkStation, standId));
if (stationConfigs == null || stationConfigs.isEmpty()) {
logger.error("请输入正确的大盒子号。");
response.setCode(ResponseCode.ERROR.getCode());
response.setMessage("请输入正确的大盒子号。");
return convertJsonString(response);
}
// 查找对应的标签配置 // 查找对应的标签配置
List<ELocationConfigLast> lightingBoxList = eLocationConfigLastService.list(new LambdaQueryWrapper<ELocationConfigLast>() List<ELocationConfigLast> lightingBoxList = eLocationConfigLastService.list(new LambdaQueryWrapper<ELocationConfigLast>()
.eq(ELocationConfigLast::getWorkStation, standId) .eq(ELocationConfigLast::getWorkStation, standId)
@ -2205,6 +2201,47 @@ public class TaskController {
response.setMessage("请将已亮灯的盒子取走并灭灯后重试。"); response.setMessage("请将已亮灯的盒子取走并灭灯后重试。");
return convertJsonString(response); return convertJsonString(response);
} }
// 判断大盒子号是否正确
List<WorkStationConfig> stationConfigs = workStationConfigService.list(new LambdaQueryWrapper<WorkStationConfig>()
.eq(WorkStationConfig::getBigBox, sortBoxRequest.getBigBoxNo())
.eq(WorkStationConfig::getWorkStation, standId));
if (stationConfigs == null || stationConfigs.isEmpty()) {
logger.error("请输入正确的大盒子号。");
response.setCode(ResponseCode.ERROR.getCode());
response.setMessage("请输入正确的大盒子号。");
return convertJsonString(response);
}
// 当前要亮灯的大盒子
WorkStationConfig currentBigBoxConfig = stationConfigs.get(0);
// 当前配置的工单数/大盒子
int orderQuantity = currentBigBoxConfig.getOrderQuantity();
if (orderQuantity <= 0) {
logger.error("当前大盒子号不装大盒子。");
response.setCode(ResponseCode.ERROR.getCode());
response.setMessage("当前大盒子号不装大盒子。");
return convertJsonString(response);
}
if (orderQuantity == 1) {
// 查询这个大盒子对应的小盒子
List<String> smallBoxListOfAll = stationConfigs.stream().map(WorkStationConfig::getSmallBox).distinct().toList();
// 找出本次工作中的标签位
List<ELocationConfigLast> eConfigLastList = eLocationConfigLastService.list(new LambdaQueryWrapper<ELocationConfigLast>()
.eq(ELocationConfigLast::getWorkStation, standId)
.in(ELocationConfigLast::getWorkCenter, smallBoxListOfAll)
.eq(ELocationConfigLast::getBoxStatus, 0)
.last("limit 1"));
// 实际本次需要亮灯的小盒子
List<String> smallBoxList = eConfigLastList.stream().map(ELocationConfigLast::getWorkCenter).distinct().toList();
} else {
//
}
// 筛选小盒子号 // 筛选小盒子号
List<String> smallBoxListOfAll = stationConfigs.stream().map(WorkStationConfig::getSmallBox).distinct().toList(); List<String> smallBoxListOfAll = stationConfigs.stream().map(WorkStationConfig::getSmallBox).distinct().toList();
// 查询该盒子下面所有的工单 // 查询该盒子下面所有的工单
@ -2283,9 +2320,14 @@ public class TaskController {
.in(ETagLocation::getELocationId, eTaskDataList.stream().map(ETaskData::getLocation).collect(Collectors.toList()))); .in(ETagLocation::getELocationId, eTaskDataList.stream().map(ETaskData::getLocation).collect(Collectors.toList())));
} }
} }
sortBoxRequest.setOrderOfOrders(1);
logger.info("处理整理盒子请求成功。"); logger.info("处理整理盒子请求成功。");
response.setCode(ResponseCode.OK.getCode()); response.setCode(ResponseCode.OK.getCode());
response.setMessage("请根据灯光拣选盒子。"); response.setMessage("请根据灯光拣选盒子。");
response.setReturnData(sortBoxRequest);
} else { } else {
logger.info("没有可亮灯的数据。"); logger.info("没有可亮灯的数据。");
response.setCode(ResponseCode.ERROR.getCode()); response.setCode(ResponseCode.ERROR.getCode());

View File

@ -1,5 +1,6 @@
package com.wms.entity.app.dto; package com.wms.entity.app.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.wms.entity.app.dto.extend.KanbanEntity; import com.wms.entity.app.dto.extend.KanbanEntity;
import lombok.Data; import lombok.Data;
@ -106,4 +107,14 @@ public class GoodsDto {
* 最后更新用户 * 最后更新用户
*/ */
private String lastUpdateUser; private String lastUpdateUser;
/**
* 热度
*/
@JsonProperty("heat")
private String heat;
/**
* 卸货点
*/
@JsonProperty("releasePoint")
private String releasePoint;
} }

View File

@ -1,5 +1,6 @@
package com.wms.entity.app.dto; package com.wms.entity.app.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.wms.entity.app.dto.extend.KanbanEntity; import com.wms.entity.app.dto.extend.KanbanEntity;
import lombok.Data; import lombok.Data;
@ -57,4 +58,14 @@ public class StockOfGoodsDto {
*/ */
@JsonProperty("kanbanList") @JsonProperty("kanbanList")
private List<KanbanEntity> kanbanList; private List<KanbanEntity> kanbanList;
/**
* 热度
*/
@JsonProperty("heat")
private String heat;
/**
* 卸货点
*/
@JsonProperty("releasePoint")
private String releasePoint;
} }

View File

@ -138,6 +138,16 @@ public class GoodsQuery extends PageQuery {
*/ */
@JsonProperty("lastUpdateUser") @JsonProperty("lastUpdateUser")
private String lastUpdateUser; private String lastUpdateUser;
/**
* 热度
*/
@JsonProperty("heat")
private String heat;
/**
* 卸货点
*/
@JsonProperty("releasePoint")
private String releasePoint;
/** /**

View File

@ -131,4 +131,14 @@ public class GoodsVo {
*/ */
@JsonProperty("lastUpdateUser") @JsonProperty("lastUpdateUser")
private String lastUpdateUser; private String lastUpdateUser;
/**
* 热度
*/
@JsonProperty("heat")
private String heat;
/**
* 卸货点
*/
@JsonProperty("releasePoint")
private String releasePoint;
} }

View File

@ -135,4 +135,14 @@ public class Goods {
*/ */
@TableField("last_update_user") @TableField("last_update_user")
private String lastUpdateUser; private String lastUpdateUser;
/**
* 热度
*/
@TableField("heat")
private String heat;
/**
* 卸货点
*/
@TableField("release_point")
private String releasePoint;
} }

View File

@ -66,7 +66,7 @@ public class WmsJobServiceImplements implements IWmsJobService {
List<String> taskGroupIds = new ArrayList<>(); List<String> taskGroupIds = new ArrayList<>();
// 这里单独处理站台拣选出库以外的任务 // 这里单独处理站台拣选出库以外的任务
for (Task task : allTasks) { for (Task task : allTasks) {
if (taskGroupIds.size() >= maxWcsAcceptNums) { if (request.size() >= maxWcsAcceptNums) {
// 每次给wcs下发数量 // 每次给wcs下发数量
break; break;
} }
@ -160,6 +160,23 @@ public class WmsJobServiceImplements implements IWmsJobService {
.eq(Task::getTaskType, TaskType.OUT.getCode()); .eq(Task::getTaskType, TaskType.OUT.getCode());
List<Task> allTasks = taskService.list(waitForDistributeTaskQuery); List<Task> allTasks = taskService.list(waitForDistributeTaskQuery);
if (!allTasks.isEmpty()) { if (!allTasks.isEmpty()) {
String max_vehicle_nums = configMap.get(ConfigMapKeyEnum.MAX_VEHICLE_NUMS.getConfigKey());
String max_wcs_accept_nums = configMap.get(ConfigMapKeyEnum.MAX_WCS_ACCEPT_NUMS.getConfigKey());
if (StringUtils.isEmpty(max_vehicle_nums) || StringUtils.isEmpty(max_wcs_accept_nums)) {
logger.error("配置未生成");
return;
}
int maxVehicleNums = Integer.parseInt(max_vehicle_nums);
int maxWcsAcceptNums = Integer.parseInt(max_wcs_accept_nums);// wcs最大一次性可接受任务数量
List<String> outsideVehicles = outsideVehiclesService.selectDistinctVehicles();
if (outsideVehicles == null || outsideVehicles.isEmpty()) {
outsideVehicles = Collections.emptyList();
}
int remainVehicleNums = maxVehicleNums - outsideVehicles.size();// 线体剩余箱子数量
if (remainVehicleNums <= 0) {
return;
}
// 需要发送给wcs的任务列表 // 需要发送给wcs的任务列表
List<WcsTaskRequest> request = new ArrayList<>(); List<WcsTaskRequest> request = new ArrayList<>();
// 已经下发的任务组列表 // 已经下发的任务组列表
@ -189,17 +206,20 @@ public class WmsJobServiceImplements implements IWmsJobService {
.eq(Stand::getStandType, 3)); .eq(Stand::getStandType, 3));
List<Task> stackRunningTasks = taskService.list(new LambdaQueryWrapper<Task>() List<Task> stackRunningTasks = taskService.list(new LambdaQueryWrapper<Task>()
.eq(Task::getTaskType, TaskType.OUT.getCode()) .eq(Task::getTaskType, TaskType.OUT.getCode())
.eq(Task::getTaskStatus, WmsTaskStatus.RUN.getCode())); .and(wrapper -> {
wrapper.eq(Task::getTaskStatus, WmsTaskStatus.WAIT.getCode())
.or().eq(Task::getTaskStatus, WmsTaskStatus.RUN.getCode());
}));
Map<Integer, Integer> runningTaskNumToEquipmentMap = new HashMap<>(); Map<Integer, Integer> runningTaskNumToEquipmentMap = new HashMap<>();
Map<Integer, List<Task>> newTaskToEquipmentMap = new HashMap<>(); Map<Integer, List<Task>> newTaskToEquipmentMap = new HashMap<>();
for (Stand stacker : stackerList) { for (Stand stacker : stackerList) {
// 找这台堆垛机正在执行的拣选出库任务数量 // 找这台堆垛机正在执行的拣选出库任务数量
runningTaskNumToEquipmentMap.put(stacker.getEquipmentId(), 0); runningTaskNumToEquipmentMap.put(stacker.getEquipmentId(), 0);
// 查询每台堆垛机还没有下发的任务 // 查询每台堆垛机还没有下发的任务
List<Task> stackNewTasks = allTasks.stream().filter(task -> List<Task> stackNewTasks = new ArrayList<>(allTasks.stream().filter(task ->
task.getIsPicking() == 1 && StringUtils.isNotEmpty(task.getPickStand()) task.getIsPicking() == 1 && StringUtils.isNotEmpty(task.getPickStand())
&& Objects.equals(stacker.getEquipmentId(), instantLocationMap.get(task.getOrigin()).getEquipmentId()) && Objects.equals(stacker.getEquipmentId(), instantLocationMap.get(task.getOrigin()).getEquipmentId())
).toList(); ).toList());
newTaskToEquipmentMap.put(stacker.getEquipmentId(), stackNewTasks); newTaskToEquipmentMap.put(stacker.getEquipmentId(), stackNewTasks);
} }
stackRunningTasks.forEach(task -> { stackRunningTasks.forEach(task -> {
@ -209,8 +229,16 @@ public class WmsJobServiceImplements implements IWmsJobService {
} }
}); });
for (Stand stacker : stackerList) { for (Stand stacker : stackerList) {
int availableTaskNum = 2 - runningTaskNumToEquipmentMap.get(stacker.getEquipmentId()); if (request.size() >= maxWcsAcceptNums || remainVehicleNums <= 0) {
// 超过wcs一次可接受数量
break;
}
int availableTaskNum = 4 - runningTaskNumToEquipmentMap.get(stacker.getEquipmentId());
while (availableTaskNum > 0) { while (availableTaskNum > 0) {
if (request.size() >= maxWcsAcceptNums || remainVehicleNums <= 0) {
// 超过wcs一次可接受数量
break;
}
// 可以继续发任务 // 可以继续发任务
List<Task> currentStackerTasks = newTaskToEquipmentMap.get(stacker.getEquipmentId()); List<Task> currentStackerTasks = newTaskToEquipmentMap.get(stacker.getEquipmentId());
// 从这些任务里面找到最适合的任务下发 // 从这些任务里面找到最适合的任务下发
@ -281,6 +309,7 @@ public class WmsJobServiceImplements implements IWmsJobService {
if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务 if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务
// 查询一下前置的任务有没有存在存在则不下发 // 查询一下前置的任务有没有存在存在则不下发
if (taskService.exists(new LambdaQueryWrapper<Task>().eq(Task::getTaskId, task.getPreTask()))) { if (taskService.exists(new LambdaQueryWrapper<Task>().eq(Task::getTaskId, task.getPreTask()))) {
currentStackerTasks.remove(task);
continue; continue;
} }
} }
@ -303,11 +332,13 @@ public class WmsJobServiceImplements implements IWmsJobService {
// 移除已经发送过的任务 // 移除已经发送过的任务
currentStackerTasks.removeIf(task -> task.getVehicleId().equals(vehicleId)); currentStackerTasks.removeIf(task -> task.getVehicleId().equals(vehicleId));
newTaskToEquipmentMap.replace(stacker.getEquipmentId(), currentStackerTasks); newTaskToEquipmentMap.replace(stacker.getEquipmentId(), currentStackerTasks);
// 可用数量-1
availableTaskNum--;
// 剩余线体可继续出库料箱数量
remainVehicleNums--;
} else { } else {
break; break;
} }
// 可用数量-1
availableTaskNum--;
} }
} }
if (request.size() == 0) { if (request.size() == 0) {

View File

@ -106,6 +106,8 @@ public class StockServiceImplements extends ServiceImpl<StockMapper, Stock> impl
tempResult.setNumOfKanban(currentGoodsList.get(0).getKanbanNum()); tempResult.setNumOfKanban(currentGoodsList.get(0).getKanbanNum());
tempResult.setNumOfPerKanban(currentGoodsList.get(0).getQuantityPerKanban()); tempResult.setNumOfPerKanban(currentGoodsList.get(0).getQuantityPerKanban());
tempResult.setKanbanList(currentGoodsList.get(0).getKanbanList()); tempResult.setKanbanList(currentGoodsList.get(0).getKanbanList());
tempResult.setHeat(currentGoodsList.get(0).getHeat());// 热度
tempResult.setReleasePoint(currentGoodsList.get(0).getReleasePoint());// 卸货点
} }
resultList.add(tempResult); resultList.add(tempResult);
} }

View File

@ -100,13 +100,13 @@ public class UploadStationConfigListener implements ReadListener<StationConfigEx
oldConfig.setLastUpdateUser(uploadUser); oldConfig.setLastUpdateUser(uploadUser);
oldConfig.setModel(stationConfigExcelVo.getModel()); oldConfig.setModel(stationConfigExcelVo.getModel());
oldConfig.setBigBox(stationConfigExcelVo.getBigBox()); oldConfig.setBigBox(stationConfigExcelVo.getBigBox());
oldWorkStationConfigMap.replace(key, oldConfig); newWorkStationConfigMap.put(key, oldConfig);
} else { } else {
WorkStationConfig newStationConfig = BeanUtil.copyProperties(stationConfigExcelVo, WorkStationConfig.class); WorkStationConfig newStationConfig = BeanUtil.copyProperties(stationConfigExcelVo, WorkStationConfig.class);
newStationConfig.setConfigId(generateId("STATION-CONFIG_")); newStationConfig.setConfigId(generateId("STATION-CONFIG_"));
newStationConfig.setLastUpdateTime(LocalDateTime.now()); newStationConfig.setLastUpdateTime(LocalDateTime.now());
newStationConfig.setLastUpdateUser(uploadUser); newStationConfig.setLastUpdateUser(uploadUser);
oldWorkStationConfigMap.put(key, newStationConfig); newWorkStationConfigMap.put(key, newStationConfig);
} }
} }
} }

View File

@ -15,6 +15,6 @@ import java.math.BigDecimal;
public class ClcKanbanRequirementExcelVo extends KanbanExcelVo { public class ClcKanbanRequirementExcelVo extends KanbanExcelVo {
@ExcelProperty("料号") @ExcelProperty("料号")
private String goodsId; private String goodsId;
@ExcelProperty("需求数量") @ExcelProperty("卸货点")
private BigDecimal requireNum; private String releasePoint;
} }

View File

@ -3,6 +3,7 @@ package com.wms.utils.excel.vo;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat; import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.wms.entity.table.Goods; import com.wms.entity.table.Goods;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -69,7 +70,7 @@ public class GoodsExcelVo extends KanbanExcelVo {
/** /**
* 料箱类型描述 * 料箱类型描述
*/ */
@ExcelProperty("料箱类型描述") @ExcelProperty("来料包装")
private String vehicleTypeDescription; private String vehicleTypeDescription;
/** /**
* 料箱类型 * 料箱类型
@ -91,7 +92,7 @@ public class GoodsExcelVo extends KanbanExcelVo {
/** /**
* 看板的数量 * 看板的数量
*/ */
@ExcelProperty("Number of kanban") @ExcelProperty("Number of Kanban")
private BigDecimal kanbanNum; private BigDecimal kanbanNum;
/** /**
* 补货点 * 补货点
@ -129,6 +130,16 @@ public class GoodsExcelVo extends KanbanExcelVo {
*/ */
@ExcelProperty("最近更新用户") @ExcelProperty("最近更新用户")
private String lastUpdateUser; private String lastUpdateUser;
/**
* 热度
*/
@ExcelProperty("热度")
private String heat;
/**
* 卸货点
*/
@ExcelProperty("卸货点")
private String releasePoint;
/** /**
* 从数据库实体转换为excel对象 * 从数据库实体转换为excel对象

View File

@ -125,7 +125,7 @@ public class KanbanExcelVo {
int sortNum = -1; int sortNum = -1;
try { try {
// 获取id排序 // 获取id排序
sortNum = Integer.parseInt(field.getName().split("#")[1]); sortNum = Integer.parseInt(field.getName().split("KANBAN")[1]);
} catch (Exception e) { } catch (Exception e) {
continue; continue;
} }

View File

@ -37,7 +37,7 @@ public class StationConfigExcelVo {
/** /**
* 工单数/大盒子 * 工单数/大盒子
*/ */
@ExcelProperty("orderQuantity") @ExcelProperty("工单数/大盒子")
private Integer orderQuantity; private Integer orderQuantity;
/** /**
* 工位 * 工位