docs(changelog): #8619 团期子订单列表——只报接送机的户不再判未提交
changelog-filename-gate / validate (push) Failing after 2s
changelog-filename-gate / validate (push) Failing after 2s
GET /v3/admin/order/group-batch/{groupBatchId}/orders:
- requirementStatus/requirementStatusName 放宽取值范围(纯接送机户不再恒为「未提交」)
- 新增 vehicleRequirements[] 逐类用车需求清单(TRAVEL 在前、TRANSFER 在后)
Refs #8619
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
这个提交包含在:
@@ -0,0 +1,405 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "8619"
|
||||
title: "团期子订单列表:只报接送机的户不再判未提交,新增逐类用车需求清单字段"
|
||||
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 #8624 已 squash 合并 dev-v3(ce7cd238e9355bdc17c45f90ace02827c7db60f5),hl-order-service-v3 dev-v3 分支已滚测试服。GET /v3/admin/order/group-batch/{groupBatchId}/orders 对真实团期 2104839654727618562 实测:同户 TRAVEL+TRANSFER 两类需求状态互不覆盖、vehicleRequirements[] 按 TRAVEL 在前 TRANSFER 在后下发,589500 团期不存在错误码实测通过。所有既有字段未删改,只放宽了车需求那组字段的取值范围并新增 vehicleRequirements。"
|
||||
updated_at: "2026-09-30"
|
||||
base: "dev-v3"
|
||||
---
|
||||
|
||||
> **存放目录**: `changelogs-v2/2026-09/`
|
||||
> **服务**: hl-order-service-v3 (端口 8086)
|
||||
> **PR**: #8624
|
||||
> **Issue**: #8619
|
||||
> **日期**: 2026-09-30
|
||||
> **影响范围**: 管理后台团期详情页「子订单列表」/ A3 接口消费方
|
||||
|
||||
## ⚠️ 关键变化
|
||||
|
||||
- **改前**:`GET /v3/admin/order/group-batch/{groupBatchId}/orders` 的车需求四个单值字段(`vehicleRequirementStatus`/`StatusName`/`Kind`/`KindName`)只从该户 **TRAVEL(行程用车)** 类需求行取值。若一个户只提交了 **TRANSFER(接送机)** 需求、没有 TRAVEL 需求,这四个字段恒被渲染成「未提交」,即使接送机需求已经在流转甚至已完成。
|
||||
- **改后**:改为按展示序(TRAVEL 优先于 TRANSFER)取该户**当前活跃需求行中的首条**,只提交接送机的户会如实报出接送机自己的状态,不再被误判未提交。
|
||||
- **新增字段 `vehicleRequirements`**:`GroupBatchOrderItemRespVO` 新增该数组字段,逐类列出该户全部活跃车需求行(TRAVEL 在前、TRANSFER 在后),每类各自独立的 `kind`/`kindName`/`status`/`statusName`,不再只能看到"展示序首条"这一个值。该户没有任何活跃车需求行时数组是 `[]`(空数组),不是 `null`。
|
||||
- **`vehicleRequirementKind` 不再恒为 `"TRAVEL"`**:只提交接送机的户,该字段与 `vehicleRequirementKindName` 现在会如实报出 `"TRANSFER"`/`"接送机"`。前端如果曾经硬编码假设这两个字段只会是 TRAVEL/行程用车,需要一并放开。
|
||||
- 其余约 25 个既有字段(订单状态、支付状态、酒店需求、出行人等)取值逻辑未变。
|
||||
|
||||
## 一、背景(选填)
|
||||
|
||||
本单与已发布的 `changelogs-v2/2026-09/30_8577_...-修改接口-管理后台.md`(#8577)修的是**同一症状家族**(只提交接送机被误判"未提交"),但**改动的是完全不同的接口/代码路径**,请勿混淆:
|
||||
|
||||
| | #8577 | #8619(本单) |
|
||||
|---|---|---|
|
||||
| 涉及接口 | `PUT` 保存车需求、`GET` 聚合草稿、`GET` 提交前校验(均在 `GroupVehicleRequirementService`) | `GET /v3/admin/order/group-batch/{groupBatchId}/orders`(团期子订单列表,`GroupBatchQueryService`/`GroupBatchConverter`) |
|
||||
| 涉及错误码 | 809121/809122/809123 | 不涉及新增/变更错误码,沿用既有 589500 |
|
||||
| 根因层 | 提交/校验链路 | 列表查询的取值范围(原只查 TRAVEL 类活跃行) |
|
||||
|
||||
两单互不覆盖,`#8577` 的改动对本接口没有影响;本接口过去存在的误判问题,`#8577` 也没有修到。
|
||||
|
||||
## 二、变更接口清单
|
||||
|
||||
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||
|---|------|------|------|----------|------|
|
||||
| 1 | 团期下子订单列表(A3) | GET | `/v3/admin/order/group-batch/{groupBatchId}/orders` | 响应字段语义收窄 + 新增字段 | `vehicleRequirementKind` 不再恒为 TRAVEL;新增 `vehicleRequirements[]` 逐类需求清单 |
|
||||
|
||||
## 三、接口详情
|
||||
|
||||
### 1. 团期下子订单列表 `GET /v3/admin/order/group-batch/{groupBatchId}/orders`
|
||||
|
||||
**VO**: `GroupBatchOrderItemRespVO`
|
||||
|
||||
#### 使用场景
|
||||
|
||||
管理后台团期详情页展示该团期下全部子订单(一个订单=一个"户")的汇总信息,含车需求配车状态一栏。前端据此渲染列表行的车需求状态标签,并可能据 `vehicleRequirementKind` 决定展示"行程用车"或"接送机"图标。
|
||||
|
||||
#### 入参
|
||||
|
||||
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||
|------|------|------|------|------|------|
|
||||
| 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 | 是否附 roomCount/roomType/specialNeeds |
|
||||
| includeCancelled | query | Boolean | 否 | 缺省 false | 是否含已取消子订单(缺省只返活跃集) |
|
||||
|
||||
#### 出参 `Result<PageResult<GroupBatchOrderItemRespVO>>`
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| orderId | String | 订单ID(Long 序列化为字符串) |
|
||||
| orderNo | String | 订单号 |
|
||||
| teamNo | String | 团号;订金支付成功后生成,未付订金为 null |
|
||||
| customerName | String | 客户姓名 |
|
||||
| participantCount | Integer | 出行人数 |
|
||||
| orderStatus / orderStatusName | String / String | 订单状态/名称 |
|
||||
| flowStatus / flowStatusName | String / String | 流程状态/名称(12 值枚举) |
|
||||
| reviewStatus / reviewStatusName | String / String | 复核状态/名称;⚠️ 与团期核单 `GroupSettlementRespVO` 同名字段含义相反 |
|
||||
| settlementStatus / settlementStatusName | String / String | 结算状态/名称;⚠️ 同样与团期核单含义相反,也不是财务 tab 的 settleStatus |
|
||||
| payStatus / payStatusName | String / String | 支付状态/名称 |
|
||||
| contractStatus / contractStatusName | String / String | 合同状态/名称 |
|
||||
| insuranceStatus / insuranceStatusName | String / String | 投保状态/名称 |
|
||||
| paidAmount / balanceAmount | String / String | 已付金额/待付余额(BigDecimal 序列化为字符串) |
|
||||
| hotelRequirementStatus / hotelRequirementStatusName | String / String | 酒店需求状态/名称;#8249 起无活跃行时为 null,不回落 PENDING |
|
||||
| **vehicleRequirementStatus** | String | 车需求状态;**本单起**取该户展示序(TRAVEL 优先)首条活跃需求行的状态,不再恒来自 TRAVEL |
|
||||
| **vehicleRequirementStatusName** | String | 车需求状态名;PENDING_REVIEW 按 kind 分叉:TRAVEL="待提交车务",TRANSFER="待审核";"未提交"现在只在该户两类需求行都不存在时才出现 |
|
||||
| **vehicleRequirementKind** | String | 车需求类别;**本单起不再恒为 "TRAVEL"**,只提交接送机的户会报 "TRANSFER" |
|
||||
| **vehicleRequirementKindName** | String | 车需求类别名;未知类别给 null,不回落编码 |
|
||||
| **vehicleRequirements** | Array<VehicleRequirementItem> | **本单新增**。该户全部活跃车需求行,TRAVEL 在前、TRANSFER 在后;一条都没有时为 `[]`(非 null) |
|
||||
| consultantName | String | 顾问姓名 |
|
||||
| totalPrice | String | 订单总价 |
|
||||
| tierCode / tierName | String / String | 价格档位编码/名称 |
|
||||
| travelerInfoComplete | Boolean | 出行人信息是否完整 |
|
||||
| roomCount | Integer | 房间数;`includeNeeds=true` 时返回 |
|
||||
| roomType / roomTypeName | String / String | 房型编码/名称;`includeNeeds=true` 时返回 |
|
||||
| specialNeeds | String | 特殊需求;`includeNeeds=true` 时返回 |
|
||||
| contactPhone | String | 联系电话(脱敏,如 `138****3046`) |
|
||||
| groupChatUnreadCount | Integer | 群聊未读数;user-service 不可达/Feign 超时/未登录时降级为 0 |
|
||||
| travelers | Array<TravelerItemVO> | 出行人明细;`includeTravelers=true` 时返回 |
|
||||
|
||||
`VehicleRequirementItem`(`vehicleRequirements` 数组元素):
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| kind | String | 需求类别,TRAVEL / TRANSFER |
|
||||
| kindName | String | 类别名,"行程用车" / "接送机" |
|
||||
| status | String | 该类需求自己的状态(见六.5 枚举) |
|
||||
| statusName | String | 状态名(PENDING_REVIEW 按 kind 分叉,见上) |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
GET /v3/admin/order/group-batch/2104839654727618562/orders?page=1&pageSize=5&includeTravelers=false&includeNeeds=false
|
||||
Authorization: Bearer {token}
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
测试服真实返回(团期 `2104839654727618562`,3 个子订单,覆盖"两类需求并存且状态不同""仅 TRAVEL"两种场景):
|
||||
|
||||
```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": "行程用车",
|
||||
"vehicleRequirements": [
|
||||
{"kind": "TRAVEL", "kindName": "行程用车", "status": "DONE", "statusName": "配车完成"},
|
||||
{"kind": "TRANSFER", "kindName": "接送机", "status": "PENDING", "statusName": "待车队配"}
|
||||
],
|
||||
"consultantName": "cw_test_7443",
|
||||
"totalPrice": "7360.00",
|
||||
"tierCode": "2A",
|
||||
"tierName": "2成人",
|
||||
"travelerInfoComplete": true,
|
||||
"roomCount": null,
|
||||
"roomType": null,
|
||||
"roomTypeName": null,
|
||||
"specialNeeds": null,
|
||||
"contactPhone": "138****3046",
|
||||
"groupChatUnreadCount": 0,
|
||||
"travelers": null
|
||||
},
|
||||
{
|
||||
"orderId": "2104839686486888449",
|
||||
"orderNo": "HL20260929154421828",
|
||||
"teamNo": "26-9436",
|
||||
"customerName": "张丽娟",
|
||||
"participantCount": 2,
|
||||
"orderStatus": "CUSTOMIZING",
|
||||
"orderStatusName": "定制中",
|
||||
"flowStatus": "PENDING_CONFIRM",
|
||||
"flowStatusName": "待确认",
|
||||
"payStatus": "FULLY_PAID",
|
||||
"payStatusName": "已付全款",
|
||||
"paidAmount": "7360.00",
|
||||
"balanceAmount": "0.00",
|
||||
"vehicleRequirementStatus": "DONE",
|
||||
"vehicleRequirementStatusName": "配车完成",
|
||||
"vehicleRequirementKind": "TRAVEL",
|
||||
"vehicleRequirementKindName": "行程用车",
|
||||
"vehicleRequirements": [
|
||||
{"kind": "TRAVEL", "kindName": "行程用车", "status": "DONE", "statusName": "配车完成"}
|
||||
],
|
||||
"totalPrice": "7360.00",
|
||||
"tierCode": "2A",
|
||||
"tierName": "2成人",
|
||||
"contactPhone": "138****3047",
|
||||
"groupChatUnreadCount": 0
|
||||
},
|
||||
{
|
||||
"orderId": "2104839729176514562",
|
||||
"orderNo": "HL20260929154432061",
|
||||
"teamNo": "26-6559",
|
||||
"customerName": "那顺",
|
||||
"participantCount": 3,
|
||||
"orderStatus": "CUSTOMIZING",
|
||||
"orderStatusName": "定制中",
|
||||
"flowStatus": "PENDING_CONFIRM",
|
||||
"flowStatusName": "待确认",
|
||||
"payStatus": "FULLY_PAID",
|
||||
"payStatusName": "已付全款",
|
||||
"paidAmount": "11620.00",
|
||||
"balanceAmount": "0.00",
|
||||
"vehicleRequirementStatus": "DONE",
|
||||
"vehicleRequirementStatusName": "配车完成",
|
||||
"vehicleRequirementKind": "TRAVEL",
|
||||
"vehicleRequirementKindName": "行程用车",
|
||||
"vehicleRequirements": [
|
||||
{"kind": "TRAVEL", "kindName": "行程用车", "status": "DONE", "statusName": "配车完成"},
|
||||
{"kind": "TRANSFER", "kindName": "接送机", "status": "PENDING_REVIEW", "statusName": "待审核"}
|
||||
],
|
||||
"totalPrice": "11620.00",
|
||||
"tierCode": "3A",
|
||||
"tierName": "3成人",
|
||||
"contactPhone": "138****3048",
|
||||
"groupChatUnreadCount": 0
|
||||
}
|
||||
],
|
||||
"total": 3,
|
||||
"page": 1,
|
||||
"pageSize": 5
|
||||
},
|
||||
"traceId": null,
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
以上三条均取自 TRAVEL+TRANSFER 两类需求并存的户,展示了两类需求各自独立取值(第三条 TRANSFER 处于 `PENDING_REVIEW` 显示为"待审核",TRAVEL 处于 `DONE` 不受影响)。**只提交接送机、完全没有 TRAVEL 需求**的户是本次修复要解决的核心场景,测试服当前团期数据中暂无这类现成样本(该形态的订单目前都不挂团期),该场景由自动化回归覆盖,见"八、测试环境已验证"。
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
分页越界的真实返回(`page=999` 超出总页数):
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": {
|
||||
"records": [],
|
||||
"total": 3,
|
||||
"page": 999,
|
||||
"pageSize": 5
|
||||
},
|
||||
"traceId": null,
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
`groupChatUnreadCount` 在 user-service 不可达、Feign 调用超时或当前登录态失效时降级返回 `0`,不抛错、不影响本接口其余字段。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
团期不存在的真实返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 589500,
|
||||
"message": "团期不存在",
|
||||
"data": null,
|
||||
"traceId": null,
|
||||
"success": false
|
||||
}
|
||||
```
|
||||
|
||||
无操作权限时返回错误码 `589507`("无操作权限(当前角色未授予团期权限,或该团期不在您名下)",源自 `GroupBatchErrorCode`,本轮测试账号为 admin 全权角色未触发,未做活体验证)。
|
||||
|
||||
#### 业务边界
|
||||
|
||||
- `groupBatchId` 对应团期不存在返回 589500,`data` 为 `null`。
|
||||
- `pageSize` 超过 200 会被后端静默截断为 200,不报错。
|
||||
- `includeCancelled` 缺省 `false`,不传时列表不含已取消子订单。
|
||||
- `vehicleRequirements` 为空数组 `[]` 表示该户当前没有任何活跃车需求行,不是接口异常;不要用 `null` 判空。
|
||||
- `vehicleRequirementKind`/`KindName` 在该户尚无任何车需求行时为 `null`,不回落成某个默认编码。
|
||||
- 两类需求同时存在时,单值字段(`vehicleRequirementStatus`/`Kind` 等)取的是**展示序(TRAVEL 优先)首条**,并非"最近更新"或"按查询顺序";需要拿到每一类各自的真实状态必须读 `vehicleRequirements[]`,不能只读单值字段。
|
||||
|
||||
## 四、契约约束与正确调用方式(接口类必写)
|
||||
|
||||
### ✅ 正确 / ❌ 错误 payload 对照
|
||||
|
||||
- ✅ 正确:判断某个户是否已提交任意车需求,遍历 `vehicleRequirements`(长度 > 0 即已提交),或分别读取 `vehicleRequirements` 中 `kind=TRAVEL`/`kind=TRANSFER` 各自的 `status`。
|
||||
- ❌ 错误:继续假设 `vehicleRequirementKind` 恒为 `"TRAVEL"` 并据此做条件分支——只提交接送机的户会被分支判空/判错。
|
||||
- ❌ 错误:把 `vehicleRequirementStatusName === "未提交"` 当作"该户任意一类车需求都未提交"的充分条件——本单之后它只代表"两类都未提交",不能再用它反推"TRAVEL 未提交"或"TRANSFER 未提交"这类更细的判断,要细分请读 `vehicleRequirements[]`。
|
||||
|
||||
### 切换状态时的必要动作
|
||||
|
||||
无需前端触发任何状态切换动作;本次是纯读接口的响应字段语义调整,不涉及写操作。
|
||||
|
||||
## 五、数据库行为(涉及写操作时必写)
|
||||
|
||||
本接口是纯查询接口,本单未新增/变更任何表结构,也未变更任何写路径。改动仅收窄/放宽了查询车需求行时的过滤条件(原实现只按 `requirement_kind = 'TRAVEL'` 取活跃行,现改为按展示序取该户全部活跃行的首条,并额外把全部活跃行一并下发到 `vehicleRequirements`)。
|
||||
|
||||
## 六、边界行为
|
||||
|
||||
- 团期不存在 → 589500,`data: null`。
|
||||
- 当前登录角色对该团期无权限 → 589507(源码定义,未做活体验证)。
|
||||
- `page`/`pageSize` 非法值(<1 或超范围)由后端静默归一/截断,不报参数校验错误。
|
||||
- 分页越界 → 返回 `records: []`,`total` 仍是真实总数,不报错。
|
||||
- `hotelRequirementStatus`/`vehicleRequirementKind` 等状态类字段在对应需求不存在时给 `null`,均不回落到某个默认状态码。
|
||||
- `groupChatUnreadCount` 在下游不可达时静默降级为 `0`。
|
||||
|
||||
## 六.5、枚举 / 数据字典(接口出现枚举时必写)
|
||||
|
||||
### vehicleRequirementKind / vehicleRequirements[].kind(`VehicleRequirementKind`)
|
||||
|
||||
| 值 | 中文名 |
|
||||
|----|--------|
|
||||
| TRAVEL | 行程用车 |
|
||||
| TRANSFER | 接送机 |
|
||||
|
||||
### vehicleRequirementStatus / vehicleRequirements[].status(`RequirementStatus`)
|
||||
|
||||
| 值 | 中文名(车需求语境) | 备注 |
|
||||
|----|----------------------|------|
|
||||
| PENDING | 待车队配 | |
|
||||
| PROCESSING | 配车中 | |
|
||||
| DONE | 配车完成 | |
|
||||
| PENDING_REVIEW | TRAVEL="待提交车务";TRANSFER="待审核" | 同一状态码按 kind 分叉出不同中文名 |
|
||||
| REJECTED_TO_CONSULTANT | 驳回顾问 | |
|
||||
| REJECTED_TO_ADMIN | 驳回管理员 | |
|
||||
| (该户无对应需求行) | 未提交 | `vehicleRequirementStatus`/`StatusName` 单值字段专属,`vehicleRequirements[]` 数组元素不会出现这个取值——没有对应行就不会出现在数组里 |
|
||||
|
||||
## 六.6、修改前后对比(修改/删除类接口必写,新增跳过)
|
||||
|
||||
### 字段级对比
|
||||
|
||||
| 字段 | 改前 | 改后 |
|
||||
|------|------|------|
|
||||
| vehicleRequirementStatus / StatusName | 只取该户 TRAVEL 类需求行的值;无 TRAVEL 行则恒为 "未提交" | 取展示序(TRAVEL 优先)首条**活跃**需求行的值;只要该户存在任意一类需求行就不再是"未提交" |
|
||||
| vehicleRequirementKind / KindName | 恒为 "TRAVEL"/"行程用车"(或该户无 TRAVEL 行时为 null) | 如实反映展示序首条需求行的真实类别,可能是 "TRANSFER"/"接送机" |
|
||||
| vehicleRequirements | 不存在该字段 | 新增,数组,逐类列出该户全部活跃需求行,空时为 `[]` |
|
||||
|
||||
### 行为级对比
|
||||
|
||||
| 场景 | 改前 | 改后 |
|
||||
|------|------|------|
|
||||
| 只提交接送机(TRANSFER),无 TRAVEL 需求 | 单值字段恒报"未提交",即便接送机已在流转甚至完成 | 单值字段如实报接送机自己的状态;`vehicleRequirements` 含 1 条 TRANSFER 记录 |
|
||||
| 只提交行程用车(TRAVEL) | 与改后一致(回归测试覆盖,行为未变) | 行为不变 |
|
||||
| 两类需求都提交 | 单值字段只能看到 TRAVEL 一类的状态,无法从列表接口直接得知 TRANSFER 的独立状态 | 单值字段仍取 TRAVEL(展示序优先),但 `vehicleRequirements` 同时给出两类各自独立的真实状态 |
|
||||
| 两类需求都未提交 | "未提交"(#8249 起已是该行为) | 行为不变,`vehicleRequirements` 为 `[]` |
|
||||
|
||||
## 六.7、影响评估(修改/删除类必写)
|
||||
|
||||
- 破坏兼容:否。既有字段名称、类型、语义边界(`null` 代表无对应需求行)均未变,改动只是放宽了 `vehicleRequirementKind` 的实际取值范围、扩大了 `vehicleRequirementStatus`/`StatusName` 能反映的真实状态覆盖面。
|
||||
- 前端是否必须同步上线:若前端曾经硬编码假设 `vehicleRequirementKind` 恒为 `"TRAVEL"`(例如据此固定展示"行程用车"图标、或对非 TRAVEL 值做兜底成空白),需要同步放开,否则只提交接送机的户在前端会展示错误的类别图标/文案,但不会报错或崩溃。
|
||||
- 若前端此前为规避"接送机被误判未提交"这个已知问题,在自己代码里做过特判/兜底逻辑,本单上线后该特判可以删除。
|
||||
|
||||
## 七、不影响范围
|
||||
|
||||
- `hotelRequirementStatus`/`hotelRequirementStatusName` 及其判空逻辑(#8249 行为)未变。
|
||||
- 订单状态、支付状态、合同状态、投保状态、复核/结算状态、价格档位、出行人相关字段等约 25 个既有字段未变。
|
||||
- 分页参数默认值与归一/截断规则未变。
|
||||
- `includeCancelled`/`includeNeeds`/`includeTravelers` 三个开关的既有行为未变。
|
||||
- `#8577` 修复的三个车需求提交/校验接口(`PUT` 保存、`GET` 聚合草稿、`GET` 提交前校验)及其错误码 809121/809122/809123,与本接口是不同代码路径,互不影响。
|
||||
- 团期详情页的"车队"chips 维度接口(`/chips/vehicle`)已支持 TRANSFER 类别展示,本次改动前后行为一致,不受影响。
|
||||
|
||||
## 八、测试环境已验证
|
||||
|
||||
**活体实测(本会话,2026-09-30,测试服 dev-v3):**
|
||||
|
||||
1. `GET /v3/admin/order/group-batch/2104839654727618562/orders?page=1&pageSize=5&includeTravelers=false&includeNeeds=false` → HTTP 200,返回 3 条真实子订单记录,其中 2 条同时具有 TRAVEL+TRANSFER 两类活跃需求行,单值字段与 `vehicleRequirements[]` 均按预期独立报出各自状态(含 `PENDING_REVIEW` 在 TRANSFER 语境下正确显示为"待审核")。原文见上「响应示例」。
|
||||
2. `GET /v3/admin/order/group-batch/999999999999999999/orders` → HTTP 200,`code:589500, message:"团期不存在"`。
|
||||
3. `GET /v3/admin/order/group-batch/2104839654727618562/orders?page=999&pageSize=5` → HTTP 200,`records:[]`,`total:3` 保留真实总数。
|
||||
|
||||
**自动化回归(`ce7cd238e9355bdc17c45f90ace02827c7db60f5`,已随 PR #8624 合入 dev-v3,覆盖测试服当前暂无现成样本的场景):**
|
||||
|
||||
- `GroupBatchConverterTest#toOrderItemVO_transferOnly_reportsRealStatusNotNotSubmitted`:该户只有一条 TRANSFER/`PENDING_REVIEW` 活跃行 → `vehicleRequirementStatusName` 报"待审核"(不是"未提交"),`vehicleRequirementKind`="TRANSFER",`vehicleRequirements` 含 1 条对应记录。这正是本单要修复的核心场景。
|
||||
- `GroupBatchConverterTest#toOrderItemVO_travelOnly_legacyFieldsUnchanged`:只有 TRAVEL 行时行为与改前一致(回归保护)。
|
||||
- `GroupBatchConverterTest#toOrderItemVO_bothKinds_statusesStayIndependent`:TRAVEL 与 TRANSFER 两类状态互不覆盖,且与查询返回顺序无关(用 TRANSFER 先于 TRAVEL 的输入顺序验证展示序不受取数顺序影响)。
|
||||
- `GroupBatchConverterTest#toOrderItemVO_neitherKind_stillNotSubmitted`:两类都无活跃行时仍报"未提交",`vehicleRequirements` 为空数组而非 null(#8249 行为回归保护)。
|
||||
- `GroupBatchConverterTest#toOrderItemVO_nullVehicleRows_emptyListNotNull`:上游传入 null 行集合时 `vehicleRequirements` 仍是空列表,不会是 null。
|
||||
- `GroupBatchConverterTest#toOrderItemVO_anyExistingRow_neverRendersNotSubmitted`(参数化,覆盖 TRAVEL/TRANSFER × 6 种状态共 12 种组合):只要该户存在任意一条需求行,`statusName` 永不为"未提交"或空白。
|
||||
- `GroupVehicleStatusNameCrossOutletTest`(#8218 既有门禁):同一 `(状态码, kind)` 对在本接口与其他读口的中文名保持一致,本次改动未破坏该跨口一致性。
|
||||
|
||||
## 十、相关文档
|
||||
|
||||
- 工单:#8619
|
||||
- PR:#8624(squash 合并 `ce7cd238e9355bdc17c45f90ace02827c7db60f5`)
|
||||
- 关联但独立的历史修复:`changelogs-v2/2026-09/30_8577_只提交接送机的户不再被判未提交用车需求-修改接口-管理后台.md`(#8577,见本文「一、背景」的区分说明)
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
### 链接
|
||||
|
||||
- Issue: https://git.1814.love/wx/HL/issues/8619
|
||||
- PR: https://git.1814.love/wx/HL/pulls/8624
|
||||
|
||||
### 联系人
|
||||
|
||||
- 后端负责人:@wx
|
||||
在新工单中引用
屏蔽一个用户