diff --git a/changelogs/2026-05/19_fix_admin_order_detail_travelers_no_longer_empty.md b/changelogs/2026-05/19_fix_admin_order_detail_travelers_no_longer_empty.md new file mode 100644 index 0000000..9ca1db7 --- /dev/null +++ b/changelogs/2026-05/19_fix_admin_order_detail_travelers_no_longer_empty.md @@ -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\ | 关联的大交通批次 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),现在可按需清理