- #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>
226 行
6.9 KiB
Markdown
226 行
6.9 KiB
Markdown
# order-v3 出行人模块: 新增 Feign 内部解密接口 + 审计表落库
|
|
|
|
> **存放目录**: 二期 v3(`order-v3` 标签) → `changelogs-v2/2026-05/`
|
|
>
|
|
> **服务**: hl-order-v3 (端口 8086)
|
|
> **PR**: #2552
|
|
> **Issue**: #2525
|
|
> **日期**: 2026-05-18
|
|
> **影响范围**: **仅后端服务 Feign 内部调用**(合同签署 / 保险出单等内部模块),**前端无关**
|
|
|
|
---
|
|
|
|
## ⚠️ 关键变化
|
|
|
|
- 新增一个 **/internal/** 路径,**仅供后端服务 Feign 调用**,经 9443 网关访问直接 403(网关白名单只放通 admin/mp/internal-feign)。前端/小程序不需要也不应调用。
|
|
- 出参含 `decryptedAt` 字段(后端解密时间戳),用于下游业务幂等与审计回溯。
|
|
- **新增审计表** `order_decrypt_audit_log`(9 字段 + 2 索引),每次解密同事务落审计行,**调用前请确认下游业务 purpose 取值正确**(枚举严格校验)。
|
|
|
|
---
|
|
|
|
## 一、背景
|
|
|
|
V5.48 §2.7 定义"敏感信息解密接口"。出行人 idNo/phone 在 v3 出行人表里为密文存储,合同签署/保险出单等内部业务需要明文。
|
|
|
|
风险点:任何解密动作必须留痕(谁、什么时候、为什么、查了哪个订单),否则一旦出现数据滥用无法溯源。本接口的关键不在"返明文",而在 **"返明文 + 强制同事务写审计"**。
|
|
|
|
---
|
|
|
|
## 二、变更接口清单
|
|
|
|
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
|
|---|------|------|------|----------|------|
|
|
| 1 | 内部查询订单出行人明文(带解密审计) | GET | `/v3/internal/order/orders/{orderId}/travelers` | 新增 | Feign 内部调用,网关 9443 直接 403 |
|
|
|
|
---
|
|
|
|
## 三、接口详情
|
|
|
|
### 1. 内部查询订单出行人明文 `GET /v3/internal/order/orders/{orderId}/travelers`
|
|
|
|
**VO**: `InternalOrderTravelerRespVO`
|
|
|
|
#### 入参
|
|
|
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
|
|------|------|------|------|------|------|
|
|
| orderId | Path | Long | 是 | 雪花 ID | 订单 ID |
|
|
| purpose | Query | String | 是 | 枚举:`CONTRACT_SIGN` / `INSURANCE_ISSUE` / `OTHER` | 解密用途,不在枚举内抛 589101 |
|
|
|
|
#### 出参 `Result<List<InternalOrderTravelerRespVO>>`
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|------|------|------|
|
|
| travelerId | Long | 出行人 ID |
|
|
| orderId | Long | 订单 ID |
|
|
| name | String | 姓名(明文) |
|
|
| idType | String | 证件类型 |
|
|
| idNo | String | 证件号(**明文**,已解密) |
|
|
| phone | String | 手机号(**明文**,已解密) |
|
|
| gender | String | 性别 |
|
|
| birthday | String | 生日 yyyy-MM-dd |
|
|
| race | String | 民族 |
|
|
| nationality | String | 国籍 |
|
|
| decryptedAt | String | 解密时间戳(yyyy-MM-dd HH:mm:ss),后端服务端时间 |
|
|
|
|
#### 响应示例
|
|
|
|
```json
|
|
{
|
|
"code": 200,
|
|
"message": "成功",
|
|
"data": [
|
|
{
|
|
"travelerId": 9023400111,
|
|
"orderId": 9020000333,
|
|
"name": "张三",
|
|
"idType": "ID_CARD",
|
|
"idNo": "110101199001011234",
|
|
"phone": "13800138000",
|
|
"gender": "MALE",
|
|
"birthday": "1990-01-01",
|
|
"race": "汉",
|
|
"nationality": "CN",
|
|
"decryptedAt": "2026-05-18 14:23:11"
|
|
}
|
|
],
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
#### 错误响应
|
|
|
|
```json
|
|
{
|
|
"code": 589100,
|
|
"message": "订单不存在或已删除,无法解密",
|
|
"success": false,
|
|
"data": null
|
|
}
|
|
```
|
|
|
|
```json
|
|
{
|
|
"code": 589101,
|
|
"message": "解密用途 purpose 不在允许枚举(CONTRACT_SIGN/INSURANCE_ISSUE/OTHER)",
|
|
"success": false,
|
|
"data": null
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 四、契约约束
|
|
|
|
| 约束 | 说明 |
|
|
|------|------|
|
|
| 调用方式 | 仅 Feign 内部调用,网关 9443 直接 403(网关白名单不放通 `/v3/internal/`) |
|
|
| purpose 必填 | 不传或为空 → 589101 |
|
|
| purpose 取值 | 严格枚举:`CONTRACT_SIGN` / `INSURANCE_ISSUE` / `OTHER`,大小写敏感 |
|
|
| 订单不存在 | 589100,不区分软删/不存在 |
|
|
| 同事务 | 查 traveler → 写审计 → 返 VO,**审计写失败整体回滚不返明文** |
|
|
|
|
---
|
|
|
|
## 五、数据库行为
|
|
|
|
### 新增审计表 `order_decrypt_audit_log`
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|------|------|------|
|
|
| id | BIGINT | 主键雪花 |
|
|
| order_id | BIGINT | 被解密订单 |
|
|
| traveler_id | BIGINT | 被解密出行人 |
|
|
| purpose | VARCHAR(32) | 解密用途 |
|
|
| operator_type | VARCHAR(32) | 调用方类型(FEIGN_INTERNAL) |
|
|
| operator_id | VARCHAR(64) | 调用方服务名/标识 |
|
|
| field_name | VARCHAR(32) | 解密字段(idNo / phone) |
|
|
| decrypted_at | DATETIME | 解密时间 |
|
|
| create_time | DATETIME | 行写入时间 |
|
|
|
|
**索引**:`idx_order_id` / `idx_decrypted_at`
|
|
|
|
**Flyway**: `V20260518_002__create_order_decrypt_audit_log.sql`
|
|
|
|
### 写入行为
|
|
|
|
- 每次调用,**每个出行人每个解密字段写 1 行**审计
|
|
- 同事务写,接口返回 N 个出行人则审计行至少 2N(idNo + phone 各 1)
|
|
- 失败回滚:整体事务回滚,**已返明文绝不可能**(返回前已 commit)
|
|
|
|
---
|
|
|
|
## 六、边界行为
|
|
|
|
- 网关 9443 调用 → 403(网关白名单拦截,**预期行为**)
|
|
- Feign 内部调用 (SSH 跳板内网 8086) → 200
|
|
- 订单不存在 / 已删除 → 589100
|
|
- purpose 非法 → 589101
|
|
- 出行人列表为空 → 返 `[]`,**仍写空审计?否**:无 traveler 不写审计,只返空数组
|
|
- 解密失败(密钥错乱等基础设施异常)→ 500,审计不落
|
|
|
|
---
|
|
|
|
## 七、不影响范围
|
|
|
|
- **仅影响**: 后端服务 Feign 内部调用链(合同签署 / 保险出单 / 财务对账等)
|
|
- **零影响**:
|
|
- 前端所有接口(管理端 + 小程序)
|
|
- 现有 `/v3/admin/order/{id}/traveler/*` 全部接口(明文 ↔ 密文转换逻辑不变)
|
|
- 出行人增/删/改接口
|
|
- 订单创建/详情/列表
|
|
- 历史数据(存量出行人无需迁移)
|
|
|
|
---
|
|
|
|
## 八、测试环境已验证
|
|
|
|
SSH 跳板内网 8086 真测:
|
|
|
|
```
|
|
GET /v3/internal/order/orders/{orderId}/travelers?purpose=CONTRACT_SIGN
|
|
→ 200 + 1 出行人 + decryptedAt 字段非空 ✓
|
|
→ audit log 写入 2 行(idNo + phone)✓
|
|
|
|
GET /v3/internal/order/orders/{orderId}/travelers?purpose=INSURANCE_ISSUE
|
|
→ 200 + 同上 ✓
|
|
→ audit log 累计 4 行 ✓
|
|
|
|
GET /v3/internal/order/orders/{orderId}/travelers?purpose=OTHER
|
|
→ 200 ✓
|
|
→ audit log 累计 6 行 ✓
|
|
|
|
GET /v3/internal/order/orders/9999999999/travelers?purpose=CONTRACT_SIGN
|
|
→ 589100 订单不存在 ✓
|
|
|
|
GET /v3/internal/order/orders/{orderId}/travelers?purpose=INVALID
|
|
→ 589101 purpose 非法 ✓
|
|
```
|
|
|
|
**网关 9443 验证**:
|
|
|
|
```
|
|
GET https://web.test.1814.love:9443/v3/internal/order/orders/{orderId}/travelers?purpose=CONTRACT_SIGN
|
|
→ 403 ✓(网关白名单拦截,预期行为)
|
|
```
|
|
|
|
审计落库总计 5+1 = 6 行,与预期一致。
|
|
|
|
---
|
|
|
|
## 九、错误码段位说明
|
|
|
|
| 错误码 | 含义 | 文档期望 | 实际 |
|
|
|--------|------|----------|------|
|
|
| 589100 | INTERNAL_ORDER_NOT_FOUND_FOR_DECRYPT | 589100 | ✅ 一致 |
|
|
| 589101 | INTERNAL_DECRYPT_PURPOSE_INVALID | 589101 | ✅ 一致 |
|
|
|
|
---
|
|
|
|
## 十、相关文档
|
|
|
|
- 关联 Issue: [wx/HL#2525](https://git.1814.love:8443/wx/HL/issues/2525)
|
|
- 关联 PR: [wx/HL#2552](https://git.1814.love:8443/wx/HL/pulls/2552)
|
|
- commit: `9cca41a5d`
|
|
- 设计文档: `docs/order-v3/V5.48 §2.7 敏感信息解密接口`
|