feat: 接受WMS任务

This commit is contained in:
2026-07-30 13:23:19 +08:00
parent cb4862571c
commit 30a6c0b4db
4 changed files with 218 additions and 5 deletions

View File

@@ -0,0 +1,6 @@
/**
* 封装处理类包
* @Author: liyongde
* @Date: 2026/7/30 13:22
*/
package org.nl.extInterface.manager;

View File

@@ -62,7 +62,7 @@ public class TaskIssueReqVO extends AcsBaseReqVO {
*/
private String remark;
/**
* 扩展参数
* 扩展参数,不在设置其他字段,所有业务所需的字段统一存放在这
*/
private Map<String, Object> payload;
/**

View File

@@ -23,7 +23,8 @@ public class TaskIssueResultRespVO {
public static class FailedTask {
/**
* 任务标识
* 任务标识LMS的任务id
* 对应acs任务表中的ext_task_id
*/
private Long taskId;

View File

@@ -1,7 +1,16 @@
package org.nl.extInterface.wms.service.impl;
import lombok.RequiredArgsConstructor;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.extern.slf4j.Slf4j;
import org.nl.acs.device.storageMgt.service.entity.StorageCell;
import org.nl.acs.device.storageMgt.service.mapper.StorageCellMapper;
import org.nl.acs.task.task.service.TaskService;
import org.nl.acs.task.task.service.dto.TaskDto;
import org.nl.extInterface.wms.data.req.OperateCheckReqVO;
import org.nl.extInterface.wms.data.req.TaskIssueReqVO;
import org.nl.extInterface.wms.data.resp.OperateCheckRespVO;
@@ -9,21 +18,218 @@ import org.nl.extInterface.wms.data.resp.TaskIssueResultRespVO;
import org.nl.extInterface.wms.service.WmsToAcsService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Service
@RequiredArgsConstructor
@Slf4j
public class WmsToAcsServiceImpl implements WmsToAcsService {
private static final String DEFAULT_TASK_TYPE = "1";
private static final String DEFAULT_ROUTE_PLAN_CODE = "normal";
@Resource
private TaskService taskService;
@Resource
private StorageCellMapper storageCellMapper;
@Override
public TaskIssueResultRespVO issueTask(List<TaskIssueReqVO> tasks) {
// todo
log.info("接受WMS下发的任务{}", JSONObject.toJSONString(tasks));
TaskIssueResultRespVO response = new TaskIssueResultRespVO();
List<TaskIssueResultRespVO.FailedTask> failedTasks = new ArrayList<>();
if (CollUtil.isEmpty(tasks)) {
response.setFailedTasks(failedTasks);
return response;
}
for (TaskIssueReqVO task : tasks) {
TaskIssueResultRespVO.FailedTask failedTask = issueSingleTask(task);
if (failedTask != null) {
failedTasks.add(failedTask);
}
}
response.setFailedTasks(failedTasks);
return response;
}
private TaskIssueResultRespVO.FailedTask issueSingleTask(TaskIssueReqVO task) {
try {
validateRequired(task);
ensureTaskNotExists(task);
TaskLocation startLocation = resolveLocation(task.getStartDeviceCode());
TaskLocation nextLocation = resolveLocation(task.getNextDeviceCode());
TaskLocation startLocation2 = resolveOptionalLocation(task.getStartDeviceCode2());
TaskLocation nextLocation2 = resolveOptionalLocation(task.getNextDeviceCode2());
TaskDto taskDto = buildTaskDto(task, startLocation, nextLocation, startLocation2, nextLocation2);
extendBeforeCreate(task, taskDto);
taskService.create(taskDto);
return null;
} catch (Exception e) {
log.warn("WMS任务下发失败, taskId={}, taskCode={}", getTaskId(task), getTaskCode(task), e);
return failedTask(getTaskId(task), e.getMessage());
}
}
private void validateRequired(TaskIssueReqVO task) {
if (task == null) {
throw new IllegalArgumentException("任务不能为空");
}
if (StrUtil.isBlank(task.getTaskCode())) {
throw new IllegalArgumentException("任务编码不能为空");
}
if (StrUtil.isBlank(task.getStartDeviceCode())) {
throw new IllegalArgumentException("起点不能为空");
}
if (StrUtil.isBlank(task.getNextDeviceCode())) {
throw new IllegalArgumentException("终点不能为空");
}
}
private void ensureTaskNotExists(TaskIssueReqVO task) {
TaskDto cachedTask = taskService.findByCodeFromCache(task.getTaskCode());
if (cachedTask != null) {
throw new IllegalArgumentException("存在相同的任务编码:" + task.getTaskCode());
}
TaskDto dbTask = taskService.findByCode(task.getTaskCode());
if (dbTask != null) {
throw new IllegalArgumentException("存在相同的任务编码:" + task.getTaskCode());
}
if (StrUtil.isNotBlank(task.getVehicleCode())) {
TaskDto vehicleTask = taskService.findByContainer(task.getVehicleCode());
if (vehicleTask != null) {
throw new IllegalArgumentException("载具" + task.getVehicleCode() + "已存在任务:" + vehicleTask.getTask_code());
}
}
}
private TaskLocation resolveLocation(String storageCode) {
TaskLocation location = resolveOptionalLocation(storageCode);
if (StrUtil.isBlank(location.getPointCode())) {
throw new IllegalArgumentException(storageCode + " 未找到对应点位");
}
return location;
}
private TaskLocation resolveOptionalLocation(String storageCode) {
if (StrUtil.isBlank(storageCode)) {
return TaskLocation.empty();
}
StorageCell storageCell = new LambdaQueryChainWrapper<>(storageCellMapper)
.eq(StorageCell::getStorage_code, storageCode)
.one();
if (storageCell == null) {
return TaskLocation.empty();
}
String pointCode = StrUtil.isBlank(storageCell.getParent_storage_code())
? storageCode
: storageCell.getStorage_code();
return new TaskLocation(pointCode, getDeviceCode(pointCode));
}
private TaskDto buildTaskDto(TaskIssueReqVO task,
TaskLocation startLocation,
TaskLocation nextLocation,
TaskLocation startLocation2,
TaskLocation nextLocation2) {
TaskDto taskDto = new TaskDto();
taskDto.setTask_id(IdUtil.simpleUUID());
taskDto.setExt_task_id(task.getTaskId() == null ? null : String.valueOf(task.getTaskId()));
taskDto.setTask_code(task.getTaskCode());
taskDto.setStart_point_code(startLocation.getPointCode());
taskDto.setStart_device_code(startLocation.getDeviceCode());
taskDto.setNext_point_code(nextLocation.getPointCode());
taskDto.setNext_device_code(nextLocation.getDeviceCode());
taskDto.setStart_point_code2(startLocation2.getPointCode());
taskDto.setStart_device_code2(startLocation2.getDeviceCode());
taskDto.setNext_point_code2(nextLocation2.getPointCode());
taskDto.setNext_device_code2(nextLocation2.getDeviceCode());
taskDto.setPriority(task.getPriority());
taskDto.setVehicle_code(task.getVehicleCode());
taskDto.setVehicle_code2(task.getVehicleCode2());
taskDto.setTask_type(StrUtil.blankToDefault(task.getTaskType(), DEFAULT_TASK_TYPE));
taskDto.setRoute_plan_code(DEFAULT_ROUTE_PLAN_CODE);
taskDto.setRemark(task.getRemark());
taskDto.setParamJson(new JSONObject(buildTaskParam(task)));
return taskDto;
}
private Map<String, Object> buildTaskParam(TaskIssueReqVO task) {
Map<String, Object> param = new LinkedHashMap<>();
if (ObjectUtil.isNotEmpty(task.getPayload())) {
param.putAll(task.getPayload());
}
putIfNotBlank(param, "agvSystemType", task.getAgvSystemType());
putIfNotBlank(param, "productArea", task.getProductArea());
putIfNotBlank(param, "traceId", task.getTraceId());
if (task.getTimestamp() != null) {
param.put("timestamp", task.getTimestamp());
}
return param;
}
private void extendBeforeCreate(TaskIssueReqVO task, TaskDto taskDto) {
// todo Extend project-specific validation or conversion by taskType/agvSystemType/payload.
}
private void putIfNotBlank(Map<String, Object> param, String key, String value) {
if (StrUtil.isNotBlank(value)) {
param.put(key, value);
}
}
private String getDeviceCode(String pointCode) {
if (StrUtil.isBlank(pointCode)) {
return pointCode;
}
return pointCode.contains("-") ? StrUtil.subBefore(pointCode, "-", false) : pointCode;
}
private TaskIssueResultRespVO.FailedTask failedTask(Long taskId, String errorMessage) {
TaskIssueResultRespVO.FailedTask failedTask = new TaskIssueResultRespVO.FailedTask();
failedTask.setTaskId(taskId);
failedTask.setErrorMessage(StrUtil.blankToDefault(errorMessage, "任务下发失败"));
return failedTask;
}
private Long getTaskId(TaskIssueReqVO task) {
return task == null ? null : task.getTaskId();
}
private String getTaskCode(TaskIssueReqVO task) {
return task == null ? null : task.getTaskCode();
}
private static class TaskLocation {
private final String pointCode;
private final String deviceCode;
private TaskLocation(String pointCode, String deviceCode) {
this.pointCode = pointCode;
this.deviceCode = deviceCode;
}
private static TaskLocation empty() {
return new TaskLocation(null, null);
}
private String getPointCode() {
return pointCode;
}
private String getDeviceCode() {
return deviceCode;
}
}
@Override
public OperateCheckRespVO checkEnableOperate(OperateCheckReqVO task) {
// todo 检测任务能否取消或者完成,取消和完成判断逻辑一样,不需要管他,先判断指令是否存在,存在则显示不允许操作,