Files
huachuang/docs/superpowers/specs/2026-07-15-task-operation-refactor-design.md

7.3 KiB
Raw Blame History

搬运任务操作重构 + PC 端操作功能设计

  • 日期2026-07-15
  • 分支feature/20260713/task-module
  • 状态:已评审通过(方案 A单类路由表

1. 背景与目标

任务状态操作目前存在两个入口:

  • ACS 入口AcsFeedbackControllerTransportTaskFeedbackServiceImpl.receiveAcsFeedback(),用字符串 if-else 按 status 分发到 handleExecuting/handlePicked/handleFinished/handleCancelled,代码凌乱。
  • PC 入口:尚不存在。前端 views/task/transporttask/index.vue 已有"完成任务/取消任务/强制完成任务"三个按钮,但都错绑在 handleEdit 上,未传操作类型。

目标:

  1. 消灭 if-else 分发,改为表驱动策略(路由表)。
  2. 操作业务代码统一集中到 TransportTaskServiceImplhandleExecuting/handlePicked/handleFinished/handleCancelled/publishEvent 方法体原样迁移,不改业务逻辑。
  3. 新增 PC 端统一操作接口 POST /task/transport-task/operatetaskId + operationType支持 FINISHED / CANCELLED / FORCE-FINISH。
  4. APPLY-AGAIN(二次请求)、FORCE-FINISH(强制完成)业务未开发,路由表中注册 todo 占位(仅打日志)。
  5. 前端按钮补齐操作类型标识与调用逻辑。

2. 操作类型与入口矩阵

操作类型 code ACS 触发 PC 触发 业务
EXECUTING EXECUTING handleExecuting已有
PICKED PICKED handlePicked已有
FINISHED FINISHED handleFinished已有
CANCELLED CANCELLED handleCancelled已有
APPLY_AGAIN APPLY-AGAIN todo未开发
FORCE_FINISH FORCE-FINISH todo未开发

3. 后端设计

3.1 枚举增强 TaskOperationTypeEnumtask-api 模块)

  • 增加两个布尔属性:acsAllowed(允许 ACS 触发)、pcAllowed(允许 PC 触发),取值见上表。
  • 增加静态解析方法 getByCode(String code):忽略大小写匹配 code,找不到返回 null

3.2 TransportTaskServiceImpl:路由表 + PC 入口

  • TransportTaskFeedbackServiceImpl 原样迁入handleExecutinghandlePickedhandleFinishedhandleCancelledpublishEventbuildCallbackReq(当前无调用方,随迁保留);依赖 TaskEventProducerTaskCommonApiFactoryOBJECT_MAPPER 相关部分随迁。
  • 路由表:EnumMap<TaskOperationTypeEnum, BiConsumer<TransportTaskDO, AcsFeedbackReqDTO>>,在 @PostConstruct 中注册六种类型;APPLY_AGAINFORCE_FINISH 注册为 todo 占位(打 log.info不做业务
  • 新增接口方法 dispatchOperation(TransportTaskDO task, TaskOperationTypeEnum type, AcsFeedbackReqDTO reqDTO):查路由表分发,查不到打 warn 日志。
  • 新增 PC 入口 operateTransportTask(TransportTaskOperateReqVO reqVO)@Transactional(rollbackFor = Exception.class)
    1. 查任务,不存在 → 抛 TRANSPORT_TASK_NOT_EXISTS
    2. getByCode 解析 operationTypenullpcAllowed=false → 抛新错误码 TRANSPORT_TASK_OPERATION_NOT_SUPPORTED
    3. 任务已终态79 完成 / 89 取消)→ 抛新错误码 TRANSPORT_TASK_ALREADY_FINALPC 端需给用户明确反馈,区别于 ACS 入口的静默幂等返回)。
    4. PC 与 ACS 的差异点——记录完成类型/来源FINISHEDtask.setFinishedType("MANUAL")(人工完成);FORCE_FINISHtask.setFinishedType("FORCE")(强制完成);CANCELLED 不设置。注意:FORCE_FINISH 的业务 handler 当前为 todo 占位、不执行 updateById,因此该 finishedType 设置在业务开发完成前不会实际落库,属预期行为。
    5. 构造仅含 taskIdstatusAcsFeedbackReqDTO,调用 dispatchOperation 走同一路由表(保持 handler 签名不变)。
  • 新错误码追加到 ErrorCodeConstants,编号顺延现有 task 模块段。

3.3 TransportTaskFeedbackServiceImpl 瘦身

只保留 ACS 前置处理,注入 TransportTaskService 后委托分发:

  1. 查任务(不存在打 warn 返回,保持现状)。
  2. 终态幂等判断(保持现状)。
  3. 保存 resultParam(保持现状)。
  4. 分发段替换为:
TaskOperationTypeEnum type = TaskOperationTypeEnum.getByCode(reqDTO.getStatus());
if (type == null || !type.isAcsAllowed()) {
    log.warn("未知或不允许的 ACS 反馈状态, taskId={}, status={}", reqDTO.getTaskId(), reqDTO.getStatus());
    return;
}
transportTaskService.dispatchOperation(task, type, reqDTO);

handle*publishEventbuildCallbackReq 从此类删除。依赖方向为 Feedback → TransportTaskService 单向,无循环依赖;receiveAcsFeedback@Transactional 保持,跨 Bean 调用按 REQUIRED 传播沿用同一事务。

3.4 Controller / VO

  • TransportTaskController 新增:
@PostMapping("/operate")
@Operation(summary = "PC 端操作搬运任务(完成/取消/强制完成)")
@PreAuthorize("@ss.hasPermission('task:transport-task:operate')")
public CommonResult<Boolean> operateTransportTask(@Valid @RequestBody TransportTaskOperateReqVO reqVO)
  • 新 VO TransportTaskOperateReqVOcontroller vo 包):@NotNull Long taskId@NotEmpty String operationType(取值 FINISHED/CANCELLED/FORCE-FINISH

4. 前端设计web-antdv-next

4.1 APIapi/task/transporttask/index.ts

/** PC 端操作搬运任务(完成/取消/强制完成) */
export function operateTransportTask(data: {
  operationType: string;
  taskId: number;
}) {
  return requestClient.post('/task/transport-task/operate', data);
}

4.2 页面(views/task/transporttask/index.vue

  • 新增操作函数:
async function handleOperate(
  row: TaskTransportTaskApi.TransportTask,
  operationType: string,
  label: string,
) {
  await confirm(`确认要${label}${row.taskCode}】吗?`);
  await operateTransportTask({ taskId: row.taskId!, operationType });
  message.success(`${label}成功`);
  handleRefresh();
}
  • 三个按钮 onClick 替换错绑的 handleEdit
    • 完成任务 → handleOperate(row, 'FINISHED', '完成任务')
    • 取消任务 → handleOperate(row, 'CANCELLED', '取消任务')
    • 强制完成任务 → handleOperate(row, 'FORCE-FINISH', '强制完成任务')
  • 备注:强制完成按钮当前 auth 复用 task:transport-task:cancel、icon 用 CANCEL,本次不调整权限(需菜单配套),仅修正绑定。

5. 错误处理

  • PC 入口:任务不存在 / 操作类型不支持 / 任务已终态,均抛 ServiceException由全局异常处理返回给前端提示。
  • ACS 入口:保持现状(不存在/终态/未知状态均打日志静默返回成功,避免 ACS 重试)。
  • MQ 发布失败:沿用 publishEvent 现有逻辑callbackStatus=FAILED + 记录错误信息)。

6. 测试与验证

  • 按项目约定本次不编写测试CLAUDE.md除非用户允许测试
  • 验证方式:后端 mvn compiletask 模块)通过;前端 lint/类型检查通过。

7. 范围外(明确不做)

  • APPLY-AGAIN、FORCE-FINISH 的具体业务实现todo 占位)。
  • 强制完成按钮的独立权限与菜单配置。
  • PC 操作联动 ACS如向 ACS 下发取消指令)。
  • finishedType 的字典配置与前端字典展示。