docs(changelog-v2): #7442 团级确认态回写 + #7443 团期身份失败关闭与按团筛选
changelog-filename-gate / validate (push) Failing after 2s
changelog-filename-gate / validate (push) Failing after 2s
两份前端交接件(consumer=admin,frontend_owner=mmg)。 订正三处事实错误: - 派车两接口的字段表曾写入源码里不存在的字段(出参 assignmentId/ createdAssignments/updatedAssignments/cancelledAssignments、入参把扁平的 dailyPlan[] 写成 dailyPlan[].assignments[] 多一层),已按 origin/dev-v3 的 CreateAssignmentReqVO / AssignmentWriteRespVO / BatchCreateAssignmentReqVO / BatchAssignmentWriteRespVO 全量重写,85 个字段逐个 grep 回源码命中 85/85; 正文保留「旧版本曾写作 X,这些字段并不存在」以接住按旧名搜索的人。 - PR 号指错:#7442 实为 PR #7862(原写 #7866,那是 finance #7396 的 PR), #7443 实为 PR #7864(原写 #7868,那根本不是 PR 号)。 - board/orders 入参表原按「完整表」形态只列了 20 个字段中的 12 个, 改为只列本次新增的 groupBatchId 并把覆盖范围写在标题与前言里。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
这个提交包含在:
@@ -0,0 +1,341 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "7442"
|
||||
title: "团级确认态 + 需求已发车务回写"
|
||||
consumer: "admin"
|
||||
author: "wx(GIT)"
|
||||
change_type: "新增接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: "mmg"
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: "2026-09-17"
|
||||
status_note: "后端交付。新增 fleet 确认整团配车端点 + order-v3 内部回写端点,支持异步回写正式用车需求状态。前端需在团期配车页增加确认按钮。"
|
||||
updated_at: "2026-09-17"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# fleet/order-v3: 团级确认态 + 需求已发车务回写
|
||||
|
||||
**存放目录**: changelogs-v2/{YYYY-MM}/(管理后台,二期 fleet + order-v3)
|
||||
|
||||
**服务**: hl-fleet-service (端口 8082)、hl-order-service-v3 (端口 8083)
|
||||
**PR**: #7862
|
||||
**Issue**: #7442 PR-B
|
||||
**日期**: 2026-09-17
|
||||
**影响范围**: 新增团期配车确认接口;新增需求状态异步回写链路
|
||||
|
||||
---
|
||||
|
||||
## 关键变化
|
||||
|
||||
1. **新增确认接口**:fleet 侧新增 `POST /admin/fleet/group-dispatch/batches/{groupBatchId}/confirm`,车务在配车计划提交并通过后,可调用本端点把整团配车定稿,转入「已确认」态。
|
||||
2. **异步回写链路**:确认成功后,fleet 侧登记一条 Outbox 意图,经 Outbox 异步投递调用 order-v3 内部端点 `POST /v3/internal/group-batch/{groupBatchId}/vehicle-requirement/dispatched`,把正式用车需求从 CONFIRMED 推进到 DISPATCHED。
|
||||
3. **新增错误码**:`602007`(无可确认行)/ `602008`(覆盖不完整)用于确认端点的校验失败。
|
||||
4. **部署顺序**:order-v3 先部署,fleet 后部署(后端实现细节)。
|
||||
|
||||
---
|
||||
|
||||
## 二、变更接口清单
|
||||
|
||||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||
|---|------|------|------|----------|------|
|
||||
| 1 | 确认整团配车 | POST | `/admin/fleet/group-dispatch/batches/{groupBatchId}/confirm` | 新增 | 车务确认配车方案落定 |
|
||||
| 2 | 回写需求已发车务 | POST | `/v3/internal/group-batch/{groupBatchId}/vehicle-requirement/dispatched` | 新增 | [内部接口] fleet 确认后异步回写需求状态 |
|
||||
|
||||
---
|
||||
|
||||
## 三、接口详情
|
||||
|
||||
### 1. 确认整团配车 `POST /admin/fleet/group-dispatch/batches/{groupBatchId}/confirm`
|
||||
|
||||
**VO**: `GroupDispatchConfirmReqVO → GroupDispatchConfirmRespVO`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
车务在看板完成团期配车计划提交后(配车行已过验证、状态为「已派车」),调用本端点把整团配车定稿、转为「已确认」态。确认成功后会异步推进正式用车需求的状态流转(CONFIRMED → DISPATCHED);需求页需自行刷新以获取最新状态。
|
||||
|
||||
#### 入参字段表
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| groupBatchId | Path | Long | 是 | - | 团期主订单 ID |
|
||||
| requirementId | Body | Long | 是 | - | 本次确认所依据的正式团级用车需求 ID(字符串序列化) |
|
||||
| requirementVersion | Body | Integer | 是 | - | 本次确认所依据的需求版本号 |
|
||||
| remark | Body | String | 否 | ≤200 字符 | 确认备注(仅留痕,不写入配车行) |
|
||||
|
||||
#### 出参字段表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| groupBatchId | String | 团期主订单 ID(字符串序列化) |
|
||||
| confirmedCount | Integer | 本次由「已派车」转为「已确认」的配车行数 |
|
||||
| alreadyConfirmedCount | Integer | 确认前已是「已确认」的配车行数 |
|
||||
| requirementId | String | 本次确认所依据的正式需求 ID(字符串序列化) |
|
||||
| requirementVersion | Integer | 本次确认所依据的需求版本 |
|
||||
| planVersion | Long | 当前团期计划版本(确认不改计划,不递增) |
|
||||
| requirementAdvanceIntent | String | 已登记的需求回写意图方向,恒为 CONFIRMED_TO_DISPATCHED |
|
||||
| coverage | Object | 按乘车分组的覆盖明细 |
|
||||
| legacyGroupRowCount | Integer | 无分组键的历史派车行数(不计入任何组的覆盖) |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```json
|
||||
POST /admin/fleet/group-dispatch/batches/1934567890123456800/confirm
|
||||
{
|
||||
"requirementId": 5501,
|
||||
"requirementVersion": 3,
|
||||
"remark": "与地接确认车辆无误"
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": {
|
||||
"groupBatchId": "1934567890123456800",
|
||||
"confirmedCount": 8,
|
||||
"alreadyConfirmedCount": 0,
|
||||
"requirementId": "5501",
|
||||
"requirementVersion": 3,
|
||||
"planVersion": 7,
|
||||
"requirementAdvanceIntent": "CONFIRMED_TO_DISPATCHED",
|
||||
"coverage": {
|
||||
"totalGroups": 2,
|
||||
"coveredGroups": 2,
|
||||
"incompleteGroups": []
|
||||
},
|
||||
"legacyGroupRowCount": 0
|
||||
},
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
N/A(团期无可确认行时返 602007 错误)。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "配车尚未覆盖完整, 不能确认: 乘车分组 A 缺失 2026-05-08",
|
||||
"data": null,
|
||||
"success": false,
|
||||
"errorCode": 602008
|
||||
}
|
||||
```
|
||||
|
||||
可能的错误码:
|
||||
- `602005` - 用车需求已更新,请刷新后重新配车
|
||||
- `602006` - 正式用车需求当前状态不允许配车
|
||||
- `602007` - 本团没有可确认的配车行,请先提交配车计划
|
||||
- `602008` - 配车尚未覆盖完整,不能确认
|
||||
- `602009` - 无法取得本团的权威乘车分组清单
|
||||
- `600008` - 并发修改
|
||||
- `600009` - 基线不可用
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- **鉴权**: 需 `fleet:group-dispatch:write` 权限
|
||||
- **幂等性**: 重复确认返 confirmedCount=0、alreadyConfirmedCount=N(属幂等成功),HTTP 200 不是错误
|
||||
- **防重提交**: 本端点无防重时间窗,连点多次都是幂等成功形态
|
||||
- **异步回写**: 响应成功仅代表意图已登记,需求状态的实际推进可能稍后才发生;需求列表页需自行刷新
|
||||
- **并发处理**: 同团的并发调用由服务端串行化处理
|
||||
|
||||
---
|
||||
|
||||
### 2. 回写需求已发车务 `POST /v3/internal/group-batch/{groupBatchId}/vehicle-requirement/dispatched`
|
||||
|
||||
⚠️ **[内部接口,不对前端开放]** fleet 侧异步回写链路调用,通过 Feign 投递。
|
||||
|
||||
**VO**: `GroupBatchVehicleRequirementDispatchedReqDTO → GroupBatchVehicleRequirementDispatchedRespDTO`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
fleet 侧确认配车后,通过 Outbox 异步机制调用本端点,把正式用车需求从 CONFIRMED 推进到 DISPATCHED 状态。该端点不对前端暴露,仅供内部服务间通信。
|
||||
|
||||
#### 入参字段表
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| groupBatchId | Path | Long | 是 | - | 团期主订单 ID |
|
||||
| requirementId | Body | Long | 是 | - | 车务确认所依据的正式需求 ID(字符串序列化) |
|
||||
| requirementVersion | Body | Integer | 是 | - | 车务确认所依据的需求版本 |
|
||||
| sourceRefNo | Body | String | 否 | - | 幂等追溯号(fleet Outbox 记录 ID,用于日志对账) |
|
||||
|
||||
#### 出参字段表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| applied | Boolean | 本次是否真的推进了需求状态 |
|
||||
| discardReason | String | applied=false 时的原因常量 |
|
||||
| requirementStatus | String | 回写后提供方当前的需求状态 |
|
||||
| requirementVersion | Integer | 回写后提供方当前的需求版本 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```json
|
||||
POST /v3/internal/group-batch/1934567890123456800/vehicle-requirement/dispatched
|
||||
{
|
||||
"requirementId": "5501",
|
||||
"requirementVersion": 3,
|
||||
"sourceRefNo": "880123"
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": {
|
||||
"applied": true,
|
||||
"discardReason": null,
|
||||
"requirementStatus": "DISPATCHED",
|
||||
"requirementVersion": 3
|
||||
},
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
applied=false 时无新状态变化,仍返 200(幂等重放或需求已变版):
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": {
|
||||
"applied": false,
|
||||
"discardReason": "IDENTITY_MISMATCH",
|
||||
"requirementStatus": "CONFIRMED",
|
||||
"requirementVersion": 4
|
||||
},
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 错误响应
|
||||
|
||||
真正的故障(DB 不可用、CAS 并发冲突)仍以异常形式返回失败 Result,由 Outbox 退避重试:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 500,
|
||||
"message": "数据库异常",
|
||||
"success": false,
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- **一律返 200**: 本端点由 Outbox 重试链路驱动,任何判定结论都再投无用,故用 applied+discardReason 标记
|
||||
- **幂等性**: 重投同一条 sourceRefNo,结果保持一致
|
||||
- **丢弃原因**:
|
||||
- `IDENTITY_MISMATCH` - 需求身份不一致
|
||||
- `REQUIREMENT_NOT_FOUND` - 该团无活跃需求
|
||||
- `ALREADY_DISPATCHED` - 需求已是完成态
|
||||
- `STATUS_INVALID` - 需求状态不允许推进
|
||||
|
||||
---
|
||||
|
||||
## 四、契约约束与正确调用方式
|
||||
|
||||
| 场景 | 做法 |
|
||||
|------|------|
|
||||
| 车务确认配车 | 调 POST /admin/fleet/group-dispatch/batches/{id}/confirm,返回 confirmedCount |
|
||||
| 处理重复确认 | confirmedCount=0 且 HTTP=200 为幂等成功 |
|
||||
| 等待需求更新 | 需求列表页需自行刷新 |
|
||||
|
||||
---
|
||||
|
||||
## 五、数据库行为
|
||||
|
||||
| 操作 | 数据库影响 |
|
||||
|------|----------|
|
||||
| 确认配车 | fleet_group_dispatch.dispatch_status → CONFIRMED |
|
||||
| Outbox 异步回写成功 | order_group_vehicle_requirement.status → DISPATCHED |
|
||||
|
||||
---
|
||||
|
||||
## 六、边界行为
|
||||
|
||||
- **无可确认行** → 602007(fail-closed)
|
||||
- **覆盖不完整** → 602008(fail-closed)
|
||||
- **需求版本不匹配** → 602005(fail-closed)
|
||||
- **并发确认** → 第二个调用见 confirmedCount=0(幂等成功)
|
||||
- **投递到达时需求已变** → applied=false + IDENTITY_MISMATCH
|
||||
|
||||
---
|
||||
|
||||
## 六.5 枚举
|
||||
|
||||
**需求回写的丢弃原因**:
|
||||
- `IDENTITY_MISMATCH` - 需求 ID/版本不符
|
||||
- `REQUIREMENT_NOT_FOUND` - 团无活跃需求
|
||||
- `ALREADY_DISPATCHED` - 需求已是完成态
|
||||
- `STATUS_INVALID` - 需求状态不允许推进
|
||||
|
||||
---
|
||||
|
||||
## 六.6 修改前后对比
|
||||
|
||||
| 端点 | 改前 | 改后 |
|
||||
|------|------|------|
|
||||
| /admin/fleet/.../confirm | 无 | 新增 POST |
|
||||
| /v3/internal/group-batch/.../dispatched | 无 | 新增 POST |
|
||||
|
||||
---
|
||||
|
||||
## 六.7 影响评估
|
||||
|
||||
- **向后兼容**: 是(新增端点)
|
||||
- **前端同步**: 是(需加确认按钮)
|
||||
- **清理点**: 无
|
||||
|
||||
---
|
||||
|
||||
## 七、不影响范围
|
||||
|
||||
- **仅影响**: 团期配车确认流程、需求状态转移
|
||||
- **零影响**: 配车提交流程、其他需求转移路径、派单列表、看板显示
|
||||
|
||||
---
|
||||
|
||||
## 八、测试环境已验证
|
||||
|
||||
```
|
||||
POST /admin/fleet/group-dispatch/batches/xxx/confirm → 200 ✓
|
||||
POST /v3/internal/group-batch/xxx/dispatched → 200 ✓
|
||||
重复确认 confirmedCount=0 ✓
|
||||
异步回写已发送 ✓
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十、相关文档
|
||||
|
||||
- Issue: [#7442](https://git.1814.love:8443/wx/HL/issues/7442)
|
||||
- PR: [#7862](https://git.1814.love:8443/wx/HL/pulls/7862)
|
||||
- Merge: [a37bd669f](https://git.1814.love:8443/wx/HL/commit/a37bd669f)
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
### 链接
|
||||
|
||||
- **Issue**: [#7442](https://git.1814.love:8443/wx/HL/issues/7442)
|
||||
- **PR**: [#7862](https://git.1814.love:8443/wx/HL/pulls/7862)
|
||||
|
||||
### 联系人
|
||||
|
||||
- **后端**: @wx
|
||||
@@ -0,0 +1,523 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "7443"
|
||||
title: "团期身份失败关闭-派车按团筛选"
|
||||
consumer: "admin"
|
||||
author: "wx(GIT)"
|
||||
change_type: "修改接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: "mmg"
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: "2026-09-17"
|
||||
status_note: "后端交付。派车子订单无团期身份时失败关闭返 602203;看板矩阵新增 groupBatchId 字段及筛选参数。"
|
||||
updated_at: "2026-09-17"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
# fleet/order-v3: 团期身份失败关闭-派车按团筛选
|
||||
|
||||
> **存放目录**: changelogs-v2/{YYYY-MM}/
|
||||
>
|
||||
> **服务**: hl-fleet-service、hl-order-service-v3
|
||||
> **PR**: #7864
|
||||
> **Issue**: #7443 AC-3/AC-5/AC-14
|
||||
> **日期**: 2026-09-17
|
||||
|
||||
---
|
||||
|
||||
## 关键变化
|
||||
|
||||
1. 派车子订单无 groupBatchId 时失败关闭返 602203
|
||||
2. 看板与矩阵新增 groupBatchId 字段
|
||||
3. 矩阵新增 groupBatchId 筛选参数
|
||||
4. 新增错误码 602203(TRANSFER_GROUP_IDENTITY_INVALID)
|
||||
|
||||
---
|
||||
|
||||
## 二、变更接口清单
|
||||
|
||||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||
|---|------|------|------|----------|------|
|
||||
| 1 | 看板列表 | GET | `/admin/fleet/board/orders` | 修改 | 响应新增 groupBatchId |
|
||||
| 2 | 矩阵日订单 | GET | `/admin/fleet/matrix/day-orders` | 修改 | 新增筛选参数;响应新增字段 |
|
||||
| 3 | 派车创建 | POST | `/admin/fleet/assignments` | 修改 | 无团期身份时返 602203 |
|
||||
| 4 | 派车批量 | POST | `/admin/fleet/assignments/batch` | 修改 | 同上 |
|
||||
|
||||
---
|
||||
|
||||
## 三、接口详情
|
||||
|
||||
### 1. 看板列表 `GET /admin/fleet/board/orders`
|
||||
|
||||
**VO**: `BoardOrderPageReqVO → BoardOrderPageRespVO`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
派单看板列表查询,新增 groupBatchId 字段显示派车行所属团期。
|
||||
|
||||
#### 入参(本次新增 1 个,其余 19 个原有参数不变)
|
||||
|
||||
> 覆盖范围:本表**只列本次新增的参数**。`BoardOrderPageReqVO` 共 20 个字段(`origin/dev-v3` = `75d77eefe`),其余 19 个(`status`/`statuses`/`startDayFrom`/`startDayTo`/`startDate`/`endDate`/`vehicleTypeKeys`/`typeKeys`/`driverName`/`keyword`/`contactName`/`contactKeyword`/`teamNo`/`consultantId`/`plannerName`/`consultantName`/`variant`/`page`/`pageSize`)语义与本次改动无关,以 Swagger 为准。
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| groupBatchId | Query | Long | 否 | 雪花 ID | 按运营团期精确筛选;与 `teamNo` 等其他条件是 **AND 交集**,不传=不按团筛 |
|
||||
|
||||
#### 出参
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| records[].groupBatchId | Long | 团期 ID(当前归属优先,降级快照;字符串序列化) |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```json
|
||||
GET /admin/fleet/board/orders?pageNo=1&pageSize=20
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"total": 1,
|
||||
"records": [{
|
||||
"orderId": "1934567890123456789",
|
||||
"orderNo": "26-0503",
|
||||
"groupBatchId": "1934567890123456800",
|
||||
"customerName": "赵先生"
|
||||
}]
|
||||
},
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": {"total": 0, "records": []},
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 403,
|
||||
"message": "权限不足",
|
||||
"success": false
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- groupBatchId 优先取当前值,降级回退快照值
|
||||
- 非团订单 groupBatchId 为 NULL
|
||||
- 已退团历史行保持快照值
|
||||
|
||||
---
|
||||
|
||||
### 2. 矩阵日订单 `GET /admin/fleet/matrix/day-orders`
|
||||
|
||||
**VO**: `date + groupBatchId(optional) → List<MatrixDayOrderVO>`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
矩阵日期弹窗,新增可选参数按团期筛选,响应新增 groupBatchId 字段。
|
||||
|
||||
#### 入参
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| date | Query | String | 是 | YYYY-MM-DD | 查询日期 |
|
||||
| groupBatchId | Query | Long | 否 | - | 团期精确筛选(当前归属优先;存量行为 NULL) |
|
||||
|
||||
#### 出参
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| groupBatchId | Long | 团期 ID(当前归属优先,降级快照) |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```json
|
||||
GET /admin/fleet/matrix/day-orders?date=2026-05-04&groupBatchId=1934567890123456800
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": [{
|
||||
"orderId": "26-0503",
|
||||
"orderNo": "26-0503",
|
||||
"groupBatchId": "1934567890123456800",
|
||||
"customerName": "赵先生"
|
||||
}],
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": [],
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 100001,
|
||||
"message": "日期格式非法",
|
||||
"success": false
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- **筛选与回显是同一个口径**:都取「当前归属优先,order-v3 降级时才回退派车行快照」
|
||||
(实现上筛选谓词直接调用回显用的同一个解析函数,不存在两套口径)
|
||||
- 与看板 `board/orders` 的 groupBatchId 口径**完全一致**,两个接口可以互相对照结果
|
||||
- 存量行 groupBatchId 为 NULL 且订单上下文也取不到时,按参数筛选落选
|
||||
- ⚠️ 已退团的历史派车行:**只要 order-v3 可用,按「当前归属」判**(即退团后不再命中原团期);
|
||||
仅在 order-v3 降级、拿不到订单上下文时,才回退到建行时固化的快照值
|
||||
|
||||
---
|
||||
|
||||
### 3. 派车创建 `POST /admin/fleet/assignments`
|
||||
|
||||
**VO**: `CreateAssignmentReqVO → AssignmentWriteRespVO`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
创建单笔派车行。新增校验:团期子订单无 groupBatchId 时拒绝返 602203。
|
||||
|
||||
#### 入参
|
||||
|
||||
**本次无新增、无修改**——请求体字段与字段语义一个字没动,本次变化只发生在**受理与否**上(见下方「错误响应」)。下表为 `CreateAssignmentReqVO`(`origin/dev-v3`)全量 28 个字段,供前端核对现状:
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| orderId | Body | Long | 否 | - | 订单 ID(雪花) |
|
||||
| orderNo | Body | String | 否 | - | 订单号(冗余,可空) |
|
||||
| requirementId | Body | Long | 否 | - | 关联用车需求 ID(同需求项在途互斥校验用,可空) |
|
||||
| fleetItemIndex | Body | Integer | 否 | 已废弃,不拒收 | 【已废弃】需求展开项次序(0起);#7067 去槽位化后创建主流程忽略、不再落库,正常派单传与不传行为一致 |
|
||||
| vehicleId | Body | Long | 是 | - | 车辆 ID(雪花) |
|
||||
| driverId | Body | Long | 是 | - | 司机 ID(雪花) |
|
||||
| startDate | Body | Date | 是 | - | 用车开始日期(出团日,闭区间起点) |
|
||||
| endDate | Body | Date | 是 | - | 用车结束日期(闭区间终点) |
|
||||
| pickupAt | Body | String | 否 | - | 接客地自由文本(城市衔接判定用) |
|
||||
| dropoffAt | Body | String | 否 | - | 送客地自由文本(城市衔接判定用) |
|
||||
| headcount | Body | Integer | 否 | - | 人数(座位不足判定用,可空时不判座位) |
|
||||
| protocolPrice | Body | BigDecimal | 否 | ≥0.00,整数最多10位/小数最多2位 | 协议价日单价(元/车天,派车时冻结);不传后端按车辆车型+开始日期价格日历兜底 |
|
||||
| vehicleFeeTotal | Body | BigDecimal | 否 | ≥0.00,整数最多10位/小数最多2位;已废弃 | 历史字段,最终总车费已改为逐日车费只读合计;**传值将被拒绝** |
|
||||
| vehicleFeeAdjustmentReason | Body | String | 否 | ≤256 | 本次单日车费与日历参考价不一致时的调整原因 |
|
||||
| dailyVehicleFees | Body | Array | 否 | - | 本次派车单日车费覆盖;未传日期使用价格日历参考价,只影响本次派车且不回写价格日历 |
|
||||
| chargeableServiceDates | Body | Array | 否 | - | 收取车费的服务日期;不传默认全部服务日,空数组表示全部免费 |
|
||||
| vehicleFeeWaiverReason | Body | String | 否 | ≤256 | 免费服务日原因;全部服务日免费时必填 |
|
||||
| confirmAllServiceDatesFree | Body | Boolean | 否 | - | 全部服务日免费二次确认;chargeableServiceDates 为空数组时必须为 true |
|
||||
| sendItinerarySms | Body | Boolean | 否 | - | 是否向该车师傅发送行程短信;不传按 false(不发) 处理,行程单短链无论是否发短信都会生成 |
|
||||
| holdMode | Body | Integer | 否 | 已废弃,取值 0/1,服务端不消费 | 已废弃:#5827 起服务端忽略本字段,一律按一步派定处理,勿再传 |
|
||||
| messageTemplateId | Body | Long | 否 | 已废弃,不消费 | 已废弃:#5827 取消「待司机确认」通知后本字段不再消费,勿再传 |
|
||||
| customBody | Body | String | 否 | ≤4000;已废弃,不消费 | 已废弃:#5827 取消「待司机确认」通知后本字段不再消费,勿再传 |
|
||||
| fromEntry | Body | String | 否 | - | 操作来源(from-board/from-vehicle/from-driver/from-matrix,仅记录来源) |
|
||||
| skipCityJunctionException | Body | Boolean | 否 | - | 跳过城市衔接例外:true=命中冲突即抛 605005(默认 false 允许城市衔接放行) |
|
||||
| strictSeats | Body | Boolean | 否 | 已废弃,忽略 | 历史兼容字段,现已忽略;车型/座位不匹配只提示不阻断 |
|
||||
| confirmCrossResident | Body | Boolean | 否 | - | 跨常驻车显式确认:true=已知司机与所选车辆不是常驻组合仍继续派车;非跨常驻车可不传 |
|
||||
| requestId | Body | String | 是 | ≤64 | 幂等请求标识(前端每次保存生成稳定值,区分故意重派与重复提交) |
|
||||
| changeRequestId | Body | Long | 否 | 创建接口不消费 | 历史兼容换车请求 ID(当前创建接口不消费) |
|
||||
|
||||
#### 出参
|
||||
|
||||
**本次无新增、无修改**——`AssignmentWriteRespVO` 结构未动。⚠️ 派单 ID 字段名是 **`id`**(不是 `assignmentId`,旧版本文档曾写错,以本条为准)。下表为全量 22 个字段:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | String | 新建派单 ID(雪花,字符串序列化) |
|
||||
| assignmentGroupId | String | 派车组 ID(雪花;同一辆车连续每日切片共用,字符串序列化);历史行无 assignmentGroupId 时回退下发 assignmentId,对任何真实行恒非空 |
|
||||
| assignmentSlotId | String | 稳定车辆槽位 ID(字符串序列化);改派产生新派车组时保持不变 |
|
||||
| assignmentStatus | String | 派单状态(#5827 提交即派定,恒 assigned) |
|
||||
| stageCode | String | 生命周期阶段码(后端统一下发) |
|
||||
| stageLabel | String | 生命周期阶段文案(后端统一下发) |
|
||||
| currentStep | Integer | 当前三阶段步骤(订单详情/排车/确认执行) |
|
||||
| skippedStepCodes | Array | 展示层被跳过的步骤;#5827 后恒为空数组,字段保留兼容 |
|
||||
| protocolPrice | String | 协议价日单价快照(元/车天,字符串序列化) |
|
||||
| vehicleFeeAutoTotal | String | 价格日历自动合计参考(字符串序列化) |
|
||||
| vehicleFeeAutoComplete | Boolean | 自动合计是否覆盖全部计费服务日 |
|
||||
| vehicleFeeTotal | String | 该车辆槽位最终总车费(字符串序列化) |
|
||||
| vehicleFeeSource | String | 最终总车费来源:AUTO、MANUAL、INCOMPLETE |
|
||||
| vehicleFeeAdjustmentReason | String | 手工总车费调整原因 |
|
||||
| dailyVehicleFees | Array | 本次派车全部服务日的逐日车费快照 |
|
||||
| holdSentAt | String | 真实 HOLD 通知发出时间;#5827 后新派车不再发该通知,恒为 null(字段保留兼容) |
|
||||
| confirmedAt | String | 派定确认时间(#5827 后恒回显) |
|
||||
| sideEffects | Object | 副作用执行结果(#5827 后恒回显) |
|
||||
| sendItinerarySms | Boolean | 车务本次是否选择向该车师傅发送行程短信 |
|
||||
| itinerarySmsEventId | String | 行程短信可靠事件 ID(字符串序列化);未勾选发送时为空 |
|
||||
| itinerarySmsStatus | String | 本次派车的初始短信状态(PENDING/NOT_SENT) |
|
||||
| dailyDifferences | Array | 最终派定失败时的逐日基线差异;成功时为空 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```json
|
||||
POST /admin/fleet/assignments
|
||||
{
|
||||
"orderId": 1934567890123456789,
|
||||
"vehicleId": 99
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": {"id": "1234567890123456789", "assignmentStatus": "assigned"},
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
N/A(操作必返结果)。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "订单的团期归属尚未回填, 无法派车",
|
||||
"success": false,
|
||||
"errorCode": 602203
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 仅团期子订单且 groupBatchId 为空时触发 602203
|
||||
- 普通订单不受影响
|
||||
- 需在订单侧补齐团期归属
|
||||
|
||||
---
|
||||
|
||||
### 4. 派车批量创建 `POST /admin/fleet/assignments/batch`
|
||||
|
||||
**VO**: `BatchCreateAssignmentReqVO → BatchAssignmentWriteRespVO`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
批量提交逐日派车方案。校验规则同单笔,单行触发 602203 即整批失败。
|
||||
|
||||
#### 入参
|
||||
|
||||
**本次无新增、无修改**——请求体结构一个字没动,`dailyPlan[]` 是**扁平**结构(`serviceDate × vehicleId × driverId`,不是嵌套 `assignments[]`)。本次变化只发生在**受理与否**上(见下方「错误响应」)。下表为 `BatchCreateAssignmentReqVO`(含内部类 `DailyPlanItem`,`origin/dev-v3`)全量字段:
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| orderId | Body | Long | 是 | - | 订单 ID |
|
||||
| orderNo | Body | String | 否 | - | 订单号冗余 |
|
||||
| requirementId | Body | Long | 是 | - | 当前生效用车需求 ID |
|
||||
| startDate | Body | Date | 是 | - | 用车开始日期 |
|
||||
| endDate | Body | Date | 是 | - | 用车结束日期 |
|
||||
| pickupAt | Body | String | 否 | - | 接客地 |
|
||||
| dropoffAt | Body | String | 否 | - | 送客地 |
|
||||
| headcount | Body | Integer | 否 | - | 乘客人数 |
|
||||
| confirmNoVehicleServiceDates | Body | Boolean | 否 | - | 逐日计划未覆盖全部服务日期(存在不配车日期)时的显式二次确认 |
|
||||
| sendItinerarySms | Body | Boolean | 否 | 不传按 false | 是否向本批各车师傅发送行程短信;整批统一决策,避免同需求同代内各组行程短信选择不一致 |
|
||||
| skipCityJunctionException | Body | Boolean | 否 | - | 跳过城市衔接例外 |
|
||||
| fromEntry | Body | String | 否 | - | 操作来源 |
|
||||
| requestId | Body | String | 是 | ≤64 | 批次级幂等请求标识 |
|
||||
| dailyPlan[] | Body | Array | 是 | ≤4000 项 | 按行程日的完整配车列表:逐项为 服务日期×车辆×司机;同一服务日允许多条;需求日期窗内未出现的服务日视为该日不配车 |
|
||||
| dailyPlan[].serviceDate | Body | Date | 是 | - | 服务日期 |
|
||||
| dailyPlan[].vehicleId | Body | Long | 是 | - | 车辆 ID |
|
||||
| dailyPlan[].driverId | Body | Long | 是 | - | 司机 ID |
|
||||
| dailyPlan[].assignmentPrice | Body | BigDecimal | 否 | ≥0.00,整数最多10位/小数最多2位 | 本车当天实际价格;可不传,未传按车型价格日历参考价兜底(与单体派单同口径) |
|
||||
| dailyPlan[].priceAdjustmentReason | Body | String | 否 | ≤256 | 实际价格与价格日历参考价不一致时的调整原因 |
|
||||
| dailyPlan[].confirmCrossResident | Body | Boolean | 否 | - | 跨常驻车显式确认 |
|
||||
| ~~items~~ | Body | - | 否 | 携带非 null 值即 400 | 已移除:去槽位化后不再有槽位序号;携带本字段将被 400 拒绝 |
|
||||
| ~~chargeableServiceDates~~ | Body | - | 否 | 携带非 null 值即 400 | 已移除:旧收费日期字段;携带将被 400 拒绝 |
|
||||
| ~~vehicleFeeWaiverReason~~ | Body | - | 否 | 携带非 null 值即 400 | 已移除:旧免费服务日字段;携带将被 400 拒绝 |
|
||||
| ~~confirmAllServiceDatesFree~~ | Body | - | 否 | 携带非 null 值即 400 | 已移除:旧免费服务日字段;携带将被 400 拒绝 |
|
||||
| ~~holdMode~~ | Body | - | 否 | 携带非 null 值即 400 | 已移除:#5827 起一步派定;携带将被 400 拒绝 |
|
||||
| ~~dailyPlan[].fleetItemIndex~~ | Body | - | 否 | 携带非 null 值即 400 | 已移除:稳定车辆槽位序号;携带将被 400 拒绝 |
|
||||
| ~~dailyPlan[].used~~ | Body | - | 否 | 携带非 null 值即 400 | 已移除:用车开关(某天不配车=该天无配置项);携带将被 400 拒绝 |
|
||||
| ~~dailyPlan[].pickupParticipant~~ | Body | - | 否 | 携带非 null 值即 400 | 已移除:接机标志改由接送机配置步骤写入;携带将被 400 拒绝 |
|
||||
|
||||
#### 出参
|
||||
|
||||
**本次无新增、无修改**——`BatchAssignmentWriteRespVO` 结构未动。⚠️ 旧版本文档曾写作 `successCount/failureCount`、`createdAssignments/updatedAssignments/cancelledAssignments`,**这些字段并不存在**,以本条为准。下表为全量字段(`assignments[]` 每项复用「3. 派车创建」出参表的 `AssignmentWriteRespVO` 结构,不在此重复展开):
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| assignments[] | Array | 按 fleetItemIndex 升序返回的派单结果 |
|
||||
| assignments[].fleetItemIndex | Integer | 当前用车需求展开后的车辆槽位序号 |
|
||||
| assignments[].assignment | Object | 复用单槽位派单响应,结构见上方「3. 派车创建」出参字段表(`AssignmentWriteRespVO`) |
|
||||
| finalPlanPublished | Boolean | 本次是否已发布最终方案;false 表示排车已落库但接送机未配齐,订单车控仍为处理中,须继续走第③步接送机配置 |
|
||||
| pickupDropoffGate | Object | 接送机门禁状态(要求日与缺口日) |
|
||||
| failedFleetItemIndex | Integer | 直接派定基线失败的车辆槽位序号 |
|
||||
| dailyDifferences | Array | 直接派定基线失败的逐日差异 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```json
|
||||
POST /admin/fleet/assignments/batch
|
||||
{
|
||||
"orderId": 1934567890123456789,
|
||||
"requirementId": 1934567890123456790,
|
||||
"startDate": "2026-05-06",
|
||||
"endDate": "2026-05-07",
|
||||
"requestId": "batch-20260917-0001",
|
||||
"dailyPlan": [
|
||||
{"serviceDate": "2026-05-06", "vehicleId": "99", "driverId": "88"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": {"assignments": [{"fleetItemIndex": 0, "assignment": {"id": "1234567890123456789"}}],
|
||||
"finalPlanPublished": true},
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
N/A(整批要么受理要么失败关闭,不存在「空成功」形态)。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "订单的团期归属尚未回填, 无法派车",
|
||||
"success": false,
|
||||
"errorCode": 602203
|
||||
}
|
||||
```
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- 单行 602203 导致整批失败
|
||||
- 其余行不落库
|
||||
- 同单笔处理规则
|
||||
|
||||
---
|
||||
|
||||
## 四、契约约束与正确调用方式
|
||||
|
||||
| 场景 | 做法 |
|
||||
|------|------|
|
||||
| 派车无团期身份 | 返 602203,需在订单侧补团期 |
|
||||
| 矩阵按团期筛选 | 传新增 groupBatchId 参数 |
|
||||
| 订单换团后 | **库列**是快照(建行时固化、不回溯刷新);**接口的回显与筛选都按当前归属**,仅 order-v3 降级时回退快照 |
|
||||
|
||||
---
|
||||
|
||||
## 五、数据库行为
|
||||
|
||||
| 操作 | 影响 |
|
||||
|------|------|
|
||||
| 创建派车(无 groupBatchId) | 拒绝 602203 |
|
||||
| 创建派车(有 groupBatchId) | fleet_assignment.group_batch_id 记录值 |
|
||||
|
||||
---
|
||||
|
||||
## 六、边界行为
|
||||
|
||||
- 团期子订单无 groupBatchId → 602203(fail-closed)
|
||||
- 普通订单 groupBatchId 为 NULL → 正常建行
|
||||
- 存量派车行 → groupBatchId 为 NULL
|
||||
- 已退团户 → `fleet_assignment.group_batch_id` **库列**保留快照值;**接口回显与筛选按当前归属**(降级时才回退该快照)
|
||||
|
||||
---
|
||||
|
||||
## 六.5 枚举
|
||||
|
||||
**新增错误码**: 602203 TRANSFER_GROUP_IDENTITY_INVALID —— 派车团期身份不可解析
|
||||
|
||||
**错误码段位**:
|
||||
- 602000-602099: 配车需求级错误
|
||||
- 602200-602299: 派车身份级错误(新增)
|
||||
|
||||
---
|
||||
|
||||
## 六.6、修改前后对比
|
||||
|
||||
| 项目 | 改前 | 改后 |
|
||||
|------|------|------|
|
||||
| BoardOrderRecordVO.groupBatchId | 不存在 | 新增(字符串序列化) |
|
||||
| MatrixDayOrderVO.groupBatchId | 不存在 | 新增(字符串序列化) |
|
||||
| GET /admin/fleet/board/orders 入参 | 无 groupBatchId | 新增可选参数 groupBatchId |
|
||||
| GET /admin/fleet/matrix/day-orders 入参 | 无 groupBatchId | 新增可选参数 groupBatchId |
|
||||
| 派车子订单无 groupBatchId 行为 | 静默建行 | 拒绝返 602203 |
|
||||
|
||||
---
|
||||
|
||||
## 六.7、影响评估
|
||||
|
||||
- **向后兼容**: 否(行为破坏性)
|
||||
- 新增参数可选,不传时兼容(正向)
|
||||
- **行为变化破坏性**:此前能建成的「团期子订单无 groupBatchId 派车」现在返 602203 拒绝
|
||||
- **前端同步**: 是(必须)
|
||||
- 看板矩阵增加 groupBatchId 字段展示
|
||||
- 矩阵增加 groupBatchId 筛选参数透传
|
||||
- 派车流程处理 602203 错误码
|
||||
- **数据**: 存量派车行 groupBatchId 为 NULL(不需迁移)
|
||||
|
||||
---
|
||||
|
||||
## 七、不影响范围
|
||||
|
||||
- 订单换团逻辑
|
||||
- 派车行后续修改
|
||||
- 其他看板筛选维度
|
||||
- 矩阵 grid 接口
|
||||
|
||||
---
|
||||
|
||||
## 八、测试环境已验证
|
||||
|
||||
```
|
||||
GET /admin/fleet/board/orders → 200 ✓
|
||||
GET /admin/fleet/matrix/day-orders?date=2026-05-04 → 200 ✓
|
||||
GET /admin/fleet/matrix/day-orders?date=2026-05-04&groupBatchId=xxx → 200 ✓
|
||||
POST /admin/fleet/assignments (无团期身份) → 602203 ✓
|
||||
POST /admin/fleet/assignments (普通订单) → 200 ✓
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十、相关文档
|
||||
|
||||
- Issue: [#7443](https://git.1814.love:8443/wx/HL/issues/7443)
|
||||
- PR: [#7864](https://git.1814.love:8443/wx/HL/pulls/7864)
|
||||
- Merge: [75d77eefe](https://git.1814.love:8443/wx/HL/commit/75d77eefe)
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
### 链接
|
||||
|
||||
- **Issue**: [#7443](https://git.1814.love:8443/wx/HL/issues/7443)
|
||||
- **PR**: [#7864](https://git.1814.love:8443/wx/HL/pulls/7864)
|
||||
- **Merge**: [75d77eefe](https://git.1814.love:8443/wx/HL/commit/75d77eefe)
|
||||
|
||||
### 联系人
|
||||
|
||||
- **后端**: @wx
|
||||
在新工单中引用
屏蔽一个用户