fix:任务创建/修改状态
This commit is contained in:
@@ -10,6 +10,7 @@
|
|||||||
3. **测试先于实现** — 写代码前先写测试(TDD)
|
3. **测试先于实现** — 写代码前先写测试(TDD)
|
||||||
4. **验证先于完成** — 声称完成前必须运行验证命令
|
4. **验证先于完成** — 声称完成前必须运行验证命令
|
||||||
5. **代码开发规则** — 遵守 `.claude/skills/nl-java-style/SKILL.md` 技能的规范要求
|
5. **代码开发规则** — 遵守 `.claude/skills/nl-java-style/SKILL.md` 技能的规范要求
|
||||||
|
6. 不需要频繁提交代码,除非用户说允许测试,否则优先不做测试
|
||||||
|
|
||||||
## 可用 Skills
|
## 可用 Skills
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
旧版本的代码可以参照:D:\Code\nl\lanzhouhailiang_one\lms\nladmin-system
|
||||||
|
里面与task相关的,是本次开发任务模块的旧版本
|
||||||
588
doc/task-service-technical-development.md
Normal file
588
doc/task-service-technical-development.md
Normal file
@@ -0,0 +1,588 @@
|
|||||||
|
# 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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 业务回调是否成功
|
||||||
|
```
|
||||||
@@ -793,7 +793,7 @@ git commit -m "feat: 新增 TransportTaskStatusClient 同步 HTTP 回调客户
|
|||||||
```java
|
```java
|
||||||
package cn.code.nl.module.task.mq;
|
package cn.code.nl.module.task.mq;
|
||||||
|
|
||||||
import cn.code.nl.module.task.dto.TaskEventMessage;
|
import cn.code.nl.module.task.mq.message.TaskEventMessage;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -889,7 +889,7 @@ import cn.code.nl.module.task.client.TransportTaskStatusClient;
|
|||||||
import cn.code.nl.module.task.dal.dataobject.transporttask.TransportTaskDO;
|
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.dal.mysql.transporttask.TransportTaskMapper;
|
||||||
import cn.code.nl.module.task.dto.AcsFeedbackReqDTO;
|
import cn.code.nl.module.task.dto.AcsFeedbackReqDTO;
|
||||||
import cn.code.nl.module.task.mq.TaskEventProducer;
|
import cn.code.nl.module.task.mq.producer.TaskEventProducer;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
@@ -977,13 +977,13 @@ import cn.code.nl.module.task.client.TransportTaskStatusClient;
|
|||||||
import cn.code.nl.module.task.dal.dataobject.transporttask.TransportTaskDO;
|
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.dal.mysql.transporttask.TransportTaskMapper;
|
||||||
import cn.code.nl.module.task.dto.AcsFeedbackReqDTO;
|
import cn.code.nl.module.task.dto.AcsFeedbackReqDTO;
|
||||||
import cn.code.nl.module.task.dto.TaskEventMessage;
|
import cn.code.nl.module.task.mq.message.TaskEventMessage;
|
||||||
import cn.code.nl.module.task.dto.TaskStatusCallbackReqDTO;
|
import cn.code.nl.module.task.dto.TaskStatusCallbackReqDTO;
|
||||||
import cn.code.nl.module.task.dto.TaskStatusCallbackRespDTO;
|
import cn.code.nl.module.task.dto.TaskStatusCallbackRespDTO;
|
||||||
import cn.code.nl.module.task.enums.CallbackStatusEnum;
|
import cn.code.nl.module.task.enums.CallbackStatusEnum;
|
||||||
import cn.code.nl.module.task.enums.TaskEventTypeEnum;
|
import cn.code.nl.module.task.enums.TaskEventTypeEnum;
|
||||||
import cn.code.nl.module.task.enums.TransportTaskStatusEnum;
|
import cn.code.nl.module.task.enums.TransportTaskStatusEnum;
|
||||||
import cn.code.nl.module.task.mq.TaskEventProducer;
|
import cn.code.nl.module.task.mq.producer.TaskEventProducer;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|||||||
@@ -36,7 +36,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.rocketmq</groupId>
|
<groupId>org.apache.rocketmq</groupId>
|
||||||
<artifactId>rocketmq-spring-boot-starter</artifactId>
|
<artifactId>rocketmq-spring-boot-starter</artifactId>
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
*
|
* 外部引用任务的task接口
|
||||||
* @Author: liyongde
|
* @Author: liyongde
|
||||||
* @Date: 2026/7/14 18:57
|
* @Date: 2026/7/14 18:57
|
||||||
*/package cn.code.nl.module.task.api;
|
*/
|
||||||
|
package cn.code.nl.module.task.api;
|
||||||
@@ -68,6 +68,9 @@ public class TransportTaskCreateReqDTO {
|
|||||||
@Schema(description = "是否自动下发")
|
@Schema(description = "是否自动下发")
|
||||||
private String isAutoIssue;
|
private String isAutoIssue;
|
||||||
|
|
||||||
|
@Schema(description = "是否创建完成")
|
||||||
|
private Boolean isCreateFinish;
|
||||||
|
|
||||||
@Schema(description = "任务类型")
|
@Schema(description = "任务类型")
|
||||||
private String taskType;
|
private String taskType;
|
||||||
|
|
||||||
@@ -87,5 +90,5 @@ public class TransportTaskCreateReqDTO {
|
|||||||
private Long sortSeq;
|
private Long sortSeq;
|
||||||
|
|
||||||
@Schema(description = "扩展参数(JSON)")
|
@Schema(description = "扩展参数(JSON)")
|
||||||
private Map<String, Object> requestParam;
|
private String requestParam;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ import cn.code.nl.framework.common.exception.ErrorCode;
|
|||||||
* @Date: 2026/7/14 13:03
|
* @Date: 2026/7/14 13:03
|
||||||
*/
|
*/
|
||||||
public interface ErrorCodeConstants {
|
public interface ErrorCodeConstants {
|
||||||
ErrorCode TRANSPORT_TASK_NOT_EXISTS = new ErrorCode(1, "搬运任务不存在");
|
ErrorCode TRANSPORT_TASK_NOT_EXISTS = new ErrorCode(5001, "搬运任务不存在");
|
||||||
ErrorCode TRANSPORT_TASK_EXISTS_UNFINISHED = new ErrorCode(2, "同业务类型下存在未完结的搬运任务");
|
ErrorCode TRANSPORT_TASK_EXISTS_UNFINISHED = new ErrorCode(5002, "同业务类型下存在未完结的搬运任务");
|
||||||
ErrorCode TRANSPORT_TASK_STATUS_NOT_ALLOW = new ErrorCode(3, "当前任务状态不允许此操作");
|
ErrorCode TRANSPORT_TASK_STATUS_NOT_ALLOW = new ErrorCode(5003, "当前任务状态不允许此操作");
|
||||||
ErrorCode TRANSPORT_TASK_CALLBACK_SEND_FAILED = new ErrorCode(4, "业务回调发送失败");
|
ErrorCode TRANSPORT_TASK_CALLBACK_SEND_FAILED = new ErrorCode(5004, "业务回调发送失败");
|
||||||
|
ErrorCode TRANSPORT_TASK_RUNNING_ALREADY_EXIST = new ErrorCode(5005, "已存在运行中的任务");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,44 @@
|
|||||||
package cn.code.nl.module.task.enums;
|
package cn.code.nl.module.task.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* 任务状态的枚举
|
||||||
* @Author: liyongde
|
* @Author: liyongde
|
||||||
* @Date: 2026/7/14 16:14
|
* @Date: 2026/7/14 16:14
|
||||||
*/public enum TransportTaskStatusEnum {
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum TransportTaskStatusEnum {
|
||||||
|
|
||||||
|
CREATED(10, "生成"),
|
||||||
|
|
||||||
|
READY(40, "待下发-起点终点确认"),
|
||||||
|
|
||||||
|
ISSUING(45, "下发中"),
|
||||||
|
|
||||||
|
ISSUED(50, "已下发"),
|
||||||
|
|
||||||
|
EXECUTING(60, "执行中"),
|
||||||
|
|
||||||
|
PICKED(61, "已取货搬运中"),
|
||||||
|
|
||||||
|
FINISHED_CALLBACK_PENDING(67, "外部完成待业务处理"),
|
||||||
|
|
||||||
|
CANCEL_EXTERNAL_PENDING(68, "外部取消中"),
|
||||||
|
|
||||||
|
CANCEL_CALLBACK_PENDING(69, "外部取消待业务处理"),
|
||||||
|
|
||||||
|
FINISHED(70, "完成"),
|
||||||
|
|
||||||
|
CANCELLED(80, "取消"),
|
||||||
|
|
||||||
|
FAILED(90, "失败");
|
||||||
|
|
||||||
|
private final Integer code;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
TransportTaskStatusEnum(Integer code, String name) {
|
||||||
|
this.code = code;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cn.code.nl.module.task.controller;
|
package cn.code.nl.module.task.controller.admin.transporttask;
|
||||||
|
|
||||||
import cn.code.nl.framework.common.pojo.CommonResult;
|
import cn.code.nl.framework.common.pojo.CommonResult;
|
||||||
import cn.code.nl.module.task.dto.AcsFeedbackReqDTO;
|
import cn.code.nl.module.task.dto.AcsFeedbackReqDTO;
|
||||||
@@ -22,7 +22,7 @@ import static cn.code.nl.framework.common.pojo.CommonResult.success;
|
|||||||
*/
|
*/
|
||||||
@Tag(name = "ACS 反馈")
|
@Tag(name = "ACS 反馈")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/task/transport")
|
@RequestMapping("/task/transport")
|
||||||
@Validated
|
@Validated
|
||||||
public class AcsFeedbackController {
|
public class AcsFeedbackController {
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package cn.code.nl.module.task.controller;
|
package cn.code.nl.module.task.controller.admin.transporttask;
|
||||||
|
|
||||||
import cn.code.nl.framework.common.pojo.CommonResult;
|
import cn.code.nl.framework.common.pojo.CommonResult;
|
||||||
import cn.code.nl.module.task.dto.TaskCallbackResultReqDTO;
|
import cn.code.nl.module.task.dto.TaskCallbackResultReqDTO;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.util.*;
|
|||||||
|
|
||||||
import cn.code.nl.framework.common.pojo.PageResult;
|
import cn.code.nl.framework.common.pojo.PageResult;
|
||||||
import cn.code.nl.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.code.nl.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.code.nl.module.task.enums.TransportTaskStatusEnum;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import cn.code.nl.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.code.nl.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.code.nl.module.task.dal.dataobject.transporttask.TransportTaskDO;
|
import cn.code.nl.module.task.dal.dataobject.transporttask.TransportTaskDO;
|
||||||
@@ -65,7 +66,7 @@ public interface TransportTaskMapper extends BaseMapperX<TransportTaskDO> {
|
|||||||
return selectOne(new LambdaQueryWrapperX<TransportTaskDO>()
|
return selectOne(new LambdaQueryWrapperX<TransportTaskDO>()
|
||||||
.eq(TransportTaskDO::getBizType, bizType)
|
.eq(TransportTaskDO::getBizType, bizType)
|
||||||
.eq(TransportTaskDO::getBizId, bizId)
|
.eq(TransportTaskDO::getBizId, bizId)
|
||||||
.lt(TransportTaskDO::getTaskStatus, "067"));
|
.lt(TransportTaskDO::getTaskStatus, TransportTaskStatusEnum.FINISHED_CALLBACK_PENDING.getCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
package cn.code.nl.module.task.framework.rpc.config;
|
package cn.code.nl.module.task.framework.rpc.config;
|
||||||
|
|
||||||
import cn.code.nl.module.task.api.TransportTaskApi;
|
|
||||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task 服务 RPC 配置
|
* Task 服务 RPC 配置
|
||||||
* <p>
|
|
||||||
* 注册 Feign 客户端,使 LMS/WMS 等调用方可通过 @Resource 注入 TransportTaskApi
|
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration(value = "taskRpcConfiguration", proxyBeanMethods = false)
|
||||||
@EnableFeignClients(clients = {TransportTaskApi.class})
|
@EnableFeignClients()
|
||||||
public class RpcConfiguration {
|
public class RpcConfiguration {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
package cn.code.nl.module.task.framework.security.config;
|
package cn.code.nl.module.task.framework.security.config;
|
||||||
|
|
||||||
import cn.code.nl.framework.security.config.AuthorizeRequestsCustomizer;
|
import cn.code.nl.framework.security.config.AuthorizeRequestsCustomizer;
|
||||||
import cn.code.nl.module.infra.enums.ApiConstants;
|
import cn.code.nl.module.task.enums.ApiConstants;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
|
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Infra 模块的 Security 配置
|
* Task 模块的 Security 配置
|
||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false, value = "taskSecurityConfiguration")
|
@Configuration(proxyBeanMethods = false, value = "taskSecurityConfiguration")
|
||||||
public class SecurityConfiguration {
|
public class SecurityConfiguration {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
*
|
* 消费者
|
||||||
* @Author: liyongde
|
* @Author: liyongde
|
||||||
* @Date: 2026/7/14 18:47
|
* @Date: 2026/7/14 18:47
|
||||||
*/package cn.code.nl.module.task.mq.consumer;
|
*/
|
||||||
|
package cn.code.nl.module.task.mq.consumer;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package cn.code.nl.module.task.dto;
|
package cn.code.nl.module.task.mq.message;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
*
|
* 信息体
|
||||||
* @Author: liyongde
|
* @Author: liyongde
|
||||||
* @Date: 2026/7/14 18:47
|
* @Date: 2026/7/14 18:47
|
||||||
*/package cn.code.nl.module.task.mq.message;
|
*/
|
||||||
|
package cn.code.nl.module.task.mq.message;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* 消息队列的消息
|
* 消息队列的消息
|
||||||
*/
|
*/
|
||||||
package cn.code.nl.module.infra.mq.message;
|
package cn.code.nl.module.task.mq;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package cn.code.nl.module.task.mq;
|
package cn.code.nl.module.task.mq.producer;
|
||||||
|
|
||||||
import cn.code.nl.module.task.dto.TaskEventMessage;
|
import cn.code.nl.module.task.mq.message.TaskEventMessage;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import cn.code.nl.module.task.client.TransportTaskStatusClient;
|
|||||||
import cn.code.nl.module.task.dal.dataobject.transporttask.TransportTaskDO;
|
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.dal.mysql.transporttask.TransportTaskMapper;
|
||||||
import cn.code.nl.module.task.dto.AcsFeedbackReqDTO;
|
import cn.code.nl.module.task.dto.AcsFeedbackReqDTO;
|
||||||
import cn.code.nl.module.task.dto.TaskEventMessage;
|
import cn.code.nl.module.task.mq.message.TaskEventMessage;
|
||||||
import cn.code.nl.module.task.dto.TaskStatusCallbackReqDTO;
|
import cn.code.nl.module.task.dto.TaskStatusCallbackReqDTO;
|
||||||
import cn.code.nl.module.task.dto.TaskStatusCallbackRespDTO;
|
import cn.code.nl.module.task.dto.TaskStatusCallbackRespDTO;
|
||||||
import cn.code.nl.module.task.enums.CallbackStatusEnum;
|
import cn.code.nl.module.task.enums.CallbackStatusEnum;
|
||||||
import cn.code.nl.module.task.enums.TaskEventTypeEnum;
|
import cn.code.nl.module.task.enums.TaskEventTypeEnum;
|
||||||
import cn.code.nl.module.task.enums.TransportTaskStatusEnum;
|
import cn.code.nl.module.task.enums.TransportTaskStatusEnum;
|
||||||
import cn.code.nl.module.task.mq.TaskEventProducer;
|
import cn.code.nl.module.task.mq.producer.TaskEventProducer;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package cn.code.nl.module.task.service.transporttask;
|
package cn.code.nl.module.task.service.transporttask;
|
||||||
|
|
||||||
|
import cn.code.nl.framework.common.exception.ServiceException;
|
||||||
import cn.code.nl.framework.common.pojo.PageResult;
|
import cn.code.nl.framework.common.pojo.PageResult;
|
||||||
import cn.code.nl.framework.common.util.object.BeanUtils;
|
import cn.code.nl.framework.common.util.object.BeanUtils;
|
||||||
import cn.code.nl.module.task.controller.admin.transporttask.vo.TransportTaskPageReqVO;
|
import cn.code.nl.module.task.controller.admin.transporttask.vo.TransportTaskPageReqVO;
|
||||||
@@ -43,21 +44,12 @@ public class TransportTaskServiceImpl implements TransportTaskService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createTransportTaskByRpc(TransportTaskCreateReqDTO reqDTO) {
|
public Long createTransportTaskByRpc(TransportTaskCreateReqDTO reqDTO) {
|
||||||
// 1. 幂等检查:同 bizType + bizId 下是否有未完结任务
|
// 1. 构建 DO 并保存
|
||||||
TransportTaskDO existing = transportTaskMapper.selectUnfinishedByBiz(
|
|
||||||
reqDTO.getBizType(), reqDTO.getBizId());
|
|
||||||
if (existing != null) {
|
|
||||||
return existing.getTaskId();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 构建 DO 并保存
|
|
||||||
TransportTaskDO task = BeanUtils.toBean(reqDTO, TransportTaskDO.class);
|
TransportTaskDO task = BeanUtils.toBean(reqDTO, TransportTaskDO.class);
|
||||||
// 参数完整 → 待下发(040),否则 → 生成(010)
|
// 参数完整 → 待下发(040),否则 → 生成(010)
|
||||||
boolean paramComplete = StrUtil.isNotBlank(reqDTO.getPointCode1())
|
task.setTaskStatus(reqDTO.getIsCreateFinish()
|
||||||
&& StrUtil.isNotBlank(reqDTO.getPointCode2());
|
? String.valueOf(TransportTaskStatusEnum.READY.getCode())
|
||||||
task.setTaskStatus(paramComplete
|
: String.valueOf(TransportTaskStatusEnum.CREATED.getCode()));
|
||||||
? String.format("%03d", TransportTaskStatusEnum.READY.getCode())
|
|
||||||
: String.format("%03d", TransportTaskStatusEnum.CREATED.getCode()));
|
|
||||||
task.setCallbackStatus(CallbackStatusEnum.PENDING.getCode());
|
task.setCallbackStatus(CallbackStatusEnum.PENDING.getCode());
|
||||||
task.setCallbackRetryCount(0);
|
task.setCallbackRetryCount(0);
|
||||||
task.setCreateMode("RPC");
|
task.setCreateMode("RPC");
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ spring:
|
|||||||
# rocketmq 配置项,对应 RocketMQProperties 配置类
|
# rocketmq 配置项,对应 RocketMQProperties 配置类
|
||||||
rocketmq:
|
rocketmq:
|
||||||
name-server: 127.0.0.1:9876 # RocketMQ Namesrv
|
name-server: 127.0.0.1:9876 # RocketMQ Namesrv
|
||||||
|
producer:
|
||||||
|
group: ${spring.application.name}_TASK_DEV_PRODUCER # 生产者分组
|
||||||
|
|
||||||
spring:
|
spring:
|
||||||
# RabbitMQ 配置项,对应 RabbitProperties 配置类
|
# RabbitMQ 配置项,对应 RabbitProperties 配置类
|
||||||
|
|||||||
@@ -64,10 +64,10 @@ mybatis-plus:
|
|||||||
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
|
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
|
||||||
global-config:
|
global-config:
|
||||||
db-config:
|
db-config:
|
||||||
id-type: NONE # “智能”模式,基于 IdTypeEnvironmentPostProcessor + 数据源的类型,自动适配成 AUTO、INPUT 模式。
|
id-type: ASSIGN_ID # 分配 ID,默认使用雪花算法。注意,Oracle、PostgreSQL、Kingbase、DB2、H2 数据库时,需要去除实体类上的 @KeySequence 注解
|
||||||
|
# id-type: NONE # “智能”模式,基于 IdTypeEnvironmentPostProcessor + 数据源的类型,自动适配成 AUTO、INPUT 模式。
|
||||||
# id-type: AUTO # 自增 ID,适合 MySQL 等直接自增的数据库
|
# id-type: AUTO # 自增 ID,适合 MySQL 等直接自增的数据库
|
||||||
# id-type: INPUT # 用户输入 ID,适合 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库
|
# id-type: INPUT # 用户输入 ID,适合 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库
|
||||||
# id-type: ASSIGN_ID # 分配 ID,默认使用雪花算法。注意,Oracle、PostgreSQL、Kingbase、DB2、H2 数据库时,需要去除实体类上的 @KeySequence 注解
|
|
||||||
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
|
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
|
||||||
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
|
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
|
||||||
banner: false # 关闭控制台的 Banner 打印
|
banner: false # 关闭控制台的 Banner 打印
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package cn.code.nl.module.task.service.transporttask;
|
package cn.code.nl.module.task.service.transporttask;
|
||||||
|
|
||||||
|
import cn.code.nl.framework.common.pojo.CommonResult;
|
||||||
|
import cn.code.nl.module.task.api.TransportTaskApi;
|
||||||
import cn.code.nl.module.task.dal.dataobject.transporttask.TransportTaskDO;
|
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.dal.mysql.transporttask.TransportTaskMapper;
|
||||||
import cn.code.nl.module.task.dto.TransportTaskCreateReqDTO;
|
import cn.code.nl.module.task.dto.TransportTaskCreateReqDTO;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
@@ -22,6 +25,34 @@ class TransportTaskServiceImplTest {
|
|||||||
@InjectMocks
|
@InjectMocks
|
||||||
private TransportTaskServiceImpl transportTaskService;
|
private TransportTaskServiceImpl transportTaskService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feign 客户端 —— 真实发起 HTTP 调用,直连本机 Controller
|
||||||
|
*/
|
||||||
|
@Mock
|
||||||
|
private TransportTaskApi transportTaskApi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 端到端:Feign → Controller → Service → Mapper
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
void testApiCreateTask() {
|
||||||
|
// given
|
||||||
|
TransportTaskCreateReqDTO req = new TransportTaskCreateReqDTO();
|
||||||
|
req.setTaskName("测试任务");
|
||||||
|
req.setOwnerService("LMS");
|
||||||
|
req.setBizType("INBOUND");
|
||||||
|
req.setBizId("INB-001");
|
||||||
|
req.setHandleCode("inboundHandler");
|
||||||
|
req.setAcsTaskType("MOVE");
|
||||||
|
req.setAgvSystemType("AGV_TYPE_A");
|
||||||
|
req.setPointCode1("1");
|
||||||
|
req.setPointCode2("2");
|
||||||
|
req.setPointCode3("3");
|
||||||
|
req.setPointCode4("4");
|
||||||
|
|
||||||
|
transportTaskApi.createTransportTask(req);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCreateTransportTaskByRpc_shouldReturnTaskId() {
|
void testCreateTransportTaskByRpc_shouldReturnTaskId() {
|
||||||
// given
|
// given
|
||||||
|
|||||||
Reference in New Issue
Block a user