# 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>` | 字段 | 类型 | 说明 | |------|------|------| | 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 敏感信息解密接口`