docs: add fleet daily assignment contract
这个提交包含在:
父节点
31b047daf9
当前提交
fb963d2133
@ -0,0 +1,396 @@
|
||||
# 【前端对接·管理后台】车务每日派车切片与车型大类需求契约
|
||||
|
||||
> Issue: [wx/HL#4837](https://git.1814.love:8443/wx/HL/issues/4837)
|
||||
> PR: [#4840](https://git.1814.love:8443/wx/HL/pulls/4840)、[#4841](https://git.1814.love:8443/wx/HL/pulls/4841)
|
||||
> 服务: `hl-order-service-v3` + `hl-fleet-service`
|
||||
> 日期: 2026-07-08
|
||||
> 影响范围: 订单调整/用车需求、车务派单、矩阵派单、派单看板、车队对账
|
||||
|
||||
## 1. 结论
|
||||
|
||||
- 用车需求只选“车型大类”,不要选具体车型型号。前端应从 `GET /admin/fleet/vehicle-types/list` 或树接口的大类节点取 `typeKey`,提交到 `fleet[].vehicleType`。
|
||||
- 当前测试库 SUV 大类 `typeKey` 是 `suv2`;后端提交后会归一保存为规范 key `suv`。前端不要自己把 `suv2` 改成具体车型 ID,也不要提交 `modelId/modelName`。
|
||||
- `fleet_assignment` 已改为“每日切片”:7 天行程同一辆车会落 7 条记录,每条 `startDate=endDate=serviceDate`。
|
||||
- 读接口仍按派车组展示,前端不要把每日切片渲染成 7 张卡。以 `assignmentGroupId` 作为同一连续派车段的稳定分组 key。
|
||||
- 历史跨天单条派车记录已通过迁移拆分;新派单创建前也会兜底拆分历史占位,再按派车组消费。
|
||||
|
||||
## 2. 用车需求车型大类
|
||||
|
||||
### 2.1 车型大类列表
|
||||
|
||||
```http
|
||||
GET /admin/fleet/vehicle-types/list
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
响应示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"id": "2057378611889180674",
|
||||
"typeKey": "suv2",
|
||||
"typeName": "SUV系列",
|
||||
"icon": "Car",
|
||||
"description": null,
|
||||
"sortOrder": 1,
|
||||
"modelCount": 5,
|
||||
"inUseCount": 4
|
||||
},
|
||||
{
|
||||
"id": "2057378611889180675",
|
||||
"typeKey": "mpv",
|
||||
"typeName": "商务车",
|
||||
"modelCount": 5,
|
||||
"inUseCount": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
前端取值规则:
|
||||
|
||||
| 用途 | 使用字段 |
|
||||
|------|----------|
|
||||
| 下拉展示 | `typeName` |
|
||||
| 提交用车需求 | `typeKey` |
|
||||
| 不可用于需求提交 | `models[].id`、`models[].modelName`、`vehicleTypeId` |
|
||||
|
||||
### 2.2 车型大类树
|
||||
|
||||
```http
|
||||
GET /admin/fleet/vehicle-types
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
响应中会带 `models[]`,这是给车型管理/价格日历/车辆档案使用的型号列表。订单用车需求仍只提交大类节点的 `typeKey`。
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": [
|
||||
{
|
||||
"id": "2057378611889180674",
|
||||
"typeKey": "suv2",
|
||||
"typeName": "SUV系列",
|
||||
"models": [
|
||||
{
|
||||
"id": "2057378611889180701",
|
||||
"modelName": "丰田普拉多",
|
||||
"seats": 7
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 3. 提交用车需求
|
||||
|
||||
```http
|
||||
PUT /v3/admin/order/2074724409473458177/vehicle-requirement
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"fleet": [
|
||||
{
|
||||
"vehicleType": "suv2",
|
||||
"seats": 7,
|
||||
"count": 1
|
||||
}
|
||||
],
|
||||
"specialTags": ["中文司机", "需要接送机"],
|
||||
"remark": "司机会蒙语,第 3 天需要儿童安全座椅"
|
||||
}
|
||||
```
|
||||
|
||||
响应示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"success": true,
|
||||
"data": {
|
||||
"id": "2074724419590119426",
|
||||
"version": 1,
|
||||
"isActive": true,
|
||||
"status": "PENDING",
|
||||
"submittedAt": "2026-07-08T13:17:03",
|
||||
"claimerId": null,
|
||||
"claimerName": null,
|
||||
"claimedAt": null,
|
||||
"branchTaken": "INIT_SUBMIT",
|
||||
"previousVersion": null,
|
||||
"assignmentDeletedCount": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
后端落库口径:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"vehicleType": "suv",
|
||||
"seats": 7,
|
||||
"count": 1
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- `suv2` 是当前测试库 SUV 大类真实 `typeKey`,后端会归一为 `suv` 参与车务过滤、矩阵、对账。
|
||||
- `seats/count` 仍按组提交;每组默认覆盖整个行程,不支持“前几天/后几天车型不同”的 UI。
|
||||
- 多车场景仍用多组或 `count>1` 表达,后端会展开为多个 `fleetItemIndex`。
|
||||
|
||||
## 4. 创建派单与每日切片
|
||||
|
||||
```http
|
||||
POST /admin/fleet/assignments
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"orderId": "2074724409473458177",
|
||||
"orderNo": "HL20260708131700144",
|
||||
"requirementId": "2074724419590119426",
|
||||
"fleetItemIndex": 0,
|
||||
"vehicleId": "2065329516292513793",
|
||||
"driverId": "2074724495473479681",
|
||||
"startDate": "2026-07-13",
|
||||
"endDate": "2026-07-18",
|
||||
"pickupAt": "海拉尔东山机场",
|
||||
"dropoffAt": "海拉尔站",
|
||||
"headcount": 2,
|
||||
"protocolPrice": "700.00",
|
||||
"holdMode": 0,
|
||||
"fromEntry": "from-board",
|
||||
"skipCityJunctionException": false,
|
||||
"strictSeats": false,
|
||||
"requestId": "fleet-assign-20260708-001"
|
||||
}
|
||||
```
|
||||
|
||||
响应示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"success": true,
|
||||
"data": {
|
||||
"id": "2074724499256741890",
|
||||
"assignmentGroupId": "333114315542499328",
|
||||
"assignmentStatus": "assigned",
|
||||
"protocolPrice": "700.00",
|
||||
"holdSentAt": null,
|
||||
"confirmedAt": "2026-07-08T13:17:22",
|
||||
"sideEffects": {
|
||||
"vehicleStatusUpdated": true,
|
||||
"driverStatusUpdated": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
落库不变量:
|
||||
|
||||
| 字段 | 口径 |
|
||||
|------|------|
|
||||
| `assignment_id` | 每日切片自己的 ID |
|
||||
| `assignment_group_id` | 同一连续派车段共用,前端展示/操作分组 key |
|
||||
| `start_date` / `end_date` | 每条切片都等于当天服务日 |
|
||||
| `service_date` | 该条切片服务日 |
|
||||
| `required_vehicle_type` | 规范车型大类 key,例如 `suv` |
|
||||
| `protocol_price` | 派车时冻结的协议价日单价 |
|
||||
|
||||
示例:2026-07-13 至 2026-07-18 会落 6 条:
|
||||
|
||||
```json
|
||||
[
|
||||
{"assignmentGroupId": "333114315542499328", "serviceDate": "2026-07-13", "startDate": "2026-07-13", "endDate": "2026-07-13"},
|
||||
{"assignmentGroupId": "333114315542499328", "serviceDate": "2026-07-14", "startDate": "2026-07-14", "endDate": "2026-07-14"},
|
||||
{"assignmentGroupId": "333114315542499328", "serviceDate": "2026-07-15", "startDate": "2026-07-15", "endDate": "2026-07-15"},
|
||||
{"assignmentGroupId": "333114315542499328", "serviceDate": "2026-07-16", "startDate": "2026-07-16", "endDate": "2026-07-16"},
|
||||
{"assignmentGroupId": "333114315542499328", "serviceDate": "2026-07-17", "startDate": "2026-07-17", "endDate": "2026-07-17"},
|
||||
{"assignmentGroupId": "333114315542499328", "serviceDate": "2026-07-18", "startDate": "2026-07-18", "endDate": "2026-07-18"}
|
||||
]
|
||||
```
|
||||
|
||||
## 5. 矩阵/看板读取口径
|
||||
|
||||
### 5.1 矩阵月视图
|
||||
|
||||
```http
|
||||
GET /admin/fleet/matrix/grid?year=2026&month=7&status=all
|
||||
```
|
||||
|
||||
响应片段:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"year": 2026,
|
||||
"month": 7,
|
||||
"daysInMonth": 31,
|
||||
"vehicles": [
|
||||
{
|
||||
"id": "2065329516292513793",
|
||||
"plate": "蒙C06E06",
|
||||
"assignments": [
|
||||
{
|
||||
"id": "2074724499256741890",
|
||||
"assignmentGroupId": "333114315542499328",
|
||||
"orderNumericId": "2074724409473458177",
|
||||
"orderNo": "HL20260708131700144",
|
||||
"startDay": 13,
|
||||
"endDay": 18,
|
||||
"startDate": "2026-07-13",
|
||||
"endDate": "2026-07-18",
|
||||
"vehicleCategory": "suv",
|
||||
"categoryLabel": "SUV",
|
||||
"assignmentStatus": "assigned",
|
||||
"protocolPrice": "700.00"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
前端处理:
|
||||
|
||||
- 月视图应按 `vehicles[].assignments[]` 渲染,一个 `assignmentGroupId` 只是一条甘特段。
|
||||
- 不要再按 DB 每日切片数量重复生成条。
|
||||
- 拖拽/操作时优先保留 `assignmentGroupId`;旧接口仍以 `assignmentId` 作为 path var 时,传该组任一 `id` 即可,后端会按组处理已接通的分组操作。
|
||||
|
||||
### 5.2 矩阵日视图
|
||||
|
||||
```http
|
||||
GET /admin/fleet/matrix/day-orders?date=2026-07-13
|
||||
```
|
||||
|
||||
响应片段:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": [
|
||||
{
|
||||
"orderNumericId": "2074724409473458177",
|
||||
"orderNo": "HL20260708131700144",
|
||||
"startDate": "2026-07-13",
|
||||
"endDate": "2026-07-18",
|
||||
"dayInTrip": 1,
|
||||
"totalDays": 6,
|
||||
"orderAssignStatus": "assigned",
|
||||
"assignments": [
|
||||
{
|
||||
"assignmentId": "2074724499256741890",
|
||||
"assignmentGroupId": "333114315542499328",
|
||||
"fleetItemIndex": 0,
|
||||
"vehicleCategory": "suv",
|
||||
"categoryLabel": "SUV",
|
||||
"vehiclePlate": "蒙C06E06",
|
||||
"driverName": "API按单险司机4792",
|
||||
"assignmentStatus": "assigned",
|
||||
"protocolPrice": "700.00"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 看板详情
|
||||
|
||||
```http
|
||||
GET /admin/fleet/board/orders/2074724409473458177
|
||||
```
|
||||
|
||||
响应关注点:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"transport": {
|
||||
"batches": [
|
||||
{
|
||||
"travelerNames": "张测试, 李测试",
|
||||
"transportNo": "CA4792",
|
||||
"time": "2026-07-13 10:45:00",
|
||||
"station": "海拉尔东山机场"
|
||||
},
|
||||
{
|
||||
"travelerNames": "张测试, 李测试",
|
||||
"transportNo": "K4792",
|
||||
"time": "2026-07-18 16:30:00",
|
||||
"station": "海拉尔站"
|
||||
}
|
||||
],
|
||||
"pickupRequired": true
|
||||
},
|
||||
"operationLog": {
|
||||
"records": [
|
||||
{
|
||||
"opType": "CONFIRMED",
|
||||
"detail": {
|
||||
"assignmentId": "2074724499256741890",
|
||||
"assignmentGroupId": "333114315542499328",
|
||||
"requiredVehicleType": "SUV",
|
||||
"requiredSeats": 7,
|
||||
"tripRange": "2026-07-13 至 2026-07-18"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"currentAssignment": {
|
||||
"id": "2074724499256741890",
|
||||
"assignmentGroupId": "333114315542499328",
|
||||
"vehiclePlate": "蒙C06E06",
|
||||
"driverName": "API按单险司机4792",
|
||||
"assignmentStatus": "assigned",
|
||||
"protocolPrice": "700.00"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- 终态 `completed/canceled` 时 `currentAssignment` 可能为 `null`,但操作日志仍保留 `assignmentGroupId`。
|
||||
- 大交通接送数据在 `transport.batches[]`;没有接送机/站时间时,调整订单快照接口使用 `vehicleTransportSummary.emptyText = "暂无接送机时间"`,见 44_4829 文档。
|
||||
|
||||
## 6. 车队对账影响
|
||||
|
||||
车队对账仍按每日服务日聚合。前端不用直接消费 `fleet_assignment` 每日切片,但要理解金额来源:
|
||||
|
||||
- `GET /admin/fleet/reconciliation/cars` 的车天数来自每日切片/对账 prep。
|
||||
- 一个 6 天派车组会贡献 6 个车天。
|
||||
- `protocolPrice` 是元/车天快照,估算金额 = 日单价 × 车天。
|
||||
|
||||
## 7. 本次验证证据
|
||||
|
||||
已在测试环境验证:
|
||||
|
||||
- 部署:`hl-fleet-service` deploy task `bcac32b8` 成功。
|
||||
- 全链路 API:`.tmp/4792_fleet_full_api_report.md`,115/115 passed。
|
||||
- 专项契约验证:`.tmp/4837_daily_slice_contract_verify.md`,9/9 passed。
|
||||
- 验证订单:`HL20260708131700144` / `2074724409473458177`。
|
||||
- 专项断言:
|
||||
- `fleet_assignment` 未删除记录中 `start_date < end_date` 数量为 0。
|
||||
- 主订单 2026-07-13 至 2026-07-18 生成 6 条每日切片。
|
||||
- 同一组 `assignmentGroupId=333114315542499328` 在矩阵月视图只出现 1 次。
|
||||
- 矩阵日视图 2026-07-13 能查到该派车组。
|
||||
- 用车需求提交 `suv2` 后,订单侧保存为规范 `suv`。
|
||||
|
||||
正在加载...
x
在新工单中引用
屏蔽一个用户