- #2517 list 路径迁移 /travelers → /traveler/list - #2518 batch-edit 真实业务+9错误码 - #2519 add 路径迁移+4错误码+@Idempotent+@Lock4j - #2520 delete 方法+路径迁移+4错误码+整事务 测试服 9443 真测全 ✅ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
189 行
6.4 KiB
Markdown
189 行
6.4 KiB
Markdown
# 出行人列表: 路径迁移 /travelers → /traveler/list
|
|
|
|
> **服务**: hl-order-service-v3 (端口 8084 / 二期)
|
|
> **PR**: #2531
|
|
> **Issue**: #2517
|
|
> **日期**: 2026-05-18
|
|
> **影响范围**: 管理后台订单详情概览 Tab 出行人区块 / F27 出行人补全列表读取
|
|
> **存放目录**: `changelogs-v2/2026-05/`(二期 v3 专属,带 -v2 后缀)
|
|
> **部署 commit**: dev-v3 `68fd00f85`
|
|
> **测试服已验证**: ✅(/@qa 通过 9443 网关 + 真 admin token round-trip)
|
|
|
|
---
|
|
|
|
## ⚠️ 关键变化(破坏性路径迁移)
|
|
|
|
接口路径从 v3 早期临时路径 `/travelers` 改为文档 V5.48 §2.1 正式路径 `/traveler/list`:
|
|
|
|
| 维度 | before(老路径,即将下线) | after(本 PR 起生效) |
|
|
|---|---|---|
|
|
| 方法 | GET | GET |
|
|
| 路径 | `/v3/admin/order/{id}/travelers` | `/v3/admin/order/{id}/traveler/list` |
|
|
|
|
**对前端的影响**: 调用方需把请求 URL 从 `/travelers` 替换为 `/traveler/list`。
|
|
**响应结构无变化**(仍是 `Result<List<TravelerVO>>` + 16 字段),前端字段映射不需要改。
|
|
|
|
---
|
|
|
|
## 一、背景
|
|
|
|
V5.48 文档 §2.1 已把出行人列表正式路径定为 `/traveler/list`(与 add / batch-edit / delete 等 §2.2~§2.4 接口的路径风格统一: 一级名词 `traveler` + 二级动词)。早期实现用了简短复数形式 `/travelers`,本 PR 完成对齐。
|
|
|
|
同时清理了 TravelerConverter 内残留的 Mock 占位注释,补齐 `transportPlanIds` 字段的真实化(从桥接表 `order_transport_plan_traveler` LEFT JOIN 取真值,而非占位空数组)。
|
|
|
|
---
|
|
|
|
## 二、变更接口清单
|
|
|
|
| # | 接口 | 方法 | 老路径 | 新路径 | 变更类型 |
|
|
|---|------|------|--------|--------|----------|
|
|
| 1 | 订单出行人列表 | GET | `/v3/admin/order/{id}/travelers` | `/v3/admin/order/{id}/traveler/list` | 破坏性路径迁移 |
|
|
|
|
---
|
|
|
|
## 三、接口详情
|
|
|
|
### 1. 订单出行人列表 `GET /v3/admin/order/{id}/traveler/list`
|
|
|
|
**VO**: `TravelerVO`(16 字段,无 *Label 衍生字段)
|
|
|
|
#### 入参
|
|
|
|
| 字段 | 位置 | 类型 | 必填 | 说明 |
|
|
|------|------|------|------|------|
|
|
| `id` | Path | Long | ✅ | 订单 ID(雪花 ID 字符串安全形式) |
|
|
|
|
#### 出参 `Result<List<TravelerVO>>`
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|------|------|------|
|
|
| `id` | Long | 出行人 ID |
|
|
| `orderId` | Long | 订单 ID |
|
|
| `travelerType` | String | ADULT / CHILD / YOUNG_CHILD / BABY |
|
|
| `name` | String? | 姓名(占位行为 null) |
|
|
| `gender` | String? | MALE / FEMALE / UNKNOWN |
|
|
| `birthday` | LocalDate? | 出生日期 |
|
|
| `idType` | String? | ID_CARD / PASSPORT / BIRTH_CERT |
|
|
| `idNo` | String? | 证件号(admin 明文,DB 加密) |
|
|
| `nationality` | String | 国籍(默认"中国") |
|
|
| `race` | String | 民族(默认"汉族") |
|
|
| `phone` | String? | 出行人手机(admin 明文) |
|
|
| `emergencyContact` | String? | 紧急联系人姓名 |
|
|
| `emergencyPhone` | String? | 紧急联系人电话(admin 明文) |
|
|
| `roomGroupNo` | Integer? | 同住分组号 |
|
|
| `profileStatus` | String | PENDING / COMPLETED |
|
|
| `transportPlanIds` | List\<Long\> | 关联大交通批次 ID 列表(来自桥接表) |
|
|
|
|
#### 请求示例
|
|
|
|
```
|
|
GET /v3/admin/order/60123456789012/traveler/list
|
|
Authorization: Bearer {admin_jwt}
|
|
```
|
|
|
|
#### 响应示例
|
|
|
|
```json
|
|
{
|
|
"code": 200,
|
|
"data": [
|
|
{
|
|
"id": 70123456789012,
|
|
"orderId": 60123456789012,
|
|
"travelerType": "ADULT",
|
|
"name": "张三",
|
|
"gender": "MALE",
|
|
"birthday": "1985-08-12",
|
|
"idType": "ID_CARD",
|
|
"idNo": "220103198508121234",
|
|
"nationality": "中国",
|
|
"race": "汉族",
|
|
"phone": "13800002046",
|
|
"emergencyContact": "李四",
|
|
"emergencyPhone": "13900008888",
|
|
"roomGroupNo": 1,
|
|
"profileStatus": "COMPLETED",
|
|
"transportPlanIds": [80012345, 80012346]
|
|
}
|
|
],
|
|
"msg": "success"
|
|
}
|
|
```
|
|
|
|
#### 空数据响应
|
|
|
|
```json
|
|
{ "code": 200, "data": [], "msg": "success" }
|
|
```
|
|
|
|
#### 错误响应
|
|
|
|
| 错误码 | 含义 |
|
|
|---|---|
|
|
| `581100` | 出行人主段位—— 订单 / 出行人不存在(本接口下订单不存在时返回空集合即 200 + `data:[]`,不报错;此码主要给 batch-edit / add / delete 用) |
|
|
|
|
---
|
|
|
|
## 四、契约约束
|
|
|
|
- 仅 admin JWT 可访问,网关层鉴权(无 token → 网关 401);跨公司读取由订单详情上下文接口在更上层校验,本接口本身只看订单 ID。
|
|
- 敏感字段(idNo / phone / emergencyPhone)**明文返回**,前端勿做二次脱敏渲染(B 端定制师业务诉求,后端已通过 EncryptTypeHandler 在 DB 层加密,VO 层明文)。
|
|
|
|
---
|
|
|
|
## 五、数据库行为
|
|
|
|
只读接口,**不产生任何 DB 写入**。
|
|
|
|
读关联表: `order_traveler` + LEFT JOIN `order_transport_plan_traveler`(取 `transportPlanIds` 真值)。
|
|
|
|
---
|
|
|
|
## 六、边界行为
|
|
|
|
- 未登录 → 401(网关拦截)
|
|
- 订单不存在 / 该订单下无出行人 → 200 + `data: []`(不 404,不抛异常)
|
|
- 出行人有未关联任何大交通的 → `transportPlanIds: []`
|
|
- 占位出行人(`name=null` `idNo=null`) → 字段为 null,不异常
|
|
|
|
---
|
|
|
|
## 七、不影响范围
|
|
|
|
- **仅影响**: 管理后台调用 `/v3/admin/order/{id}/travelers` 的请求 URL 拼接
|
|
- **零影响**:
|
|
- 响应结构 / 字段名 / 字段类型 / 字段值(VO 完全不变)
|
|
- mp 端出行人列表接口(走 `/v3/mp/...`,独立路径,未涉及)
|
|
- 订单详情主聚合接口 `/v3/admin/order/{id}` 内 `overview.travelers` 嵌套数组(已复用同 VO,本次未改)
|
|
- Feign 跨服务 internal 接口 `/internal/order/orders/{orderId}/travelers`(internal 路径独立,未涉及)
|
|
|
|
---
|
|
|
|
## 八、测试环境已验证
|
|
|
|
```
|
|
GET https://web.test.1814.love:9443/v3/admin/order/60123456789012/traveler/list
|
|
Authorization: Bearer {admin_jwt}
|
|
→ 200 + List<TravelerVO> 16 字段齐全 ✓
|
|
→ transportPlanIds 真值(非占位空数组)✓
|
|
→ 老路径 /travelers 已无返回(404)✓
|
|
```
|
|
|
|
---
|
|
|
|
## 九、相关历史 PR
|
|
|
|
| PR | Issue | 说明 | 是否仍有效 |
|
|
|----|-------|------|------------|
|
|
| #2124 | #2123 | /traveler/list 入参精简 + 敏感字段改明文(早期路径用 /travelers) | 部分有效(敏感字段口径保留,路径被本 PR 覆盖) |
|
|
| #2125 | - | detail.overview.travelers 复用 TravelerVO 完整字段 | ✅ 有效 |
|
|
| **本 PR #2531** | **#2517** | 路径正式迁 /traveler/list + transportPlanIds 真实化 | ✅ 最新 |
|
|
|
|
---
|
|
|
|
## 十、相关文档
|
|
|
|
- API SPEC: `D:/work2/HL-v3/docs/order-v3/api/API-SPEC-V5.48.html` §2.1
|
|
- 关联 Issue: [wx/HL#2517](https://git.1814.love:8443/wx/HL/issues/2517)
|
|
- 关联 PR: [wx/HL#2531](https://git.1814.love:8443/wx/HL/pulls/2531)
|