20 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 | 8518 | 派单看板列表与汇总下发用车需求类别 requirementKind,支持按类别筛选 | admin | wx(GIT) | 修改接口 | deployed | verified | implemented | mmg | 2f65d1f756f98453acf91cd32d1866eed3f01f5c | v2.1 | 2026-09-30 | PR #8534(fix(fleet): 派单看板列表下发用车需求类别并支持按类别筛,关联 #8518)已合并 dev-v3,滚动部署测试服 hl-fleet-service @ dfb5db832(2026-09-29 17:48:30)。requirementKind/requirementKindLabel 两字段与同名可选筛选参数已实测:基线 47 条,TRAVEL 37/TRANSFER 10,两档相加等于基线且交集为空,requirementId 集合与基线一致;非法值返 100001。前端 2026-09-30 已交付:看板列表加「类别」列直显 requirementKindLabel(NTag info/warning 读英文码,不自译),orderKind 页签旁加类别页签且列表+汇总两接口同传(空=不过滤),与 orderKind 可同传 AND;586 例全绿。 | 2026-09-30 | dev-v3 |
hl-fleet-service: 派单看板下发用车需求类别 requirementKind
服务: hl-fleet-service
PR: #8534(已合入 dev-v3,squash dfb5db832)
Issue: #8518
日期: 2026-09-29
影响范围: 管理后台车务「派单看板」的列表与汇总两个读口
⚠️ 关键变化
- 派单看板「团期订单 / 全部订单」列表上,同一订单若同时存在行程用车与接送机两条用车需求,会出两张卡——两张卡的订单号、团号、客户、定制师、行程日期、人数逐字相同,此前没有任何字段能分辨哪张是接送机。
GET /admin/fleet/board/orders的data.records[]新增requirementKind/requirementKindLabel两个字段,恒成对非空:requirementKind取值TRAVEL(行程用车)/TRANSFER(接送机),requirementKindLabel是对应中文标签,由后端下发,前端不要自己做kind → 中文的映射。GET /admin/fleet/board/orders与GET /admin/fleet/board/summary新增同名可选查询参数requirementKind,两个接口共用同一入参 VO。不传或传空串 = 不过滤,两类都返。requirementKind与既有的orderKind是两个互不相交的维度:orderKind分订单归属(ALL/NORMAL/GROUP),requirementKind分需求类别。两者可同传按 AND 组合,串用不会报错,只会筛出错误的行数,详见「四、契约约束与正确调用方式」。- 非法取值不被静默容忍:非
TRAVEL/TRANSFER且非空一律 HTTP 200 + bodycode=100001,data=null、success=false。 GET /admin/fleet/board/summary的statusCounts与statusOptions[].count随requirementKind一起收窄;idleVehicleCount/idleDriverCount是全局物理资源指标,不受该筛选影响。statusCounts里的unassignedUrgent/holdingUrgent是unassigned/holding的子集(statusOptions里以urgentCount形式出现),不是独立状态桶,前端加总时不要重复计入。
一、背景
车务派单看板存在同订单出两张卡、字段完全相同、无法分辨哪张是接送机的问题(wx/HL#8518)。本次为每条 record 补充需求类别下发(requirementKind/requirementKindLabel),并给列表与汇总两个读口各加一个同名可选筛选参数,用于把两类需求分列展示或过滤。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 派单看板列表 | GET | /admin/fleet/board/orders |
新增出参字段 + 可选入参 | 新增 requirementKind/requirementKindLabel 出参字段;新增可选筛选参数 requirementKind,非法值返 100001 |
| 2 | 派单看板汇总 | GET | /admin/fleet/board/summary |
新增可选入参 | 新增可选筛选参数 requirementKind(与列表共用同一入参 VO),statusCounts/statusOptions[].count 随之收窄 |
三、接口详情
1. 派单看板列表 GET /admin/fleet/board/orders
VO: BoardOrderPageReqVO → BoardOrderRecordVO
使用场景
车务「派单看板」主列表。同一订单同时存在行程用车与接送机两条用车需求时会各出一张卡,此前两卡逐字段相同、无法分辨。本次每条 record 补充需求类别,前端可据此区分两张卡,或用新增的 requirementKind 查询参数直接按类别筛选。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| requirementKind | Query | String | 否 | TRAVEL / TRANSFER;其余非空值返 100001 |
🆕 本次新增。用车需求类别筛选:TRAVEL=只看行程用车,TRANSFER=只看接送机。不传或传空串=不过滤,两类都返。与既有 orderKind(订单归属维度)互不相交,可同传按 AND 组合 |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| data.records[].orderId | String | 订单 ID |
| data.records[].requirementId | String | 用车需求 ID |
| data.records[].teamNo | String | 团号 |
| data.records[].virtualPending | Boolean | 是否为还没有任何派车行的虚拟待派卡片 |
| data.records[].requirementKind | String | 🆕 本次新增。用车需求类别:TRAVEL 行程用车 / TRANSFER 接送机。取本条记录所属需求自身的类别,恒非空 |
| data.records[].requirementKindLabel | String | 🆕 本次新增。类别中文标签:行程用车 / 接送机。由后端下发,前端不要自己做 kind→中文 的映射,与 requirementKind 恒成对非空 |
请求示例
GET /admin/fleet/board/orders?orderKind=ALL&pageSize=100&requirementKind=TRANSFER HTTP/1.1
Host: <测试服网关>
Authorization: Bearer <token>
(GET 无请求体)
响应示例
以下为按 requirementKind=TRANSFER 过滤后(实测命中 10 条)摘录其中 1 条,仅列本次相关字段与几个已知存在的字段(完整响应还含既有其余字段,本文档未逐一核对不重复列出);orderId 为 2026-09-29 17:48 测试服实测命中的真实并存订单之一(该订单同时存在 TRAVEL、TRANSFER 两条记录),requirementId/teamNo 为示意值:
{
"code": 200,
"message": "成功",
"data": {
"records": [
{
"orderId": "2101566624467419137",
"requirementId": "<示意值,真实用车需求 ID>",
"teamNo": "<示意值,真实团号>",
"virtualPending": false,
"requirementKind": "TRANSFER",
"requirementKindLabel": "接送机"
}
],
"total": 10,
"page": 1,
"pageSize": 100
},
"traceId": null,
"success": true
}
空数据 / 降级响应
本次测试窗口内 requirementKind=TRAVEL(37 条)与 requirementKind=TRANSFER(10 条)均非空,未专门验证 0 命中场景。requirementKind 非法取值走「错误响应」,不属于本节的空数据场景。
order-v3 整体不可达、取不到需求身份时的降级口径:requirementKind 回退 TRAVEL,与该场景下特殊诉求/备注回退快照同属既有降级口径。
错误响应
requirementKind 非法(非 TRAVEL/TRANSFER 且非空),2026-09-29 测试服实测原文:
{
"code": 100001,
"message": "参数非法: requirementKind 仅支持 TRAVEL/TRANSFER,传入非法值:BOGUS",
"data": null,
"traceId": null,
"success": false
}
HTTP 状态行仍是 200,判据在 body 的 code / success,不要只看状态码。
业务边界
- 真实卡与虚拟待派卡(
virtualPending=true)一律非空——实测 47 条里 10 条虚拟待派卡两字段全部有值。 - 纯接送机订单(没有 active 行程用车需求)如实返
TRANSFER,不受「顶层requirementId恒指TRAVEL」那条既有契约影响。 - 类别取自卡片自身归属的那条需求,不读订单级单值字段——单值恒取身份列表首项(两类并存时是
TRAVEL)。 - order-v3 降级取不到需求身份时回退
TRAVEL(与该场景下特殊诉求/备注回退快照同属既有降级口径)。 requirementKind与orderKind是两个互不相交的维度,串用不会报错,只会筛出错误的行数,详见「四、契约约束与正确调用方式」。
2. 派单看板汇总 GET /admin/fleet/board/summary
VO: BoardOrderPageReqVO → BoardSummaryVO
使用场景
派单看板顶部的状态页签计数来源,与列表接口共用同一套筛选参数(同一入参 VO)。切换需求类别筛选时要和列表接口同步传同一个 requirementKind,否则会出现「列表条数与状态页签计数对不上」的界面表现。
入参字段表
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| requirementKind | Query | String | 否 | TRAVEL / TRANSFER;其余非空值返 100001 |
🆕 本次新增,与列表接口同名同取值、同缺省语义,两接口共用同一入参 VO BoardOrderPageReqVO |
出参字段表
| 字段 | 类型 | 说明 |
|---|---|---|
| data.statusCounts | Object | 各状态桶计数,随 requirementKind 一起收窄 |
| data.statusCounts.unassigned | Integer | 待派车状态桶计数,随 requirementKind 收窄 |
| data.statusCounts.unassignedUrgent | Integer | unassigned 的子集(加急),不是独立状态桶 |
| data.statusCounts.holding | Integer | 排车中状态桶计数,随 requirementKind 收窄 |
| data.statusCounts.holdingUrgent | Integer | holding 的子集(加急),不是独立状态桶 |
| data.statusOptions[].count | Integer | 状态下拉选项计数,随 requirementKind 一起收窄,与 statusCounts 同口径 |
| data.statusOptions[].urgentCount | Integer | 该状态下的加急子集计数 |
| data.idleVehicleCount | Integer | 空闲车辆数:全局物理资源指标,不受 requirementKind 影响 |
| data.idleDriverCount | Integer | 空闲司机数:全局物理资源指标,不受 requirementKind 影响 |
请求示例
GET /admin/fleet/board/summary?orderKind=ALL&requirementKind=TRAVEL HTTP/1.1
Host: <测试服网关>
Authorization: Bearer <token>
(GET 无请求体)
响应示例
以下为字段结构示意,statusCounts 内部逐桶数值为示意拆分(本次仅验证 requirementKind=TRAVEL 六桶之和 = 37,与列表 total=37 对齐,未逐桶记录具体读数;真实数值见「八、测试环境已验证」):
{
"code": 200,
"message": "成功",
"data": {
"statusCounts": {
"unassigned": "<示意值,六桶之和已实测=37>",
"unassignedUrgent": "<示意值,unassigned 的子集>",
"holding": "<示意值>",
"holdingUrgent": "<示意值,holding 的子集>"
},
"statusOptions": [
{ "count": "<示意值>", "urgentCount": "<示意值>" }
],
"idleVehicleCount": "<全局值,不随 requirementKind 变化>",
"idleDriverCount": "<全局值,不随 requirementKind 变化>"
},
"traceId": null,
"success": true
}
空数据 / 降级响应
本次测试窗口内 requirementKind=TRAVEL/TRANSFER 两档六桶合计均非空(37/10)。降级口径与列表接口相同:order-v3 整体不可达时 requirementKind 判定回退 TRAVEL。
错误响应
requirementKind 非法取值时与列表接口同一错误码,2026-09-29 测试服实测原文:
{
"code": 100001,
"message": "参数非法: requirementKind 仅支持 TRAVEL/TRANSFER,传入非法值:BOGUS",
"data": null,
"traceId": null,
"success": false
}
业务边界
statusCounts的unassignedUrgent/holdingUrgent是unassigned/holding的子集(statusOptions里以urgentCount出现),不是独立状态桶,前端加总统计时不要重复计入。idleVehicleCount/idleDriverCount是全局物理资源指标,切换requirementKind时这两个数字不受影响。- 切换需求类别筛选页签时,务必与列表接口同步传同一个
requirementKind,否则会出现列表条数与状态页签计数对不上的情况。 requirementKind非法取值的错误码、报文格式与列表接口完全一致。
四、契约约束与正确调用方式
requirementKind 与 orderKind 是两个互不相交的维度
| 维度 | orderKind |
requirementKind |
|---|---|---|
| 问题 | 这个订单当前属不属于某个运营团期 | 这条用车需求本身是行程用车还是接送机 |
| 取值 | ALL / NORMAL / GROUP |
TRAVEL / TRANSFER |
| 缺省 | 不传或空串 = ALL(不过滤) |
不传或空串 = 不过滤(两类都返) |
| 组合方式 | 与 requirementKind 按 AND 组合 |
同左 |
两者语义完全独立,串用不会报错,只会筛出错误的行数——例如把 requirementKind 误传成了 orderKind 的取值(如 orderKind=TRANSFER),不会命中任何非法校验(TRANSFER 不在 orderKind 枚举内,会被 orderKind 自己的校验拦成 100001),但如果误把 orderKind 的取值传给 requirementKind(如 requirementKind=GROUP),同样会被 requirementKind 自己的校验拦截,报文里的字段名与传入值都能定位到问题,不会静默放行成一个"看似合理"的过滤结果。
非法取值处理
requirementKind 非 TRAVEL/TRANSFER 且非空 → code=100001,报文格式固定为 参数非法: requirementKind 仅支持 TRAVEL/TRANSFER,传入非法值:<原始传入值>,HTTP 状态行仍是 200,判据在 body。
两接口需同步传参
GET /admin/fleet/board/orders 与 GET /admin/fleet/board/summary 共用同一入参 VO(BoardOrderPageReqVO)。切换需求类别页签时必须把 requirementKind 同时传给两个接口,否则会出现「列表 10 条、状态页签写着 47 条」这类界面对不上的情况。
五、数据库行为
本次变更的两个接口都是只读 GET,零数据库写入,不产生任何落库副作用。requirementKind 只影响查询结果的过滤范围,不改写任何行。
六、边界行为
- 真实卡与虚拟待派卡(
virtualPending=true)在requirementKind/requirementKindLabel两个新字段上一律非空——实测 47 条里 10 条虚拟待派卡两字段全部有值。 - 纯接送机订单(没有 active 行程用车需求)如实返
TRANSFER,不受「顶层requirementId恒指TRAVEL」那条既有契约影响。 - 需求类别取自卡片自身归属的那条需求,不读订单级单值字段——订单级单值字段恒取身份列表首项(两类并存时是
TRAVEL)。 - order-v3 整体不可达、取不到需求身份时,
requirementKind回退TRAVEL,与该场景下特殊诉求/备注回退快照同属既有降级口径。 requirementKind大小写敏感:只有精确的TRAVEL/TRANSFER合法。requirementKind与既有全部筛选条件(含orderKind、groupBatchId、statuses、日期、车型、consultantId、keyword)都是 AND 组合。
六.5、枚举 / 数据字典
requirementKind
所属字段: requirementKind(两个接口共用的查询参数,同名出现在列表响应的 data.records[].requirementKind) | 类型: String
| 值 | 中文标签(requirementKindLabel) |
说明 |
|---|---|---|
TRAVEL |
行程用车 | 常规行程用车需求 |
TRANSFER |
接送机 | 接送机用车需求 |
不传、传空串 = 不过滤,两类都返。其余任何取值(含大小写不符)返 100001。
六.6、修改前后对比
字段级对比
| 字段 | 改前 | 改后 |
|---|---|---|
requirementKind(两个接口的 query) |
不存在,传了被忽略 | 可选参数,TRAVEL/TRANSFER,缺省不过滤,非法值返 100001 |
data.records[].requirementKind(列表响应) |
不存在 | 🆕 新增字段,恒非空,取该卡片自身归属需求的类别 |
data.records[].requirementKindLabel(列表响应) |
不存在 | 🆕 新增字段,中文标签,与 requirementKind 恒成对非空 |
statusCounts / statusOptions[].count(汇总响应) |
不随需求类别过滤 | 随 requirementKind 一起收窄 |
行为级对比
| 行为 | 改前 | 改后 |
|---|---|---|
| 同订单行程用车+接送机并存 | 两张卡逐字段相同,前端无法分辨哪张是接送机 | 两张卡各自携带 requirementKind/requirementKindLabel,可据此区分 |
| 按需求类别筛选看板 | 不支持 | 支持 requirementKind=TRAVEL/TRANSFER 直接筛 |
传了不识别的 requirementKind |
参数不存在,被忽略 | 返 code=100001,不静默放行 |
六.7、影响评估
- 是否破坏向后兼容: 否。不传
requirementKind的旧调用行为与改前完全一致(不过滤,两类都返),响应只新增字段,不删改任何既有字段。 - 前端是否必须同步上线: 视需求而定——若要解决「同订单两张卡无法区分接送机」这个问题,需要前端读取新字段渲染区分,或使用新参数筛选;不读取新字段时界面行为与改动前完全一致,不会报错。
- 前端 workaround 清理点: 此前前端没有任何字段可用于区分两类需求;若曾用行程备注、行程日期或别的间接线索猜测哪张卡是接送机,可以改用
requirementKind精确判断。
七、不影响范围
- 仅影响:
GET /admin/fleet/board/orders与GET /admin/fleet/board/summary两个读口。 - 零影响:
orderKind维度及其既有筛选行为(本次未改动该维度任何逻辑);- 派车、改派、取消等所有写口(本次改动只涉及看板列表与汇总两个读口);
idleVehicleCount/idleDriverCount全局物理资源指标;- 小程序端全部接口(派单看板为管理后台专属能力)。
八、测试环境已验证
测试服 hl-fleet-service 已部署 dfb5db832(2026-09-29 17:48:30)。窗口 orderKind=ALL&pageSize=100 实测:
GET /admin/fleet/board/orders?orderKind=ALL&pageSize=100 → 200,基线 47 条
requirementKind 分布 {TRAVEL: 37, TRANSFER: 10}
requirementKindLabel 分布 {行程用车: 37, 接送机: 10}
两字段 47 条全部非空(含 10 条虚拟待派卡)
GET /admin/fleet/board/orders?orderKind=ALL&pageSize=100&requirementKind=TRAVEL → 200,返回 37 条,全为 TRAVEL
GET /admin/fleet/board/orders?orderKind=ALL&pageSize=100&requirementKind=TRANSFER → 200,返回 10 条,全为 TRANSFER
37 + 10 = 47(两档相加等于基线,requirementId 集合与基线完全一致)
GET /admin/fleet/board/orders?orderKind=ALL&pageSize=100&requirementKind= → 200,返回 47 条,与不传一致
GET /admin/fleet/board/orders?orderKind=ALL&pageSize=100&requirementKind=BOGUS → 200 + code 100001
GET /admin/fleet/board/summary?orderKind=ALL → 六个状态桶合计 47
GET /admin/fleet/board/summary?orderKind=ALL&requirementKind=TRAVEL → 六个状态桶合计 37
GET /admin/fleet/board/summary?orderKind=ALL&requirementKind=TRANSFER → 六个状态桶合计 10
三档与列表 total 逐一对齐(47/37/10)
同一订单出两张卡(TRAVEL + TRANSFER 并存)的订单实测 4 个,例如 2101566624467419137、2101146798373339137。
十、相关文档
- 关联 Issue: wx/HL#8518
- 关联 PR: wx/HL#8534
关联 / 联系人
链接
联系人
- 后端责任人: wx(GIT)
- 问题反馈: wx/HL Issue #8518 评论区