fix(admin-order-detail): PR #2571 补通 overview.travelers 真实出行人数据

订单详情接口 GET /v3/admin/order/{id} 的 overview.travelers 字段
原来恒为空数组占位,现已接通真实出行人列表(按 traveler_id 升序)。
字段口径与 /traveler/list 完全一致,admin 端明文返回敏感字段。
这个提交包含在:
yaosutu 2026-05-19 02:47:37 +08:00
父节点 ffecdc6fd6
当前提交 67a38f91bf

查看文件

@ -0,0 +1,167 @@
# API 变更通知
**更新时间**: 2026-05-19 00:00
**PR**: #2571 fix(order-v3): 补通 overview.travelers 真实出行人数据Issue #2460 遗留债)
## ✨ 订单详情接口 overview.travelers 字段从占位空数组变为真实出行人列表
### 变了什么(前端视角)
`GET /v3/admin/order/{id}` 的响应中,`data.overview.travelers` 字段此前**永远返回空数组 `[]`**Issue #2460 PR-1 当时留了 TODO 占位)。
本次修复已将其**接通真实数据**,现在返回完整的出行人列表,字段口径与 `GET /v3/admin/order/{id}/traveler/list` 完全一致。
**对照表**
| 字段 | 原来 | 现在 |
|------|------|------|
| `data.overview.travelers` | 永远 `[]` | 真实出行人列表(按 traveler_id 升序) |
### 前端要改的地方
这是**可选优化**,不是必须改:
1. **进入订单详情页时**:可直接从 `overview.travelers` 读取出行人数据,省去再调一次 `/v3/admin/order/{id}/traveler/list`
2. **保持现有调用方式也完全没问题**`/traveler/list` 接口字段口径不变,两个来源数据一致。
3. **如果原先有 workaround**(比如检测到 `travelers` 为空就补一次 list 请求):确认接口已返回真实数据后可以清理掉这段逻辑。
### 涉及的接口 / 模块
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 订单详情 | GET | `/v3/admin/order/{id}` | 🔧 字段行为修复 | `overview.travelers` 从空数组变为真实数据 |
### 接口详细定义
#### 订单详情
- **使用场景**:管理后台进入订单详情页时调用,返回订单概览 + 出行人列表等聚合信息
- **路径参数**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 是 | 订单 ID |
- **请求示例**
```
GET /v3/admin/order/1234567890
Authorization: Bearer {token}
```
- **响应示例(完整 overview.travelers 部分)**
```json
{
"code": 200,
"msg": "success",
"data": {
"overview": {
"travelers": [
{
"id": 987654321,
"orderId": 1234567890,
"travelerType": "ADULT",
"name": "张三",
"gender": "MALE",
"birthday": "1990-06-15",
"idType": "IDCARD",
"idNo": "110101199006151234",
"nationality": "中国",
"race": "汉族",
"phone": "13800138000",
"emergencyContact": "李四",
"emergencyPhone": "13900139000",
"roomGroupNo": 1,
"profileStatus": "COMPLETED",
"transportPlanIds": [1001, 1002]
},
{
"id": 987654322,
"orderId": 1234567890,
"travelerType": "CHILD",
"name": "张小五",
"gender": "MALE",
"birthday": "2018-03-20",
"idType": "IDCARD",
"idNo": "110101201803201234",
"nationality": "中国",
"race": "汉族",
"phone": null,
"emergencyContact": "张三",
"emergencyPhone": "13800138000",
"roomGroupNo": 1,
"profileStatus": "COMPLETED",
"transportPlanIds": []
}
]
}
}
}
```
- **overview.travelers 数组元素字段说明**
| 字段 | 类型 | 说明 | 备注 |
|------|------|------|------|
| id | Long | 出行人 ID | 雪花 ID |
| orderId | Long | 所属订单 ID | |
| travelerType | String | 出行人类型 | 枚举,见下表 |
| name | String | 姓名 | |
| gender | String | 性别 | 枚举MALE / FEMALE |
| birthday | String | 生日 | 格式 yyyy-MM-dd |
| idType | String | 证件类型 | 枚举,见下表 |
| idNo | String | 证件号 | **admin 端明文返回**(后台 DB 加密存储)|
| nationality | String | 国籍 | 默认"中国" |
| race | String | 民族 | 默认"汉族" |
| phone | String | 手机号 | **admin 端明文返回**;儿童可为 null |
| emergencyContact | String | 紧急联系人姓名 | 可为 null |
| emergencyPhone | String | 紧急联系人手机 | **admin 端明文返回**;可为 null |
| roomGroupNo | Integer | 同住分组号 | 相同数字表示同住一间 |
| profileStatus | String | 资料完善状态 | 枚举,见下表 |
| transportPlanIds | List\<Long\> | 关联的大交通批次 ID 列表 | 无关联时为空数组 `[]` |
### 枚举 / 字典值
#### travelerType出行人类型
| 值 | 中文 | 说明 |
|----|------|------|
| ADULT | 成人 | |
| YOUNG | 青年 / 学生 | |
| CHILD | 儿童 | |
| BABY | 婴儿 | |
#### idType证件类型
| 值 | 中文 | 说明 |
|----|------|------|
| IDCARD | 居民身份证 | 最常见 |
| PASSPORT | 护照 | |
| HKMO | 港澳居民来往内地通行证 | |
| TAIWAN | 台湾居民来往大陆通行证 | |
| OTHER | 其他 | |
#### gender性别
| 值 | 中文 |
|----|------|
| MALE | 男 |
| FEMALE | 女 |
#### profileStatus资料状态
| 值 | 中文 | 说明 |
|----|------|------|
| PENDING | 待完善 | 出行人资料未填完整 |
| COMPLETED | 已完善 | 出行人资料齐全 |
### 业务规则 / 校验规则
- 排序:按出行人 ID`traveler_id`)升序
- 数据来源:与 `GET /v3/admin/order/{id}/traveler/list` **完全一致**,由同一个 `TravelerService.listTravelers` 方法产出,字段值不会有差异
- **敏感字段**`idNo``phone``emergencyPhone` 在 admin 端明文返回业务需要,例如紧急情况联系,在小程序端mp和内部接口internal走脱敏,后台 DB 使用 AES 加密存储
### 向后兼容性说明
- 本次变更**完全向后兼容**:字段名 / 路径 / 类型结构均无变化,只是原来恒为 `[]` 的字段现在有了真实内容
- 前端无需强制修改,保持调用 `/traveler/list` 的逻辑也能正常工作
- 若前端原有 workaround检测 `travelers` 为空时额外请求 list,现在可按需清理