# 【前端对接·管理后台】车务菜单全接口验收与契约收口 > **Issue**: [wx/HL#4756](https://git.1814.love:8443/wx/HL/issues/4756) > **PR**: [wx/HL#4757](https://git.1814.love:8443/wx/HL/pulls/4757), [wx/HL#4758](https://git.1814.love:8443/wx/HL/pulls/4758), [wx/HL#4759](https://git.1814.love:8443/wx/HL/pulls/4759) > **追加验证**: 2026-07-06 独立账号 `fleet_mgr_4760/VEHICLE_MANAGER`、`designer_4760/CUSTOMIZER` > **服务**: hl-fleet-service + hl-order-service-v3 > **日期**: 2026-07-05 > **影响范围**: 管理后台车务管理全菜单 --- ## 1. 结论 - 测试服已完成真实 API 回归:车务菜单级 `23/23` 通过,覆盖后台端点 `76` 个。 - 2026-07-06 追加独立账号回归:读接口/只读场景 `32/32` 通过;写接口探针 `22/22` 通过,覆盖派单预检、创建、确认、取消、司机险任务、车队对账实付保存/清空、模板渲染/错误分支。 - 补充全链路回归 `31/31` 通过,多订单并发回归 `10/10` 通过。 - 已修复派单重复确认返回 `100000` 的问题,现在返回业务码 `605020 当前派单状态不允许此操作`。 - `/admin/fleet/**` 已按当前登录角色拦截:车务角色可访问,定制师角色会返回 `403`。 --- ## 2. 前端必须处理 | 场景 | 前端处理 | |------|----------| | 当前角色 | 车务菜单只能由 `VEHICLE_MANAGER` 或 `SUPER_ADMIN` 访问;`CUSTOMIZER` 访问 `/admin/fleet/**` 返回 `403`,提示切换车务角色。测试服使用独立账号 `fleet_mgr_4760` / `designer_4760` 验证,不再用 `admin` / `wx` 当业务账号。 | | 车务工作台 | `GET /admin/profile/dashboard?period=today` 在 `VEHICLE_MANAGER` 角色下由 user-service 代理 fleet 真实看板数据;不要再读旧订单统计或本地 mock。 | | 司机结算方式 | 司机新增/编辑/导入使用字典 `driver_settlement_mode`:`direct`=直接结算,`fleet_leader`=车队长结算。不要再传旧值 `captain`。 | | 待审核详情 ID | `GET /admin/fleet/drivers/pending/{pendingId}` 响应主键字段是 `id`,不是 `pendingId`;路径变量仍叫 `pendingId`。 | | 派单重复确认 | `POST /admin/fleet/assignments/{assignmentId}/confirm` 只允许 `holding -> assigned`;非 `holding` 返回 `605020`。 | | 取消重复操作 | 终态派单再次取消也返回 `605020`。 | | 快速连点 | 多个写接口有幂等保护,会返回 `100502`,前端按钮需要 loading/disabled。不要把 `100502` 当系统故障。 | | 价格日历多车型批量设价 | `PUT /admin/fleet/pricing-calendar/batch-set` 幂等窗口是 300 秒,同一批完全相同入参会返回 `100502`。 | | 价格日历删除 | `DELETE /admin/fleet/pricing-calendar/{vehicleModelId}` 使用 query 参数 `startDate`、`endDate`,不要放 body。 | | 车型树字段 | `GET /admin/fleet/vehicle-types` 大类和车型主键都读 `id`;不要读旧的 `typeId`。 | | 看板 summary | 使用 `pendingUrgentCount`、`holdingTimeoutCount`;不要自造旧字段。 | | 车辆 busy | 车辆新增/编辑不能人工写 `vehicleStatus=busy`,返回 `600112`;busy 只能由派单占用反算。 | | 常驻司机冲突 | 车辆指定常驻司机时,司机已被别车占用返回 `605022`;司机侧改绑目标车已被占用返回 `605023`。 | | 自带车审核 | H5 自带车 `regCertUsage` 为营运类时必须带 `operationLicenseUrls`。 | --- ## 3. 本次确认的菜单覆盖 | 菜单 | 关键接口 | |------|----------| | 车务工作台 | `/admin/profile/dashboard?period=today` | | 派单看板 | `/admin/fleet/board/summary`, `/orders`, `/orders/{orderId}`, `/timeline`, `/expiry`, `/assignments/**` | | 矩阵派单 | `/admin/fleet/matrix/grid`, `/unassigned-orders`, `/day-orders` | | 车队对账 | `/admin/fleet/reconciliation/cars`, `/insurance`, `/periods`, `/actual`, `/close`, `/reopen`, `/pending-compensations/**`, `/export/cars` | | 价格日历 | `/admin/fleet/pricing-calendar/overview`, `/{vehicleModelId}`, `/{vehicleModelId}/status`, `/batch-set` | | 车辆档案 | `/admin/fleet/vehicles/page`, `/{vehicleId}`, `/{vehicleId}/disable`, `/{vehicleId}/enable`, `/import`, `/import/template` | | 车型管理库 | `/admin/fleet/vehicle-types`, `/list`, `/page`, `/models/page`, `/{typeId}`, `/{typeId}/models`, `/models/{modelId}` | | 司机档案 | `/admin/fleet/drivers/page`, `/options`, `/{driverId}`, `/{driverId}/resident-vehicle`, `/{driverId}/blacklist`, `/{driverId}/unban`, `/batch-season-renew`, `/import`, `/import/template` | | 待审核/自助录入 | `/admin/fleet/drivers/pending/**`, `/admin/fleet/h5/token`, `/h5/tokens/**`, `/app/h5/driver-onboard/**` | | 车管模板 | `/admin/fleet/message-templates/**` | --- ## 4. 统一调用约定 ### 4.1 Header 管理后台车务接口统一走测试域名: ```http Authorization: Bearer Content-Type: application/json ``` 角色边界: - `fleet_mgr_4760/VEHICLE_MANAGER`:允许访问 `/admin/fleet/**`。 - `designer_4760/CUSTOMIZER`:访问 `/admin/fleet/**` 返回 `403`,前端应提示切换车务角色。 - `/app/h5/**`:公开 H5 入口,不走车务角色 guard,但需要 `token` 参数。 ### 4.2 成功响应包 ```json { "code": 200, "message": "成功", "success": true, "data": {} } ``` ### 4.3 失败响应包 ```json { "code": 605020, "message": "当前派单状态不允许此操作", "success": false, "data": null } ``` > 说明:下面示例来自本次测试服真实 API 回归结构,手机号、token、部分 ID 做了脱敏或占位。前端处理长整型 ID 时建议按字符串保存,避免 JS 精度问题。 ### 4.4 分页与全量接口约定 - 公共分页对象 `page/pageSize` 的上限仍为 `100`,车务模块不绕过公共上限。 - 页面列表、弹窗选择、远程搜索列表继续调用分页接口,前端分页选项不要超过 `100`。 - 下拉、筛选、树形选择等“需要全量选项”的场景不要用 `pageSize=200/1000` 拉分页接口,应改用对应的非分页轻量端点。 - 当前可用非分页端点: ```http GET /admin/fleet/vehicle-types GET /admin/fleet/vehicle-types/list GET /admin/fleet/drivers/options?keyword=王&limit=20 GET /admin/fleet/message-templates GET /admin/fleet/reconciliation/periods?fromMonth=2026-01 ``` | 场景 | 正确接口 | 不要这么调 | |------|----------|------------| | 车辆列表页/车辆档案分页 | `GET /admin/fleet/vehicles/page?page=1&pageSize=24` | 不要 `pageSize>100` | | 派单弹窗选择车辆 | `GET /admin/fleet/vehicles/page?page=1&pageSize=10&vehicleStatus=idle` | 不要用一个下拉一次拉全部车辆 | | 车型大类筛选下拉 | `GET /admin/fleet/vehicle-types/list` | 不要 `/vehicle-types/page?pageSize=1000` | | 大类+型号树选择 | `GET /admin/fleet/vehicle-types` | 不要按每个大类再批量扫 `/models/page` | | 司机远程搜索下拉 | `GET /admin/fleet/drivers/options?keyword=王&limit=20` | 不要 `/drivers/page?pageSize=1000` | | 车管模板列表 | `GET /admin/fleet/message-templates` | 该接口本身不分页,不要拼 page/pageSize | | 车队对账主数据 | `GET /admin/fleet/reconciliation/cars` / `insurance` | 主数据不分页,不要自己从车辆/司机分页接口拼 mock | 如果后续前端出现新的“确实需要全量车辆选项”的页面,不要扩大 `/vehicles/page` 上限;先提需求补一个窄字段的车辆 options 接口,限定字段和筛选条件。 ### 4.5 车务工作台 车务首页入口仍走用户服务的角色分发接口;当前登录角色必须是 `VEHICLE_MANAGER`: ```http GET /admin/profile/dashboard?period=today ``` 响应: ```json { "code": 200, "message": "成功", "success": true, "data": { "pendingArrangeVehicle": 3, "upcomingTrips": [ { "orderId": "70123456789", "assignmentId": "80123456789", "orderNo": "HL202607010001", "productName": "呼伦贝尔 6 日", "customerName": "张先生", "departureDate": "2026-07-10", "endDate": "2026-07-15", "headcount": 4, "status": "unassigned_urgent", "statusLabel": "待派", "urgentBadge": "T-1" } ] } } ``` 字段口径: | 字段 | 说明 | |------|------| | `pendingArrangeVehicle` | 来源 fleet 派单看板 `pendingCount`,即当前待派单数,含紧急待派。 | | `upcomingTrips` | 来源 fleet 派单看板列表,近 7 天游程,最多 5 条。 | | `status` | 车务派单态:`unassigned`、`unassigned_urgent`、`holding`、`holding_urgent`、`assigned`。 | | `orderId` / `assignmentId` | 长整型按字符串处理,前端不要转 JS Number。 | 这不是分页不足问题;工作台不应从 `/admin/fleet/vehicles/page` 或旧 `DashboardStats` 拼数据,也不应使用本地 `useFleetStore` mock。 --- ## 5. 订单前置:新建订单、出行人、大交通、用车需求 车务矩阵/看板的数据不是 mock,也不是手工造 fleet 数据;前置链路必须从 wx 定制师订单开始。 ### 5.1 新建订单 ```http POST /v3/admin/order ``` 请求: ```json { "productId": 2056938821550747650, "tierSeq": 1, "departureDate": "2026-07-18", "customerName": "API测试车务", "customerPhone": "199****0001", "adultCount": 2, "childCount": 0, "youngChildCount": 0, "babyCount": 0, "roomCount": 1, "customerRemark": "fleet full api regression with transport", "tags": ["API_TEST_FLEET_FULL"] } ``` 响应: ```json { "code": 200, "success": true, "data": { "orderId": "2073749536638992386", "orderNo": "HL20260705204312543" } } ``` ### 5.2 补全出行人 ```http PUT /v3/admin/order/{orderId}/traveler-info ``` 请求: ```json { "travelers": [ { "name": "接口测试甲", "gender": "1", "birthday": "1988-01-02", "idType": "ID_CARD", "idNo": "11010119880102****", "nationality": "中国", "race": "汉族", "phone": "199****0002", "emergencyContact": "接口测试联络", "emergencyPhone": "199****0003", "roomGroupNo": 1 } ], "emergencyContactName": "接口测试联络", "emergencyContactPhone": "199****0004", "customerRemark": "fleet full regression traveler completed with transport" } ``` 响应: ```json { "code": 200, "success": true, "data": { "createdCount": 2, "pendingCount": 0, "allCompleted": true } } ``` ### 5.3 写入到达/返程大交通 ```http POST /v3/admin/order/{orderId}/transport-plan/batch ``` 请求: ```json { "plans": [ { "direction": "ARRIVAL", "transportType": "FLIGHT", "transportNo": "CAFULL", "carrier": "中国国际航空", "departStation": "北京首都T3", "arriveStation": "海拉尔东山机场", "departTime": "2026-07-18T08:00:00", "arriveTime": "2026-07-18T10:30:00", "travelerIds": ["2073749539415625730", "2073749539419820033"], "pickupRequired": true, "pickupRemark": "T3 出口举牌接机", "remark": "fleet full arrival transport" }, { "direction": "DEPARTURE", "transportType": "TRAIN", "transportNo": "KFULL", "carrier": "中国铁路", "departStation": "海拉尔站", "arriveStation": "北京站", "departTime": "2026-07-20T18:00:00", "arriveTime": "2026-07-21T08:30:00", "travelerIds": ["2073749539415625730", "2073749539419820033"], "pickupRequired": true, "pickupRemark": "送站到候车厅", "remark": "fleet full departure transport" } ] } ``` 响应: ```json { "code": 200, "success": true, "data": { "deletedCount": 0, "createdCount": 2, "plans": [ { "id": "2073749541168844802", "orderId": "2073749536638992386", "direction": "ARRIVAL", "transportType": "FLIGHT", "transportNo": "CAFULL", "travelers": [ { "id": "2073749539415625730", "name": "接口测试甲", "travelerType": "ADULT" } ] } ] } } ``` ### 5.4 提交用车需求 ```http PUT /v3/admin/order/{orderId}/vehicle-requirement ``` 请求: ```json { "fleet": [ { "vehicleType": "SUV", "seats": 5, "count": 1 } ], "remark": "fleet full api regression with transport", "specialTags": ["API_TEST_FLEET_FULL", "HAS_TRANSPORT"] } ``` 响应: ```json { "code": 200, "success": true, "data": { "requirementId": "2073749544025161730", "status": "PENDING", "version": 1, "vehicleTypeSummary": "SUV×1" } } ``` --- ## 6. 派单看板与矩阵派单 ### 6.1 看板 summary ```http GET /admin/fleet/board/summary ``` 响应: ```json { "code": 200, "success": true, "data": { "pendingCount": 14, "pendingUrgentCount": 0, "todayDepartCount": 3, "idleVehicleCount": 8, "idleDriverCount": 7, "holdingTimeoutCount": 0, "statusCounts": { "unassigned": 14, "holding": 0, "assigned": 2, "completed": 1, "canceled": 0 } } } ``` 前端注意:使用 `pendingUrgentCount`、`holdingTimeoutCount`,不要读旧字段。 ### 6.2 看板订单列表 ```http GET /admin/fleet/board/orders?page=1&pageSize=20&keyword=HL20260705204312543&statuses=assigned&statuses=completed&variant=list ``` 响应: ```json { "code": 200, "success": true, "data": { "records": [ { "id": "2073749536638992386", "orderNo": "HL20260705204312543", "customerName": "API测试车务", "headcount": 2, "startDate": "2026-07-18", "endDate": "2026-07-20", "assignmentStatus": "assigned", "vehicleTypeSummary": "SUV×1", "transport": { "batches": [ { "transportNo": "CAFULL", "station": "海拉尔东山机场", "travelerNames": ["接口测试甲"] }, { "transportNo": "KFULL", "station": "海拉尔站", "travelerNames": ["接口测试甲"] } ] } } ], "total": 1, "page": 1, "pageSize": 20 } } ``` ### 6.3 看板详情与时间线 ```http GET /admin/fleet/board/orders/{orderId} GET /admin/fleet/board/orders/{orderId}/timeline ``` 详情响应: ```json { "code": 200, "success": true, "data": { "id": "2073749536638992386", "orderNo": "HL20260705204312543", "customerName": "API测试车务", "headcount": 2, "startDate": "2026-07-18", "endDate": "2026-07-20", "transport": { "batches": [ { "transportNo": "CAFULL", "time": "2026-07-18T10:30:00", "station": "海拉尔东山机场" }, { "transportNo": "KFULL", "time": "2026-07-20T18:00:00", "station": "海拉尔站" } ] }, "progressSteps": [], "operationLog": [], "currentAssignment": { "id": "2073749544096460802", "assignmentStatus": "assigned", "vehicleId": "2073749553340706818", "driverId": "2073749552489267202" }, "relatedDetailReady": true } } ``` 时间线响应: ```json { "code": 200, "success": true, "data": [ { "eventType": "requirement_created", "eventTime": "2026-07-05T20:43:12", "content": "用车需求已提交" }, { "eventType": "assigned", "eventTime": "2026-07-05T20:43:18", "content": "已确认派车" } ] } ``` ### 6.4 矩阵 grid、未派、当天订单 ```http GET /admin/fleet/matrix/grid?year=2026&month=7&typeKeys=suv&fleets=own&season=active GET /admin/fleet/matrix/unassigned-orders?year=2026&month=7&typeKeys=suv GET /admin/fleet/matrix/day-orders?date=2026-07-18 ``` grid 响应: ```json { "code": 200, "success": true, "data": { "year": 2026, "month": 7, "daysInMonth": 31, "weekendDays": [4, 5, 11, 12, 18, 19, 25, 26], "vehicles": [ { "vehicleId": "2073749553340706818", "plate": "蒙A-69665", "fleet": "own", "driverName": "API师傅69665", "days": [ { "date": "2026-07-18", "status": "assigned", "orderNo": "HL20260705204312543" } ] } ], "statusCounts": { "totalAssignments": 84, "unassignedAssignments": 82, "assignedAssignments": 2, "totalOrders": 83, "unassignedOrders": 81, "partialOrders": 0, "assignedOrders": 2 }, "unassignedWindowCount": 14 } } ``` 未派/当天订单记录至少关注: ```json { "orderNo": "HL20260705204312543", "orderNumericId": "2073749536638992386", "startDate": "2026-07-18", "endDate": "2026-07-20", "headcount": 2, "vehicleTypeSummary": "SUV×1" } ``` --- ## 7. 派单操作接口 ### 7.1 预校验 ```http POST /admin/fleet/assignments/precheck ``` 请求: ```json { "vehicleId": "2073749553340706818", "driverId": "2073749552489267202", "orderId": "2073749536638992386", "startDate": "2026-07-18", "endDate": "2026-07-20", "headcount": 2, "pickupAt": "hailar", "dropoffAt": "hailar" } ``` 响应: ```json { "code": 200, "success": true, "data": { "conflict": false, "conflicts": [], "warnings": [] } } ``` ### 7.2 创建派单 ```http POST /admin/fleet/assignments ``` 请求: ```json { "vehicleId": "2073749553340706818", "driverId": "2073749552489267202", "orderId": "2073749536638992386", "orderNo": "HL20260705204312543", "requirementId": "2073749544025161730", "fleetItemIndex": 0, "startDate": "2026-07-18", "endDate": "2026-07-20", "headcount": 2, "pickupAt": "hailar", "dropoffAt": "hailar", "holdMode": 1, "fromEntry": "from-matrix", "strictSeats": true, "skipCityJunctionException": false, "requestId": "front-assign-20260705-001" } ``` 响应: ```json { "code": 200, "success": true, "data": { "id": "2073749544096460802", "assignmentStatus": "holding", "holdSentAt": "2026-07-05T20:43:18", "sideEffects": { "vehicleStatusUpdated": "busy", "driverStatusUpdated": "busy", "reconPrepRowsCreated": 0, "reconPrepMarkedCanceled": null } } } ``` `holdMode`: - `1`:先占位/待司机确认,后续调 confirm。 - `0`:直接派定,返回 `assignmentStatus=assigned` 和 `confirmedAt`。 ### 7.3 确认、取消、撤销取消、提前完结 ```http POST /admin/fleet/assignments/{assignmentId}/confirm DELETE /admin/fleet/assignments/{assignmentId} POST /admin/fleet/assignments/{assignmentId}/restore-cancel POST /admin/fleet/assignments/{assignmentId}/early-complete ``` 确认请求: ```json { "driverReplyNote": "接口测试确认接单" } ``` 确认响应: ```json { "code": 200, "success": true, "data": { "id": "2073749544096460802", "assignmentStatus": "assigned", "confirmedAt": "2026-07-05T20:43:20", "itineraryUrl": "https://web.test.1814.love:9443/fleet/itinerary/", "sideEffects": { "vehicleStatusUpdated": "busy", "driverStatusUpdated": "busy", "reconPrepRowsCreated": 0 } } } ``` 取消请求: ```json { "cancelReason": "客户取消", "driverNotified": true, "notifyNote": "已电话通知司机", "cutoffDate": "2026-07-18" } ``` 提前完结请求: ```json { "completeReason": "行程提前结束", "cutoffDate": "2026-07-18" } ``` 关键错误: ```json { "code": 605020, "message": "当前派单状态不允许此操作", "success": false } ``` ```json { "code": 605021, "message": "当前状态不可提前完结", "success": false } ``` ```json { "code": 605001, "message": "派单冲突:该车日期段已派", "success": false } ``` --- ## 8. H5 行程单响应结构 ```http GET /app/h5/itinerary/{token} ``` 响应: ```json { "code": 200, "success": true, "data": { "orderId": "HL20260705204312543", "theme": "呼籁旅行", "dateRange": "2026-07-18 至 2026-07-20", "days": 3, "headcount": 2, "customer": "API测试车务", "contactName": "接口测试联络", "contactPhone": "199****0004", "route": "海拉尔", "transport": { "arrive": { "transportNo": "CAFULL", "time": "2026-07-18T10:30:00", "station": "海拉尔东山机场", "remark": "fleet full arrival transport" }, "depart": { "transportNo": "KFULL", "time": "2026-07-20T18:00:00", "station": "海拉尔站", "remark": "fleet full departure transport" }, "batches": [ { "travelerNames": ["接口测试甲", "接口测试乙"], "transportNo": "CAFULL", "time": "2026-07-18T10:30:00", "station": "海拉尔东山机场" } ], "note": "" }, "vehicle": { "plate": "蒙A-69665", "model": "SUV", "seats": 5 }, "driver": { "name": "API师傅69665", "phoneMasked": "199****9999" }, "daily": [], "subsidy": { "meal": null, "lodging": null, "garage": null, "note": null }, "expireAt": "2026-07-27T23:59:59+08:00" } } ``` 前端注意:大交通要从 `transport.arrive`、`transport.depart` 和 `transport.batches` 取,不能只读旧的单字段。 --- ## 9. 司机档案与车辆档案 ### 9.1 新增/编辑司机 ```http POST /admin/fleet/drivers PUT /admin/fleet/drivers/{driverId} ``` 请求: ```json { "name": "API师傅69665", "phone": "199****9999", "idCard": "11010119800101****", "gender": "1", "nation": "汉族", "years": 8, "driverStatus": "idle", "season": "active", "preferredTypeKey": "suv", "preferredModel": "SUV", "vehicleSource": "company", "settlementMode": "fleet_leader", "license": { "no": "L6966520260705", "type": "C1", "expire": "2035-12-31", "issuedBy": "测试交管" }, "insurance": { "type": "none" }, "tags": ["API_TEST_FLEET_FULL"], "attachments": [] } ``` 响应: ```json { "code": 200, "success": true, "data": { "id": "2073749552489267202", "name": "API师傅69665", "phone": "199****9999", "driverStatus": "idle", "season": "active", "settlementMode": "fleet_leader", "license": { "no": "L6966520260705", "type": "C1", "expire": "2035-12-31" }, "insurance": { "type": "none" }, "tags": ["API_TEST_FLEET_FULL"] } } ``` `settlementMode` 只允许: | 值 | 展示 | |----|------| | `direct` | 直接结算 | | `fleet_leader` | 车队长结算 | > 当前字典库真实值是 `fleet_leader`。`captain` 是旧草稿值,后端不会按该值入库,前端新增/编辑/导入都不要再传。 非法值响应: ```json { "code": 100001, "message": "参数非法: 司机结算方式非法,取值来自字典 driver_settlement_mode「直接结算」「车队长结算」,值=bad_mode", "success": false } ``` ### 9.2 司机分页、下拉、常驻车、拉黑/解封 ```http GET /admin/fleet/drivers/page?page=1&pageSize=10&keyword=API&season=active&driverStatus=idle&tagName=API_TEST_MENU_DRIVER GET /admin/fleet/drivers/options?keyword=199&limit=50 PUT /admin/fleet/drivers/{driverId}/resident-vehicle POST /admin/fleet/drivers/{driverId}/blacklist POST /admin/fleet/drivers/{driverId}/unban ``` 常驻车请求: ```json { "vehicleId": "2073749553340706818" } ``` 拉黑请求: ```json { "blacklistReason": "菜单验收拉黑" } ``` 重复快速提交可能返回: ```json { "code": 100502, "message": "拉黑处理中,请勿重复提交", "success": false } ``` ### 9.3 新增/编辑车辆 ```http POST /admin/fleet/vehicles PUT /admin/fleet/vehicles/{vehicleId} ``` 请求: ```json { "plate": "蒙A-69665", "vehicleModelId": "2064991856994758657", "fleet": "own", "ownerType": "company", "primaryDriverId": "2073749552489267202", "vehicleStatus": "idle", "vin": "LSVAPI475169665", "regDate": "2024-01-01", "inspectDue": "2030-12-31", "insureDue": "2030-12-31", "regCertUsage": "营运租赁", "regCertNo": "REG69665", "regCertOwner": "呼籁测试", "attachments": [] } ``` 响应: ```json { "code": 200, "success": true, "data": { "id": "2073749553340706818", "plate": "蒙A-69665", "vehicleModelId": "2064991856994758657", "typeKey": "suv", "fleet": "own", "ownerType": "company", "vehicleStatus": "idle", "primaryDriverName": "API师傅69665", "primaryDriverLicenseType": "C1" } } ``` 前端限制: - 新增/编辑不能人工提交 `vehicleStatus=busy`。 - 个人自带车不能手动停用/启用。 - 常驻司机冲突:车辆侧返回 `605022`,司机侧返回 `605023`。 busy 错误响应: ```json { "code": 600112, "message": "车辆占用态只能在空闲与维保间人工切换,在用(busy)由系统派单写入", "success": false } ``` ### 9.4 导入/模板下载 ```http GET /admin/fleet/drivers/import/template POST /admin/fleet/drivers/import GET /admin/fleet/vehicles/import/template POST /admin/fleet/vehicles/import ``` 导入为 `multipart/form-data`: ```http file=@drivers.csv; type=text/csv ``` 司机导入响应: ```json { "code": 200, "success": true, "data": { "totalRows": 1, "insertedCount": 1, "renewedCount": 0, "warnedCount": 0, "errorCount": 0 } } ``` 错误后缀: ```json { "code": 100001, "message": "参数非法: 不支持的文件类型,仅支持 .xlsx / .xls / .csv", "success": false } ``` --- ## 10. 车型管理库 ### 10.1 车型树与分页 ```http GET /admin/fleet/vehicle-types GET /admin/fleet/vehicle-types/list GET /admin/fleet/vehicle-types/page?page=1&pageSize=5&typeKey=suv GET /admin/fleet/vehicle-types/models/page?page=1&pageSize=5&modelName=丰田 ``` 车型树响应: ```json { "code": 200, "success": true, "data": [ { "id": "2064991856000000001", "typeKey": "suv", "typeName": "SUV系列", "sortOrder": 1, "models": [ { "id": "2064991856994758657", "modelName": "丰田普拉多", "seats": 5, "basePrice": "800.00", "alias": "普拉多" } ] } ] } ``` 前端注意:大类和车型型号主键都读 `id`,不要读旧 `typeId`。 ### 10.2 大类/型号 CRUD ```http POST /admin/fleet/vehicle-types PUT /admin/fleet/vehicle-types/{typeId} POST /admin/fleet/vehicle-types/{typeId}/models PUT /admin/fleet/vehicle-types/models/{modelId} DELETE /admin/fleet/vehicle-types/models/{modelId} DELETE /admin/fleet/vehicle-types/{typeId} ``` 新增大类请求: ```json { "typeKey": "api4756", "typeName": "API测试大类", "sortOrder": 999, "icon": "Car", "description": "issue4756 api regression" } ``` 新增型号请求: ```json { "modelName": "API测试车型", "seats": 6, "basePrice": 123.45, "alias": "API4756", "sortOrder": 1 } ``` 删除有子型号的大类: ```json { "code": 600104, "message": "大类下存在型号,不能删除", "success": false } ``` --- ## 11. 价格日历 ### 11.1 查询总览和车型月历 ```http GET /admin/fleet/pricing-calendar/overview?startDate=2026-07-18&endDate=2026-07-20 GET /admin/fleet/pricing-calendar/{vehicleModelId}?year=2026&month=7 ``` 总览响应: ```json { "code": 200, "success": true, "data": { "startDate": "2026-07-18", "endDate": "2026-07-20", "globalMinPrice": "777.00", "globalMaxPrice": "888.00", "holidays": [], "types": [ { "typeKey": "suv", "typeName": "SUV系列", "models": [ { "vehicleModelId": "2064991856994758657", "modelName": "丰田普拉多", "minPrice": "777.00", "maxPrice": "888.00" } ] } ] } } ``` 月历响应: ```json { "code": 200, "success": true, "data": { "year": 2026, "month": 7, "vehicleModelId": "2064991856994758657", "modelName": "丰田普拉多", "prices": [ { "date": "2026-07-18", "dayPrice": "777.00", "status": "AVAILABLE", "remark": "菜单验收多车型" } ] } } ``` ### 11.2 单车型设价、状态、批量设价、删除 ```http PUT /admin/fleet/pricing-calendar/{vehicleModelId} PUT /admin/fleet/pricing-calendar/{vehicleModelId}/status PUT /admin/fleet/pricing-calendar/batch-set DELETE /admin/fleet/pricing-calendar/{vehicleModelId}?startDate=2026-07-18&endDate=2026-07-20 ``` 单车型 ABS 请求: ```json { "startDate": "2026-07-18", "endDate": "2026-07-20", "adjustMode": "ABS", "dayPrice": 888, "status": "AVAILABLE", "remark": "菜单验收 ABS" } ``` DELTA 周末请求: ```json { "startDate": "2026-07-18", "endDate": "2026-07-20", "adjustMode": "DELTA", "adjustValue": -10, "weekendOnly": true, "status": "AVAILABLE", "remark": "菜单验收 DELTA" } ``` 批量设价请求: ```json { "vehicleModelIds": ["2064991856994758657"], "startDate": "2026-07-18", "endDate": "2026-07-20", "adjustMode": "ABS", "dayPrice": 777, "status": "AVAILABLE", "excludeDates": ["2026-07-20"], "remark": "菜单验收多车型" } ``` 成功响应: ```json { "code": 200, "message": "成功", "success": true, "data": null } ``` 互斥错误: ```json { "code": 400, "message": "工作日/周末/节假日筛选不可同时启用", "success": false } ``` 日期范围错误: ```json { "code": 600501, "message": "日期范围非法:开始日期不能晚于结束日期", "success": false } ``` 前端注意:`batch-set` 幂等窗口 300 秒,同一批完全相同入参快速重复提交会返回 `100502`。 --- ## 12. 待审核与司机自助录入 H5 ### 12.1 生成录入 token ```http POST /admin/fleet/h5/token ``` 新招请求: ```json { "mode": "new", "name": "自助师傅", "phone": "199****9992", "expireDays": 2 } ``` 续签请求: ```json { "mode": "renew", "targetDriverId": "2073749552489267202", "expireDays": 2 } ``` 响应: ```json { "code": 200, "success": true, "data": { "pendingId": "2073749600606318594", "token": "", "url": "https://web.test.1814.love:9443/fleet/driver-onboard?token=", "shortUrl": "https://t.cn/xxxx", "expireAt": "2026-07-07T20:43:30", "qrCodeUrl": "https://..." } } ``` ### 12.2 H5 初始化、上传、提交 ```http GET /app/h5/driver-onboard/init?token= POST /app/h5/driver-onboard/upload POST /app/h5/driver-onboard/submit/new POST /app/h5/driver-onboard/submit/renew ``` init 响应: ```json { "code": 200, "success": true, "data": { "mode": "new", "tokenValid": true, "tokenState": "editable", "stepConfig": {}, "expireAt": "2026-07-07T20:43:30" } } ``` upload 为 `multipart/form-data`: ```http token= groupKey=fleet-menu-test file=@photo.png ``` upload 响应: ```json { "code": 200, "success": true, "data": { "url": "https://hlgl-test.oss-cn-beijing.aliyuncs.com/test/fleet-menu-test/2026/07/05/xxx.png" } } ``` 新招提交请求: ```json { "token": "", "name": "自助师傅", "phone": "199****9992", "gender": "1", "nation": "汉族", "drivingYears": 7, "idCard": "11010119800101****", "idCardFrontUrl": "https://.../front.png", "idCardBackUrl": "https://.../back.png", "licenseNo": "LH54756", "licenseClass": "C1", "licenseExpire": "2035-12-31", "licenseFrontUrl": "https://.../license-front.png", "licenseBackUrl": "https://.../license-back.png", "hasOwnVehicle": true, "vehicle": { "plate": "蒙E-4756", "model": "菜单自带车", "vin": "LSVH500000004756", "seats": 5, "fleet": "own", "annualInspectDate": "2030-12-31", "regDate": "2024-01-01", "insureDue": "2030-12-31", "regCertUsage": "营运租赁", "regCertNo": "REGH54756", "regCertOwner": "自助师傅", "regFrontUrl": "https://.../reg-front.png", "regBackUrl": "https://.../reg-back.png", "exteriorUrls": ["https://.../car-out.png"], "interiorUrls": ["https://.../car-in.png"], "insuranceUrls": ["https://.../insurance.png"], "inspectionUrls": ["https://.../inspection.png"], "operationLicenseUrls": ["https://.../operation-license.png"] }, "preferredCategory": "suv", "preferredModel": "菜单自带车", "vehicleSource": "own", "vehicleNotes": "菜单级验收", "emergency": { "name": "自助联络", "phone": "199****9993", "relation": "同事" }, "portraitUrl": "https://.../portrait.png", "healthCertUrls": ["https://.../health.png"] } ``` 提交响应: ```json { "code": 200, "success": true, "data": { "pendingId": "2073749372209688577", "estimatedReviewHours": 24 } } ``` 前端注意:`regCertUsage` 为营运类时,`operationLicenseUrls` 必须上传;否则审核通过会返回 `600406`。 ### 12.3 待审核列表、详情、通过、驳回 ```http GET /admin/fleet/drivers/pending?page=1&pageSize=10&mode=new&reviewStatus=pending GET /admin/fleet/drivers/pending/{pendingId} POST /admin/fleet/drivers/pending/{pendingId}/approve POST /admin/fleet/drivers/pending/{pendingId}/reject ``` 详情响应: ```json { "code": 200, "success": true, "data": { "id": "2073749372209688577", "mode": "new", "reviewStatus": "pending", "name": "自助师傅", "phone": "199****9992", "idCard": "11010119800101****", "photos": [], "vehicle": { "plate": "蒙E-4756", "hasOwnVehicle": true } } } ``` 前端注意:详情响应主键字段是 `id`,路径变量仍然是 `pendingId`。 通过请求: ```json { "approveReason": "菜单验收通过", "ownVehicle": { "vehicleModelId": "2064991856994758657", "fleet": "own", "plate": "蒙E-4756", "ownerType": "personal", "vin": "LSVH5APP00004756" } } ``` 通过响应: ```json { "code": 200, "success": true, "data": { "driverId": "2073749397010608129", "vehicleId": "2073749397039968257" } } ``` 驳回请求: ```json { "rejectReason": "证件照片不清晰" } ``` 驳回原因为空: ```json { "code": 400, "message": "驳回原因不能为空", "success": false } ``` 重复审核: ```json { "code": 600400, "message": "该记录已处理(已通过或已驳回),不可重复审核", "success": false } ``` --- ## 13. 车队对账 前端当前若仍用本地 `useFleetStore` / mock 计算车队对账,需要切到本节接口;后端主数据不是分页接口,返回结构也不是旧的 `records/total`。 ### 13.1 查询车费、保险、对账期 ```http GET /admin/fleet/reconciliation/cars?periodStart=2026-07-01&periodEnd=2026-07-31&fleets=own GET /admin/fleet/reconciliation/insurance?periodStart=2026-07-01&periodEnd=2026-07-31 GET /admin/fleet/reconciliation/periods?fromMonth=2026-01 GET /admin/fleet/reconciliation/export/cars?periodStart=2026-07-01&periodEnd=2026-07-31&fleets=own ``` 车费响应: ```json { "code": 200, "message": "成功", "success": true, "data": { "periodLabel": "2026-07", "periodStart": "2026-07-01", "periodEnd": "2026-07-31", "fleets": [ { "fleet": "own", "fleetName": "自有车队", "orderCount": 3, "estimatedTotal": "27000.00", "payableTotal": "27000.00", "actualTotal": "26000.00", "settleMode": "OWN_COST", "diff": "-1000.00", "closed": false, "vehicles": [ { "vehicleId": "2064991856994758657", "plate": "蒙A-88888", "modelName": "丰田汉兰达", "seats": 7, "orderCount": 3, "days": 18, "avgPerDay": "1500.00", "amount": "27000.00", "payableAmount": "27000.00" } ] } ], "grandTotal": { "estimated": "27000.00", "payable": "27000.00", "actual": "26000.00", "diff": "-1000.00", "totalDays": 18, "totalOrderCount": 3 } } } ``` 字段口径: | 字段 | 说明 | |------|------| | `fleets[].orderCount` | 车队内订单数,后端已按 `orderNo` 去重 | | `fleets[].estimatedTotal` | 对客报价合计,利润分析用 | | `fleets[].payableTotal` | 对车队应付合计,车队成本基准 | | `fleets[].actualTotal` | 车务/财务手工录入实付,未录为 `null` | | `fleets[].diff` | `actualTotal - payableTotal`,未录实付为 `null` | | `fleets[].closed` | 整月关账状态;非自然月查询恒为 `false` | | `vehicles[].days` | 车天,来自 active prep 行数 | | `vehicles[].avgPerDay` | `payableAmount / days` | | `grandTotal.totalOrderCount` | 全车队订单数,后端跨车队全局去重,前端不要用明细求和 | 保险响应: ```json { "code": 200, "message": "成功", "success": true, "data": { "periodLabel": "2026-07", "grandTotal": "250.00", "fleets": [ { "fleet": "own", "sourceSubtotals": { "manual": "120.00", "baoyou": "130.00" }, "typeCounts": { "annual": 1, "perTrip": 1, "none": 0 }, "drivers": [ { "driverId": "188800000000000001", "name": "王师傅", "phone": "138****1234", "insuranceType": "annual", "insuranceSource": "MANUAL", "billingMethod": "年保险按日摊销", "annualPremium": "3650.00", "perDayRate": null, "totalPremium": null, "orderCount": 2, "days": 12, "insuranceAmount": "120.00" }, { "driverId": "188800000000000002", "name": "李师傅", "phone": "139****5678", "insuranceType": "", "insuranceSource": "BAOYOU", "billingMethod": "保游网实际出单", "annualPremium": null, "perDayRate": null, "totalPremium": "130.00", "orderCount": 1, "days": 3, "insuranceAmount": "130.00" } ] } ] } } ``` 保险字段口径: | 字段 | 说明 | |------|------| | `insuranceSource` | 分组主键,取 `MANUAL/BAOYOU/NONE`;不要用 `insuranceType` 分组 | | `insuranceType` | 司机配置类型,`annual/perTrip/none`;保游实际出单行可能为空字符串 | | `sourceSubtotals.manual` | 手填年保费/行程险摊销小计 | | `sourceSubtotals.baoyou` | 保游实际出单摊销小计 | | `typeCounts` | 车队内司机保险类型计数 | | `grandTotal` | 全车队保险成本合计,不含 `NONE` | 对账期响应: ```json { "code": 200, "message": "成功", "success": true, "data": [ { "label": "2026-07", "periodStart": "2026-07-01", "periodEnd": "2026-07-31", "closed": false, "reopened": false } ] } ``` ### 13.2 录入实付、关账、重开、补偿 ```http PUT /admin/fleet/reconciliation/actual POST /admin/fleet/reconciliation/close POST /admin/fleet/reconciliation/reopen GET /admin/fleet/reconciliation/pending-compensations?page=1&pageSize=5&status=PENDING POST /admin/fleet/reconciliation/pending-compensations/{id}/resolve ``` 录入实付请求: ```json { "periodStart": "2026-07-01", "periodEnd": "2026-07-31", "fleet": "own", "actualAmount": "26000.00", "note": "菜单验收录入" } ``` 响应: ```json { "code": 200, "message": "成功", "success": true, "data": { "id": "2073749573041356801", "diff": "-1000.00", "payableEstimated": "27000.00", "estimated": "27000.00" } } ``` 清空实付:`actualAmount` 传 `null` 或省略,后端软删该 `(periodStart, fleet)` 实付行,响应中 `diff` 返 `null`。 补偿列表响应: ```json { "code": 200, "message": "成功", "success": true, "data": { "page": 1, "pageSize": 5, "total": 1, "records": [ { "compId": "2073749573041356802", "assignmentId": "2073749573041356803", "orderId": "2073749536638992386", "periodLabel": "2026-07", "opType": "TRUNCATE", "serviceDateFrom": "2026-07-20", "reason": "提前完结截断触及已关账期 2026-07", "status": "PENDING", "createTime": "2026-07-06T10:00:00", "resolvedAt": null, "resolvedBy": null, "resolveRemark": null } ] } } ``` 处置补偿请求: ```json { "remark": "已线下补对账,差额计入 2026-08 调整" } ``` 处置补偿响应: ```json { "code": 200, "message": "成功", "success": true, "data": { "compId": "2073749573041356802", "status": "RESOLVED", "resolvedAt": "2026-07-06T10:30:00", "resolvedBy": "1001" } } ``` 负数错误: ```json { "code": 605608, "message": "实际金额必须大于等于0", "success": false } ``` 非自然月关账: ```json { "code": 605605, "message": "仅支持按自然月关账,自定义区间为只读分析", "success": false } ``` 非超管重开: ```json { "code": 403001, "message": "无权限,仅超级管理员可重开账", "success": false } ``` --- ## 14. 车管模板 模板列表是非分页接口;前端页面不要传 `page/pageSize`。测试服如果返回空数组,表示当前库没有配置模板,不是分页问题。 ```http GET /admin/fleet/message-templates GET /admin/fleet/message-templates?templateType=hold_notify POST /admin/fleet/message-templates POST /admin/fleet/message-templates/{templateId}/render PUT /admin/fleet/message-templates/{templateId} DELETE /admin/fleet/message-templates/{templateId} ``` 新增请求: ```json { "templateName": "API派车通知", "templateType": "hold_notify", "bodyTemplate": "您好 {{driver.name}},订单 {{order.no}} 已派车,车牌 {{vehicle.plate}}", "variablesHelp": "{\"driver.name\":\"司机姓名\"}", "isDefault": false, "sortOrder": 99 } ``` 响应: ```json { "code": 200, "success": true, "data": { "id": "2073749573041356801", "templateName": "API派车通知", "templateType": "hold_notify", "bodyTemplate": "您好 {{driver.name}},订单 {{order.no}} 已派车,车牌 {{vehicle.plate}}", "isDefault": false, "sortOrder": 99 } } ``` 渲染请求: ```json { "orderId": "2073749536638992386", "driverId": "2073749573041356803", "vehicleId": "2073749573041356804" } ``` 渲染响应: ```json { "code": 200, "success": true, "data": { "renderedBody": "您好 API师傅,订单 已派车,车牌 蒙A-69665", "variablesUsed": ["driver.name", "order.no", "vehicle.plate"] } } ``` 说明:当前 `driver.*`、`vehicle.*` 可按 ID 渲染;`order.*` / `itinerary.*` 本期仍走占位端口,缺值会替换为空串,不报错。前端不要传 `orderNo/driverName/vehiclePlate`,这些不是该接口入参字段。 变量缺失: ```json { "code": 600800, "message": "模板变量缺失", "success": false } ``` --- ## 14.5 2026-07-06 独立账号写接口实测样本 本节是测试服真实返回,用于前端逐字段对齐。账号:`fleet_mgr_4760/VEHICLE_MANAGER`。测试派单已取消回滚,产生的司机险待处理任务已标记 `IGNORED`,不会污染待处理列表。 ### 14.5.1 派单预检、创建、确认、取消 预检请求: ```json { "orderId": "2070756230887890945", "vehicleId": "2067084363580760065", "driverId": "2065272150960357378", "startDate": "2026-07-06", "endDate": "2026-07-08", "pickupAt": "hailar", "dropoffAt": "hailar", "headcount": 2 } ``` 预检响应: ```json { "code": 200, "message": "成功", "data": { "conflict": false, "conflicts": [], "warnings": [] } } ``` 创建 holding 请求: ```json { "orderId": "2070756230887890945", "vehicleId": "2067084363580760065", "driverId": "2065272150960357378", "startDate": "2026-07-06", "endDate": "2026-07-08", "headcount": 2, "holdMode": 1, "fromEntry": "api-test-4760", "strictSeats": false, "skipCityJunctionException": false, "requestId": "api-test-4760-9ap9s565" } ``` 创建响应: ```json { "code": 200, "message": "成功", "data": { "id": "2070756257240694786", "assignmentStatus": "holding", "holdSentAt": "2026-07-06T...", "confirmedAt": null, "sideEffects": null } } ``` 确认请求: ```json { "driverReplyNote": "API测试4760:司机已确认,确认后立即取消回滚" } ``` 确认响应: ```json { "code": 200, "message": "成功", "data": { "assignmentStatus": "assigned", "confirmedAt": "2026-07-06T...", "itineraryUrl": "https://web.test.1814.love:9443/fleet/itinerary/...", "sideEffects": { "vehicleStatusUpdated": "busy", "driverStatusUpdated": "busy", "reconPrepRowsCreated": 0, "reconPrepMarkedCanceled": null } } } ``` 取消请求: ```json { "cancelReason": "API测试4760:确认写接口后立即取消释放,不作为真实用车", "driverNotified": true, "notifyNote": "API自动化回滚,未实际通知司机", "cutoffDate": "2026-07-06" } ``` 取消响应: ```json { "code": 200, "message": "成功", "data": { "assignmentStatus": "canceled", "sideEffects": { "vehicleStatusUpdated": "idle", "driverStatusUpdated": "idle", "reconPrepRowsCreated": null, "reconPrepMarkedCanceled": 0 } } } ``` 取消后订单详情: ```json { "code": 200, "data": { "id": "2070756230887890945", "currentAssignment": null, "transport": { "arrive": null, "depart": null, "batches": [] } } } ``` 前端注意:无大交通时 `transport` 仍返回稳定结构,不要因为 `batches=[]` 就认为接口缺字段;有大交通的真实样本会返回 `arrive/depart/batches`。 ### 14.5.2 司机险任务动作 确认派单后,司机为 `perTrip`,自动生成 3 条投保任务: ```http GET /admin/fleet/insurance/tasks?page=1&pageSize=20&assignmentId=2070756257240694786 ``` 响应摘要: ```json { "code": 200, "data": { "page": 1, "pageSize": 20, "total": 3, "records": [ { "taskType": "PURCHASE", "taskStatus": "PENDING", "source": "BAOYOU", "errorCode": "540005", "errorMessage": "保险计划不存在", "suggestedAction": "请核对司机档案、保险计划和保司返回信息后重试;线下处理必须填写真实保费、保单号和凭证", "serviceDate": "2026-07-06", "retryCount": 0 } ] } } ``` 线下完成缺凭证请求: ```json { "policyNo": "API-TEST-NO-PROOF", "premiumAmount": "1.00", "proofUrls": [], "remark": "API测试缺凭证校验" } ``` 响应: ```json { "code": 400, "message": "线下凭证不能为空", "success": false } ``` 忽略测试任务请求: ```json { "remark": "API测试4760回滚派单产生,非真实用车任务,已确认忽略" } ``` 响应: ```json { "code": 200, "data": { "taskStatus": "IGNORED", "taskStatusLabel": "已忽略" } } ``` 清理后待处理确认: ```http GET /admin/fleet/insurance/tasks?page=1&pageSize=20&assignmentId=2070756257240694786&pendingOnly=true ``` ```json { "code": 200, "data": { "page": 1, "pageSize": 20, "total": 0, "records": [] } } ``` ### 14.5.3 车队对账实际金额保存与清空 录入请求: ```json { "periodStart": "2026-07-01", "periodEnd": "2026-07-31", "fleet": "own", "actualAmount": "1.23", "note": "API测试4760:写接口探针,随后清空" } ``` 录入响应: ```json { "code": 200, "data": { "id": "2073981751427821569", "diff": "-12878.67", "payableEstimated": "12879.90", "estimated": "12879.90" } } ``` 清空请求: ```json { "periodStart": "2026-07-01", "periodEnd": "2026-07-31", "fleet": "own", "actualAmount": null, "note": "API测试4760:清空写接口探针" } ``` 清空响应: ```json { "code": 200, "data": { "id": "2073981751427821569", "diff": null, "payableEstimated": "12879.90", "estimated": "12879.90" } } ``` 负数错误: ```json { "code": 605608, "message": "实际金额必须大于等于0", "success": false } ``` ### 14.5.4 模板渲染 渲染请求: ```json { "orderId": "2070756230887890945", "vehicleId": "2067084363580760065", "driverId": "2065272150960357378" } ``` 响应字段: ```json { "code": 200, "data": { "renderedBody": "渲染后的正文", "variablesUsed": [ "order.no", "order.startDate", "order.endDate", "order.customer", "order.headcount", "vehicle.plate", "vehicle.model" ] } } ``` --- ## 15. 前端错误码与按钮状态处理 | code | 场景 | 前端处理 | |------|------|----------| | `403` | 定制师访问车务后台 | 提示切换到车务角色,不重试。 | | `401` | 未登录访问后台 | 跳登录或刷新登录态。 | | `100001` / `400` | 参数校验失败 | 展示后端 message,定位表单字段。 | | `100502` | 幂等保护/快速连点 | 保持按钮 loading/disabled,不当作系统故障。 | | `600112` | 人工设置车辆 busy | 前端禁止 busy 选项;busy 只由派单占用写入。 | | `600208` | 非黑名单司机解封 | 展示业务态提示,刷新司机状态。 | | `600400` | 待审记录重复审核 | 刷新待审列表/详情。 | | `600406` | 自带车审核缺要件 | 提示补车型、车队、车牌或营运证。 | | `600501` | 价格日期范围非法 | 检查开始/结束日期。 | | `605001` | 车辆/司机派单冲突 | 展示冲突,刷新矩阵占用。 | | `605020` | 非 holding 确认或终态取消 | 刷新派单详情,不重复提交。 | | `605021` | 终态重复提前完结 | 刷新派单详情。 | | `605022` | 车辆常驻司机被占用 | 前端提示先解绑原车辆。 | | `605023` | 司机绑定目标车被占用 | 前端提示更换车辆或解除占用。 | | `605605` | 非自然月关账 | 禁止自定义区间关账,只读分析即可。 | | `605608` | 实付金额负数 | 表单限制 `actualAmount >= 0`。 | | `605609` | 关账补偿不存在 | 刷新补偿列表。 | --- ## 16. 验证证据 - 菜单级真实 API:`23/23` 通过,订单 `HL20260705204251138`,覆盖 76 个后台端点。 - 全链路真实 API:`31/31` 通过,订单 `HL20260705204312543`。 - 多订单并发:`10/10` 通过,真实创建 3 个订单 `HL20260705204330462`、`HL20260705204332693`、`HL20260705204334918`,仅 1 单派单成功,其余按 `605001` 冲突返回。 - 2026-07-06 独立账号读接口回归:`32/32` 通过,报告 `HL-v3/.tmp/4760_independent_api_report.md`。覆盖工作台、角色 403、派单看板、矩阵、车辆/车型、司机、价格日历、车管模板、车队对账、保险任务、真实大交通样本。 - 2026-07-06 独立账号写接口探针:`22/22` 通过,报告 `HL-v3/.tmp/4760_write_api_report.md`。覆盖 `precheck/create/confirm/cancel`、司机险任务生成和忽略、`offline-done` 缺凭证校验、对账实付保存/清空、模板渲染和非法变量。 - 本地后端验证: - `mvn -pl hl-fleet-service -am "-Dtest=AssignmentServiceTest,FleetAdminRoleGuardInterceptorTest" -DfailIfNoTests=false test` 通过,69 tests。 - `mvn -pl hl-fleet-service -am "-Dtest=DriverSettlementModeDictResolverTest,DriverControllerTest,DriverImportServiceTest,DriverServiceTest,DriverCrudIntegrationTest,FleetInsuranceTaskServiceTest,AssignmentControllerTest" -DfailIfNoTests=false test` 通过,221 tests。 - `mvn -pl hl-fleet-service -am -DskipTests compile` 通过。 - `git diff --check` 通过,无空白错误。 - `mvn -pl hl-fleet-service spotless:check` 通过。