16 KiB
schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
| schema | ticket | title | consumer | author | change_type | backend_status | gateway_status | frontend_status | frontend_owner | frontend_ref | target_release | verified_at | status_note | updated_at | base |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hl-changelog/v2 | 8301 | 车务看板带日期筛选时,单条 requirement_id 为空的派车行不再清空整个日期窗 | admin | wx(GIT) | 修改接口 | deployed | verified | not_required | 前端 2026-09-24 核验 not_required:接口契约零变化(路径/参数/字段/错误码全不变),纯后端行为修正——带日期筛选时 requirement_id 空脏行由整窗失败关闭返空改为跳过+WARN,同窗其余订单照常返回。grep 实证:看板列表前端只渲染 records,无对「整窗空」的特殊分支/依赖;fleet/board 前端 requirementId 唯一消费点在 useNoVehicleDeclaration(读详情 /orders/{orderId} 查无车声明),与看板列表日期分支无关。后端修正让数据更完整,前端天然受益零改动。 | 2026-09-24 | dev-v3 |
fleet: 看板日期筛选分支的脏行失败关闭收窄为跳过单行
存放目录:
changelogs-v2/2026-09/服务: hl-fleet-service PR: #8310 Issue: #8301 日期: 2026-09-24 影响范围: 管理后台「车务看板」订单列表/网格视图(带日期筛选时)
⚠️ 关键变化
带日期筛选时,单条脏数据不再清空整个日期窗。 此前只要日期窗里存在任意一条 requirement_id 为空的派车行,GET /admin/fleet/board/orders(带 startDate/endDate 或 startDayFrom/startDayTo)就整页返回 records=[]、total=0、code=200,不报错——页面上看到的是「这几天没有订单」而不是任何异常。现在这条行被跳过并记 WARN(WARN 里带 orderId/assignmentId/assignmentGroupId),同一日期窗内其余订单照常返回,与不带日期筛选时的既有口径一致。
接口契约零变化:路径、参数、字段、类型、必填性、枚举、错误码全部不变,只修正日期分支的行为。
一、背景
车务看板带日期筛选时走一条独立的「当前主单日期候选」扫描分支。该分支原本把四类候选行异常合并成一个失败关闭条件,其中一类是「派车行的 requirement_id 为空」——这是历史数据迁移、手工修数或未来写路径缺陷可能留下的占位行。这类行本身匹配不上任何用车需求,在不带日期的路径里只是被跳过并记一条汇总 WARN;但在日期分支里,它会让同页全部订单的候选一起作废,表现为整窗静默返回空。
本次把该条件按成因拆开:真正影响槽位聚合正确性的三类结构性畸形(行对象缺失、主单 ID 缺失、派车组 ID 与派车 ID 同时缺失)以及重复槽位键仍然失败关闭,只是各自补一条带定位信息的 WARN;requirement_id 为空的行改为逐行剔除并记 WARN。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 看板订单列表 | GET | /admin/fleet/board/orders |
行为变更(契约不变) | 带日期筛选时,requirement_id 为空的派车行由「整窗失败关闭」改为「跳过该行 + WARN」 |
三、接口详情
1. 看板订单列表 GET /admin/fleet/board/orders
VO: BoardOrderPageReqVO → BoardOrderPageRespVO(records: BoardOrderRecordVO[])
使用场景
管理后台「车务看板」订单列表/网格视图(variant=list|grid)。车务人员按状态、日期、团号、车型等条件筛出待派/已派订单卡片,逐卡执行改派、派车、查看行程等操作。本次改动只影响带日期筛选时该列表返回的记录集合。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| startDate | Query | LocalDate | ❌ | yyyy-MM-dd |
行程日期窗起(startDayFrom 的兼容别名) |
| endDate | Query | LocalDate | ❌ | yyyy-MM-dd |
行程日期窗止(startDayTo 的兼容别名) |
| startDayFrom | Query | LocalDate | ❌ | yyyy-MM-dd |
行程日期窗起;为空时回落到 startDate |
| startDayTo | Query | LocalDate | ❌ | yyyy-MM-dd |
行程日期窗止;为空时回落到 endDate |
| statuses / status | Query | String[] / String | ❌ | 枚举:unassigned/unassigned_urgent/holding/holding_urgent/assigned/canceled/completed | 状态筛选,可多选;status 为单值兼容别名 |
| vehicleTypeKeys / typeKeys | Query | String[] | ❌ | 车型大类字典值 | 车型多选筛选 |
| keyword / driverName / contactName / teamNo / plannerName | Query | String | ❌ | - | 关键字、司机、联系人、团号、定制师等模糊搜索 |
| groupBatchId | Query | Long | ❌ | 等值匹配 | 运营团期 ID |
| consultantId | Query | Long | ❌ | - | 定制师 ID 精确筛选 |
| variant | Query | String | ❌ | list/grid |
视图口径 |
| page(或 pageNo) | Query | Integer | ❌ | ≥1,缺省 1 | 页码 |
| pageSize | Query | Integer | ❌ | 1-100 | 每页条数 |
本单不新增、不删除、不改任何参数的类型与必填性;上表只为把「受影响的日期参数」放进完整上下文。
出参 Result<BoardOrderPageRespVO>
| 字段 | 类型 | 说明 |
|---|---|---|
| records | BoardOrderRecordVO[] | 本页看板卡片;本次改动只影响带日期筛选时该数组的内容 |
| total | Long | 命中总数;带日期筛选时不再被单条脏行清零 |
| page | Integer | 当前页码 |
| pageSize | Integer | 每页条数 |
| records[].id | Long | 派车行/虚拟条目主键 |
| records[].orderId / orderNo / teamNo | Long / String / String | 子订单 ID、订单编号、团号 |
| records[].assignmentId / assignmentGroupId / requirementId | Long | 派车行 ID、派车分组 ID、当前用车需求 ID |
| records[].assignmentStatus | String | 派单状态码 |
| records[].virtualPending | Boolean | 虚拟待派卡标记(真实记录恒为 false) |
| records[].groupVehicleCovered | Boolean | 团车整段接管标记(详见 #8235 交接件) |
| records[].urgentBadge / canAssign / dispatchReadOnly | String / Boolean / Boolean | 加急标签、可派车、只读 |
| records[].startDate / endDate | LocalDate | 行程起止日期 |
| records[].currentVehiclePlate / currentDriverName | String | 当前车辆车牌 / 司机姓名 |
请求示例
GET /admin/fleet/board/orders?startDate=2026-11-01&endDate=2026-11-10&variant=list&pageNo=1&pageSize=20
响应示例
{
"code": 200,
"message": "成功",
"data": {
"records": [
{
"id": 7330843067599549,
"orderId": 2101014943313670001,
"orderNo": "HL20261106000001",
"teamNo": null,
"assignmentId": 7330843067599549,
"assignmentGroupId": 7330843067599549,
"requirementId": 2101014943313670100,
"assignmentStatus": "holding",
"virtualPending": false,
"groupVehicleCovered": null,
"urgentBadge": null,
"canAssign": true,
"dispatchReadOnly": false,
"startDate": "2026-11-06",
"endDate": "2026-11-07",
"currentVehiclePlate": null,
"currentDriverName": null
}
],
"total": 1,
"page": 1,
"pageSize": 20
},
"success": true
}
空数据 / 降级响应
无匹配记录时返回空数组与 total=0,不报错:
{
"code": 200,
"message": "成功",
"data": { "records": [], "total": 0, "page": 1, "pageSize": 20 },
"success": true
}
带日期筛选时的空列表仍不等同于「该日期窗确实无单」:日期候选扫描取数失败、结果集缺失、候选行结构畸形(行对象缺失 / 主单 ID 缺失 / 派车组 ID 与派车 ID 同时为空)或槽位键重复时,本页仍按既有 fail-closed 口径整体返回空,但每一种成因现在都会在 hl-fleet-service 日志里留下一条可区分的 WARN。不带日期筛选的查询不走这条分支。
错误响应
{
"code": 401,
"message": "未登录或登录已过期",
"success": false,
"data": null
}
业务边界
- 只影响带日期筛选的分支。不带日期的查询、车辆矩阵接口、看板汇总接口的口径与本次改动前完全一致。
requirement_id为空的派车行会被剔除:该行原本在不带日期的路径里也匹配不上任何用车需求、不可能出现在看板上,因此剔除它不会让本该展示的卡片消失。- 若某订单在日期窗内只有这一条脏行,该订单在带日期的视图里看不到——这与它不带日期时的既有表现一致;让它可见需要的是数据修复,不是看板放行。
- 日期候选结果集本身取到空(无订单上下文)时不查派车行,正常返回空页。
- 鉴权:管理后台登录态,未登录 401(网关拦截)。
四、契约约束与正确调用方式
✅ 正确 / ❌ 错误用法对照
| 场景 | 说明 |
|---|---|
✅ 直接使用 total 与 records |
结构与字段均未变,前端无需做任何解析适配 |
| ✅ 把带日期筛选返回的空列表理解为「结构性异常或确实无单」 | 本次改动后,单条 requirement_id 为空的脏行不再制造这种空结果;剩余会制造空结果的是结构性畸形(行缺失、主单 ID 缺失、槽位键缺失或重复),均会在服务端留 WARN |
| ❌ 为「带日期筛选可能返回空」保留前端兜底或本地缓存回填 | 本次改动后不再是必需;保留也不会出错,但会把真实的结构性畸形空结果一并掩盖 |
| ❌ 依赖后端 WARN 的具体文案做前端逻辑 | WARN 只面向排障,文案不是契约 |
切换状态时的必要动作
无。本接口是只读 GET,跳过脏行的判定完全由后端在读取时完成,不接受前端传参覆盖,也不需要前端在请求前做任何字段准备。
六、边界行为
- 未登录 → 401(网关拦截)
- 无匹配记录 → 200 + 空数组、
total=0,不报错 - 日期候选行含
requirement_id为空的行 → 200,该行被跳过并记 WARN,其余订单照常返回(本次改动) - 日期候选行结构畸形(行对象缺失 / 主单 ID 缺失 / 派车组 ID 与派车 ID 同时缺失)或槽位键重复 → 200 + 整页空(既有 fail-closed 口径保留),并新增带定位信息的 WARN
- order-v3 日期候选页取数失败、超过单次一致性快照上限或上下文畸形 → 200 + 整页空(既有 fail-closed 口径保留)
- 虚拟待派候选层不可用(开关关闭或远端候选不可用)→ 只丢虚拟条目,真实派车行照常返回
六.6、修改前后对比
字段级对比
| 字段 | 改前 | 改后 | 变化说明 |
|---|---|---|---|
| 请求 / 响应字段 | 无变化 | 无变化 | 本次为纯行为修正,不新增、不删除、不改类型 |
行为级对比
| 行为 | 改前 | 改后 | 影响 |
|---|---|---|---|
日期窗内某订单存在一条 requirement_id 为空的派车行 |
整窗返回 records=[]、total=0、code=200,服务端无日志 |
只跳过该行并记 WARN,同窗其余订单正常返回 | 带日期筛选的列表不再被单条脏数据清空 |
| 同一数据不带日期查询 | 该行被跳过 + 一条汇总 WARN | 不变 | 无 |
| 日期候选出现重复槽位键 | 整页失败关闭,无日志 | 整页失败关闭(不变),新增带重复键样本的 WARN | 排障可定位 |
| 日期候选行结构畸形(行缺失 / 主单 ID 缺失 / 槽位键全缺) | 整页失败关闭,无日志 | 整页失败关闭(不变),新增带成因与定位字段的 WARN | 排障可定位 |
六.7、影响评估
- 是否破坏向后兼容: 否。请求参数、响应结构、字段类型与错误码全部不变,仅带日期筛选时的记录集合与
total不再被单条脏数据清零。 - 前端是否必须同步上线: 否。前端无需修改即可受益。
- 前端 workaround 清理点: 若前端此前针对「带日期筛选偶发返回空」做过兜底或本地回填,可以在确认后移除;保留不影响功能。
七、不影响范围
- 仅影响:管理后台「车务看板」订单列表/网格视图(
/admin/fleet/board/orders)在带日期筛选时的记录集合与total。 - 零影响:
- 不带日期筛选的看板订单列表口径
- 车辆矩阵未派清单、网格与月度统计(
/admin/fleet/matrix/**,不走日期候选扫描分支) - 看板汇总与统计接口
- 派车、改派、确认等写接口
- 用车需求与派车行的数据结构、状态机与任何表结构
八、测试环境已验证
测试服部署(deploy:test 单写租约):hl-fleet-service 2026-09-24 10:49:54 滚动部署到 dev-v3 @ cc70c9ba3(该提交是本次 squash 合并 48c755fd1 的后代),实例 8187 / 8087 均 UP 且健康检查通过。
网关实测(https://api.test.1814.love,管理后台登录态切到车务角色):
| # | 请求 | 修复前 total |
修复后 total |
|---|---|---|---|
| 1 | GET /admin/fleet/board/orders(不带日期) |
243 | 243(对照组,未变)✓ |
| 2 | ...&startDate=2026-11-01&endDate=2026-11-10(窗内含脏行) |
0 | 8 ✓ |
| 3 | ...&startDayFrom=2026-11-01&startDayTo=2026-11-10(同窗别名参数) |
0 | 8 ✓ |
| 4 | ...&startDate=2026-09-24&endDate=2026-11-04(窗内不含脏行) |
71 | 71(对照组,未变)✓ |
| 5 | ...&startDate=2026-11-06&endDate=2026-11-06(脏行当天) |
0 | 6 ✓ |
| 6 | ...&startDate=2026-11-05&endDate=2026-11-07 |
0 | 6 ✓ |
服务端逐行 WARN(两个实例各两条,与上表实测同刻,原始行):
2026-09-24 10:50:56.063 [http-nio-8087-exec-1] WARN c.h.f.b.service.BoardCandidateSource - 车务看板列表日期候选剔除无用车需求ID的派单行(本行不参与候选): orderId=2101014943313670146 assignmentId=7330843067599548 assignmentGroupId=7330843067599548
2026-09-24 10:50:56.556 [http-nio-8187-exec-2] WARN c.h.f.b.service.BoardCandidateSource - 车务看板列表日期候选剔除无用车需求ID的派单行(本行不参与候选): orderId=2101014943313670146 assignmentId=7330843067599548 assignmentGroupId=7330843067599548
那条脏行(assignment_id=7330843067599548,order_id=2101014943313670146,行程日期 2026-11-06)本身不再出现在任何日期窗结果里——它匹配不上任何用车需求,本就无法在看板渲染;关键变化是它不再让同窗其余订单一起消失。
本地验证:定向 42/42 绿、看板与矩阵影响面回归 379/379 绿、spotless:check 与 mvn -o -pl hl-fleet-service -am verify 均 BUILD SUCCESS(该模块 4766 个用例 0 失败 0 错误 6 跳过)。
十、相关文档
- 关联 Issue: wx/HL#8301
- 关联 PR: wx/HL#8310
- 同一接口的上一份交接件(#8235,看板订单记录新增
groupVehicleCovered),其中「带日期筛选的既有 fail-closed 口径」一条由本文件取代