- #2525 Feign /internal/order/orders/{orderId}/travelers + 解密审计表 + 589100/589101 - #2526 smart-parse 智能批量解析 + 581131-581134 + P0 审计红线 5 合规 - #2527 validate 字段对齐 v2(6→4 必填) + 581102 复用 测试服 9443 真测全 ✅ (commit f8a34607,含 31 Flyway migrations) #2525 经 SSH 内网 8086 真测(internal 路径 9443 返 403 是预期) #2526 异常路径全过,正常落库待前端联调补做(代码层 IT 已覆盖) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
213 行
6.4 KiB
Markdown
213 行
6.4 KiB
Markdown
# order-v3 出行人模块: validate 接口字段判定对齐 v2(6 → 4 必填字段)
|
|
|
|
> **存放目录**: 二期 v3(`order-v3` 标签) → `changelogs-v2/2026-05/`
|
|
>
|
|
> **服务**: hl-order-v3 (端口 8086)
|
|
> **PR**: #2553
|
|
> **Issue**: #2527
|
|
> **日期**: 2026-05-18
|
|
> **影响范围**: 管理后台订单详情页"出行人完整性校验"提示文案 → **路径不变,字段判定变化**
|
|
|
|
---
|
|
|
|
## ⚠️ 关键变化
|
|
|
|
- **路径不变**:`GET /v3/admin/order/{id}/traveler/validate`
|
|
- **字段判定变化**:必填字段从 **6 个 → 4 个**(name / idType / idNo / phone)
|
|
- `gender` / `birthday` / `race` / `nationality` **改为可选**,**不再进 incompleteList.missingFields**
|
|
- `incompleteList[].name` **改为脱敏**(首字符 + `*`)
|
|
- 前端调用方式不变,但**展示给客服的"缺哪些字段"提示会变少**
|
|
|
|
---
|
|
|
|
## 一、背景
|
|
|
|
V5.48 §2.9 要求 v3 validate 与 v2 一期对齐。
|
|
|
|
v2 一期实战中,客服只关心 4 个字段(姓名/证件类型/证件号/手机号),其他字段(性别/生日/民族/国籍)由后端从身份证号自动解析或后续补录,**不算"出行人信息不完整"**。
|
|
|
|
v3 早期版本沿用了 V5.0 设计的 6 字段判定,导致客服侧总是看到"出行人信息不完整,缺生日"的红字提示,实则不影响出行,产生噪音。
|
|
|
|
本次对齐 v2,**4 字段全有就算完整**。
|
|
|
|
---
|
|
|
|
## 二、变更接口清单
|
|
|
|
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
|
|---|------|------|------|----------|------|
|
|
| 1 | 出行人完整性校验 | GET | `/v3/admin/order/{id}/traveler/validate` | **字段判定变化**(路径不变) | 6 → 4 必填字段;name 脱敏 |
|
|
|
|
---
|
|
|
|
## 三、接口详情
|
|
|
|
### 1. 出行人完整性校验 `GET /v3/admin/order/{id}/traveler/validate`
|
|
|
|
**VO**: `TravelerValidateRespVO`
|
|
|
|
#### 入参
|
|
|
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
|
|------|------|------|------|------|------|
|
|
| id | Path | Long | 是 | 雪花 ID | 订单 ID |
|
|
|
|
#### 出参 `Result<TravelerValidateRespVO>`
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|------|------|------|
|
|
| expectedCount | Integer | 订单应有出行人数(来自订单 traveler_count) |
|
|
| actualCount | Integer | 实际已录入出行人数 |
|
|
| countMismatch | Boolean | 数量是否不一致 |
|
|
| incompleteList | List | 信息不完整的出行人列表 |
|
|
| incompleteList[].travelerId | Long | 出行人 ID |
|
|
| incompleteList[].name | String | **脱敏后姓名**(首字符 + `*`,如"张*"、"李*") |
|
|
| incompleteList[].missingFields | List<String> | 缺失字段名,**仅可能为 `name`/`idType`/`idNo`/`phone` 4 个值之一** |
|
|
|
|
#### 响应示例(完整)
|
|
|
|
```json
|
|
{
|
|
"code": 200,
|
|
"message": "成功",
|
|
"data": {
|
|
"expectedCount": 3,
|
|
"actualCount": 3,
|
|
"countMismatch": false,
|
|
"incompleteList": []
|
|
},
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
#### 响应示例(数量不一致 + 信息不完整)
|
|
|
|
```json
|
|
{
|
|
"code": 200,
|
|
"data": {
|
|
"expectedCount": 3,
|
|
"actualCount": 2,
|
|
"countMismatch": true,
|
|
"incompleteList": [
|
|
{
|
|
"travelerId": 9023400111,
|
|
"name": "张*",
|
|
"missingFields": ["phone"]
|
|
},
|
|
{
|
|
"travelerId": 9023400112,
|
|
"name": "李*",
|
|
"missingFields": ["idNo", "phone"]
|
|
}
|
|
]
|
|
},
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
#### 错误响应
|
|
|
|
```json
|
|
{ "code": 581102, "message": "订单不存在或已删除", "success": false }
|
|
```
|
|
|
|
---
|
|
|
|
## 四、字段判定规则(本次重点)
|
|
|
|
| 字段 | v3 旧版判定 | v3 新版判定(本次) | v2 |
|
|
|------|-------------|---------------------|-----|
|
|
| name | 必填 | **必填** | 必填 |
|
|
| idType | 必填 | **必填** | 必填 |
|
|
| idNo | 必填 | **必填** | 必填 |
|
|
| phone | 必填 | **必填** | 必填 |
|
|
| gender | 必填 | **可选**(不进 missingFields) | 可选 |
|
|
| birthday | 必填 | **可选**(不进 missingFields) | 可选 |
|
|
| race | 必填 | **可选** | 可选 |
|
|
| nationality | 必填 | **可选** | 可选 |
|
|
|
|
判定逻辑:**4 个必填字段任一为 null 或空字符串 → 该出行人进 incompleteList**,missingFields 只列出缺失的 4 字段之一。
|
|
|
|
---
|
|
|
|
## 五、契约约束
|
|
|
|
| 约束 | 说明 |
|
|
|------|------|
|
|
| 路径 | **不变**,前端无需改 URL |
|
|
| 入参 | **不变**,只有 path 上 orderId |
|
|
| 出参字段名 | **不变**,但 `missingFields` 内可能值从 8 → 4 |
|
|
| name 脱敏 | 出参 `incompleteList[].name` **改为脱敏**,前端无需自己再脱敏 |
|
|
|
|
---
|
|
|
|
## 六、数据库行为
|
|
|
|
- **无写操作**(纯查询接口)
|
|
- 查询逻辑:order_traveler WHERE order_id = ? AND deleted_at IS NULL,在 Service 层逐字段判空
|
|
|
|
---
|
|
|
|
## 七、边界行为
|
|
|
|
- 订单不存在 / 已删除 → 581102
|
|
- 订单存在但 traveler_count = 0 → expectedCount=0, actualCount=0, countMismatch=false, incompleteList=[]
|
|
- 订单存在但无出行人录入 → expectedCount=N, actualCount=0, countMismatch=true
|
|
- 所有出行人 4 字段齐全 → incompleteList=[]
|
|
- 出行人 name 字段本身为空 → name 字段返 `*`(单字符脱敏)
|
|
|
|
---
|
|
|
|
## 八、不影响范围
|
|
|
|
- **仅影响**: 管理后台订单详情页"出行人完整性"提示文案的显示
|
|
- **零影响**:
|
|
- 出行人增/删/改接口(`add` / `edit` / `delete`)
|
|
- smart-parse 智能批量解析(见 #2526)
|
|
- Feign 内部解密(见 #2525)
|
|
- 小程序所有接口
|
|
- 订单状态机(本接口不参与状态流转)
|
|
- 数据库表结构
|
|
|
|
---
|
|
|
|
## 九、测试环境已验证
|
|
|
|
经 9443 网关真 admin token 测试:
|
|
|
|
```
|
|
GET /v3/admin/order/{id}/traveler/validate 正常订单
|
|
→ 200 + expectedCount=2 + actualCount=2 + incompleteList=[] ✓
|
|
|
|
GET /v3/admin/order/{id}/traveler/validate 数量不一致
|
|
→ 200 + countMismatch=true ✓
|
|
|
|
GET /v3/admin/order/{id}/traveler/validate 缺 phone 字段
|
|
→ 200 + incompleteList[0].missingFields=["phone"] ✓
|
|
→ name 脱敏 "张*" ✓
|
|
|
|
GET /v3/admin/order/{id}/traveler/validate 仅缺 gender/birthday(旧版应报缺,新版应通过)
|
|
→ 200 + incompleteList=[] ✓(新版 4 字段判定不算缺)
|
|
|
|
GET /v3/admin/order/9999999999/traveler/validate
|
|
→ 581102 订单不存在 ✓
|
|
```
|
|
|
|
---
|
|
|
|
## 十、错误码段位说明
|
|
|
|
| 错误码 | 含义 | 文档期望 | 实际 | 原因 |
|
|
|--------|------|----------|------|------|
|
|
| 581102 | TRAVELER_VALIDATE_ORDER_NOT_FOUND | 581124 | **581102 复用** | 581124 已被 TRANSPORT_PLAN_INVALID_MODE 占用,文档侧 follow-up 修文档 |
|
|
|
|
---
|
|
|
|
## 十一、相关文档
|
|
|
|
- 关联 Issue: [wx/HL#2527](https://git.1814.love:8443/wx/HL/issues/2527)
|
|
- 关联 PR: [wx/HL#2553](https://git.1814.love:8443/wx/HL/pulls/2553)
|
|
- commit: `d9bc8371`
|
|
- 设计文档: `docs/order-v3/V5.48 §2.9 validate 接口对齐 v2`
|