docs(changelog): 派车取消司机确认环节一步到位派定(#5827 / PR #5873)——含测试服实测证据
所有检测均成功
changelog-filename-gate / validate (push) Successful in 2s
所有检测均成功
changelog-filename-gate / validate (push) Successful in 2s
这个提交包含在:
父节点
de43d84f12
当前提交
5644bbf4e0
@ -0,0 +1,284 @@
|
|||||||
|
---
|
||||||
|
schema: "hl-changelog/v2"
|
||||||
|
ticket: "5827"
|
||||||
|
title: "⚠️ 派车取消「司机确认」环节:提交即派定、行程单短链直接生成;新增 sendItinerarySms 勾选字段;driver-confirmation 端点下线"
|
||||||
|
consumer: "admin"
|
||||||
|
change_type: "修改接口"
|
||||||
|
author: "wx(GIT)"
|
||||||
|
backend_status: "deployed"
|
||||||
|
gateway_status: "not_required"
|
||||||
|
frontend_status: "pending"
|
||||||
|
frontend_owner: "mmg"
|
||||||
|
frontend_ref: ""
|
||||||
|
target_release: ""
|
||||||
|
verified_at: ""
|
||||||
|
status_note: "PR #5873 已合并 dev-v3 并部署测试服(19:22:57 构建,jar 早于进程启动,确认跑新代码)。测试服真实 API 实测通过:driver-confirmation 端点 404 已下线;不传 holdMode 不再 400;派车响应 assignmentStatus=assigned + confirmedAt 有值(提交即派定);未传 sendItinerarySms 时 itinerarySmsStatus=NOT_SENT 且 outbox 无 ITINERARY_SMS/HOLD_NOTIFICATION(不勾不发、Step3 不发通知);行程单链接派车后立即可打开(HTTP 200,带真实定稿代际);看板 progressSteps 三步、holdNotificationStatus=NOT_REQUIRED、状态文案已更新。实测使用无人占用的测试单,验证后已取消还原。"
|
||||||
|
updated_at: "2026-08-11"
|
||||||
|
base: "dev-v3"
|
||||||
|
---
|
||||||
|
|
||||||
|
# ⚠️ 车务派车取消「司机确认」环节 —— 一步到位派定(#5827)
|
||||||
|
|
||||||
|
> **服务**: hl-fleet-service
|
||||||
|
> **性质**: **破坏性变更**(流程步骤减少、端点下线、默认行为变更),前端必须跟进
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、业务变化(一句话)
|
||||||
|
|
||||||
|
**派车提交即派定**:不再有「等司机回复确认 → 车务登记司机已确认 → 车务确认执行」这一段,提交后当场落 `assigned`、当场生成行程单短链,车务**不用再点第二次**。
|
||||||
|
|
||||||
|
配套:**Step3 不再自动给司机发「排车待确认」通知**;行程短信改为**只在车务显式勾选时发这一次**。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、变更接口清单
|
||||||
|
|
||||||
|
| 方法 | 路径 | 变更 |
|
||||||
|
|---|---|---|
|
||||||
|
| `POST` | `/admin/fleet/assignments` | 请求新增 `sendItinerarySms`;响应新增三字段;`holdMode` 摘 `@NotNull` 并废弃;提交即派定 |
|
||||||
|
| `POST` | `/admin/fleet/assignments/batch` | 同上(`sendItinerarySms` 放 body 顶层,批次级统一决策) |
|
||||||
|
| `POST` | `/admin/fleet/assignments/{assignmentId}/change` | 同上;不勾选不再给司机重发行程短信 |
|
||||||
|
| `POST` | `/admin/fleet/assignments/{assignmentId}/driver-confirmation` | **端点下线** |
|
||||||
|
| `POST` | `/admin/fleet/assignments/{assignmentId}/confirm` | 契约文案更新(不再要求「已登记司机确认」);新流程下非必经步骤 |
|
||||||
|
| `POST` | `/admin/fleet/assignments/requirements/{requirementId}/confirm` | 同上 |
|
||||||
|
| `POST` | `/admin/fleet/assignments/{assignmentId}/cancel` | 错误码清单更正:605024 → **605028** |
|
||||||
|
| `GET` | `/admin/fleet/board/orders/{orderId}` | `holdNotificationStatus` / `currentStep` / `stageCode` / 状态说明文案语义变更 |
|
||||||
|
|
||||||
|
## 三、⚠️ 前端必须做的四件事
|
||||||
|
|
||||||
|
### 1. 删掉「待司机确认」开关
|
||||||
|
|
||||||
|
派车表单底部的「待司机确认 · 先锁定司机并发送通知」开关(`holdMode`)**请删除**。
|
||||||
|
|
||||||
|
- 后端已**摘除该字段的 `@NotNull`**,不传不会再 400;
|
||||||
|
- 字段保留兼容但**服务端一律忽略**(传任何值都按一步派定处理)。
|
||||||
|
|
||||||
|
### 2. 删掉「等待司机回复确认」整块 UI
|
||||||
|
|
||||||
|
- 司机回复摘要输入框
|
||||||
|
- 司机确认凭证上传(最多 10 个)
|
||||||
|
- 「登记司机已确认」按钮
|
||||||
|
|
||||||
|
对应端点 **`POST /admin/fleet/assignments/{assignmentId}/driver-confirmation` 已下线**。
|
||||||
|
|
||||||
|
### 3. 新增「发送行程短信」勾选,并在派车/改派时传 `sendItinerarySms`
|
||||||
|
|
||||||
|
**这是本次最关键的行为变更。** 详见第四节。
|
||||||
|
|
||||||
|
### 4. 派车向导由 4 步改为 3 步
|
||||||
|
|
||||||
|
「订单详情 → 排车 → 确认执行」。后端 `currentStep` 已由 4 改 3,`stageCode` 不再产出 `driver_confirmed`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、新增字段 `sendItinerarySms`(三个写端点)
|
||||||
|
|
||||||
|
### 请求
|
||||||
|
|
||||||
|
| 端点 | 位置 | 字段 | 类型 | 必填 | 缺省 |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| `POST /admin/fleet/assignments` | body 顶层 | `sendItinerarySms` | Boolean | 否 | **不传 = `false` = 不发** |
|
||||||
|
| `POST /admin/fleet/assignments/batch` | **body 顶层**(不是 items 里) | `sendItinerarySms` | Boolean | 否 | 不传 = `false` |
|
||||||
|
| `POST /admin/fleet/assignments/{assignmentId}/change` | body 顶层 | `sendItinerarySms` | Boolean | 否 | 不传 = `false` |
|
||||||
|
|
||||||
|
> 批量为**批次级统一决策**:整批用同一个值,避免同一需求同一代际内 `itinerary_sms_decision` 不一致。
|
||||||
|
|
||||||
|
### 响应(三个端点新增,与 `ConfirmRespVO` 同口径)
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| `sendItinerarySms` | Boolean | 本次是否选择发送行程短信 |
|
||||||
|
| `itinerarySmsEventId` | String(雪花,字符串序列化) | 行程短信事件 ID;未发送时为 `null` |
|
||||||
|
| `itinerarySmsStatus` | String | `PENDING`(已入队待发) / `NOT_SENT`(未勾选,不发) |
|
||||||
|
|
||||||
|
### 🔴 行为口径(务必理解)
|
||||||
|
|
||||||
|
- **不勾(含不传)→ 一条司机短信都不发**。
|
||||||
|
- **行程单短链与短信无关**:不发短信也照样生成短链、照样可打开。
|
||||||
|
- 改派同理:**「只改计费日期 / 只改车费」不勾就不会给司机重发短信**(此前会重发)。
|
||||||
|
- 改派的幂等载荷哈希**不含**该字段:同一 `requestId` 改了勾选再提交会返回已冻结的旧回执,**换新 `requestId` 即生效**。
|
||||||
|
|
||||||
|
### 请求示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
POST /admin/fleet/assignments
|
||||||
|
Authorization: Bearer <admin token>
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"orderId": 2086270138171994114,
|
||||||
|
"vehicleId": 2064998142394183681,
|
||||||
|
"driverId": 2065272145633591298,
|
||||||
|
"startDate": "2026-08-17",
|
||||||
|
"endDate": "2026-08-19",
|
||||||
|
"headcount": 10,
|
||||||
|
"sendItinerarySms": true,
|
||||||
|
"requestId": "f3c1c8e2-0a1a-4f2b-9a77-1b2c3d4e5f60"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 成功响应示例(**测试服实测原样**,未传 `sendItinerarySms` / 未传 `holdMode`)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"data": {
|
||||||
|
"id": "2086824442578542594",
|
||||||
|
"assignmentGroupId": "2086824442578542594",
|
||||||
|
"assignmentSlotId": "345214258881105920",
|
||||||
|
"assignmentStatus": "assigned",
|
||||||
|
"stageCode": "assigned",
|
||||||
|
"stageLabel": "已派车",
|
||||||
|
"currentStep": 3,
|
||||||
|
"skippedStepCodes": [],
|
||||||
|
"protocolPrice": "800.00",
|
||||||
|
"vehicleFeeAutoTotal": "2400.00",
|
||||||
|
"vehicleFeeAutoComplete": true,
|
||||||
|
"vehicleFeeTotal": "2400.00",
|
||||||
|
"vehicleFeeSource": "AUTO",
|
||||||
|
"vehicleFeeAdjustmentReason": null,
|
||||||
|
"dailyVehicleFees": null,
|
||||||
|
"holdSentAt": null,
|
||||||
|
"confirmedAt": "2026-08-11 19:28:02",
|
||||||
|
"sideEffects": {
|
||||||
|
"vehicleStatusUpdated": "busy",
|
||||||
|
"driverStatusUpdated": "busy",
|
||||||
|
"reconPrepRowsCreated": 0,
|
||||||
|
"reconPrepMarkedCanceled": null
|
||||||
|
},
|
||||||
|
"sendItinerarySms": false,
|
||||||
|
"itinerarySmsEventId": null,
|
||||||
|
"itinerarySmsStatus": "NOT_SENT",
|
||||||
|
"dailyDifferences": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
勾选发短信时,仅这三个字段不同:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"sendItinerarySms": true,
|
||||||
|
"itinerarySmsEventId": "345528786529423360",
|
||||||
|
"itinerarySmsStatus": "PENDING"
|
||||||
|
```
|
||||||
|
|
||||||
|
### ⚠️ 行程单链接不在派车响应里
|
||||||
|
|
||||||
|
派车响应**不含** `itineraryUrl`。行程单链接在**看板订单详情**里取:
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /admin/fleet/board/orders/{orderId}
|
||||||
|
→ data.currentAssignment.itineraryUrl
|
||||||
|
```
|
||||||
|
|
||||||
|
**实测**:派车成功后立刻读该字段即有值,且链接**当场可打开**(HTTP 200 返回完整行程数据),token 内 `dispatchPlanGeneration` 为**真实定稿代际**(不是待确认期的 `0` 哨兵)。
|
||||||
|
|
||||||
|
**未勾选发短信时链接同样可用** —— 行程单链接与是否发短信无关。
|
||||||
|
|
||||||
|
> 补充说明:`fleet_itinerary_short_link` 里的**短码**(`/s/xxxx` 形式)只在**发短信时**才铸造(它只服务于短信长度限制)。不发短信时使用的是上面这个完整 token 链接,功能等价、当场可用。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、废弃字段(保留兼容,服务端忽略)
|
||||||
|
|
||||||
|
| 字段 | 所在端点 | 现在的行为 |
|
||||||
|
|---|---|---|
|
||||||
|
| `holdMode` | create / batch / change | **已摘 `@NotNull`**,传任何值都被忽略,一律按一步派定落库 |
|
||||||
|
| `messageTemplateId` | create / batch.items / change | 已废弃(不再发「待司机确认」通知,无模板可冻结) |
|
||||||
|
| `customBody` | create / batch.items / change | 同上 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、下线端点
|
||||||
|
|
||||||
|
| 方法 | 路径 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| `POST` | `/admin/fleet/assignments/{assignmentId}/driver-confirmation` | 「登记司机已确认」,随司机确认环节一并下线 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、响应语义变更(读侧)
|
||||||
|
|
||||||
|
| 位置 | 原来 | 现在 |
|
||||||
|
|---|---|---|
|
||||||
|
| 派车/批量/改派响应 `assignmentStatus` | 可能是 `holding` | **恒 `assigned`** |
|
||||||
|
| 派车/批量/改派响应 `skippedStepCodes` | 可能非空 | **恒空数组**(字段保留兼容) |
|
||||||
|
| 派车/批量/改派响应 `holdSentAt` | 可能有值 | **恒 `null`** |
|
||||||
|
| 派车/批量/改派响应 `confirmedAt` | 仅确认后才有 | **恒有值**(提交即派定) |
|
||||||
|
| 看板 `currentAssignment.holdNotificationStatus` | `assigned`/`completed` 行恒返回 `PENDING` | **恒返回 `NOT_REQUIRED`**(此前会诱导车务点无效重发) |
|
||||||
|
| 生命周期 `currentStep` | 四阶段 / 4 | **三阶段 / 3** |
|
||||||
|
| 生命周期 `stageCode` | 可能是 `driver_confirmed` | **不再产出该派生态**(时间轴事件类型 `driver_confirmed` 仍保留,用于存量数据回显) |
|
||||||
|
| `holding` 状态中文名 | 「待确认」 | **「待确认执行」**(新流程下只有存量数据会停在该态) |
|
||||||
|
| 看板状态筛选项「已派车」说明 | 「司机已确认,派车已生效」 | **「车务已派定,行程单已生成」** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、错误码变化
|
||||||
|
|
||||||
|
### 从契约中移除(不会再抛出,常量保留仅供历史数据字典对照)
|
||||||
|
|
||||||
|
| 码 | 原含义 |
|
||||||
|
|---|---|
|
||||||
|
| `605024` | 排车模式不合法 |
|
||||||
|
| `605025` | 请先登记司机已确认接单 |
|
||||||
|
|
||||||
|
### 更正(此前文档错标)
|
||||||
|
|
||||||
|
`POST /admin/fleet/assignments/{assignmentId}/cancel` 的错误码清单里原写「605024 取消生效日无效」是**错标**(605024 的真实含义是排车模式不合法),已更正为:
|
||||||
|
|
||||||
|
| 码 | 含义 |
|
||||||
|
|---|---|
|
||||||
|
| `605028` | 生效日期不在派单服务日期范围内 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、不变的部分(免得误删)
|
||||||
|
|
||||||
|
- **行程单短链**照常生成,且带真实定稿代际;短链身份与「是否发短信」无关。
|
||||||
|
- **时间轴事件类型 `driver_confirmed`** 保留(存量数据回显用)。
|
||||||
|
- **取消 / 撤销取消 / 改派 / 逐日派车**的既有入参与语义不变。
|
||||||
|
- 保险投保时序、槽位锁互斥、占用释放四条链路不变。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、验证证据
|
||||||
|
|
||||||
|
### 测试服实测(2026-08-11 19:22 部署,19:28 实测)
|
||||||
|
|
||||||
|
部署核实:服务器仓库含合并提交 `1c46e6abf`;fleet jar 构建于 19:22:57,两个实例进程分别启动于 19:23:08 / 19:23:25(**jar 早于进程,确认跑的是新代码**);8087 / 8187 健康检查均 200。
|
||||||
|
|
||||||
|
| 验证项 | 方法 | 结果 |
|
||||||
|
|---|---|---|
|
||||||
|
| `driver-confirmation` 端点已下线 | `POST .../driver-confirmation` | **HTTP 404「接口不存在」** ✅ |
|
||||||
|
| 不传 `holdMode` 不再 400 | 派车请求省略该字段 | **code 200** ✅ |
|
||||||
|
| **提交即派定** | 派车响应 | `assignmentStatus: "assigned"` + `confirmedAt: "2026-08-11 19:28:02"`,**无需第二次调用** ✅ |
|
||||||
|
| 向导 3 步 | 派车响应 + 看板 | `currentStep: 3`;看板 `progressSteps = [ORDER_DETAIL, DISPATCH, CONFIRM_EXECUTE]` ✅ |
|
||||||
|
| `skippedStepCodes` 恒空 / `holdSentAt` 恒 null | 派车响应 | `[]` / `null` ✅ |
|
||||||
|
| **不勾不发** | 未传 `sendItinerarySms` | `sendItinerarySms: false`、`itinerarySmsStatus: "NOT_SENT"`、`itinerarySmsEventId: null` ✅ |
|
||||||
|
| **Step3 不发任何通知** | 查 outbox 全部事件 | 只有 `OCCUPANCY_RECOMPUTE` + `ASSIGNED`(均 SUCCESS),**无 `ITINERARY_SMS`、无 `HOLD_NOTIFICATION`** ✅ |
|
||||||
|
| **行程单链接直接可用** | 看板 `itineraryUrl` → 直接 GET | **HTTP 200 返回完整行程**,token 内 `dispatchPlanGeneration` 为真实定稿代际 ✅ |
|
||||||
|
| `holdNotificationStatus` 修复 | 看板 `currentAssignment` | 已派定行返回 **`NOT_REQUIRED`**(此前恒 `PENDING`)✅ |
|
||||||
|
| 状态说明文案 | 看板 `statusOptions` | `holding` →「车务已排车,待车务确认执行」;`assigned` →「车务已派定,行程单已生成」✅ |
|
||||||
|
| 占用副作用 | 派车响应 `sideEffects` | 车与司机均置 `busy` ✅ |
|
||||||
|
|
||||||
|
> 实测用的是一张**无人使用的测试单**(非现场在用订单),验证完毕已通过业务接口取消还原,占用已释放、无脏数据残留。
|
||||||
|
|
||||||
|
### 后端质量门禁(rebase 到最新 dev-v3 后)
|
||||||
|
|
||||||
|
| 项 | 结果 |
|
||||||
|
|---|---|
|
||||||
|
| `mvn -pl hl-fleet-service clean test-compile` | BUILD SUCCESS |
|
||||||
|
| `mvn -pl hl-fleet-service test -Dtest=*ArchTest` | Tests run **13**,Failures 0 |
|
||||||
|
| `mvn -pl hl-fleet-service spotless:check` | BUILD SUCCESS |
|
||||||
|
| `mvn -pl hl-fleet-service test`(全量) | Tests run **3605**,Failures **0**,Errors **0**,Skipped 5(Docker 门控自跳过的容器类 IT) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十一、关联
|
||||||
|
|
||||||
|
- 工单 #5827
|
||||||
|
- 换版槽位人工制:#5810
|
||||||
|
- 换版后看板缺口:#5824
|
||||||
|
- 换版即作废定稿:#5851
|
||||||
正在加载...
x
在新工单中引用
屏蔽一个用户