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

140 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 搬运任务操作重构 + PC 端操作功能设计
- 日期2026-07-15
- 分支feature/20260713/task-module
- 状态:已评审通过(方案 A单类路由表
## 1. 背景与目标
任务状态操作目前存在两个入口:
- **ACS 入口**`AcsFeedbackController``TransportTaskFeedbackServiceImpl.receiveAcsFeedback()`,用字符串 if-else 按 `status` 分发到 `handleExecuting/handlePicked/handleFinished/handleCancelled`,代码凌乱。
- **PC 入口**:尚不存在。前端 `views/task/transporttask/index.vue` 已有"完成任务/取消任务/强制完成任务"三个按钮,但都错绑在 `handleEdit` 上,未传操作类型。
目标:
1. 消灭 if-else 分发,改为表驱动策略(路由表)。
2. 操作业务代码统一集中到 `TransportTaskServiceImpl``handleExecuting/handlePicked/handleFinished/handleCancelled/publishEvent` 方法体**原样迁移**,不改业务逻辑。
3. 新增 PC 端统一操作接口 `POST /task/transport-task/operate`taskId + 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 枚举增强 `TaskOperationTypeEnum`task-api 模块)
- 增加两个布尔属性:`acsAllowed`(允许 ACS 触发)、`pcAllowed`(允许 PC 触发),取值见上表。
- 增加静态解析方法 `getByCode(String code)`:忽略大小写匹配 `code`,找不到返回 `null`
### 3.2 `TransportTaskServiceImpl`:路由表 + PC 入口
-`TransportTaskFeedbackServiceImpl` **原样迁入**`handleExecuting``handlePicked``handleFinished``handleCancelled``publishEvent``buildCallbackReq`(当前无调用方,随迁保留);依赖 `TaskEventProducer``TaskCommonApiFactory``OBJECT_MAPPER` 相关部分随迁。
- 路由表:`EnumMap<TaskOperationTypeEnum, BiConsumer<TransportTaskDO, AcsFeedbackReqDTO>>`,在 `@PostConstruct` 中注册六种类型;`APPLY_AGAIN``FORCE_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` 解析 operationType`null``pcAllowed=false` → 抛新错误码 `TRANSPORT_TASK_OPERATION_NOT_SUPPORTED`
3. 任务已终态79 完成 / 89 取消)→ 抛新错误码 `TRANSPORT_TASK_ALREADY_FINAL`PC 端需给用户明确反馈,区别于 ACS 入口的静默幂等返回)。
4. **PC 与 ACS 的差异点——记录完成类型/来源**`FINISHED``task.setFinishedType("MANUAL")`(人工完成);`FORCE_FINISH``task.setFinishedType("FORCE")`(强制完成);`CANCELLED` 不设置。注意:`FORCE_FINISH` 的业务 handler 当前为 todo 占位、不执行 `updateById`,因此该 finishedType 设置在业务开发完成前不会实际落库,属预期行为。
5. 构造仅含 `taskId``status``AcsFeedbackReqDTO`,调用 `dispatchOperation` 走同一路由表(保持 handler 签名不变)。
- 新错误码追加到 `ErrorCodeConstants`,编号顺延现有 task 模块段。
### 3.3 `TransportTaskFeedbackServiceImpl` 瘦身
只保留 ACS 前置处理,注入 `TransportTaskService` 后委托分发:
1. 查任务(不存在打 warn 返回,保持现状)。
2. 终态幂等判断(保持现状)。
3. 保存 `resultParam`(保持现状)。
4. 分发段替换为:
```java
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*``publishEvent``buildCallbackReq` 从此类删除。依赖方向为 Feedback → TransportTaskService 单向,无循环依赖;`receiveAcsFeedback``@Transactional` 保持,跨 Bean 调用按 REQUIRED 传播沿用同一事务。
### 3.4 Controller / VO
- `TransportTaskController` 新增:
```java
@PostMapping("/operate")
@Operation(summary = "PC 端操作搬运任务(完成/取消/强制完成)")
@PreAuthorize("@ss.hasPermission('task:transport-task:operate')")
public CommonResult<Boolean> operateTransportTask(@Valid @RequestBody TransportTaskOperateReqVO reqVO)
```
- 新 VO `TransportTaskOperateReqVO`controller vo 包):`@NotNull Long taskId``@NotEmpty String operationType`(取值 FINISHED/CANCELLED/FORCE-FINISH
## 4. 前端设计web-antdv-next
### 4.1 API`api/task/transporttask/index.ts`
```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`
- 新增操作函数:
```ts
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 compile`task 模块)通过;前端 lint/类型检查通过。
## 7. 范围外(明确不做)
- APPLY-AGAIN、FORCE-FINISH 的具体业务实现todo 占位)。
- 强制完成按钮的独立权限与菜单配置。
- PC 操作联动 ACS如向 ACS 下发取消指令)。
- `finishedType` 的字典配置与前端字典展示。