11 KiB
11 KiB
【前端对接·管理后台】车务每日派车切片与车型大类需求契约
Issue: wx/HL#4837
PR: #4840、#4841
服务:hl-order-service-v3+hl-fleet-service
日期: 2026-07-08
影响范围: 订单调整/用车需求、车务派单、矩阵派单、派单看板、车队对账
1. 结论
- 用车需求只选“车型大类”,不要选具体车型型号。前端应从
GET /admin/fleet/vehicle-types/list或树接口的大类节点取typeKey,提交到fleet[].vehicleType。 - 当前测试库 SUV 大类
typeKey是suv2;后端提交后会归一保存为规范 keysuv。前端不要自己把suv2改成具体车型 ID,也不要提交modelId/modelName。 fleet_assignment已改为“每日切片”:7 天行程同一辆车会落 7 条记录,每条startDate=endDate=serviceDate。- 读接口仍按派车组展示,前端不要把每日切片渲染成 7 张卡。以
assignmentGroupId作为同一连续派车段的稳定分组 key。 - 历史跨天单条派车记录已通过迁移拆分;新派单创建前也会兜底拆分历史占位,再按派车组消费。
2. 用车需求车型大类
2.1 车型大类列表
GET /admin/fleet/vehicle-types/list
Authorization: Bearer <token>
响应示例:
{
"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 车型大类树
GET /admin/fleet/vehicle-types
Authorization: Bearer <token>
响应中会带 models[],这是给车型管理/价格日历/车辆档案使用的型号列表。订单用车需求仍只提交大类节点的 typeKey。
{
"code": 200,
"data": [
{
"id": "2057378611889180674",
"typeKey": "suv2",
"typeName": "SUV系列",
"models": [
{
"id": "2057378611889180701",
"modelName": "丰田普拉多",
"seats": 7
}
]
}
]
}
3. 提交用车需求
PUT /v3/admin/order/2074724409473458177/vehicle-requirement
Authorization: Bearer <token>
Content-Type: application/json
{
"fleet": [
{
"vehicleType": "suv2",
"seats": 7,
"count": 1
}
],
"specialTags": ["中文司机", "需要接送机"],
"remark": "司机会蒙语,第 3 天需要儿童安全座椅"
}
响应示例:
{
"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
}
}
后端落库口径:
[
{
"vehicleType": "suv",
"seats": 7,
"count": 1
}
]
说明:
suv2是当前测试库 SUV 大类真实typeKey,后端会归一为suv参与车务过滤、矩阵、对账。seats/count仍按组提交;每组默认覆盖整个行程,不支持“前几天/后几天车型不同”的 UI。- 多车场景仍用多组或
count>1表达,后端会展开为多个fleetItemIndex。
4. 创建派单与每日切片
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"
}
响应示例:
{
"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 条:
[
{"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 矩阵月视图
GET /admin/fleet/matrix/grid?year=2026&month=7&status=all
响应片段:
{
"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 矩阵日视图
GET /admin/fleet/matrix/day-orders?date=2026-07-13
响应片段:
{
"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 看板详情
GET /admin/fleet/board/orders/2074724409473458177
响应关注点:
{
"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-servicedeploy taskbcac32b8成功。 - 全链路 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。