187 行
9.7 KiB
Markdown
187 行
9.7 KiB
Markdown
---
|
||
schema: "hl-changelog/v2"
|
||
ticket: "6152"
|
||
title: "车务派单异常态——已派车后取消进异常桶,处置完成转已完结"
|
||
consumer: "admin"
|
||
author: "wx"
|
||
change_type: "新增接口"
|
||
backend_status: "deployed"
|
||
gateway_status: "verified"
|
||
frontend_status: "verified"
|
||
frontend_owner: "mmg"
|
||
frontend_ref: "36261d83"
|
||
target_release: ""
|
||
verified_at: "2026-08-23"
|
||
status_note: "车务派单看板/详情:①已派车后取消的订单不再落「已取消」消失,改进新「异常」桶等人工处置;②详情已取消/异常槽位行补 serviceDate/startDate/endDate 三字段(根治行级释放占用解析服务日失败误拦截);③操作时间线新增「订单异常」「异常处置完成」系统留痕;④新增处置完成写口 POST /admin/fleet/assignments/resolve-exception。前端需适配异常分面 Tab + 详情异常行操作入口。"
|
||
updated_at: "2026-08-22"
|
||
base: "dev-v3"
|
||
generated: "2026-08-22T17:20:00+08:00"
|
||
---
|
||
|
||
# 【新增接口·管理后台】车务派单异常态——已派车后取消进异常桶,处置完成转已完结(#6152)
|
||
|
||
> **PR**: #6177(功能)+ #6178(complete_source 列宽修复) | **服务**: hl-fleet-service | **作者**: wx | **更新时间**: 2026-08-22
|
||
|
||
## 背景
|
||
|
||
现网案例:订单 26-9250(行程中中止,出团 2 天后取消)。派单看板详情显示「暂无逐日逐车方案 / 暂无实际用车费用」,已派好的车辆/司机明细完全看不到;且车辆/司机占用残留需人工释放,行级释放对已取消全程槽行报错「缺少该派单的服务日期」(前端解析服务日 7 种来源在已取消行上全空)。
|
||
|
||
**业务口径(wx 2026-08-22 拍板)**:
|
||
- 「已取消」分面只装**未派车即取消**的单;
|
||
- 凡**已派车(holding/assigned)后取消**(出行前取消/订单整体取消/行程中终止)一律进**异常桶**,保留车辆/司机占用,等车务人工处置;
|
||
- 异常处置完成后流转到「已完结」终态(对标房务异常桶「标记完成」)。
|
||
|
||
## 变更接口
|
||
|
||
### 新增端点
|
||
|
||
`POST /admin/fleet/assignments/resolve-exception`(异常处置完成):把该订单全部异常派单行转已完结。入参 `orderId`(整单级处置)+ `requestId`(幂等);前置门禁:车辆/司机占用须先经「一键清除已取消派单的占用」释放,否则 605072 拦回;无异常行幂等返回 0。
|
||
|
||
**请求**:
|
||
|
||
```json
|
||
{
|
||
"orderId": "2086697882311680002",
|
||
"requestId": "resolve-exception-20260822-001"
|
||
}
|
||
```
|
||
|
||
**响应(成功,处置 N 行)**:
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"message": "成功",
|
||
"data": {
|
||
"resolvedCount": 4,
|
||
"assignmentIds": ["2086811469462011905", "2086811469466206209", "2086811469466206210", "2086811469470400514"]
|
||
},
|
||
"traceId": null,
|
||
"success": true
|
||
}
|
||
```
|
||
|
||
**响应(幂等重放/无异常行)**:`data` 为 `{"resolvedCount": 0, "assignmentIds": []}`,同样 code=200。
|
||
|
||
**响应(占用未清拦回)**:
|
||
|
||
```json
|
||
{
|
||
"code": 605072,
|
||
"message": "异常派单的车辆/司机占用尚未释放,请先释放资源再处置完成",
|
||
"data": null,
|
||
"traceId": null,
|
||
"success": false
|
||
}
|
||
```
|
||
|
||
**错误码**:`605072`(占用未释放)、`605073`(异常态写口锁——异常行拒绝确认/改派/拒接/软清/提前完结等推进类写操作)。
|
||
|
||
### 修改端点
|
||
|
||
#### `GET /admin/fleet/board/summary`(看板汇总)
|
||
|
||
`statusOptions` 新增第 6 项、`statusCounts` 新增 `exception` 计数。响应片段(实测):
|
||
|
||
```json
|
||
{
|
||
"statusCounts": {"unassigned": 52, "holding": 1, "assigned": 20, "completed": 1, "canceled": 12, "exception": 1, "unassignedUrgent": 44, "holdingUrgent": 1},
|
||
"statusOptions": [
|
||
{"value": "canceled", "label": "已取消", "description": "派车需求已取消(仅未派车即取消,#6152)", "count": 12, "urgentCount": 0},
|
||
{"value": "exception", "label": "异常", "description": "已派车后再取消,待人工处置(释放资源后处置完成)", "count": 1, "urgentCount": 0}
|
||
]
|
||
}
|
||
```
|
||
|
||
(statusOptions 完整共 6 项:待派车/排车中/已派车/已完结/已取消/异常,上表仅示后两项。)
|
||
|
||
#### `GET /admin/fleet/board/orders`(看板列表)
|
||
|
||
`statuses` 筛选参数新增合法值 `exception`;混合取消订单(部分行已派落异常+部分未派占位落取消)的代表状态= exception(落异常桶);每条记录 `assignmentSlots[]` 槽位行**新增 `serviceDate`/`startDate`/`endDate` 三字段**。槽位行片段(实测):
|
||
|
||
```json
|
||
{
|
||
"assignmentId": "2086811469462011905",
|
||
"assignmentStatus": "exception",
|
||
"serviceDate": null,
|
||
"startDate": "2026-08-27",
|
||
"endDate": "2026-08-27",
|
||
"vehiclePlate": "蒙A-H7777",
|
||
"driverName": "阿木古愣"
|
||
}
|
||
```
|
||
|
||
逐日切片行 `serviceDate` 有值;全程槽行 `serviceDate=null`,用 `startDate`~`endDate` 展开解析服务日。
|
||
|
||
#### `GET /admin/fleet/board/orders/{orderId}`(看板详情)
|
||
|
||
`vehicleSlots[]` 的 `slotStatus` 新增值 `exception`(`slotStatusLabel`=「异常」),身份字段保留展示不清空并带 `cancelReason`。槽位行片段(实测):
|
||
|
||
```json
|
||
{
|
||
"assignmentSlotId": "345201285773004800",
|
||
"slotStatus": "exception",
|
||
"slotStatusLabel": "异常",
|
||
"cancelReason": "6152异常桶验收-5784测试单",
|
||
"assignmentId": "2086811469462011905",
|
||
"serviceStartDate": "2026-08-28",
|
||
"serviceEndDate": "2026-08-31",
|
||
"serviceDays": 4,
|
||
"vehiclePlate": "蒙A-G8888",
|
||
"vehicleModel": "别克GL8",
|
||
"driverName": "满都拉",
|
||
"driverPhone": "135****5003",
|
||
"canDelete": true
|
||
}
|
||
```
|
||
|
||
(详情槽位用的是 `serviceStartDate`/`serviceEndDate` 字段名,列表槽位是 `startDate`/`endDate`,勿混用。)
|
||
|
||
#### `GET /admin/fleet/orders/{orderId}/operation-log`(派单操作时间线)
|
||
|
||
新增 `opType` 枚举值。新条目片段(实测):
|
||
|
||
```json
|
||
{
|
||
"id": "2091082889029419011",
|
||
"time": "2026-08-22 16:39:46",
|
||
"opType": "exception_marked",
|
||
"opTypeLabel": "订单异常",
|
||
"summary": "系统 订单异常:出行前取消,原因:6152异常桶验收-5784测试单",
|
||
"operatorName": "系统",
|
||
"effectiveDate": null,
|
||
"detailJson": "{\"scene\":\"出行前取消\",\"reason\":\"6152异常桶验收-5784测试单\",\"exceptionRowCount\":4}"
|
||
}
|
||
```
|
||
|
||
`exception_resolved` 条目:`opTypeLabel`=「异常处置完成」,summary 形如「admin 异常处置完成:共 4 行派单转已完结」,`detailJson` 为 `{"resolvedCount":4}`。存量已派后取消单读侧合成兜底(scene 判定:有终止退款标记=行程中终止 > order_cancelled=订单取消 > 出行前取消)。
|
||
|
||
#### `DELETE /admin/fleet/assignments/{assignmentId}`(取消派单)
|
||
|
||
已派车(holding/assigned)行取消后目标态从 canceled 改为 **exception**,响应 `data.assignmentStatus="exception"`、`sideEffects.vehicleStatusUpdated/driverStatusUpdated` 仍为 `"busy"`(保留占用);未派占位行维持 canceled。其余响应结构不变。
|
||
|
||
#### `POST /admin/fleet/assignments/clear-cancelled-occupancy`(一键清除占用)
|
||
|
||
圈定集合从已取消扩为已取消+异常;异常行的释放= 异常桶里的「释放资源」动作。响应结构不变(`vehicleDriverPairs`/`intentsWritten`/`assignmentIds[]`,实测 `vehicleDriverPairs:2, intentsWritten:2`)。
|
||
|
||
## 行为语义变化(前端需知)
|
||
|
||
1. **取消已派车的派单不再释放车辆/司机占用**:取消后车/司机仍 busy,须走「一键清除已取消派单的占用」释放后才能「处置完成」转已完结。推荐操作流:取消(自动进异常桶)→ 看板异常 Tab 找到单 → 详情释放占用(整单级或行级)→ 处置完成(resolve-exception)→ 单进已完结。
|
||
2. **「已取消」Tab 单量会减少**:已派车后取消的单从该 Tab 移出进「异常」Tab,属预期口径变化。
|
||
3. **详情已取消/异常行现在能解析服务日**:`serviceDate`/`startDate`/`endDate` 三字段补齐后,行级释放占用不再被前端解析盲区误拦截(#6114 修复)。
|
||
4. **撤销取消(restore-cancel)支持异常行**:误操作可撤销回原状态。
|
||
5. 保险退保、需求重开等取消副作用链路对异常行照常触发(占用保留语义只影响车/司机缓存态)。
|
||
|
||
## 前端动作
|
||
|
||
1. 看板新增「异常」Tab/分面(数据已在 statusOptions 返回,value=exception,红色系建议);
|
||
2. 详情槽位行(异常态)展示身份字段 +「释放占用」「处置完成」操作入口(按 slotStatus/assignmentStatus=exception 自判,与已取消行同模式);
|
||
3. 行级释放占用改用 serviceDate(null 时 startDate~endDate 展开)解析服务日;
|
||
4. 操作时间线渲染新 opTypeLabel(订单异常/异常处置完成),徽标文案直接用后端 label 勿硬编码。
|
||
|
||
## 验证证据
|
||
|
||
- 单测:3854 tests 全绿(含状态机 12 转移/看板分面/Mapper 圈定/resolve-exception 5 例)+ ArchTest 门禁 + spotless。
|
||
- TEST 网关实测(订单 2086697882311680002,验 5784A 测试单):取消 assigned 派单 → `assignmentStatus="exception"` 且车/司机保持 busy ✓;异常分面 count=1 ✓;resolve-exception 占用未清 605072 拦回 ✓;异常行 soft-clear 605073 拦截 ✓;操作时间线 `exception_marked` 留痕(系统·出行前取消+原因)✓;详情异常槽位身份字段保留 + serviceDate/startDate/endDate 补齐 ✓;清占用后车辆转 idle ✓;**处置完成闭环**:resolve-exception 成功转 4 行已完结(resolvedCount=4)✓、异常分面归 0 ✓、`exception_resolved` 留痕(共 4 行派单转已完结)✓、同 requestId 重放幂等返 0 ✓、终态行写口闸回归正常(605043)✓。
|
||
- 列宽修复:complete_source VARCHAR(16)→32(EXCEPTION_RESOLVE 17 字符落库超长,网关实测发现,PR #6178 已合并随本单部署)。
|