# Task 服务技术开发文档 ## 1. 服务定位 `Task` 服务基于 `task_transport_job` 表,负责搬运任务的通用生命周期管理和 ACS 交互。 整体链路: ```text LMS/WMS 创建搬运任务 -> Task 保存任务 -> Task 自动或手动下发 ACS -> ACS 反馈执行中、取货、完成、取消 -> Task 更新任务状态 -> Task 通过 MQ 通知 LMS/WMS 执行业务完成/取消 -> LMS/WMS 处理后回传结果 -> Task 更新最终完成/取消状态 ``` Task 服务不处理 LMS/WMS 的具体业务数据,例如生产计划、备货区点位、库存、入库单、出库单。业务逻辑由 LMS/WMS 内部 handler 处理。 ## 2. Task 服务除 CRUD 外的核心业务 Task 服务核心能力包括: ```text 1. 接收 LMS/WMS 创建任务 2. 保存任务标准数据 3. 定时扫描并自动下发任务 4. 将 task_transport_job 转换为 AcsTaskDto 5. 调用 ACS 下发任务 6. 接收 ACS 状态反馈 7. 维护任务状态机 8. 发布完成/取消 MQ 给 LMS/WMS 9. 接收 LMS/WMS 业务处理结果 10. 处理下发失败、回调失败、超时补偿 11. 幂等和并发控制 12. 任务过程日志记录 ``` ## 3. 表字段和核心职责对应关系 ### 3.1 业务路由字段 | 字段 | 作用 | | --- | --- | | `owner_service` | 决定 MQ 发送给 LMS 还是 WMS | | `biz_type` | 业务类型,用于查询、统计、防重复创建 | | `biz_id` | 业务侧记录 ID,LMS/WMS 回调时定位业务数据 | | `handle_code` | LMS/WMS 内部 handler 编码 | 完成/取消时路由: ```text owner_service -> MQ Tag 或目标服务 handle_code -> LMS/WMS 内部 handlerMap ``` ### 3.2 ACS 下发字段 | 字段 | 对应 AcsTaskDto | | --- | --- | | `task_id` | `taskId` | | `task_code` | `taskCode` | | `acs_task_type` | `taskType` | | `point_code1` | `startDeviceCode` | | `point_code2` | `nextDeviceCode` | | `point_code3` | `startDeviceCode2` | | `point_code4` | `nextDeviceCode2` | | `vehicle_code` | `vehicleCode` | | `vehicle_code2` | `vehicleCode2` | | `priority` | `priority` | | `product_area` | `productArea` | | `agv_system_type` | `agvSystemType` | | `request_param` | `interactionJson` | ### 3.3 参数快照字段 | 字段 | 说明 | | --- | --- | | `request_param` | LMS/WMS 创建任务扩展参数,同时作为 `interactionJson` 来源 | | `dispatch_param` | Task 下发 ACS 的 `AcsTaskDto` 报文快照 | | `result_param` | ACS 反馈报文 | ### 3.4 回调字段 | 字段 | 说明 | | --- | --- | | `callback_status` | 业务回调状态:PENDING/SUCCESS/FAILED | | `callback_retry_count` | 业务回调重试次数 | | `callback_error_msg` | 业务回调失败原因 | ## 4. 任务状态设计 推荐状态码: | 状态码 | 状态名称 | 修改阶段 | | --- | --- | --- | | `10` | 生成 | 创建任务但条件不完整 | | `40` | 待下发 | 起点终点确认,允许下发 | | `45` | 下发中 | Task 准备调用 ACS 前 | | `50` | 已下发 | ACS 接收任务成功 | | `60` | 执行中 | ACS 反馈执行中 | | `61` | 已取货搬运中 | ACS 反馈取货完成,部分任务有 | | `67` | 外部完成待业务处理 | ACS 完成,等待 LMS/WMS 业务完成 | | `68` | 外部取消中 | Task 正在调用 ACS 取消 | | `69` | 外部取消待业务处理 | ACS 取消成功,等待 LMS/WMS 回滚 | | `70` | 完成 | LMS/WMS 业务完成成功 | | `80` | 取消 | LMS/WMS 业务取消成功 | | `90` | 失败 | 下发失败、取消失败、不可恢复异常 | 常用查询: ```sql -- 外部未完成任务,用于防止重复创建 SELECT * FROM task_transport_job WHERE deleted = b'0' AND biz_type = ? AND task_status < '067'; ``` ```sql -- 未最终结束任务 SELECT * FROM task_transport_job WHERE deleted = b'0' AND task_status < '070'; ``` ```sql -- 业务回调失败任务 SELECT * FROM task_transport_job WHERE deleted = b'0' AND task_status IN ('067', '069') AND callback_status = 'FAILED'; ``` ## 5. 创建任务 ### 5.1 接口 ```text POST /rpc-api/task/transport/create ``` ### 5.2 创建请求核心字段 ```java public class TransportTaskCreateReqDTO { private String taskName; private String ownerService; private String bizType; private String bizId; private String handleCode; private String taskType; private String acsTaskType; private String agvSystemType; private String pointCode1; private String pointCode2; private String pointCode3; private String pointCode4; private String vehicleCode; private String vehicleCode2; private String priority; private String productArea; private String isAutoIssue; private Map requestParam; } ``` ### 5.3 创建逻辑 ```text 1. 校验 owner_service、handle_code、acs_task_type 等必要字段 2. 生成 task_id、task_code 3. 保存业务归属字段 owner_service、biz_type、biz_id、handle_code 4. 保存 ACS 下发字段 point_code、vehicle_code、acs_task_type 等 5. 保存 request_param 6. 参数完整则 task_status = 040,否则 task_status = 010 ``` ## 6. 自动下发任务 ### 6.1 定时器 推荐定时任务: ```text autoIssueTransportTaskJob ``` 扫描条件: ```sql SELECT * FROM task_transport_job WHERE deleted = b'0' AND is_auto_issue = '1' AND task_status = '040' ORDER BY priority DESC, create_time ASC LIMIT ?; ``` ### 6.2 抢占任务 为避免并发重复下发,先做状态抢占: ```sql UPDATE task_transport_job SET task_status = '045', update_time = NOW() WHERE task_id = ? AND task_status = '040'; ``` 影响行数为 1 才继续下发。 ### 6.3 下发流程 ```text 1. 查询 040 待下发任务 2. 抢占为 045 下发中 3. 转换成 AcsTaskDto 4. 保存 dispatch_param 5. 调用 ACS 下发接口 6. 成功:task_status = 050,保存 external_task_no 7. 失败:task_status = 090 或恢复 040,记录错误 ``` ## 7. AcsTaskDto 转换 ### 7.1 DTO ```java public class AcsTaskDto { private String taskId; private String taskCode; private String taskType; private String startDeviceCode; private String nextDeviceCode; private String startDeviceCode2; private String nextDeviceCode2; private String vehicleCode; private String vehicleCode2; private String priority; private String productArea; private String agvSystemType; private Map interactionJson; } ``` ### 7.2 转换器 ```java @Component public class AcsTaskDtoConverter { public AcsTaskDto convert(TaskTransportJobDO task) { AcsTaskDto dto = new AcsTaskDto(); dto.setTaskId(String.valueOf(task.getTaskId())); dto.setTaskCode(task.getTaskCode()); dto.setTaskType(task.getAcsTaskType()); dto.setStartDeviceCode(task.getPointCode1()); dto.setNextDeviceCode(task.getPointCode2()); dto.setStartDeviceCode2(task.getPointCode3()); dto.setNextDeviceCode2(task.getPointCode4()); dto.setVehicleCode(task.getVehicleCode()); dto.setVehicleCode2(task.getVehicleCode2()); dto.setPriority(task.getPriority()); dto.setProductArea(task.getProductArea()); dto.setAgvSystemType(task.getAgvSystemType()); dto.setInteractionJson(JsonUtils.parseMap(task.getRequestParam())); return dto; } } ``` ## 8. ACS 下发服务 ### 8.1 ACS Client ```java public interface AcsClient { AcsIssueResult issueTask(AcsTaskDto taskDto); AcsCancelResult cancelTask(String externalTaskNo, Long taskId); } ``` ### 8.2 下发服务职责 ```text TransportTaskIssueService.issue(taskId) -> 查询任务 -> 抢占状态 040 -> 045 -> AcsTaskDtoConverter.convert -> 保存 dispatch_param -> acsClient.issueTask -> 成功 045 -> 050 -> 失败记录错误 ``` ## 9. ACS 反馈接收 ### 9.1 接口 ```text POST /api/task/transport/acs-feedback ``` ### 9.2 反馈 DTO ```java public class AcsFeedbackReqDTO { private Long taskId; private String taskCode; private String externalTaskNo; private String status; private String eventId; private Map payload; } ``` ### 9.3 状态处理 | ACS 反馈 | Task 更新 | | --- | --- | | 执行中 | `task_status = 060` | | 已取货 | `task_status = 061` | | 完成 | `task_status = 067`, `callback_status = PENDING` | | 取消成功 | `task_status = 069`, `callback_status = PENDING` | 所有反馈均保存到: ```text result_param ``` 完成和取消反馈后,需要发布 MQ 给 LMS/WMS。 ## 10. 完成/取消 MQ 事件 ### 10.1 Topic 设计 ```text Topic = TASK_EVENT_TOPIC Tag = owner_service ``` 示例: ```text TASK_EVENT_TOPIC:LMS TASK_EVENT_TOPIC:WMS ``` ### 10.2 消息结构 ```java public class TaskEventMessage { private String eventId; private String eventType; // TASK_FINISHED / TASK_CANCELLED private Long taskId; private String taskCode; private String ownerService; private String bizType; private String bizId; private String handleCode; private Map payload; } ``` ### 10.3 发布逻辑 ```text 1. 查询 task_transport_job 2. 构造 TaskEventMessage 3. topic = TASK_EVENT_TOPIC 4. tag = owner_service 5. 发送 MQ 6. 发送失败:callback_status = FAILED,记录 callback_error_msg ``` ## 11. 接收业务回调结果 LMS/WMS 消费 MQ 后,内部通过 `handle_code` 找 handler 执行业务逻辑。处理完成后回调 Task。 接口: ```text POST /rpc-api/task/transport/callback-result ``` DTO: ```java public class TaskCallbackResultReqDTO { private Long taskId; private String eventId; private String eventType; private String result; // SUCCESS / FAILED private String message; } ``` 状态更新: | 场景 | Task 更新 | | --- | --- | | 完成业务成功 | `task_status = 070`, `callback_status = SUCCESS` | | 完成业务失败 | `task_status = 067`, `callback_status = FAILED`, `callback_retry_count + 1` | | 取消业务成功 | `task_status = 080`, `callback_status = SUCCESS` | | 取消业务失败 | `task_status = 069`, `callback_status = FAILED`, `callback_retry_count + 1` | ## 12. 人工完成和取消 ### 12.1 人工完成 ```text PC 点击完成 -> Task 校验任务 -> task_status = 067 -> callback_status = PENDING -> 发布 TASK_FINISHED MQ -> 页面提示:完成请求已提交,业务处理中 ``` ### 12.2 人工取消 未下发任务: ```text 010/040 -> 069 -> 发布 TASK_CANCELLED MQ ``` 已下发任务: ```text 050/060/061 -> 068 -> 调 ACS 取消 -> 069 -> 发布 TASK_CANCELLED MQ ``` ## 13. 补偿和重试 ### 13.1 回调失败重试 扫描: ```sql SELECT * FROM task_transport_job WHERE deleted = b'0' AND task_status IN ('067', '069') AND callback_status = 'FAILED' AND callback_retry_count < ?; ``` 处理: ```text 重新发布 TASK_FINISHED 或 TASK_CANCELLED callback_retry_count + 1 ``` ### 13.2 PENDING 超时补偿 扫描: ```text task_status IN ('067', '069') callback_status = PENDING update_time 超过阈值 ``` 处理: ```text 重新发布 MQ 或标记 FAILED ``` ### 13.3 下发中超时补偿 扫描: ```text task_status = 045 update_time 超过阈值 ``` 处理: ```text 查询 ACS 是否已收到任务;无法确认则恢复 040 或标记 090 ``` ## 14. 幂等控制 ### 14.1 创建幂等 防重复创建示例: ```sql SELECT * FROM task_transport_job WHERE deleted = b'0' AND owner_service = ? AND biz_type = ? AND biz_id = ? AND task_status < '067'; ``` ### 14.2 下发幂等 通过 `040 -> 045` 条件更新抢占。 ### 14.3 ACS 反馈幂等 建议引入反馈日志表记录 `eventId`。第一版至少根据状态判断: ```text 已是 070,不重复处理完成 已是 067,不重复发布完成 MQ ``` ### 14.4 业务回调结果幂等 如果已是最终态: ```text task_status = 070 或 080 ``` 再次收到成功回调时直接返回成功。 ## 15. 推荐模块结构 ```text nl-module-task-server controller TransportTaskController AcsFeedbackController api TransportTaskApiImpl service TransportTaskService TransportTaskIssueService TransportTaskFeedbackService TransportTaskCallbackService TransportTaskCancelService TransportTaskRetryService converter AcsTaskDtoConverter mq TaskEventProducer job AutoIssueTransportTaskJob CallbackRetryJob dal dataobject/TaskTransportJobDO mapper/TaskTransportJobMapper enums TransportTaskStatusEnum CallbackStatusEnum TaskEventTypeEnum ``` ## 16. 总结 Task 服务的核心不是简单 CRUD,而是搬运任务生命周期中台。 核心职责: ```text 接收任务 -> 保存任务 -> 自动下发 -> 转换 AcsTaskDto -> 调 ACS -> 接收反馈 -> 发布业务事件 -> 接收业务结果 -> 最终完成/取消 -> 补偿重试 ``` 关键路由: ```text owner_service 决定事件给 LMS/WMS handle_code 决定业务服务内部哪个 handler 处理 ``` 关键状态: ```text task_status 表示任务流转到哪一步 callback_status 表示 LMS/WMS 业务回调是否成功 ```