Compare commits

..

2 Commits

Author SHA1 Message Date
504b7cb96b 新方式暂存 2025-11-13 08:46:47 +08:00
3ab5b1af0b 修正 2025-10-16 09:31:02 +08:00
13 changed files with 835 additions and 233 deletions

View File

@ -1,8 +1,11 @@
package com.wms.constants.enums;
import lombok.Getter;
/**
* 库存状态枚举
*/
@Getter
public enum StockStatus {
OK(0, "库存正常"),
OUT(1, "出库中"),
@ -10,6 +13,7 @@ public enum StockStatus {
MOVE(3, "移库中"),
PICKING(4, "拣选中"),
BACK(5, "回库中"),
OUTED(6, "已出库"),
LOCK(9, "库存锁定");
private final Integer code;
@ -21,11 +25,4 @@ public enum StockStatus {
this.value = value;
}
public Integer getCode() {
return code;
}
public String getValue() {
return value;
}
}

View File

@ -490,8 +490,8 @@ public class TaskController {
taskService.remove(new LambdaQueryWrapper<Task>().eq(Task::getTaskId, inTask.getTaskId()));
// 移除当前料箱所有的拣选任务
pickTaskService.remove(new LambdaQueryWrapper<PickTask>().eq(PickTask::getVehicleId, inTask.getVehicleId()));
// 移除当前料箱所有的outsideVehicles
outsideVehiclesService.remove(new LambdaQueryWrapper<OutsideVehicles>().eq(OutsideVehicles::getVehicleId, inTask.getVehicleId()));
// 移除当前料箱所有的outsideVehicles---todo 这张表已经废弃不用
// outsideVehiclesService.remove(new LambdaQueryWrapper<OutsideVehicles>().eq(OutsideVehicles::getVehicleId, inTask.getVehicleId()));
// 清除当前料箱的所有盘点任务
inventoryService.remove(new LambdaQueryWrapper<InventoryList>().eq(InventoryList::getVehicleId, inTask.getVehicleId()));
}
@ -512,7 +512,7 @@ public class TaskController {
.set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())
.eq(Vehicle::getVehicleId, outTask.getVehicleId())
.ne(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode()));
// 当前载具上所有库存状态设置为拣选
// 当前载具上所有库存状态设置为拣选---todo 是否要更改为outed状态
stockService.update(new LambdaUpdateWrapper<Stock>()
.set(Stock::getStockStatus, StockStatus.PICKING.getCode())
.eq(Stock::getVehicleId, outTask.getVehicleId())
@ -522,12 +522,12 @@ public class TaskController {
.set(PickTask::getPickStatus, PickTaskStatusEnum.NEW.getCode())
.eq(PickTask::getVehicleId, outTask.getVehicleId())
.eq(PickTask::getPickStatus, PickTaskStatusEnum.TEMP.getCode()));
// 设置特殊
standStackerTaskService.update(new LambdaUpdateWrapper<StandStackerTask>()
.set(StandStackerTask::getTaskStatus, 1)
.set(StandStackerTask::getFinishTime, LocalDateTime.now())
.eq(StandStackerTask::getVehicleId, outTask.getVehicleId())
.ne(StandStackerTask::getTaskStatus, 1));
// 设置特殊---todo 此表废弃
// standStackerTaskService.update(new LambdaUpdateWrapper<StandStackerTask>()
// .set(StandStackerTask::getTaskStatus, 1)
// .set(StandStackerTask::getFinishTime, LocalDateTime.now())
// .eq(StandStackerTask::getVehicleId, outTask.getVehicleId())
// .ne(StandStackerTask::getTaskStatus, 1));
} else {// 代表整出
// 删除当前载具上所有库存
List<Stock> removeStocks = stockService.list(new LambdaQueryWrapper<Stock>().eq(Stock::getVehicleId, outTask.getVehicleId()));
@ -1084,23 +1084,8 @@ public class TaskController {
wcsETaskRequest.setOrderId(generateId(workQuery.getGoodsId() + "_"));
wcsETaskRequest.setVehicleNo(vehicleId);
String sendToWcsETaskUrl = configMap.get(ConfigMapKeyEnum.URL_WCS_E_TASK.getConfigKey());
if (StringUtils.isEmpty(sendToWcsETaskUrl)) {
// url地址为空
logger.error("向Wcs发送电子标签亮灯任务的地址为空");
throw new Exception("向Wcs发送电子标签亮灯任务的地址为空");
} else {
// 发送信息
logger.info("发送电子标签亮灯请求:{}", convertJsonString(wcsETaskRequest));
ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(sendToWcsETaskUrl, convertJsonString(wcsETaskRequest)), ResponseEntity.class);
try {
logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "发送电子标签任务", "eTagTask", convertJsonString(wcsETaskRequest), convertJsonString(result), sendToWcsETaskUrl, LocalDateTime.now(), "WMS"));
} catch (Exception e) {
logger.error("插入日志错误");
}
if (result == null || !Objects.equals(result.getCode(), ResponseCode.OK.getCode())) {
logger.error("发送电子标签亮灯任务失败:{}", convertJsonString(result));
throw new Exception("发送电子标签亮灯任务失败");
} else {
// TODO 这里是模拟的
// 更新workFlow数据
workFlowService.updateBatchById(workFlows);
// 更新亮灯数据
@ -1109,8 +1094,36 @@ public class TaskController {
.set(ETagLocation::getTaskType, wcsETaskRequest.getTaskType())
.set(ETagLocation::getVehicleNo, wcsETaskRequest.getVehicleNo())
.in(ETagLocation::getELocationId, eTaskDataList.stream().map(ETaskData::getLocation).collect(Collectors.toList())));
}
}
// TODO 模拟结束要去掉注释
// if (StringUtils.isEmpty(sendToWcsETaskUrl)) {
// // url地址为空
// logger.error("向Wcs发送电子标签亮灯任务的地址为空");
// throw new Exception("向Wcs发送电子标签亮灯任务的地址为空");
// } else {
// // 发送信息
// logger.info("发送电子标签亮灯请求:{}", convertJsonString(wcsETaskRequest));
// ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(sendToWcsETaskUrl, convertJsonString(wcsETaskRequest)), ResponseEntity.class);
// try {
// logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "发送电子标签任务", "eTagTask", convertJsonString(wcsETaskRequest), convertJsonString(result), sendToWcsETaskUrl, LocalDateTime.now(), "WMS"));
// } catch (Exception e) {
// logger.error("插入日志错误");
// }
// if (result == null || !Objects.equals(result.getCode(), ResponseCode.OK.getCode())) {
// logger.error("发送电子标签亮灯任务失败:{}", convertJsonString(result));
// throw new Exception("发送电子标签亮灯任务失败");
// } else {
// // 更新workFlow数据
// workFlowService.updateBatchById(workFlows);
// // 更新亮灯数据
// etagLocationService.update(new LambdaUpdateWrapper<ETagLocation>()
// .set(ETagLocation::getPickStatus, 1)
// .set(ETagLocation::getTaskType, wcsETaskRequest.getTaskType())
// .set(ETagLocation::getVehicleNo, wcsETaskRequest.getVehicleNo())
// .in(ETagLocation::getELocationId, eTaskDataList.stream().map(ETaskData::getLocation).collect(Collectors.toList())));
// }
// }
}
// 更新站台数据
standService.update(new LambdaUpdateWrapper<Stand>()
@ -1399,39 +1412,49 @@ public class TaskController {
}
// 更新实际拣选数量
workFlow.setPickedNum(workFlow.getPickedNum().add(BigDecimal.valueOf(eTaskFeedbackRequest.getConfirmNum())));
if (eTaskFeedbackRequest.getConfirmNum().compareTo(eTaskFeedbackRequest.getNeedNum()) < 0) {
int diffNum = eTaskFeedbackRequest.getNeedNum() - eTaskFeedbackRequest.getConfirmNum();
// 查站台要料表---未分配以及分配但未完全分配
GoodsToStation goodsToStation = goodsToStationService.getOne(new LambdaQueryWrapper<GoodsToStation>()
.eq(GoodsToStation::getWorkStation, workFlow.getWorkStation())
.eq(GoodsToStation::getGoodsId, workFlow.getGoodsId())
.last("limit 1"));
if (goodsToStation != null) {
// 更新站台要料数量
BigDecimal newDistributeNum = goodsToStation.getDistributedNum().subtract(BigDecimal.valueOf(diffNum));
goodsToStation.setDistributedNum(newDistributeNum.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : newDistributeNum);
goodsToStation.setDistributeStatus(1);
goodsToStationService.updateById(goodsToStation);
}
// 查询当前站台的拣货任务
PickTask pickTask = pickTaskService.getOne(new LambdaQueryWrapper<PickTask>()
.eq(PickTask::getStandId, workFlow.getWorkStation())
.eq(PickTask::getPickStatus, PickTaskStatusEnum.FINISH.getCode())
.last("limit 1"));
if (pickTask != null) {
// 更新当前的outsideVehicles状态为一个新状态拉取任务时不拉取它
List<OutsideVehicles> outsideVehiclesList = outsideVehiclesService.list(new LambdaQueryWrapper<OutsideVehicles>()
.eq(OutsideVehicles::getVehicleId, pickTask.getVehicleId())
.eq(OutsideVehicles::getGoodsId, workFlow.getGoodsId()));
for (OutsideVehicles outsideVehicles : outsideVehiclesList) {
outsideVehicles.setOutStatus(2);
}
outsideVehiclesService.updateBatchById(outsideVehiclesList);
}
// 更新workFlow状态
workFlow.setLightStatus(0);// 未亮灯
workFlow.setWorkStatus(1);// 正在做
} else {
// todo---下面两张表废弃使用
// if (eTaskFeedbackRequest.getConfirmNum().compareTo(eTaskFeedbackRequest.getNeedNum()) < 0) {
// int diffNum = eTaskFeedbackRequest.getNeedNum() - eTaskFeedbackRequest.getConfirmNum();
// // 查站台要料表---未分配以及分配但未完全分配
// GoodsToStation goodsToStation = goodsToStationService.getOne(new LambdaQueryWrapper<GoodsToStation>()
// .eq(GoodsToStation::getWorkStation, workFlow.getWorkStation())
// .eq(GoodsToStation::getGoodsId, workFlow.getGoodsId())
// .last("limit 1"));
// if (goodsToStation != null) {
// // 更新站台要料数量
// BigDecimal newDistributeNum = goodsToStation.getDistributedNum().subtract(BigDecimal.valueOf(diffNum));
// goodsToStation.setDistributedNum(newDistributeNum.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : newDistributeNum);
// goodsToStation.setDistributeStatus(1);
// goodsToStationService.updateById(goodsToStation);
// }
// // 查询当前站台的拣货任务
// PickTask pickTask = pickTaskService.getOne(new LambdaQueryWrapper<PickTask>()
// .eq(PickTask::getStandId, workFlow.getWorkStation())
// .eq(PickTask::getPickStatus, PickTaskStatusEnum.FINISH.getCode())
// .last("limit 1"));
// if (pickTask != null) {
// // 更新当前的outsideVehicles状态为一个新状态拉取任务时不拉取它
// List<OutsideVehicles> outsideVehiclesList = outsideVehiclesService.list(new LambdaQueryWrapper<OutsideVehicles>()
// .eq(OutsideVehicles::getVehicleId, pickTask.getVehicleId())
// .eq(OutsideVehicles::getGoodsId, workFlow.getGoodsId()));
// for (OutsideVehicles outsideVehicles : outsideVehiclesList) {
// outsideVehicles.setOutStatus(2);
// }
// outsideVehiclesService.updateBatchById(outsideVehiclesList);
// }
// // 更新workFlow状态
// workFlow.setLightStatus(0);// 未亮灯
// workFlow.setWorkStatus(1);// 正在做
// } else {
// if (workFlow.getPickedNum().compareTo(workFlow.getNeedNum()) < 0) {
// // 缺料未完成
// workFlow.setLightStatus(0);// 未亮灯
// workFlow.setWorkStatus(1);// 正在做
// } else {
// workFlow.setLightStatus(2);// 已拍灯
// workFlow.setWorkStatus(2);// 已完成
// }
// }
if (workFlow.getPickedNum().compareTo(workFlow.getNeedNum()) < 0) {
// 缺料未完成
workFlow.setLightStatus(0);// 未亮灯
@ -1440,7 +1463,6 @@ public class TaskController {
workFlow.setLightStatus(2);// 已拍灯
workFlow.setWorkStatus(2);// 已完成
}
}
// 更新workFlow
workFlow.setFinishTime(LocalDateTime.now());
workFlowService.updateById(workFlow);
@ -1560,8 +1582,8 @@ public class TaskController {
.last("limit 1"));
if (pickTask == null) {
// 没有拣货任务直接放行
// 调用Wcs的放行接口
wcsService.sendWcsDisposeVehicle(new WcsDisposeVehicleRequest(standId, null));
// 调用Wcs的放行接口 TODO 测试时注释
// wcsService.sendWcsDisposeVehicle(new WcsDisposeVehicleRequest(standId, null));
// 更新站台信息
standService.update(new LambdaUpdateWrapper<Stand>()
.set(Stand::getLastUseTime, LocalDateTime.now())
@ -1587,24 +1609,25 @@ public class TaskController {
stockService.updateById(existStock);
stockUpdateRecordService.addStockUpdateRecord(originStock, existStock, StockUpdateReasonEnum.CONFIRM_UPDATE.getReason(), workConfirmRequest.getUserName(), quantityBefore);
}
OutsideVehicles currentGoodsVehicle = outsideVehiclesService.getOne(new LambdaQueryWrapper<OutsideVehicles>()
.eq(OutsideVehicles::getVehicleId, pickTask.getVehicleId())
.eq(OutsideVehicles::getGoodsId, workConfirmRequest.getGoodsId())
.last("limit 1"));
if (workConfirmRequest.getRemainNumReal().compareTo(BigDecimal.ZERO) == 0) {// 实际剩余数量为0
// 更新流转载具表剩余数量
if (currentGoodsVehicle != null) {
currentGoodsVehicle.setRemainNum(BigDecimal.ZERO);
currentGoodsVehicle.setOutStatus(2);
outsideVehiclesService.updateById(currentGoodsVehicle);
}
} else {
// 更新流转载具表剩余数量 todo
if (currentGoodsVehicle != null) {
currentGoodsVehicle.setRemainNum(currentGoodsVehicle.getRemainNum().add(workConfirmRequest.getRemainNumReal().subtract(workConfirmRequest.getRemainNumOrigin())));
outsideVehiclesService.updateById(currentGoodsVehicle);
}
}
// todo---此表废弃使用
// OutsideVehicles currentGoodsVehicle = outsideVehiclesService.getOne(new LambdaQueryWrapper<OutsideVehicles>()
// .eq(OutsideVehicles::getVehicleId, pickTask.getVehicleId())
// .eq(OutsideVehicles::getGoodsId, workConfirmRequest.getGoodsId())
// .last("limit 1"));
// if (workConfirmRequest.getRemainNumReal().compareTo(BigDecimal.ZERO) == 0) {// 实际剩余数量为0
// // 更新流转载具表剩余数量
// if (currentGoodsVehicle != null) {
// currentGoodsVehicle.setRemainNum(BigDecimal.ZERO);
// currentGoodsVehicle.setOutStatus(2);
// outsideVehiclesService.updateById(currentGoodsVehicle);
// }
// } else {
// // 更新流转载具表剩余数量 todo
// if (currentGoodsVehicle != null) {
// currentGoodsVehicle.setRemainNum(currentGoodsVehicle.getRemainNum().add(workConfirmRequest.getRemainNumReal().subtract(workConfirmRequest.getRemainNumOrigin())));
// outsideVehiclesService.updateById(currentGoodsVehicle);
// }
// }
} else {
if (existStock != null && existStock.getGoodsRelated() != null) {
if (workConfirmRequest.getRemainNumOrigin().compareTo(BigDecimal.ZERO) == 0) {
@ -1615,13 +1638,14 @@ public class TaskController {
existStock.setGoodsRelated(goodsDetail);
stockService.updateById(existStock);
stockUpdateRecordService.addStockUpdateRecord(originStock, existStock, StockUpdateReasonEnum.CONFIRM_UPDATE.getReason(), workConfirmRequest.getUserName(), quantityBefore);
OutsideVehicles currentGoodsVehicle = outsideVehiclesService.getOne(new LambdaQueryWrapper<OutsideVehicles>()
.eq(OutsideVehicles::getVehicleId, pickTask.getVehicleId())
.eq(OutsideVehicles::getGoodsId, workConfirmRequest.getGoodsId())
.last("limit 1"));
currentGoodsVehicle.setRemainNum(BigDecimal.ZERO);
currentGoodsVehicle.setOutStatus(2);
outsideVehiclesService.updateById(currentGoodsVehicle);
// todo---此表废弃使用
// OutsideVehicles currentGoodsVehicle = outsideVehiclesService.getOne(new LambdaQueryWrapper<OutsideVehicles>()
// .eq(OutsideVehicles::getVehicleId, pickTask.getVehicleId())
// .eq(OutsideVehicles::getGoodsId, workConfirmRequest.getGoodsId())
// .last("limit 1"));
// currentGoodsVehicle.setRemainNum(BigDecimal.ZERO);
// currentGoodsVehicle.setOutStatus(2);
// outsideVehiclesService.updateById(currentGoodsVehicle);
}
}
}
@ -1665,8 +1689,8 @@ public class TaskController {
pickTaskRecordService.save(pickTaskRecord);
// 删除当前拣选任务
pickTaskService.removeById(pickTask);
// 不需要放行
wcsService.sendWcsDisposeVehicle(new WcsDisposeVehicleRequest(standId, pickTask.getVehicleId()));
// 不需要放行 TODO 测试时注释
// wcsService.sendWcsDisposeVehicle(new WcsDisposeVehicleRequest(standId, pickTask.getVehicleId()));
// 判断是不是已经完成工作
if (workFlowService.exists(new LambdaQueryWrapper<WorkFlow>()
.eq(WorkFlow::getWorkStation, standId)
@ -1704,8 +1728,8 @@ public class TaskController {
pickTaskRecordService.save(pickTaskRecord);
// 删除当前拣选任务
pickTaskService.removeById(pickTask);
// 放行
wcsService.sendWcsDisposeVehicle(new WcsDisposeVehicleRequest(standId, pickTask.getVehicleId()));
// 放行 TODO 测试时注释
// wcsService.sendWcsDisposeVehicle(new WcsDisposeVehicleRequest(standId, pickTask.getVehicleId()));
// 判断是不是已经完成工作
if (workFlowService.exists(new LambdaQueryWrapper<WorkFlow>()
.eq(WorkFlow::getWorkStation, standId)

View File

@ -26,4 +26,8 @@ public class StockDetailInfo {
* 入库库存总数
*/
private BigDecimal totalNum;
/**
* 可用数量---当回库时设置为和剩余数量一致
*/
private BigDecimal usableNum;
}

View File

@ -54,6 +54,11 @@ public class WorkFlowVo {
*/
@JsonProperty("needNum")
private BigDecimal needNum;
/**
* 需求数量
*/
@JsonProperty("distributedNum")
private BigDecimal distributedNum;
/**
* 亮灯状态
* 0未亮灯

View File

@ -104,4 +104,9 @@ public class WorkFlow {
*/
@TableField("big_box")
private String bigBox;
/**
* 已分配数量
*/
@TableField("distributed_num")
private BigDecimal distributedNum;
}

View File

@ -101,4 +101,9 @@ public class WorkFlowLast {
*/
@TableField("big_box")
private String bigBox;
/**
* 已分配数量
*/
@TableField("distributed_num")
private BigDecimal distributedNum;
}

View File

@ -25,6 +25,6 @@ public class DataClearExecutor implements Job {
// 删除日志数据
wmsJobService.deleteLogsRegularly();
// 删除记录数据
wmsJobService.deleteRecordsRegularly();
// wmsJobService.deleteRecordsRegularly();
}
}

View File

@ -1,8 +1,5 @@
package com.wms.quartz.job_executor;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wms.constants.enums.ConfigMapKeyEnum;
import com.wms.entity.table.Stand;
import com.wms.service.StandService;
import com.wms.service.business.IWorkService;
import com.wms.utils.StringUtils;
@ -12,7 +9,6 @@ import org.quartz.*;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import static com.wms.config.InitLocalConfig.configMap;
import static com.wms.utils.StringUtils.convertJsonString;
@ -45,6 +41,8 @@ public class KateWorkExecutor implements Job {
createWork();
// 执行工作
doWork();
// 修复工作
repairWork();
}
/**
@ -63,13 +61,13 @@ public class KateWorkExecutor implements Job {
try {
workService.createTempWorkFlows();
} catch (Exception e) {
log.error("创建当日工作发生错误:{}", e.getMessage());
log.error("创建当日工作发生异常:{}", convertJsonString(e));
}
try {
// 分配工作
workService.distributeWorks();
} catch (Exception e) {
log.error("分配工作时发生错误:{}", e.getMessage());
log.error("分配工作时发生异常:{}", convertJsonString(e));
}
}
@ -81,17 +79,33 @@ public class KateWorkExecutor implements Job {
if (StringUtils.isEmpty(startWork) || !startWork.equals("1")) {
return;
}
// 轮询工作站台判断是否需要下发任务
List<Stand> stands = standService.list(new LambdaQueryWrapper<Stand>()
.eq(Stand::getIsLock, 0).eq(Stand::getStandStatus, 0)
.eq(Stand::getStandType, 2));
List<String> standIds = stands.stream().map(Stand::getStandId).toList();
for (String standId : standIds) {
try {
workService.doWork(standId);
workService.doWorkMethod2();
} catch (Exception e) {
log.error("执行工作时发生错误:{}", convertJsonString(e.getMessage()));
}
log.error("执行工作时发生异常:{}", convertJsonString(e));
}
// // 轮询工作站台判断是否需要下发任务
// List<Stand> stands = standService.list(new LambdaQueryWrapper<Stand>()
// .eq(Stand::getIsLock, 0).eq(Stand::getStandStatus, 0)
// .eq(Stand::getStandType, 2));
// List<String> standIds = stands.stream().map(Stand::getStandId).toList();
// for (String standId : standIds) {
// try {
// workService.doWork(standId);
// } catch (Exception e) {
// log.error("执行工作时发生错误:{}", convertJsonString(e.getMessage()));
// }
// }
}
/**
* 修复工作
*/
public void repairWork() {
try {
workService.repairWork();
} catch (Exception e) {
log.error("修复工作发生异常:{}", convertJsonString(e));
}
}
}

View File

@ -13,6 +13,16 @@ public interface IWorkService {
*/
void doWork(String workStation) throws Exception;
/**
* 新的执行工作
*/
void doWorkMethod2();
/**
* 修复工作
*/
void repairWork();
/**
* 完成工作
* @param workStation 工作站台

View File

@ -14,6 +14,7 @@ import com.wms.entity.app.wcs.WcsTaskRequest;
import com.wms.entity.table.*;
import com.wms.service.*;
import com.wms.service.business.IWmsJobService;
import com.wms.utils.DbTransUtils;
import com.wms.utils.HttpUtils;
import com.wms.utils.StringUtils;
import com.wms.utils.WmsUtils;
@ -65,6 +66,7 @@ public class WmsJobServiceImplements implements IWmsJobService {
private final IStockUpdateRecordService iStockUpdateRecordService;// 库存更新记录服务
private final UploadRecordService uploadRecordService;// 文件上传记录服务
private final InventoryHistoryService inventoryHistoryService;
private final DbTransUtils dbTransUtils;
/**
* 发送正常的任务
@ -103,12 +105,12 @@ public class WmsJobServiceImplements implements IWmsJobService {
continue;
}
}
if (task.getTaskPriority() == 1) {
if (Objects.equals(task.getTaskType(), TaskType.OUT.getCode())
&& task.getIsPicking() == 1 && StringUtils.isNotEmpty(task.getPickStand())) {
continue;
}
}
// if (task.getTaskPriority() == 1) {
// if (Objects.equals(task.getTaskType(), TaskType.OUT.getCode())
// && task.getIsPicking() == 1 && StringUtils.isNotEmpty(task.getPickStand())) {
// continue;
// }
// }
// 创建发送的任务
WcsTaskRequest tempTask = new WcsTaskRequest();
tempTask.setTaskId(task.getTaskGroup());
@ -127,48 +129,50 @@ public class WmsJobServiceImplements implements IWmsJobService {
// 已经发送过的任务组
taskGroupIds.add(task.getTaskGroup());
}
if (request.size() == 0) {
if (request.isEmpty()) {
// 没有新任务发送
return;
}
// 发送任务
String url = configMap.get(ConfigMapKeyEnum.URL_WCS_TASK.getConfigKey());
if (url != null) {
logger.info("向WCS发送任务地址{},请求详情:{}", url, convertJsonString(request));
ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(request)), ResponseEntity.class);
try {
logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送任务", "SetStackerTask", JSON.toJSONString(request), JSON.toJSONString(result), url, LocalDateTime.now(), "WMS"));
} catch (Exception e) {
logger.error("插入日志错误。");
}
if (result == null) {
logger.error("发送任务异常。");
} else {
if (Objects.equals(ResponseCode.OK.getCode(), result.getCode())) {
logger.info("发送WCS任务成功。");
taskService.update(new LambdaUpdateWrapper<Task>()
.set(Task::getTaskStatus, WmsTaskStatus.WAIT.getCode())
.in(Task::getTaskGroup, taskGroupIds)
.eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode()));
} else {
// 判断returnData的数据
if (result.getReturnData() != null) {
List<WcsTaskRequest> errorTasks = JSON.parseArray(result.getReturnData().toString(), WcsTaskRequest.class);
if (!errorTasks.isEmpty()) {
List<String> failedTaskIds = errorTasks.stream().map(WcsTaskRequest::getTaskId).distinct().toList();
// 更新任务状态为异常
taskService.update(new LambdaUpdateWrapper<Task>()
.set(Task::getTaskStatus, WmsTaskStatus.EXCEPTION.getCode())
.in(Task::getTaskGroup, failedTaskIds)
.eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode()));
}
}
logger.error("发送任务错误:{}", convertJsonString(result));
}
}
} else {
logger.error("WCS发送任务地址为空。");
}
// 下面这行代码模拟wcs下发成功
simulateSendPickOutTasks(taskGroupIds, Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
// // 发送任务
// String url = configMap.get(ConfigMapKeyEnum.URL_WCS_TASK.getConfigKey());
// if (url != null) {
// logger.info("向WCS发送任务地址{},请求详情:{}", url, convertJsonString(request));
// ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(request)), ResponseEntity.class);
// try {
// logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送任务", "SetStackerTask", JSON.toJSONString(request), JSON.toJSONString(result), url, LocalDateTime.now(), "WMS"));
// } catch (Exception e) {
// logger.error("保存发送任务的日志错误。");
// }
// if (result == null) {
// logger.error("发送任务异常。");
// } else {
// if (Objects.equals(ResponseCode.OK.getCode(), result.getCode())) {
// logger.info("发送WCS任务成功。");
// taskService.update(new LambdaUpdateWrapper<Task>()
// .set(Task::getTaskStatus, WmsTaskStatus.WAIT.getCode())
// .in(Task::getTaskGroup, taskGroupIds)
// .eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode()));
// } else {
// // 判断returnData的数据
// if (result.getReturnData() != null) {
// List<WcsTaskRequest> errorTasks = JSON.parseArray(result.getReturnData().toString(), WcsTaskRequest.class);
// if (!errorTasks.isEmpty()) {
// List<String> failedTaskIds = errorTasks.stream().map(WcsTaskRequest::getTaskId).distinct().toList();
// // 更新任务状态为异常
// taskService.update(new LambdaUpdateWrapper<Task>()
// .set(Task::getTaskStatus, WmsTaskStatus.EXCEPTION.getCode())
// .in(Task::getTaskGroup, failedTaskIds)
// .eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode()));
// }
// }
// logger.error("发送任务错误:{}", convertJsonString(result));
// }
// }
// } else {
// logger.error("WCS发送任务地址为空。");
// }
}
} catch (Exception exception) {
logger.error("向WCS发送任务时发生异常{}", convertJsonString(exception));
@ -572,30 +576,32 @@ public class WmsJobServiceImplements implements IWmsJobService {
requestSingle.setRemark("站台拣选任务");
request.add(requestSingle);
}
if (!request.isEmpty()) {
// 发送任务
String url = configMap.get(ConfigMapKeyEnum.URL_WCS_PICK_TASK.getConfigKey());
if (url != null) {
logger.info("向WCS发送拣选任务地址{},请求详情:{}", url, convertJsonString(request));
ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(request)), ResponseEntity.class);
try {
logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送拣选任务", "setConveyTask", convertJsonString(request), convertJsonString(result), url, LocalDateTime.now(), "WMS"));
} catch (Exception e) {
logger.error("插入日志错误。");
}
if (result != null && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) {
logger.info("发送拣选任务成功。");
pickTaskService.update(new LambdaUpdateWrapper<PickTask>()
.set(PickTask::getPickStatus, PickTaskStatusEnum.SEND.getCode())
.in(PickTask::getVehicleId, vehicleAndStansMap.keySet())
.eq(PickTask::getPickStatus, PickTaskStatusEnum.NEW.getCode()));
} else {
logger.error("发送拣选任务错误:{}", convertJsonString(result));
}
} else {
logger.error("WCS发送拣选任务地址为空。");
}
}
// 下面是模拟发送wcs拣选任务
simulateSendPickTasks(vehicleAndStansMap.keySet().stream().toList());
// if (!request.isEmpty()) {
// // 发送任务
// String url = configMap.get(ConfigMapKeyEnum.URL_WCS_PICK_TASK.getConfigKey());
// if (url != null) {
// logger.info("向WCS发送拣选任务地址{},请求详情:{}", url, convertJsonString(request));
// ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(request)), ResponseEntity.class);
// try {
// logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送拣选任务", "setConveyTask", convertJsonString(request), convertJsonString(result), url, LocalDateTime.now(), "WMS"));
// } catch (Exception e) {
// logger.error("插入日志错误。");
// }
// if (result != null && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) {
// logger.info("发送拣选任务成功。");
// pickTaskService.update(new LambdaUpdateWrapper<PickTask>()
// .set(PickTask::getPickStatus, PickTaskStatusEnum.SEND.getCode())
// .in(PickTask::getVehicleId, vehicleAndStansMap.keySet())
// .eq(PickTask::getPickStatus, PickTaskStatusEnum.NEW.getCode()));
// } else {
// logger.error("发送拣选任务错误:{}", convertJsonString(result));
// }
// } else {
// logger.error("WCS发送拣选任务地址为空。");
// }
// }
} catch (Exception exception) {
logger.error("向WCS发送拣选任务时发生异常{}", convertJsonString(exception));
throw new Exception("向WCS发送拣选任务时发生异常。");
@ -710,12 +716,12 @@ public class WmsJobServiceImplements implements IWmsJobService {
int interval = 180;// 普通接口记录默认保留180天
int importantInterval = 365;// 重要接口记录默认保留一年
try {
interval = Integer.parseInt(configMap.get(ConfigMapKeyEnum.LOG_DELETE_INTERVAL.getConfigKey()));
interval = Integer.parseInt(configMap.get(ConfigMapKeyEnum.RECORD_DELETE_INTERVAL.getConfigKey()));
} catch (Exception e) {
logger.error("获取普通记录清理天数错误使用默认值180天");
}
try {
importantInterval = Integer.parseInt(configMap.get(ConfigMapKeyEnum.LOG_DELETE_INTERVAL.getConfigKey()));
importantInterval = Integer.parseInt(configMap.get(ConfigMapKeyEnum.IMPORTANT_RECORD_DELETE_INTERVAL.getConfigKey()));
} catch (Exception e) {
logger.error("获取重要记录清理天数错误使用默认值365天");
}
@ -938,7 +944,7 @@ public class WmsJobServiceImplements implements IWmsJobService {
// 判断数据行是不是过多
int rowCount = list.size();
// 每50万行一个文件
int rowCountPerFile = 300000;
int rowCountPerFile = 100000;
int fileCounts = (rowCount + rowCountPerFile - 1) / rowCountPerFile;
for (int i = 1; i <= fileCounts; i++) {
List<T> dividedList = list.subList((i - 1) * rowCountPerFile, Math.min(i * rowCountPerFile, rowCount));
@ -1280,22 +1286,29 @@ public class WmsJobServiceImplements implements IWmsJobService {
// .max(Comparator.comparingInt(Map.Entry::getValue))
// .map(Map.Entry::getKey)
// .orElse("");
// new 查找已下发状态以上最少箱子的站台
String standId = standPickCountsMap.entrySet().stream()
.min(Comparator.comparingInt(Map.Entry::getValue))
.map(Map.Entry::getKey)
.orElse("");
// 对这些站台进行排序从少到多
List<String> standIds = standPickCountsMap.entrySet().stream()
.sorted(Comparator.comparingInt(Map.Entry::getValue))
.map(Map.Entry::getKey).toList();
List<String> minStandVehicleIds = new ArrayList<>();
String minStandId = "";
for (String standId : standIds) {
// 查找这个站台未下发的料箱
List<String> vehicleIds = standPickTasks.stream()
minStandVehicleIds = standPickTasks.stream()
.filter(pickTask -> pickTask.getPickStatus().equals(PickTaskStatusEnum.TEMP.getCode())
&& thisStackerVehicleIds.contains(pickTask.getVehicleId()) && standId.equals(pickTask.getStandId()))
.map(PickTask::getVehicleId)
.distinct()
.toList();
if (vehicleIds.isEmpty()) {
if (!minStandVehicleIds.isEmpty()) {
minStandId = standId;
break;
}
}
if (minStandVehicleIds.isEmpty()) {
break;
}
List<String> vehicleIds = minStandVehicleIds;
// 生成箱子-站台数量的Map
Map<String, Integer> vehicleStandsMap = new HashMap<>();
standPickTasks.forEach(pickTask -> {
@ -1342,7 +1355,7 @@ public class WmsJobServiceImplements implements IWmsJobService {
// 添加特殊任务
newStandStackerTask.setVehicleId(task.getVehicleId());
newStandStackerTask.setStackerId(stacker.getEquipmentId());
newStandStackerTask.setStandId(standId);
newStandStackerTask.setStandId(minStandId);
newStandStackerTask.setTaskType(2);
newStandStackerTask.setTaskStatus(0);
newStandStackerTask.setCreateTime(LocalDateTime.now());
@ -1354,7 +1367,7 @@ public class WmsJobServiceImplements implements IWmsJobService {
// 已经发送过的vehicleId
pickVehicleIds.add(vehicleId);
availNum--;
standPickCountsMap.put(standId, standPickCountsMap.get(standId) + 1);
standPickCountsMap.put(minStandId, standPickCountsMap.getOrDefault(minStandId, 0) + 1);
}
}
}
@ -1364,6 +1377,7 @@ public class WmsJobServiceImplements implements IWmsJobService {
// 没有新任务发送
return;
}
// 下面这行代码模拟wcs下发成功
// simulateSendPickOutTasks(taskGroupIds, pickVehicleIds, needAddStandStackerTasks, needRemoveStandStackerTasks);
// 发送任务
String url = configMap.get(ConfigMapKeyEnum.URL_WCS_TASK.getConfigKey());
@ -1455,13 +1469,13 @@ public class WmsJobServiceImplements implements IWmsJobService {
/**
* 模拟出库发送成功
* @param taskGroupIds
* @param pickVehicleIds
* @param needAddStandStackerTasks
* @param needRemoveStandStackerTasks
* @param taskGroupIds 任务组
* @param pickVehicleIds 拣选料箱id
* @param needAddStandStackerTasks 需要添加的堆垛机站台任务
* @param needRemoveStandStackerTasks 需要移除的堆垛机站台任务
*/
void simulateSendPickOutTasks(List<String> taskGroupIds, List<String> pickVehicleIds, List<StandStackerTask> needAddStandStackerTasks, List<StandStackerTask> needRemoveStandStackerTasks) {
logger.info("发送WCS拣选出库任务成功");
logger.info("模拟发送wcs任务");
taskService.update(new LambdaUpdateWrapper<Task>()
.set(Task::getTaskStatus, WmsTaskStatus.WAIT.getCode())
.in(Task::getTaskGroup, taskGroupIds)
@ -1473,7 +1487,10 @@ public class WmsJobServiceImplements implements IWmsJobService {
.in(OutsideVehicles::getVehicleId, pickVehicleIds));
}
// 更新特殊信息
if (!needAddStandStackerTasks.isEmpty()) {
standStackerTaskService.saveBatch(needAddStandStackerTasks);
}
if (!needRemoveStandStackerTasks.isEmpty()) {
standStackerTaskService.removeBatchByIds(needRemoveStandStackerTasks);
List<StandStackerTaskBak> needSaveRecords = new ArrayList<>();
for (StandStackerTask standStackerTask : needRemoveStandStackerTasks) {
@ -1484,3 +1501,16 @@ public class WmsJobServiceImplements implements IWmsJobService {
standStackerTaskBakService.saveBatch(needSaveRecords);
}
}
/**
* 模拟发送拣选任务
* @param vehicleIds 载具号
*/
void simulateSendPickTasks(List<String> vehicleIds) {
logger.info("模拟发送拣选任务。");
dbTransUtils.useTran(() -> pickTaskService.update(new LambdaUpdateWrapper<PickTask>()
.set(PickTask::getPickStatus, PickTaskStatusEnum.SEND.getCode())
.in(PickTask::getVehicleId, vehicleIds)
.eq(PickTask::getPickStatus, PickTaskStatusEnum.NEW.getCode())));
}
}

View File

@ -6,10 +6,12 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wms.constants.enums.*;
import com.wms.entity.app.dto.WorkCenterAndOrderDto;
import com.wms.entity.app.dto.extend.StockDetailInfo;
import com.wms.entity.table.*;
import com.wms.service.*;
import com.wms.service.business.IWmsTaskService;
import com.wms.service.business.IWorkService;
import com.wms.utils.DbTransUtils;
import com.wms.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
@ -57,6 +59,7 @@ public class WorkServiceImplements implements IWorkService {
private final WorkFlowLastService workFlowLastService;// 服务
private final List<String> workCreatingStations = new ArrayList<>();// 当前正在创建任务的站台
private final VehicleService vehicleService;// 料箱服务
private final DbTransUtils dbTransUtils;// 事务事务工具类
//获取配置文件的是否添加了需求时间
@ -267,6 +270,478 @@ public class WorkServiceImplements implements IWorkService {
}
}
/**
* 新的执行工作方法
*/
@Override
public void doWorkMethod2() {
// 查询一些配置信息
String max_vehicle_nums = configMap.get(ConfigMapKeyEnum.MAX_VEHICLE_NUMS.getConfigKey());
String max_vehicle_nums_before = configMap.get(ConfigMapKeyEnum.MAX_VEHICLE_BEFORE.getConfigKey());
String max_vehicle_nums_after = configMap.get(ConfigMapKeyEnum.MAX_VEHICLE_AFTER.getConfigKey());
String max_stand_vehicle_nums = configMap.get(ConfigMapKeyEnum.MAX_STAND_VEHICLE_NUMS.getConfigKey());
if (!"1".equals(configMap.get(ConfigMapKeyEnum.SAME_AREA.getConfigKey()))) {
if (StringUtils.isEmpty(max_vehicle_nums) || StringUtils.isEmpty(max_stand_vehicle_nums)) {
logger.info("允许不同区域时配置未生成。");
return;
}
} else {
if (StringUtils.isEmpty(max_vehicle_nums_before) || StringUtils.isEmpty(max_vehicle_nums_after) || StringUtils.isEmpty(max_stand_vehicle_nums)) {
logger.info("不允许不同区域时配置未生成。");
return;
}
}
// 查找到未完成的工作
List<WorkFlow> unfinishedWorkFlowList = workFlowService.list(new LambdaQueryWrapper<WorkFlow>()
.notIn(WorkFlow::getWorkStatus, -1, 2));
if (unfinishedWorkFlowList.isEmpty()) {
// 没有未完成的工作
logger.info("没有未完成的工作。");
return;
}
// 查询拣选任务
List<PickTask> pickTaskList = pickTaskService.list();
// 本次可以出库的站台
List<String> thisTimeCanOutStandIds = new ArrayList<>();
if (!"1".equals(configMap.get(ConfigMapKeyEnum.SAME_AREA.getConfigKey()))) {
List<String> standIdsTotal = List.of("ASRS-#1", "ASRS-#2", "ASRS-#3", "ASRS-#4", "ASRS-#5", "ASRS-#6", "ASRS-#7", "ASRS-#8", "ASRS-#9");
int maxVehicleNums = Integer.parseInt(max_vehicle_nums);// 线体最大箱子数量
// 根据载具号map一下
List<String> outVehicleIdList = pickTaskList.stream().map(PickTask::getVehicleId).distinct().toList();
if (outVehicleIdList.size() < maxVehicleNums) {
thisTimeCanOutStandIds.addAll(standIdsTotal);
}
} else {
List<String> standIdsBefore = List.of("ASRS-#1", "ASRS-#2", "ASRS-#3", "ASRS-#4", "ASRS-#5");
List<String> standIdsAfter = List.of("ASRS-#6", "ASRS-#7", "ASRS-#8", "ASRS-#9");
int maxVehicleNumsBefore = Integer.parseInt(max_vehicle_nums_before);// 前区线体最大箱子数量
int maxVehicleNumsAfter = Integer.parseInt(max_vehicle_nums_after);// 后区线体最大箱子数量
Map<String, Integer> vehicleMapBefore = new HashMap<>();
Map<String, Integer> vehicleMapAfter = new HashMap<>();
for (PickTask tempPickTask : pickTaskList) {
// 前区箱子
if (standIdsBefore.contains(tempPickTask.getStandId()) && !vehicleMapBefore.containsKey(tempPickTask.getVehicleId())) {
vehicleMapBefore.put(tempPickTask.getVehicleId(), 1);
}
// 后区箱子
if (standIdsAfter.contains(tempPickTask.getStandId()) && !vehicleMapAfter.containsKey(tempPickTask.getVehicleId())) {
vehicleMapAfter.put(tempPickTask.getVehicleId(), 1);
}
}
// 前区可以
if (vehicleMapBefore.size() < maxVehicleNumsBefore) {
thisTimeCanOutStandIds.addAll(standIdsBefore);
}
// 后区可以
if (vehicleMapAfter.size() < maxVehicleNumsAfter) {
thisTimeCanOutStandIds.addAll(standIdsAfter);
}
}
if (thisTimeCanOutStandIds.isEmpty()) {
// 没有可出库的站台
logger.info("本次无可需要出库的站台。");
return;
}
// 找出所有可用设备
List<Stand> stands = standService.list(new LambdaQueryWrapper<Stand>()
.eq(Stand::getIsLock, 0).eq(Stand::getStandStatus, 0));
// 备料站台---从9号站台开始
List<Stand> canUsePickStands = stands.stream().filter(stand -> stand.getStandType() == 2 && thisTimeCanOutStandIds.contains(stand.getStandId())).sorted(Comparator.comparing(Stand::getStandId).reversed()).toList();
// 找出所有可用堆垛机---从5号堆垛机开始
List<Stand> stackerList = stands.stream().filter(stand -> stand.getStandType() == 3).sorted(Comparator.comparingInt(Stand::getEquipmentId).reversed()).toList();
if (canUsePickStands.isEmpty() || stackerList.isEmpty()) {
// 没有可用站台或者可用堆垛机
logger.info("没有可用站台或者可用堆垛机。");
return;
}
List<String> canUseStandIdList = new ArrayList<>();
for (Stand canUseStand : canUsePickStands) {
// 查找这个站台已经生成的拣选任务
List<PickTask> pickTasksOfThisStand = pickTaskList.stream().filter(pickTask -> Objects.equals(pickTask.getStandId(), canUseStand.getStandIp())).distinct().toList();
if (pickTasksOfThisStand.size() > Integer.parseInt(max_vehicle_nums_before)) {
// 此站台已生成任务超过阈值
logger.info("站台{}已生成任务数量超过阈值。", canUseStand.getStandId());
continue;
}
canUseStandIdList.add(canUseStand.getStandId());
}
// 需要更新的数据
List<String> thisTimeOutVehicleIds = new ArrayList<>();// 本次出库的载具号
List<Task> needAddTaskList = new ArrayList<>();// 需要添加的任务数据
Map<String, PickTask> needAddPickTaskMap = new HashMap<>();// 需要添加的拣选任务数据
List<String> needUpdateWorkFlowIds = new ArrayList<>();// 需要更新的工作流id
List<String> needUpdateOrderIds = new ArrayList<>();// 需要更新的工单id
List<String> thisTimeCannotOutVehicleIds = new ArrayList<>();// 本次不能出库的载具号
// 查询出所有的库存
List<Stock> allStockList = stockService.list();
// 第一次循环分出已经出库的物料
Map<String, Integer> outedGoodsIdMap = new HashMap<>();
for (Stock stock : allStockList) {
if (Objects.equals(stock.getStockStatus(), StockStatus.OK.getCode()) || Objects.equals(stock.getStockStatus(), StockStatus.BACK.getCode()) || Objects.equals(stock.getStockStatus(), StockStatus.LOCK.getCode())) {
continue;
}
String goodsId = stock.getGoodsRelated().getGoodsId();
if (!outedGoodsIdMap.containsKey(goodsId)) {
outedGoodsIdMap.put(goodsId, 1);
}
}
// 查询出当前所有的出库任务拣选
List<Task> outTaskList = taskService.list(new LambdaQueryWrapper<Task>()
.eq(Task::getTaskType, TaskType.OUT.getCode())
.eq(Task::getTaskPriority, 1)
.eq(Task::getIsPicking, 1));
// 分出在库的物料
List<Stock> onStockStockList = allStockList.stream().filter(stock -> Objects.equals(stock.getStockStatus(), StockStatus.OK.getCode())).sorted(Comparator.comparing(Stock::getCreateTime)).toList();
for (String standId : canUseStandIdList) {
Map<Integer, String> equipVehicleOfThisStandMap = new HashMap<>();
// 生成这个站台在这个设备出库的箱子
for (Task task : outTaskList) {
if (StringUtils.isEmpty(task.getPickStand())) {
// 没有站台那么跳过
continue;
}
int equipmentId = getStackerIdByLocationId(task.getOrigin());
if (equipmentId != 0 && !equipVehicleOfThisStandMap.containsKey(equipmentId) && Objects.equals(task.getPickStand(), standId)) {
// 当前设备当前站台的任务
equipVehicleOfThisStandMap.put(equipmentId, task.getVehicleId());
}
}
Map<String, String> thisStandOutVehicleMap = new HashMap<>();// 键为载具号值为库存id
for (Stock stock : onStockStockList) {
if (!Objects.equals(stock.getStockStatus(), StockStatus.OK.getCode())) {
// 只允许在库库存操作
continue;
}
// 这个载具本次不允许出库
if (thisTimeCannotOutVehicleIds.contains(stock.getVehicleId())) {
continue;
}
// 同一物料同一时间只能在外面一个箱子
if (outedGoodsIdMap.containsKey(stock.getGoodsRelated().getGoodsId())) {
thisTimeCannotOutVehicleIds.add(stock.getVehicleId());
continue;
}
// 如果载具在本次出库的载具列表中那么修改库存状态
if (thisTimeOutVehicleIds.contains(stock.getVehicleId())) {
stock.setStockStatus(StockStatus.OUT.getCode());
continue;
}
// 获取这条库存的设备号
int equipmentId = getStackerIdByLocationId(stock.getLocationId());
if (equipmentId == 0) {
logger.info("载具{},库位{},未查到对应的设备号。", stock.getVehicleId(), stock.getLocationId());
continue;
}
// 判断这个设备能否出库
if (equipVehicleOfThisStandMap.containsKey(equipmentId)) {
// 这个站台在这台设备已经生成过任务不再重复生成
continue;
}
// 判断这个库存是否被当前站台需要
BigDecimal originNum = stock.getGoodsRelated().getRemainNum();
BigDecimal afterNum = stock.getGoodsRelated().getRemainNum();
for (WorkFlow workFlow : unfinishedWorkFlowList) {
if (afterNum.compareTo(BigDecimal.ZERO) <= 0) {
break;
}
if (Objects.equals(workFlow.getWorkStation(), standId) && Objects.equals(workFlow.getGoodsId(), stock.getGoodsRelated().getGoodsId())) {
BigDecimal needNum = workFlow.getNeedNum().subtract(workFlow.getDistributedNum() == null ? BigDecimal.ZERO : workFlow.getDistributedNum());
if (needNum.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
if (afterNum.compareTo(needNum) >= 0) {
afterNum = afterNum.subtract(needNum);
workFlow.setDistributedNum(workFlow.getNeedNum());
} else {
afterNum = BigDecimal.ZERO;
workFlow.setDistributedNum(workFlow.getDistributedNum() == null ? afterNum : workFlow.getDistributedNum().add(afterNum));
}
workFlow.setWorkStatus(1);
// 添加需要更新的工作流id
if (!needUpdateWorkFlowIds.contains(workFlow.getWorkFlowId())) {
needUpdateWorkFlowIds.add(workFlow.getWorkFlowId());
}
// 添加需要更新的工单id
if (!needUpdateOrderIds.contains(workFlow.getOrderId())) {
needUpdateOrderIds.add(workFlow.getOrderId());
}
}
}
if (afterNum.compareTo(originNum) != 0) {
// 使用过该库存更新数量
stock.setStockStatus(StockStatus.OUT.getCode());
StockDetailInfo goodsRelated = stock.getGoodsRelated();
goodsRelated.setRemainNum(afterNum);
stock.setGoodsRelated(goodsRelated);
// 创建出库任务
Task vehicleOutTask = new Task();
vehicleOutTask.setTaskId(generateId("CK_"));
vehicleOutTask.setTaskType(TaskType.OUT.getCode());
vehicleOutTask.setTaskGroup(generateId(""));
vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode());
vehicleOutTask.setTaskPriority(1);
vehicleOutTask.setVehicleId(stock.getVehicleId());
vehicleOutTask.setUserName("WMS_AUTO");
vehicleOutTask.setOrigin(stock.getLocationId());
vehicleOutTask.setDestination("");
vehicleOutTask.setCreateTime(LocalDateTime.now());
vehicleOutTask.setIsPicking(1);
vehicleOutTask.setPickStand(standId);
needAddTaskList.add(vehicleOutTask);
// 创建拣选任务
String key = stock.getVehicleId() + "_" + standId;
// 此次新建的保存过
if (needAddPickTaskMap.containsKey(key)) {
continue;
}
// 暂存拣选任务
PickTask tempPickTask = new PickTask();
tempPickTask.setPickTaskId(key);
tempPickTask.setVehicleId(stock.getVehicleId());
tempPickTask.setStandId(standId);
tempPickTask.setPickStatus(PickTaskStatusEnum.TEMP.getCode());
tempPickTask.setLastUpdateTime(LocalDateTime.now());
needAddPickTaskMap.put(key, tempPickTask);
// 添加本次出库载具
thisTimeOutVehicleIds.add(stock.getVehicleId());
// 添加设备
equipVehicleOfThisStandMap.put(equipmentId, stock.getVehicleId());
// 此处是为了将同一个载具尽量在同一个站台捡完
thisStandOutVehicleMap.put(stock.getVehicleId(), stock.getStockId());
}
}
for (Stock stock : onStockStockList) {
if (Objects.equals(stock.getStockStatus(), StockStatus.OK.getCode())) {
continue;
}
// 这个站台本次出库的载具
if (thisStandOutVehicleMap.containsKey(stock.getVehicleId()) && !Objects.equals(thisStandOutVehicleMap.get(stock.getVehicleId()), stock.getStockId())) {
// 判断这个料当前站台需不需要---主要消耗一下数量
BigDecimal originNum = stock.getGoodsRelated().getRemainNum();
BigDecimal afterNum = stock.getGoodsRelated().getRemainNum();
for (WorkFlow workFlow : unfinishedWorkFlowList) {
if (afterNum.compareTo(BigDecimal.ZERO) <= 0) {
break;
}
if (Objects.equals(workFlow.getWorkStation(), standId) && Objects.equals(workFlow.getGoodsId(), stock.getGoodsRelated().getGoodsId())) {
BigDecimal needNum = workFlow.getNeedNum().subtract(workFlow.getDistributedNum() == null ? BigDecimal.ZERO : workFlow.getDistributedNum());
if (needNum.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
if (afterNum.compareTo(needNum) >= 0) {
afterNum = afterNum.subtract(needNum);
workFlow.setDistributedNum(workFlow.getNeedNum());
} else {
afterNum = BigDecimal.ZERO;
workFlow.setDistributedNum(workFlow.getDistributedNum() == null ? afterNum : workFlow.getDistributedNum().add(afterNum));
}
workFlow.setWorkStatus(1);
// 添加需要更新的工作流id
if (!needUpdateWorkFlowIds.contains(workFlow.getWorkFlowId())) {
needUpdateWorkFlowIds.add(workFlow.getWorkFlowId());
}
// 添加需要更新的工单id
if (!needUpdateOrderIds.contains(workFlow.getOrderId())) {
needUpdateOrderIds.add(workFlow.getOrderId());
}
}
}
if (afterNum.compareTo(originNum) != 0) {
// 使用过该库存更新数量
stock.setStockStatus(StockStatus.OUT.getCode());
StockDetailInfo goodsRelated = stock.getGoodsRelated();
goodsRelated.setRemainNum(afterNum);
stock.setGoodsRelated(goodsRelated);
}
}
}
}
// 再循环一次库存只判断出库的
for (Stock stock : onStockStockList) {
if (!Objects.equals(stock.getStockStatus(), StockStatus.OUT.getCode())) {
continue;
}
if (!thisTimeOutVehicleIds.contains(stock.getVehicleId())) {
continue;
}
// 判断这个料当前站台需不需要---主要消耗一下数量
BigDecimal originNum = stock.getGoodsRelated().getRemainNum();
BigDecimal afterNum = stock.getGoodsRelated().getRemainNum();
for (WorkFlow workFlow : unfinishedWorkFlowList) {
if (afterNum.compareTo(BigDecimal.ZERO) <= 0) {
break;
}
if (Objects.equals(workFlow.getGoodsId(), stock.getGoodsRelated().getGoodsId())) {
BigDecimal needNum = workFlow.getNeedNum().subtract(workFlow.getDistributedNum() == null ? BigDecimal.ZERO : workFlow.getDistributedNum());
if (needNum.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
if (afterNum.compareTo(needNum) >= 0) {
afterNum = afterNum.subtract(needNum);
workFlow.setDistributedNum(workFlow.getNeedNum());
} else {
afterNum = BigDecimal.ZERO;
workFlow.setDistributedNum(workFlow.getDistributedNum() == null ? afterNum : workFlow.getDistributedNum().add(afterNum));
}
workFlow.setWorkStatus(1);
// 添加需要更新的工作流id
if (!needUpdateWorkFlowIds.contains(workFlow.getWorkFlowId())) {
needUpdateWorkFlowIds.add(workFlow.getWorkFlowId());
}
// 添加需要更新的工单id
if (!needUpdateOrderIds.contains(workFlow.getOrderId())) {
needUpdateOrderIds.add(workFlow.getOrderId());
}
// 创建拣选任务
String key = stock.getVehicleId() + "_" + workFlow.getWorkStation();
// 此次新建的保存过
if (needAddPickTaskMap.containsKey(key)) {
continue;
}
// 暂存拣选任务
PickTask tempPickTask = new PickTask();
tempPickTask.setPickTaskId(key);
tempPickTask.setVehicleId(stock.getVehicleId());
tempPickTask.setStandId(workFlow.getWorkStation());
tempPickTask.setPickStatus(PickTaskStatusEnum.TEMP.getCode());
tempPickTask.setLastUpdateTime(LocalDateTime.now());
needAddPickTaskMap.put(key, tempPickTask);
}
}
if (afterNum.compareTo(originNum) != 0) {
// 使用过该库存更新数量
stock.setStockStatus(StockStatus.OUT.getCode());
StockDetailInfo goodsRelated = stock.getGoodsRelated();
goodsRelated.setRemainNum(afterNum);
stock.setGoodsRelated(goodsRelated);
}
}
// 处理需要更新的数据
List<WorkFlow> finalUpdateWorkFlowList = unfinishedWorkFlowList.stream().filter(workFlow -> needUpdateWorkFlowIds.contains(workFlow.getWorkFlowId())).toList();
boolean doTransResult = dbTransUtils.useTran(() -> {
if (!thisTimeOutVehicleIds.isEmpty()) {
vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
.set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())
.in(Vehicle::getVehicleId, thisTimeOutVehicleIds));
stockService.update(new LambdaUpdateWrapper<Stock>()
.set(Stock::getStockStatus, StockStatus.OUT.getCode())
.in(Stock::getVehicleId, thisTimeOutVehicleIds));
if (!needAddTaskList.isEmpty()) {
taskService.saveBatch(needAddTaskList);
}
if (!needAddPickTaskMap.isEmpty()) {
pickTaskService.saveBatch(needAddPickTaskMap.values());
}
if (!finalUpdateWorkFlowList.isEmpty()) {
workFlowService.updateBatchById(finalUpdateWorkFlowList);
}
if (!needUpdateOrderIds.isEmpty()) {
kateOrdersService.update(new LambdaUpdateWrapper<KateOrders>()
.set(KateOrders::getOrderStatus, 2)
.in(KateOrders::getOrderId, needUpdateOrderIds));
}
}
});
if (!doTransResult) {
logger.error("解析工作生成任务时,数据库事务执行错误。");
}
}
/**
* 修复工作
*/
@Override
public void repairWork() {
// 查找到未完成的工作
List<WorkFlow> unfinishedWorkFlowList = workFlowService.list(new LambdaQueryWrapper<WorkFlow>()
.notIn(WorkFlow::getWorkStatus, -1, 2));
if (unfinishedWorkFlowList.isEmpty()) {
// 没有未完成的工作
logger.info("没有未完成的待修复的工作。");
return;
}
// 查找所有的库存
List<Stock> stockList = stockService.list(new LambdaQueryWrapper<Stock>()
.ne(Stock::getStockStatus, StockStatus.LOCK.getCode()));
// 根据在库物料号map一下
Map<String, List<String>> onStockGoodsIdToVehicleIdsMap = new HashMap<>();
// 根据不在库的物料号map一下
Map<String, List<String>> notOnStockGoodsIdToVehicleIdsMap = new HashMap<>();
for (Stock stock : stockList) {
String goodsId = stock.getGoodsRelated().getGoodsId();
if (Objects.equals(stock.getStockStatus(), StockStatus.OK.getCode())) {
if (onStockGoodsIdToVehicleIdsMap.containsKey(goodsId)) {
List<String> oldVehicleList = onStockGoodsIdToVehicleIdsMap.get(goodsId);
oldVehicleList.add(stock.getVehicleId());
onStockGoodsIdToVehicleIdsMap.put(goodsId, oldVehicleList);
} else {
onStockGoodsIdToVehicleIdsMap.put(goodsId, new ArrayList<>(List.of(stock.getVehicleId())));
}
} else {
if (notOnStockGoodsIdToVehicleIdsMap.containsKey(goodsId)) {
List<String> oldVehicleList = notOnStockGoodsIdToVehicleIdsMap.get(goodsId);
oldVehicleList.add(stock.getVehicleId());
notOnStockGoodsIdToVehicleIdsMap.put(goodsId, oldVehicleList);
} else {
notOnStockGoodsIdToVehicleIdsMap.put(goodsId, new ArrayList<>(List.of(stock.getVehicleId())));
}
}
}
List<WorkFlow> needUpdateWorkFlowList = new ArrayList<>();
for (WorkFlow workFlow : unfinishedWorkFlowList) {
if (workFlow.getPickedNum().compareTo(workFlow.getNeedNum()) >= 0) {
// 实际已经完成但未标记为完成的工作流
workFlow.setDistributedNum(workFlow.getPickedNum());
workFlow.setWorkStatus(2);
needUpdateWorkFlowList.add(workFlow);
continue;
}
// 需求的数量未全部分配时查询是否还有库存
if (!onStockGoodsIdToVehicleIdsMap.containsKey(workFlow.getGoodsId()) && !notOnStockGoodsIdToVehicleIdsMap.containsKey(workFlow.getGoodsId())) {
// 缺料
workFlow.setWorkStatus(2);
if (StringUtils.isEmpty(workFlow.getOpUser())) {
workFlow.setOpUser("缺料系统自动完成。");
} else {
workFlow.setOpUser(workFlow.getOpUser() + ";缺料系统自动完成。");
}
needUpdateWorkFlowList.add(workFlow);
continue;
}
// 有在库数量但是没有非在库数量时
if (onStockGoodsIdToVehicleIdsMap.containsKey(workFlow.getGoodsId()) && !notOnStockGoodsIdToVehicleIdsMap.containsKey(workFlow.getGoodsId())) {
// 更新已分配数量
workFlow.setDistributedNum(workFlow.getPickedNum());
needUpdateWorkFlowList.add(workFlow);
}
}
// 更新工作流
boolean doTransResult = dbTransUtils.useTran(() -> {
if (!needUpdateWorkFlowList.isEmpty()) {
workFlowService.updateBatchById(needUpdateWorkFlowList);
}
});
if (!doTransResult) {
logger.error("修复工作流时,执行数据库事务发生错误。");
}
}
/**
* 根据库位号获得设备号
* @param locationId 库位号
* @return 设备号/堆垛机号
*/
private int getStackerIdByLocationId(String locationId) {
if (StringUtils.isEmpty(locationId)) {
return 0;
}
Location targetLocation = instantLocationMap.get(locationId);
if (targetLocation == null) {
return 0;
}
return targetLocation.getEquipmentId();
}
/**
* 新版完成工作
*

View File

@ -93,10 +93,10 @@ public class JobServiceImpl implements IJobService {
// 这里写死五个定时器
jobBeans.add(new JobBean("CommonTaskSender", CommonTaskSender.class, "0/2 * * * * ?", 2000, JobTimerTypeEnums.SIMPLE.getType(), 1));
jobBeans.add(new JobBean("PickTaskSender", PickTaskSender.class, "0/2 * * * * ?", 2000, JobTimerTypeEnums.SIMPLE.getType(), 1));
jobBeans.add(new JobBean("PickOutTaskSender", PickOutTaskSender.class, "0/2 * * * * ?", 2000, JobTimerTypeEnums.SIMPLE.getType(), 1));
jobBeans.add(new JobBean("PickOutTaskSender", PickOutTaskSender.class, "0/2 * * * * ?", 2000, JobTimerTypeEnums.SIMPLE.getType(), 0));
// jobBeans.add(new JobBean("KateWorkExecutor", KateWorkExecutor.class, "0/20 * * * * ?", 20000, JobTimerTypeEnums.SIMPLE.getType(), 1));
jobBeans.add(new JobBean("KateWorkExecutor", KateWorkExecutor.class, "0 0 * * * ?", 20000, JobTimerTypeEnums.SIMPLE.getType(), 1));
jobBeans.add(new JobBean("DataClearExecutor", DataClearExecutor.class, "0 0 3 * * ?", 2000, JobTimerTypeEnums.CRON.getType(), 1));
jobBeans.add(new JobBean("DataClearExecutor", DataClearExecutor.class, "0 0 23 * * ?", 2000, JobTimerTypeEnums.CRON.getType(), 1));
for (JobBean jobBean : jobBeans) {
createJob(jobBean);
}

View File

@ -0,0 +1,33 @@
package com.wms.utils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
@Component
@RequiredArgsConstructor
public class DbTransUtils {
private final PlatformTransactionManager transactionManager;
/**
* 执行一个事务方法
* @param baseTran 事务类
* @return 执行结果
*/
public boolean useTran(Runnable baseTran) {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = transactionManager.getTransaction(def);
try {
baseTran.run();
transactionManager.commit(status);
return true;
} catch (Exception e) {
transactionManager.rollback(status);
return false;
}
}
}