diff --git a/changelogs-v2/2026-08/04_5463_派单司机员工手机号解密降级容错-修改接口-管理后台.md b/changelogs-v2/2026-08/04_5463_派单司机员工手机号解密降级容错-修改接口-管理后台.md new file mode 100644 index 0000000..3ce1625 --- /dev/null +++ b/changelogs-v2/2026-08/04_5463_派单司机员工手机号解密降级容错-修改接口-管理后台.md @@ -0,0 +1,119 @@ +--- +schema: "hl-changelog/v2" +ticket: "5463" +title: "派单司机/员工手机号密文解密失败降级容错" +consumer: "admin" +change_type: "修改接口" +backend_status: "deployed" +gateway_status: "verified" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "2026-08-04" +status_note: "订单详情/行程接口对手机号密文解密失败(keyVersion 缺失/密文损坏)不再 500,降级返回空手机号;后端 warn 日志含 keyVersion 与密文指纹,不含明文。" +updated_at: "2026-08-04" +base: "dev-v3" +--- + +# 【修改接口·管理后台】派单司机/员工手机号密文解密失败降级容错 (#5463) + +> **PR**: #5464 | **服务**: order-v3 | **更新时间**: 2026-08-04 + +## 1. 接口背景 + +订单详情/行程接口对含派单司机/员工手机号密文的记录,在密钥版本缺失或密文损坏时返回 500(`assignment phone key version is unavailable`),用户端订单详情页直接报错不可用。本次改为解密失败降级:仅手机号字段返回空,订单其余字段正常展示。 + +## 变更接口清单 + +| # | 接口名 | 方法 | 路径 | 变更类型 | 说明 | +|---|--------|------|------|----------|------| +| 1 | 订单行程(v2 详情页) | GET | `/v3/admin/order/{id}/itinerary` | 修改 | 手机号解密失败不再 500,降级为空展示 | +| 2 | 订单详情(9 Tab 聚合) | GET | `/v3/admin/order/{id}` | 修改 | 车辆/人员手机号解密失败不再 500,降级为空展示 | + +## 2. 行为变化 + +| 场景 | 原来 | 现在 | +|------|------|------| +| 派单/员工手机号密文 keyVersion 缺失(如配置未下发) | 整接口 500 | 200,手机号字段为 `null`/空,其余字段正常 | +| 密文损坏 / Base64 非法 / AAD 不匹配 | 整接口 500 | 200,手机号字段为 `null`/空,其余字段正常 | +| 手机号无密文(明文快照或空) | 正常展示 | 不变 | +| 密钥配置齐全且密文正常 | 正常解密展示 | 不变 | + +**涉及字段**(响应中车辆/人员相关节点): + +| 字段 | 类型 | 变化 | +|------|------|------| +| 车辆行 `driverPhone`(订单行程/详情车辆列表) | string | 解密失败时为 `null`(原来导致整接口 500) | +| 签收凭证 `driverPhone` / `guidePhone` / `leaderPhone` | string | 解密失败时为 `null`(原来导致整接口 500) | + +## 3. 接口详情 + +### 3.1 订单行程 + +- **方法/路径**:`GET /v3/admin/order/{id}/itinerary` +- **认证**:管理后台登录态(定制师/车务均可) +- **无请求体**;`id` 为订单雪花 ID。 +- **典型成功示例**(手机号解密失败时,其余字段完整返回): + +``` +GET /v3/admin/order/2084280253366124546/itinerary +Authorization: Bearer +(无请求体) +``` + +```json +{ + "code": 200, + "message": "成功", + "data": { + "orderId": "2084280253366124546", + "orderNo": "HL20260803220000001", + "vehicles": [ + { + "assignmentId": "2084280300000000001", + "driverName": "张师傅", + "driverPhone": null, + "licensePlate": "蒙A-12345", + "serviceStartDate": "2026-08-03", + "serviceEndDate": "2026-08-05" + } + ] + } +} +``` + +### 3.2 订单详情 + +- **方法/路径**:`GET /v3/admin/order/{id}` +- **行为**:与 3.1 一致;聚合内所有来源自 `driver_phone_ciphertext` / `staff_phone_ciphertext` 的手机号字段在解密失败时均为 `null`,不再触发整接口 500。 + +## 4. 错误码 + +无新增错误码。解密失败不再返回 500,改为 200 + 字段 `null`;后端以 warn 日志记录(`assignment phone decrypt degraded: ... keyVersion=... envelopeFingerprint=...`),日志不含明文与密钥。 + +## 5. 前端需要做什么 + +- 无需代码改动即可恢复可用(页面从 500 变为正常打开)。 +- 请确认车辆/人员手机号为空(`null`)时页面展示兜底(如显示 `-` 或留空),避免出现 `undefined` 文案。 +- 前端遇到 `driverPhone` 为空时,不要向用户提示“数据异常”,按“暂无/未填写”处理即可。 + +## 6. 后端测试、部署与网关验证 + +- 单元测试:`AssignmentPhoneCryptoTest` 10 个(正常解密 / keyVersion 缺失 / 损坏密文 / Base64 非法 / AAD 不匹配 / AAD 身份缺失 / 加密 fail-fast / previous-keys 轮换)全部通过。 +- 模块验证:`mvn -pl hl-order-service-v3 -am verify` 7414 测试 0 失败。 +- 部署:TEST 环境 hl-order-service-v3 已部署。 +- 网关验证:原 500 订单(`2084280253366124546` / `2084280407016062978`)`GET /v3/admin/order/{id}/itinerary` 恢复 200,手机号字段降级为空,其余字段正常。 + +## 验证证据 + +- 单元测试:`AssignmentPhoneCryptoTest` 10 个用例(正常 v1/v2 往返、keyVersion 缺失降级 null、损坏密文降级 null、Base64 非法降级 null、AAD 不匹配降级 null、AAD 身份缺失降级 null、加密 fail-fast、previous-keys 轮换)全通过。 +- 模块验证:`mvn -pl hl-order-service-v3 -am verify` 7414 测试 0 失败。 +- 部署:TEST 环境 hl-order-service-v3 rolling 部署完成(dev-v3 @ fcde24ec,双实例 UP)。 +- 网关验证(wx=CUSTOMIZER):原 500 订单 `2084280253366124546` / `2084280407016062978` / `2084278362947158017` 的 `GET /v3/admin/order/{id}/itinerary` 全部恢复 200;含 v1 密文的订单 `2084266179660013569` 车辆行 `driverPhoneMasked` 正常掩码回显(测试服已补配 v1 密钥,存量 414 条密文可解密;无密钥时走降级路径返回空,由单元测试覆盖)。 + +## 关联 / 联系人 + +### 联系人 + +- **后端负责人**: @wx