feat: 检测是否允许操作任务

This commit is contained in:
2026-07-30 14:14:37 +08:00
parent 30a6c0b4db
commit cc73aa4175
2 changed files with 245 additions and 177 deletions

View File

@@ -0,0 +1,204 @@
package org.nl.extInterface.manager;
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 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.common.exception.BadRequestException;
import org.nl.extInterface.wms.data.req.TaskIssueReqVO;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.LinkedHashMap;
import java.util.Map;
@Component
public class WmsTaskCreateManager {
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;
public void create(TaskIssueReqVO task) throws Exception {
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);
}
private void validateRequired(TaskIssueReqVO task) {
if (task == null) {
throw new BadRequestException("任务不能为空");
}
if (ObjectUtil.isEmpty(task.getTaskId())) {
throw new BadRequestException("LMS的任务id不能为空");
}
if (StrUtil.isBlank(task.getTaskCode())) {
throw new BadRequestException("任务编码不能为空");
}
if (StrUtil.isBlank(task.getStartDeviceCode())) {
throw new BadRequestException("起点不能为空");
}
if (StrUtil.isBlank(task.getNextDeviceCode())) {
throw new BadRequestException("终点不能为空");
}
}
private void ensureTaskNotExists(TaskIssueReqVO task) {
TaskDto cachedTask = taskService.findByCodeFromCache(task.getTaskCode());
if (cachedTask != null) {
throw new BadRequestException("存在相同的任务编码:" + task.getTaskCode());
}
TaskDto dbTask = taskService.findByCode(task.getTaskCode());
if (dbTask != null) {
throw new BadRequestException("存在相同的任务编码:" + task.getTaskCode());
}
if (StrUtil.isBlank(task.getVehicleCode())) {
return;
}
TaskDto vehicleTask = taskService.findByContainer(task.getVehicleCode());
if (vehicleTask != null) {
throw new BadRequestException("载具" + task.getVehicleCode() + "已存在任务:" + vehicleTask.getTask_code());
}
}
private TaskLocation resolveLocation(String storageCode) {
TaskLocation location = resolveOptionalLocation(storageCode);
if (StrUtil.isBlank(location.getPointCode())) {
throw new BadRequestException(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(getRoutePlanCode(task));
taskDto.setRemark(task.getRemark());
taskDto.setParamJson(new JSONObject(buildTaskParam(task)));
return taskDto;
}
private String getRoutePlanCode(TaskIssueReqVO task) {
String routePlanCode = getPayloadString(task, "routePlanCode");
if (StrUtil.isBlank(routePlanCode)) {
routePlanCode = getPayloadString(task, "route_plan_code");
}
return StrUtil.blankToDefault(routePlanCode, DEFAULT_ROUTE_PLAN_CODE);
}
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 String getPayloadString(TaskIssueReqVO task, String key) {
if (task.getPayload() == null) {
return null;
}
Object value = task.getPayload().get(key);
return value == null ? null : String.valueOf(value);
}
private void extendBeforeCreate(TaskIssueReqVO task, TaskDto taskDto) {
// 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 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;
}
}
}

View File

@@ -1,16 +1,16 @@
package org.nl.extInterface.wms.service.impl;
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 com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.instruction.domain.InstructionMybatis;
import org.nl.acs.task.instruction.service.InstructionService;
import org.nl.acs.task.task.domain.Task;
import org.nl.acs.task.task.service.TaskService;
import org.nl.acs.task.task.service.dto.TaskDto;
import org.nl.extInterface.manager.WmsTaskCreateManager;
import org.nl.extInterface.wms.data.req.OperateCheckReqVO;
import org.nl.extInterface.wms.data.req.TaskIssueReqVO;
import org.nl.extInterface.wms.data.resp.OperateCheckRespVO;
@@ -20,22 +20,21 @@ 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
@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 WmsTaskCreateManager wmsTaskCreateManager;
@Resource
private TaskService taskService;
@Resource
private StorageCellMapper storageCellMapper;
private InstructionService instructionService;
@Override
public TaskIssueResultRespVO issueTask(List<TaskIssueReqVO> tasks) {
@@ -61,179 +60,44 @@ public class WmsToAcsServiceImpl implements WmsToAcsService {
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);
wmsTaskCreateManager.create(task);
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;
log.warn("WMS任务下发失败, taskId={}, taskCode={}", task.getTaskId(), task.getTaskCode(), e);
TaskIssueResultRespVO.FailedTask failedTask = new TaskIssueResultRespVO.FailedTask();
failedTask.setTaskId(task.getTaskId());
failedTask.setErrorMessage(StrUtil.blankToDefault(e.getMessage(), "任务下发失败"));
return failedTask;
}
}
@Override
public OperateCheckRespVO checkEnableOperate(OperateCheckReqVO task) {
// todo 检测任务能否取消或者完成,取消和完成判断逻辑一样,不需要管他,先判断指令是否存在,存在则显示不允许操作,
// 原因是任务执行中如果没有指令只有任务也是不允许操作原因是ACS存在任务
return null;
OperateCheckRespVO response = new OperateCheckRespVO();
if (task == null || ObjectUtil.isEmpty(task.getTaskId())) {
response.setEnableOperate(false);
response.setMessage("LMS任务ID不能为空");
return response;
}
Task acsTask = taskService.getOne(new LambdaQueryWrapper<Task>()
.eq(Task::getExt_task_id, String.valueOf(task.getTaskId()))
.last("limit 1"));
if (acsTask == null) {
response.setEnableOperate(true);
return response;
}
long instructionCount = instructionService.count(new LambdaQueryWrapper<InstructionMybatis>()
.eq(InstructionMybatis::getTask_id, acsTask.getTask_id()));
if (instructionCount > 0) {
response.setEnableOperate(false);
response.setMessage("ACS存在对应任务指令不允许完成或取消");
return response;
}
response.setEnableOperate(false);
response.setMessage("ACS存在对应任务不允许完成或取消");
return response;
}
}