opt:任务完成取消与ACS确认是否可行
This commit is contained in:
@@ -1,22 +0,0 @@
|
||||
package cn.code.nl.module.task.job.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 基础DTO对象
|
||||
* @Author: liyongde
|
||||
* @Date: 2026/7/24 8:49
|
||||
*/
|
||||
@Data
|
||||
public class AcsBaseReqDTO {
|
||||
/**
|
||||
* 请求号: traceId
|
||||
*/
|
||||
private String traceId;
|
||||
|
||||
/**
|
||||
*
|
||||
* 时间
|
||||
*/
|
||||
private Long timestamp;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.code.nl.module.task.job.dto;
|
||||
|
||||
import cn.code.nl.framework.common.pojo.AcsBaseRespDTO;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
@@ -8,22 +9,7 @@ import java.util.List;
|
||||
* ACS 任务下发响应
|
||||
*/
|
||||
@Data
|
||||
public class AcsIssueResultDTO {
|
||||
|
||||
/**
|
||||
* 是否整体成功
|
||||
*/
|
||||
private Boolean success;
|
||||
|
||||
/**
|
||||
* 响应编码
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 响应消息
|
||||
*/
|
||||
private String msg;
|
||||
public class AcsIssueResultRespDTO extends AcsBaseRespDTO {
|
||||
|
||||
/**
|
||||
* 下发失败的任务
|
||||
@@ -0,0 +1,31 @@
|
||||
package cn.code.nl.module.task.job.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* ACS 任务操作校验请求
|
||||
*/
|
||||
@Data
|
||||
public class AcsOperateCheckReqDTO {
|
||||
|
||||
/**
|
||||
* 任务标识
|
||||
*/
|
||||
private Long taskId;
|
||||
|
||||
/**
|
||||
* 任务编码
|
||||
*/
|
||||
private String taskCode;
|
||||
|
||||
/**
|
||||
* 操作类型
|
||||
*/
|
||||
private String operationType;
|
||||
|
||||
/**
|
||||
* 生产区域
|
||||
*/
|
||||
private String productArea;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package cn.code.nl.module.task.job.dto;
|
||||
|
||||
import cn.code.nl.framework.common.pojo.AcsBaseRespDTO;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* ACS 任务操作校验响应
|
||||
*/
|
||||
@Data
|
||||
public class AcsOperateCheckRespDTO extends AcsBaseRespDTO {
|
||||
|
||||
/**
|
||||
* 是否允许操作
|
||||
*/
|
||||
private Boolean enableOperate;
|
||||
|
||||
/**
|
||||
* 是否允许操作,兼容 ACS 字段
|
||||
*/
|
||||
private Boolean canOperate;
|
||||
|
||||
/**
|
||||
* 是否允许操作,兼容通用 data 字段
|
||||
*/
|
||||
private Boolean data;
|
||||
|
||||
/**
|
||||
* 不允许操作的原因
|
||||
*/
|
||||
private String message;
|
||||
|
||||
}
|
||||
@@ -2,15 +2,18 @@ package cn.code.nl.module.task.job.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import cn.code.nl.framework.common.pojo.AcsBaseReqDTO;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 下发给ACS的实体
|
||||
*
|
||||
* @Author: liyongde
|
||||
* @Date: 2026/7/23 17:10
|
||||
*/
|
||||
@Data
|
||||
public class AcsTaskDTO extends AcsBaseReqDTO{
|
||||
public class AcsTaskDTO extends AcsBaseReqDTO {
|
||||
/**
|
||||
* 任务标识
|
||||
*/
|
||||
|
||||
@@ -8,7 +8,7 @@ import cn.code.nl.module.infra.api.config.ConfigApi;
|
||||
import cn.code.nl.module.task.dal.dataobject.transporttask.TransportTaskDO;
|
||||
import cn.code.nl.module.task.dal.mysql.transporttask.TransportTaskMapper;
|
||||
import cn.code.nl.module.task.enums.TransportTaskStatusEnum;
|
||||
import cn.code.nl.module.task.job.dto.AcsIssueResultDTO;
|
||||
import cn.code.nl.module.task.job.dto.AcsIssueResultRespDTO;
|
||||
import cn.code.nl.module.task.job.dto.AcsTaskDTO;
|
||||
import cn.code.nl.module.task.utils.AcsTaskUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
@@ -67,7 +67,7 @@ public class TransportTaskIssueManager {
|
||||
String requestJson = JsonUtils.toJsonString(acsTasks);
|
||||
try {
|
||||
String serverAddress = getAcsServerAddress(productArea);
|
||||
AcsIssueResultDTO result = AcsUtil.post(serverAddress, ACS_TASK_API, acsTasks, AcsIssueResultDTO.class);
|
||||
AcsIssueResultRespDTO result = AcsUtil.post(serverAddress, ACS_TASK_API, acsTasks, AcsIssueResultRespDTO.class);
|
||||
handleIssueResult(tasks, result);
|
||||
} catch (Exception ex) {
|
||||
log.error("自动下发任务失败,productArea={},tasks={}", productArea, requestJson, ex);
|
||||
@@ -97,13 +97,13 @@ public class TransportTaskIssueManager {
|
||||
* @param tasks 本次下发任务
|
||||
* @param result ACS 响应
|
||||
*/
|
||||
private void handleIssueResult(List<TransportTaskDO> tasks, AcsIssueResultDTO result) {
|
||||
private void handleIssueResult(List<TransportTaskDO> tasks, AcsIssueResultRespDTO result) {
|
||||
if (result == null) {
|
||||
tasks.forEach(task -> updateIssueFailed(task.getTaskId(), "ACS 返回为空", null));
|
||||
return;
|
||||
}
|
||||
String resultJson = JsonUtils.toJsonString(result);
|
||||
List<AcsIssueResultDTO.FailedTask> failedTasks = result.getFailedTasks() == null
|
||||
List<AcsIssueResultRespDTO.FailedTask> failedTasks = result.getFailedTasks() == null
|
||||
? Collections.emptyList()
|
||||
: result.getFailedTasks();
|
||||
if (Boolean.FALSE.equals(result.getSuccess()) && CollUtil.isEmpty(failedTasks)) {
|
||||
@@ -111,9 +111,9 @@ public class TransportTaskIssueManager {
|
||||
tasks.forEach(task -> updateIssueFailed(task.getTaskId(), errorMessage, resultJson));
|
||||
return;
|
||||
}
|
||||
Map<Long, AcsIssueResultDTO.FailedTask> failedTaskMap = failedTasks.stream()
|
||||
Map<Long, AcsIssueResultRespDTO.FailedTask> failedTaskMap = failedTasks.stream()
|
||||
.filter(failedTask -> failedTask.getTaskId() != null)
|
||||
.collect(Collectors.toMap(AcsIssueResultDTO.FailedTask::getTaskId, Function.identity(), (first, second) -> first));
|
||||
.collect(Collectors.toMap(AcsIssueResultRespDTO.FailedTask::getTaskId, Function.identity(), (first, second) -> first));
|
||||
Set<Long> failedTaskIds = failedTaskMap.keySet();
|
||||
for (TransportTaskDO task : tasks) {
|
||||
if (failedTaskIds.contains(task.getTaskId())) {
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
package cn.code.nl.module.task.manage;
|
||||
|
||||
import cn.code.nl.framework.common.exception.ServiceException;
|
||||
import cn.code.nl.framework.common.pojo.CommonResult;
|
||||
import cn.code.nl.framework.common.util.http.AcsUtil;
|
||||
import cn.code.nl.framework.common.util.json.JsonUtils;
|
||||
import cn.code.nl.module.infra.api.config.ConfigApi;
|
||||
import cn.code.nl.module.task.dal.dataobject.transporttask.TransportTaskDO;
|
||||
import cn.code.nl.module.task.enums.TaskOperationTypeEnum;
|
||||
import cn.code.nl.module.task.job.dto.AcsOperateCheckRespDTO;
|
||||
import cn.code.nl.module.task.job.dto.AcsOperateCheckReqDTO;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* PC 端任务操作 ACS 校验管理器
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class TransportTaskOperateCheckManager {
|
||||
|
||||
private static final String TASK_OPERATE_ENABLE_CONFIG_KEY = "task-operate-enable";
|
||||
private static final String TASK_OPERATE_ENABLE_VALUE = "1";
|
||||
private static final String ACS_OPERATE_CHECK_API = "/acs-api/wms/check-enable-operate";
|
||||
private static final String ACS_SERVER_ADDRESS_CONFIG_SUFFIX = "-acs-server-address";
|
||||
|
||||
@Resource
|
||||
private ConfigApi configApi;
|
||||
|
||||
/**
|
||||
* 按配置校验 PC 端是否允许完成或取消任务
|
||||
*
|
||||
* @param task 任务信息
|
||||
* @param type 操作类型
|
||||
*/
|
||||
public void checkEnableOperate(TransportTaskDO task, TaskOperationTypeEnum type) {
|
||||
if (!needCheckAcs()) {
|
||||
return;
|
||||
}
|
||||
String serverAddress = getAcsServerAddress(task.getProductArea());
|
||||
AcsOperateCheckReqDTO reqDTO = buildReqDTO(task, type);
|
||||
AcsOperateCheckRespDTO result;
|
||||
try {
|
||||
result = AcsUtil.post(serverAddress, ACS_OPERATE_CHECK_API, reqDTO, AcsOperateCheckRespDTO.class);
|
||||
} catch (ServiceException ex) {
|
||||
log.error("ACS 操作校验请求失败,reqDTO={}", JsonUtils.toJsonString(reqDTO), ex);
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
log.error("ACS 操作校验请求失败,reqDTO={}", JsonUtils.toJsonString(reqDTO), ex);
|
||||
throw new ServiceException(500, "ACS操作校验失败");
|
||||
}
|
||||
handleCheckResult(reqDTO, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否需要请求 ACS 校验
|
||||
*/
|
||||
private boolean needCheckAcs() {
|
||||
CommonResult<String> result = configApi.getConfigValueByKey(TASK_OPERATE_ENABLE_CONFIG_KEY);
|
||||
return TASK_OPERATE_ENABLE_VALUE.equals(result.getCheckedData());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 ACS 服务地址
|
||||
*
|
||||
* @param productArea 生产区域
|
||||
* @return ACS 服务地址
|
||||
*/
|
||||
private String getAcsServerAddress(String productArea) {
|
||||
if (StrUtil.isBlank(productArea)) {
|
||||
throw new ServiceException(500, "生产区域为空,无法获取 ACS 服务地址");
|
||||
}
|
||||
String configKey = productArea + ACS_SERVER_ADDRESS_CONFIG_SUFFIX;
|
||||
CommonResult<String> result = configApi.getConfigValueByKey(configKey);
|
||||
String serverAddress = result.getCheckedData();
|
||||
if (StrUtil.isBlank(serverAddress)) {
|
||||
throw new ServiceException(500, "未配置 ACS 服务地址:" + configKey);
|
||||
}
|
||||
return serverAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 ACS 操作校验请求
|
||||
*/
|
||||
private AcsOperateCheckReqDTO buildReqDTO(TransportTaskDO task, TaskOperationTypeEnum type) {
|
||||
AcsOperateCheckReqDTO reqDTO = new AcsOperateCheckReqDTO();
|
||||
reqDTO.setTaskId(task.getTaskId());
|
||||
reqDTO.setTaskCode(task.getTaskCode());
|
||||
reqDTO.setOperationType(type.getCode());
|
||||
reqDTO.setProductArea(task.getProductArea());
|
||||
return reqDTO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 ACS 操作校验结果
|
||||
*/
|
||||
private void handleCheckResult(AcsOperateCheckReqDTO reqDTO, AcsOperateCheckRespDTO result) {
|
||||
if (result == null) {
|
||||
throw new ServiceException(500, "ACS 操作校验返回为空");
|
||||
}
|
||||
Boolean enableOperate = getEnableOperate(result);
|
||||
if (Boolean.TRUE.equals(enableOperate)) {
|
||||
return;
|
||||
}
|
||||
String message = getMessage(result);
|
||||
log.warn("ACS 拒绝 PC 端任务操作,reqDTO={},result={}",
|
||||
JsonUtils.toJsonString(reqDTO), JsonUtils.toJsonString(result));
|
||||
throw new ServiceException(500, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 ACS 是否允许操作
|
||||
*/
|
||||
private Boolean getEnableOperate(AcsOperateCheckRespDTO result) {
|
||||
if (result.getEnableOperate() != null) {
|
||||
return result.getEnableOperate();
|
||||
}
|
||||
if (result.getCanOperate() != null) {
|
||||
return result.getCanOperate();
|
||||
}
|
||||
if (result.getData() != null) {
|
||||
return result.getData();
|
||||
}
|
||||
return result.getSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 ACS 拒绝原因
|
||||
*/
|
||||
private String getMessage(AcsOperateCheckRespDTO result) {
|
||||
if (StrUtil.isNotBlank(result.getMessage())) {
|
||||
return result.getMessage();
|
||||
}
|
||||
return StrUtil.blankToDefault(result.getMsg(), "ACS 不允许执行该操作");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -73,6 +73,7 @@ public class TransportTaskOperationManager {
|
||||
handler.accept(task, reqDTO);
|
||||
} catch (Exception ex) {
|
||||
log.error("[messageResend][执行异常][lockKey={}]", task.getTaskId(), ex);
|
||||
throw new ServiceException(500, ex.getMessage());
|
||||
} finally {
|
||||
if (lock.isHeldByCurrentThread()) {
|
||||
lock.unlock();
|
||||
|
||||
@@ -16,6 +16,7 @@ import cn.code.nl.module.task.enums.FinishedTypeEnum;
|
||||
import cn.code.nl.module.task.enums.TaskOperationTypeEnum;
|
||||
import cn.code.nl.module.task.enums.TransportTaskStatusEnum;
|
||||
import cn.code.nl.module.task.manage.TransportTaskIssueManager;
|
||||
import cn.code.nl.module.task.manage.TransportTaskOperateCheckManager;
|
||||
import cn.code.nl.module.task.manage.TransportTaskOperationManager;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
@@ -50,6 +51,9 @@ public class TransportTaskServiceImpl implements TransportTaskService {
|
||||
@Resource
|
||||
private TransportTaskIssueManager transportTaskIssueManager;
|
||||
|
||||
@Resource
|
||||
private TransportTaskOperateCheckManager transportTaskOperateCheckManager;
|
||||
|
||||
@Override
|
||||
public Long createTransportTask(TransportTaskSaveReqVO createReqVO) {
|
||||
TransportTaskDO transportTask = BeanUtils.toBean(createReqVO, TransportTaskDO.class);
|
||||
@@ -130,6 +134,9 @@ public class TransportTaskServiceImpl implements TransportTaskService {
|
||||
|| TransportTaskStatusEnum.CANCELLED.getCode().equals(task.getTaskStatus())) {
|
||||
throw exception(TRANSPORT_TASK_ALREADY_FINAL);
|
||||
}
|
||||
if (type == TaskOperationTypeEnum.FINISHED || type == TaskOperationTypeEnum.CANCELLED) {
|
||||
transportTaskOperateCheckManager.checkEnableOperate(task, type);
|
||||
}
|
||||
if (type == TaskOperationTypeEnum.FINISHED) {
|
||||
task.setFinishedType(FinishedTypeEnum.MANUAL.getCode());
|
||||
} else if (type == TaskOperationTypeEnum.FORCE_FINISH) {
|
||||
|
||||
Reference in New Issue
Block a user