--- schema: "hl-changelog/v2" ticket: "8543" title: "团期订单 Tab 用车状态三处读口按需求类别拆分并统一文案" consumer: "admin" author: "wx(GIT)" change_type: "修改接口" backend_status: "deployed" gateway_status: "verified" frontend_status: "pending" frontend_owner: "" frontend_ref: "" target_release: "" verified_at: "" status_note: "PR #8592 合并 dev-v3(bc80606ac2);hl-order-service-v3 dev-v3 分支部署测试网关 @ 99fb369ba 并实测:配车芯片明细端点 items[] 按用车类别拆项、同一 orderId 出现两次(TRAVEL/TRANSFER 各一);totalCount/doneCount 由户数变为条目数(实测 5 项 3 完成,对应 3 户);子订单列表新增 vehicleRequirementKind 字段恒为 TRAVEL;文案分支待车队配/配车完成/待提交车务/待审核均已实测复现;团期列表页 chipStats.vehicle 与明细端点同步联动同一计数口径。" updated_at: "2026-09-30" base: "dev-v3" --- # hl-order-service-v3: 团期订单 Tab 用车状态三处读口按需求类别拆分并统一文案 > **存放目录**: `changelogs-v2/2026-09/` > **服务**: hl-order-service-v3 (端口 8086) > **PR**: #8592 > **Issue**: #8543 > **日期**: 2026-09-30 > **影响范围**: 团期配车芯片明细端点 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/vehicle`、团期下子订单列表端点 `GET /v3/admin/order/group-batch/{groupBatchId}/orders`;团期列表/看板端点的 `chipStats.vehicle` 计数口径联动变化(无字段新增,纯语义联动) --- ## ⚠️ 关键变化 - 🔴 **破坏性变更**:`GET .../chips/vehicle` 的 `items[]` 从**一户一项**改为**一户每类一项**——同一户同时有"行程用车"(TRAVEL)与"接送机"(TRANSFER)两类需求时,`items[]` 里会出现两条 `orderId` 相同、`kind` 不同的记录。**前端不得再按 `orderId` 去重**,去重会随机丢掉其中一类需求的状态。 - `totalCount` / `doneCount` 的口径随之从"户数"变为"条目数":一户两类需求算两条,分母跟着变大。实测团期批次 T26-3963 为例:3 户、5 条需求行,`totalCount=5`(不是 3),`doneCount=3`。 - `GroupBatchChipItemRespVO`(仅配车芯片会用到)新增 `kind`(TRAVEL/TRANSFER,可空)与 `kindName`(配对中文名,可空)两个字段;房/导/摄/约/保五个芯片的 `items[]` 里这两个字段恒为 `null`。 - `GroupBatchOrderItemRespVO`(子订单列表 `.../orders` 出参)新增 `vehicleRequirementKind` 与 `vehicleRequirementKindName` 两个字段——是新增字段不是破坏性变更。这一列**当前恒为 TRAVEL**:子订单列表每户只占一行,装不下两类需求,上游按 TRAVEL 过滤取行;要看接送机需求要走配车芯片明细(一户两类各占一项)。 - 用车状态文案本次统一(此前配车芯片明细端点的映射与子订单列表端点各写各的,现在两处一致):`PENDING`→**待车队配**、`PENDING_REVIEW` 按 `kind` 分叉(TRAVEL 出**待提交车务**、TRANSFER 出**待审核**)、`REJECTED_TO_CONSULTANT`→**已驳回定制师**、`REJECTED_TO_ADMIN`→**已驳回管理员**、`DONE`→**配车完成**。 - 该户 `needsIt=true` 但尚无任何 active 车需求行时(已声明要用车、但一行都没提交),配车芯片明细该户仍占一项,`kind`/`status` 为 `null`、`statusName` 为**未提交**(源码逻辑与 PR 说明已确认,本轮实测样本未覆盖到该分支,样本团期均已提交需求行)。 - 团期列表页(`GET /v3/admin/order/group-batch`)与看板端点每行的 `chipStats.vehicle.total`/`chipStats.vehicle.done` 与本次改动**共用同一套聚合算法**(`GroupBatchChipResolver.aggregateAll`),因此同步从"户数"变为"条目数"——实测同一团期批次两处读数逐位一致(5/3 与 3/1)。这两个端点本身**没有新增字段**,只是既有的 `total`/`done` 计数口径联动变了,前端若在列表页展示"配车 X/Y"这类徽标也要同步理解口径变化。 --- ## 二、变更接口清单 | # | 接口 | 方法 | 路径 | 变更类型 | 说明 | |---|------|------|------|----------|------| | 1 | 团期配车芯片明细 | GET | `/v3/admin/order/group-batch/{groupBatchId}/chips/vehicle` | 🔴 破坏性变更 + 字段新增 | `items[]` 按用车类别拆项,同一 `orderId` 可出现两次;新增 `kind`/`kindName`;`totalCount`/`doneCount` 语义由户数变为条目数 | | 2 | 团期下子订单列表 | GET | `/v3/admin/order/group-batch/{groupBatchId}/orders` | 字段新增 | 新增 `vehicleRequirementKind`/`vehicleRequirementKindName`(当前恒为 TRAVEL);`vehicleRequirementStatusName` 的 `PENDING_REVIEW` 文案按 `kind` 分叉 | --- ## 三、接口详情 ### 1. 团期配车芯片明细 `GET /v3/admin/order/group-batch/{groupBatchId}/chips/vehicle` **VO**: `(无请求体,仅路径参数)` → `GroupBatchChipDetailVO` #### 使用场景 车务/团期管理员在团期订单 Tab 展开"配车"芯片查看逐户用车状态明细时调用。六个芯片(房/车/导/摄/约/保)共用同一套 `GroupBatchChipDetailVO` 响应结构与六个并列端点,本条目专指配车芯片(其余五芯片本次未受影响,`kind`/`kindName` 在那五芯片下恒为 `null`)。 #### 入参字段表 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |------|------|------|------|------|------| | groupBatchId | Path | Long | ✅ | - | 团期批次 ID | #### 出参字段表 以下是本次新增/变化的字段;`GroupBatchChipDetailVO` 顶层其余字段(`chipLabel`/`aggregateStatus`/`aggregateStatusName`/`staffList`)与 `items[]` 内未变化的字段(`orderId`/`orderNo`/`teamNo`/`customerName`/`peopleCount`/`needsIt`/`claimerId`/`claimerName`/`claimerSource`/`updateTime`/`staffs`)结构未变,不重复列出。 | 字段 | 类型 | 说明 | |------|------|------| | totalCount | Integer | 🔴 语义变化:改前是"计入统计的户数",改后是"条目数"(一户两类需求算两条) | | doneCount | Integer | 🔴 语义变化:口径随 `totalCount` 同步改为条目数 | | items[] | List | 🔴 数组长度语义变化:一户两类需求时占两个元素,`orderId` 相同 | | items[].kind | String,可空 | 新增:用车类别(`TRAVEL` 行程用车 / `TRANSFER` 接送机);该户尚无任何 active 车需求行时为 `null`(此时该户仍占一项,`status` 为 `null`,`statusName` 为"未提交");房/导/摄/约/保五芯片恒为 `null` | | items[].kindName | String,可空 | 新增:`kind` 配对中文名(行程用车/接送机);`kind` 为 `null` 或枚举外未知码时为 `null`——编码不回落当中文展示 | | items[].statusName | String,可空 | 文案统一:`PENDING`→待车队配、`PENDING_REVIEW` 按 `kind` 分叉(TRAVEL→待提交车务,TRANSFER→待审核)、`REJECTED_TO_CONSULTANT`→已驳回定制师、`REJECTED_TO_ADMIN`→已驳回管理员、`DONE`→配车完成 | #### 请求示例 ```http GET /v3/admin/order/group-batch/2104839654727618562/chips/vehicle ``` #### 响应示例 真实实测(团期批次 T26-3963,3 户 5 项,含同一 `orderId` 两类需求各占一项): ```json {"code":200,"message":"成功","data":{"batchId":"2104839654727618562","groupBatchId":"2104839654727618562","chipLabel":"配车","aggregateStatus":"DOING","aggregateStatusName":"进行中","totalCount":5,"doneCount":3,"staffList":null,"items":[{"orderId":"2104839654652121090","orderNo":"HL20260929154414207","teamNo":"26-2313","contactName":"李文博","customerName":"李文博","peopleCount":2,"status":"DONE","statusText":"配车完成","statusName":"配车完成","needsIt":true,"kind":"TRAVEL","kindName":"行程用车","updateTime":null,"claimerId":null,"claimerName":null,"claimerSource":null,"staffs":null},{"orderId":"2104839654652121090","orderNo":"HL20260929154414207","teamNo":"26-2313","contactName":"李文博","customerName":"李文博","peopleCount":2,"status":"PENDING","statusText":"待车队配","statusName":"待车队配","needsIt":true,"kind":"TRANSFER","kindName":"接送机","updateTime":null,"claimerId":null,"claimerName":null,"claimerSource":null,"staffs":null},{"orderId":"2104839686486888449","orderNo":"HL20260929154421828","teamNo":"26-9436","contactName":"张丽娟","customerName":"张丽娟","peopleCount":2,"status":"DONE","statusText":"配车完成","statusName":"配车完成","needsIt":true,"kind":"TRAVEL","kindName":"行程用车","updateTime":null,"claimerId":null,"claimerName":null,"claimerSource":null,"staffs":null},{"orderId":"2104839729176514562","orderNo":"HL20260929154432061","teamNo":"26-6559","contactName":"那顺","customerName":"那顺","peopleCount":3,"status":"DONE","statusText":"配车完成","statusName":"配车完成","needsIt":true,"kind":"TRAVEL","kindName":"行程用车","updateTime":null,"claimerId":null,"claimerName":null,"claimerSource":null,"staffs":null},{"orderId":"2104839729176514562","orderNo":"HL20260929154432061","teamNo":"26-6559","contactName":"那顺","customerName":"那顺","peopleCount":3,"status":"PENDING_REVIEW","statusText":"待审核","statusName":"待审核","needsIt":true,"kind":"TRANSFER","kindName":"接送机","updateTime":null,"claimerId":null,"claimerName":null,"claimerSource":null,"staffs":null}]},"traceId":null,"success":true} ``` 另一团期批次(T26-6001,含"待提交车务"文案分支,TRAVEL 类 `PENDING_REVIEW`)实测节选: ```json {"orderId":"2104840685708525570","orderNo":"HL20260929154820126","teamNo":"26-0805","contactName":"谢丽萍","customerName":"谢丽萍","peopleCount":2,"status":"PENDING_REVIEW","statusText":"待提交车务","statusName":"待提交车务","needsIt":true,"kind":"TRAVEL","kindName":"行程用车","updateTime":null,"claimerId":null,"claimerName":null,"claimerSource":null,"staffs":null} ``` #### 空数据 / 降级响应 - 团期批次不存在:返回业务错误(见"错误响应"),`data` 为 `null`。 - 团期下暂无子订单:`items` 为空数组,`totalCount`/`doneCount` 均为 `0`。 - 户已声明要用车(`needs_vehicle=true`)但尚未提交任何车需求行:该户仍占一项,`kind`/`status` 为 `null`,`statusName` 为"未提交"(源码逻辑已确认,本轮实测样本未覆盖到该分支)。 #### 错误响应 ```json {"code":589500,"message":"团期不存在","data":null,"traceId":null,"success":false} ``` #### 业务边界 - 🔴 `items[]` 按 `orderId` 去重是错误用法——同一户两类需求会被拆成两个数组元素,去重会随机丢掉其中一类的状态展示。 - `totalCount`/`doneCount` 不再等于该团期的户数,若页面上另有独立的"户数"展示(如团期基础信息),不要复用这两个字段去推导户数。 - `kind`/`kindName` 只在配车芯片有意义,其余五芯片(房/导/摄/约/保)该字段恒为 `null`,前端渲染这五个芯片时不需要处理 `kind` 分支。 - `statusName` 的四个文案改动是全量替换(不是新增枚举值),旧文案(待车务配/驳回给定制师/驳回给管理员)不会再出现,前端若按旧文案字符串做过特殊判断需要同步更新。 ### 2. 团期下子订单列表 `GET /v3/admin/order/group-batch/{groupBatchId}/orders` **VO**: `(无请求体,Path + Query 参数)` → `PageResult` #### 使用场景 团期订单 Tab 展示子订单摘要列表(客户姓名、各状态列、支付/结算信息)时调用,是该 Tab 的主表格数据源。 #### 入参字段表 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |------|------|------|------|------|------| | groupBatchId | Path | Long | ✅ | - | 团期 ID | | page | Query | Integer | ❌ | 缺省 1,<1 归一为 1 | 页码,从 1 起 | | pageSize | Query | Integer | ❌ | 缺省 20,<1 归一为 20,>200 截断为 200 | 每页条数 | | includeTravelers | Query | Boolean | ❌ | 缺省 true | 是否附出行人明细(证件号/手机号一律不返回),本次未变 | | includeNeeds | Query | Boolean | ❌ | 缺省 true | 是否附房数/房型/特殊需求,本次未变 | | includeCancelled | Query | Boolean | ❌ | 缺省 false | 是否含已取消子订单,本次未变 | #### 出参字段表 以下只列本次新增/变化的字段;`GroupBatchOrderItemRespVO` 其余既有字段(`orderId`/`customerName`/各状态码与状态中文名/金额字段/`travelers` 等)结构未变,不重复列出。 | 字段 | 类型 | 说明 | |------|------|------| | vehicleRequirementKind | String,可空 | 新增:本行车需求的用车类别(`TRAVEL`/`TRANSFER`)。**当前恒为 `TRAVEL`**——子订单列表每户只占一行,装不下两类,上游按 TRAVEL 过滤取行;接送机需求要看配车芯片明细(`.../chips/vehicle`,一户两类各占一项)。无 active 车需求行时为 `null`,与 `vehicleRequirementStatus` 同生同灭 | | vehicleRequirementKindName | String,可空 | 新增:`vehicleRequirementKind` 配对中文名(行程用车/接送机);枚举外未知码不回落编码,直接给 `null` | | vehicleRequirementStatusName | String,可空 | 既有字段,文案口径调整:`PENDING_REVIEW` 的措辞随同行的 `vehicleRequirementKind` 分叉——TRAVEL 下发"待提交车务"(该状态上没有逐户审核动作,推走它的是团期管理员整团一次的"提交车务"),TRANSFER 下发"待审核";由于本字段随行的 `vehicleRequirementKind` 当前恒为 TRAVEL,本端点实际只会出现"待提交车务"这一支 | #### 请求示例 ```http GET /v3/admin/order/group-batch/2104839654727618562/orders?page=1&pageSize=20 ``` #### 响应示例 真实实测(团期批次 T26-3963,节选第 1 条完整记录): ```json {"code":200,"message":"成功","data":{"records":[{"orderId":"2104839654652121090","orderNo":"HL20260929154414207","teamNo":"26-2313","customerName":"李文博","participantCount":2,"orderStatus":"CUSTOMIZING","orderStatusName":"定制中","flowStatus":"RESOURCE_PREPARING","flowStatusName":"资源准备","reviewStatus":null,"reviewStatusName":null,"settlementStatus":"NONE","settlementStatusName":"未结算","payStatus":"FULLY_PAID","payStatusName":"已付全款","contractStatus":null,"contractStatusName":null,"insuranceStatus":null,"insuranceStatusName":null,"paidAmount":"7360.00","balanceAmount":"0.00","hotelRequirementStatus":null,"hotelRequirementStatusName":null,"vehicleRequirementStatus":"DONE","vehicleRequirementStatusName":"配车完成","vehicleRequirementKind":"TRAVEL","vehicleRequirementKindName":"行程用车","consultantName":"cw_test_7443","totalPrice":"7360.00","tierCode":"2A","tierName":"2成人","travelerInfoComplete":true,"roomCount":1,"roomType":null,"roomTypeName":null,"specialNeeds":"夫妻同行,携带摄影器材较多,需预留后备箱空间","contactPhone":"138****3046","groupChatUnreadCount":0,"travelers":[{"name":"李文博","type":"ADULT","age":46,"birthdayInTrip":false},{"name":"赵梦琪","type":"ADULT","age":43,"birthdayInTrip":false}]}],"total":3,"page":1,"pageSize":20},"traceId":null,"success":true} ``` #### 空数据 / 降级响应 - 团期批次不存在:返回业务错误(见"错误响应")。 - 团期下暂无子订单(或 `includeCancelled=false` 时全部已取消):`records` 为空数组,`total=0`。 - 该户无 active 车需求行:`vehicleRequirementStatus`/`vehicleRequirementKind` 均为 `null`;`vehicleRequirementStatusName`/`vehicleRequirementKindName` 按该户 `needsVehicle` 分叉——`true` 出"未提交",否则为 `null`。 #### 错误响应 ```json {"code":589500,"message":"团期不存在","data":null,"traceId":null,"success":false} ``` #### 业务边界 - `vehicleRequirementKind` 在本端点当前恒为 `TRAVEL`,不能据此推断"该团期没有接送机需求"——接送机需求存在与否要看配车芯片明细端点。 - `vehicleRequirementStatusName` 的 `PENDING_REVIEW` 分支文案取决于 `vehicleRequirementKind`,但本端点该列恒为 TRAVEL,因此实际只会看到"待提交车务",不会看到"待审核"(后者只出现在配车芯片明细的 TRANSFER 项上)。 - 无 active 车需求行时 `vehicleRequirementStatus` 为 `null` 不回落 `PENDING`(#8249 起既有行为,本次未变)——`PENDING` 是需求行的真实状态之一,没有行时借用它会与"未提交"矛盾。 --- ## 四、契约约束与正确调用方式 > 本节只写后端接受/拒绝的规则与语义边界,不写 UI 渲染建议。 ### ✅ 正确 / ❌ 错误 payload 对照 | 场景 | payload / 响应 | |------|-----------------| | ✅ 渲染配车芯片明细列表 | 按数组下标或 `orderId`+`kind` 复合键渲染每一项,允许同一 `orderId` 出现多行 | | ✅ 展示配车芯片"已完成 N/M" | 直接用 `doneCount`/`totalCount`,两者已经是同一口径(条目数),无需自行按户去重再算 | | ❌ 用 `items[].orderId` 做 `Map` 的 key 或做 `Set` 去重 | 一户两类需求时后写入的会覆盖/顶掉先写入的那一条,界面上会静默丢失一类需求的状态 | | ❌ 用子订单列表的 `vehicleRequirementKind` 判断该团期是否存在接送机需求 | 该列当前恒为 TRAVEL,对接送机需求零分辨力;接送机需求判断要调配车芯片明细 | ### 切换状态时的必要动作 前端如果此前在配车芯片渲染层用 `orderId` 做过 `key`/去重/索引,本次上线前必须改为 `orderId + kind` 复合键;否则界面在两类需求并存的户上会稳定丢失一类需求的展示,且是静默丢失(不报错)。 --- ## 五、数据库行为 两个端点均为只读查询,无数据库写操作。配车芯片明细与子订单列表内部均从 `order_vehicle_requirement`(车需求行表)按 `order_id` 聚合取最新一版需求行,`kind` 直接取自需求行的 `requirement_kind` 列,不做兜底改写;历史行 `requirement_kind` 为 `NULL` 时 `kind`/`kindName` 原样透出 `null`,不会被兜底成 `TRAVEL`。 --- ## 六、边界行为 - 户尚未提交任何车需求行、但已声明要用车(`needs_vehicle=true`)→ 配车芯片该户仍占一项,`kind`/`status` 为 `null`,`statusName`="未提交" - 户完全不需要用车(`needs_vehicle=false`)→ 该户在配车芯片 `items[]` 中不出现 - 户同时有 TRAVEL 与 TRANSFER 两类 active 需求行 → 配车芯片占两项,`orderId` 相同、`kind` 不同 - 户只有一类需求行 → 配车芯片只占一项,不会补一个空的另一类占位项 - 需求行历史 `requirement_kind` 为 `NULL` → `kind`/`kindName` 原样为 `null`,不兜底为 `TRAVEL` - 子订单列表 `.../orders` 每户恒只出一行、按 TRAVEL 过滤取需求行,不受该户是否有 TRANSFER 需求影响 --- ## 六.5、枚举 / 数据字典 ### 用车类别(`VehicleRequirementKind`,`items[].kind` / `vehicleRequirementKind`) **所属字段**: `GroupBatchChipItemRespVO.kind`、`GroupBatchOrderItemRespVO.vehicleRequirementKind` | **类型**: `String` | 值 | 中文 | 本次是否新增 | 说明 | |----|------|------|------| | `TRAVEL` | 行程用车 | 既有枚举值,本次新增到这两个字段 | 团期行程内的用车安排 | | `TRANSFER` | 接送机 | 既有枚举值,本次新增到这两个字段 | 接送机场/车站,独立于行程用车 | | `null` | (无展示) | - | 该户尚无 active 车需求行时的状态,不是第三个枚举值 | ### 车需求状态中文名(`statusName` / `vehicleRequirementStatusName`,`PENDING_REVIEW` 按 `kind` 分叉) **所属字段**: `items[].statusName`(配车芯片)、`vehicleRequirementStatusName`(子订单列表) | **类型**: `String` | 状态码 | 中文(本次前) | 中文(本次后) | 说明 | |--------|----------------|----------------|------| | `PENDING` | 待车务配(仅配车芯片明细,子订单列表原已是"待车队配") | 待车队配 | 两处读口统一为同一文案 | | `PROCESSING` | 配车中 | 配车中 | 未变 | | `DONE` | 配车完成 | 配车完成 | 未变 | | `PENDING_REVIEW`(TRAVEL) | 待审核(配车芯片明细此前不分类别) | 待提交车务 | 按 `kind` 新分叉 | | `PENDING_REVIEW`(TRANSFER) | 待审核 | 待审核 | 未变(新分叉后仍是这个文案) | | `REJECTED_TO_CONSULTANT` | 驳回给定制师(仅配车芯片明细) | 已驳回定制师 | 两处读口统一为同一文案 | | `REJECTED_TO_ADMIN` | 驳回给管理员(仅配车芯片明细) | 已驳回管理员 | 两处读口统一为同一文案 | | `null`(有需求但未提交) | 待审核(配车芯片明细此前误落到这一支) | 未提交 | 修正误报——"未提交"与"已提交等审核"是两个不同状态,此前混在一起 | ## 六.6、修改前后对比 ### 字段级对比 | 字段 | 改前 | 改后 | |------|------|------| | `GroupBatchChipItemRespVO.kind` | 不存在 | 新增,`String`,可空,仅配车芯片有值,其余五芯片恒 `null` | | `GroupBatchChipItemRespVO.kindName` | 不存在 | 新增,`String`,可空 | | `GroupBatchChipDetailVO.totalCount`(配车芯片) | 户数 | 条目数(一户两类算两条) | | `GroupBatchChipDetailVO.doneCount`(配车芯片) | 已完成户数 | 已完成条目数 | | `GroupBatchChipDetailVO.items[]`(配车芯片) | 一户一项 | 一户每类一项,`orderId` 可重复 | | `GroupBatchOrderItemRespVO.vehicleRequirementKind` | 不存在 | 新增,`String`,可空,当前恒为 `TRAVEL` | | `GroupBatchOrderItemRespVO.vehicleRequirementKindName` | 不存在 | 新增,`String`,可空 | | 团期列表/看板 `chipStats.vehicle.total`/`.done` | 户数 | 条目数(共用配车芯片同一聚合算法,联动变化,字段本身未新增) | ### 行为级对比 | 场景 | 改前 | 改后 | |------|------|------| | 户同时有 TRAVEL + TRANSFER 需求 | 配车芯片只显示其中一类,另一类无声消失 | 两类各占一项,均可见 | | 户已声明用车但未提交需求行 | 落到"待审核",看起来像已提交 | 落到"未提交",与已提交待审核区分开 | | `PENDING_REVIEW` 状态文案 | 配车芯片明细恒显示"待审核";子订单列表已按 kind 分叉(源于 #8218) | 配车芯片明细与子订单列表口径统一,均按 kind 分叉 | | 配车芯片 `PENDING`/`REJECTED_TO_CONSULTANT`/`REJECTED_TO_ADMIN` 文案 | 待车务配/驳回给定制师/驳回给管理员 | 待车队配/已驳回定制师/已驳回管理员 | | 配车芯片 `totalCount`/`doneCount` 与列表页 `chipStats.vehicle` 关系 | 两处各自独立计算,可能不一致 | 共用同一聚合算法,逐位一致 | ## 六.7、影响评估 - **是否破坏向后兼容**: 是——`.../chips/vehicle` 的 `items[]` 数组长度与 `orderId` 唯一性假设改变,任何按 `orderId` 做 key/去重/索引的前端代码都会在两类需求并存的户上产生数据丢失;`totalCount`/`doneCount` 数值口径也变了,若前端拿它们除以户数算百分比会得到错误结果。 - **前端是否必须同步上线**: 是(针对配车芯片展示场景)——只要页面渲染配车芯片明细,就必须按 `orderId+kind` 复合键处理 `items[]`;子订单列表的两个新字段是纯新增,不改也不会报错,但不展示就拿不到用车类别信息。 - **前端 workaround 清理点**: 若此前为"同一户两类需求显示不全/互相覆盖"这类现象写过特殊兼容或只取第一条的逻辑,现在后端已按类别拆项,可以确认不再需要。 --- ## 七、不影响范围 - **仅影响**: 配车芯片明细端点 `GET .../chips/vehicle` 的 `items[]` 结构与 `totalCount`/`doneCount` 语义;子订单列表端点 `GET .../orders` 新增两个字段;团期列表/看板端点 `chipStats.vehicle` 的计数口径(字段本身未变)。 - **零影响**: - 房/导/摄/约/保五个芯片明细端点(`GET .../chips/{hotel|guide|photo|contract|insurance}`)的字段结构与计数口径 - 团期下子订单列表其余既有字段(金额、支付、结算、房需求等) - 户级用车需求明细端点 `GET .../requirement/vehicle-households`(本次为纯内部代码去重,零响应契约变化,见下方"八、测试环境已验证"说明) - 配车需求本身的写口(提交/确认/驳回等)不受本次改动影响 --- ## 八、测试环境已验证 服务:`hl-order-service-v3`,dev-v3 分支部署测试网关 @ `99fb369ba`(含 #8543 所在提交 `bc80606ac2`),测试网关 `https://api.test.1814.love`;样本均为测试服现存真实业务数据: ``` ✓ 团期批次 T26-3963(groupBatchId=2104839654727618562,3 户): GET .../chips/vehicle → totalCount=5 doneCount=3 李文博(orderId=2104839654652121090):TRAVEL/DONE/配车完成 + TRANSFER/PENDING/待车队配(同一 orderId 两项) 那顺(orderId=2104839729176514562):TRAVEL/DONE/配车完成 + TRANSFER/PENDING_REVIEW/待审核(同一 orderId 两项) 张丽娟(orderId=2104839686486888449):仅 TRAVEL/DONE/配车完成(一项) GET .../orders → 3 条记录,vehicleRequirementKind 均为 "TRAVEL"(与源码"本列当前恒为 TRAVEL"一致) ✓ 团期批次 T26-6001(groupBatchId=2104840641651556353,3 户): GET .../chips/vehicle → totalCount=3 doneCount=1 董海涛:TRAVEL/DONE/配车完成 + TRANSFER/PENDING/待车队配 谢丽萍:TRAVEL/PENDING_REVIEW/待提交车务(复现"待提交车务"文案分支) ✓ 团期列表页 GET /v3/admin/order/group-batch 逐页扫描,同两个 groupBatchId 的 chipStats.vehicle: {total:5, done:3} 与 {total:3, done:1},与明细端点 totalCount/doneCount 逐位一致(重复请求 5 次读数稳定) ✓ 错误响应:不存在的 groupBatchId → 两端点均返回 {"code":589500,"message":"团期不存在"} ``` 注:`kind=null`(户已声明用车但未提交需求行,`statusName`="未提交")与配车芯片明细的 `REJECTED_TO_CONSULTANT`/`REJECTED_TO_ADMIN` 两个文案分支,本轮实测样本团期未覆盖到(样本户均已提交需求行且未被驳回);这三个分支的契约已在源码逐一核实(`GroupBatchChipResolver.vehicleItemsOf`、`GroupBatchConverter.resolveRequirementStatusName`),前端应按此契约实现,不依赖本轮是否观测到该取值。 --- ## 十、相关文档 - 关联 Issue: [wx/HL#8543](https://git.1814.love/wx/HL/issues/8543) - 关联 PR: [wx/HL#8592](https://git.1814.love/wx/HL/pulls/8592) ## 关联 / 联系人 ### 链接 - **Issue**: [#8543](https://git.1814.love/wx/HL/issues/8543) - **PR**: [#8592](https://git.1814.love/wx/HL/pulls/8592) - **Merge commit**: [bc80606ac2](https://git.1814.love/wx/HL/commit/bc80606ac2) ### 联系人 - **后端负责人**: @wx