---
schema: "hl-changelog/v2"
ticket: "frontend"
title: "调整订单弹窗手机号/证件号脱敏值误回传：未修改字段被当改动提交，后端报『格式非法』"
consumer: "admin"
change_type: "前端缺陷"
author: "wx(GIT)"
backend_status: "not_required"
gateway_status: "not_required"
frontend_status: "implemented"
frontend_owner: "mmg"
frontend_ref: "d4d25a1c"
target_release: ""
verified_at: "2026-08-12"
status_note: "后端零改动，契约已支持『不改不传』。调整订单弹窗里手机号/证件号是脱敏回显（如 185****2756、110101****1234）。若用户没改这两列，前端不应把脱敏值回传后端——后端按『值变化』判改动，脱敏串 ≠ 明文会被误判为『改了』，再走格式校验报『手机号格式非法（应为 11 位数字）/证件号格式非法』。契约：AdjustmentSubmitReqVO.updates.people.travelers.update[].phone/idNo 传 null（或整个字段省略）= 保留原值不动；只有用户输入了新的完整明文值才提交。快照 GET /v3/admin/order/{id}/adjustment/snapshot?scope=PEOPLE 与订单详情 customerInfo.travelers 均返回明文（admin 端专用），可编辑初始值应取明文，不要取脱敏串。前端 2026-08-12 已修复并交付：真根因比本条所述更准——①buildTravelerPayload 未填敏感字段回传 ''（''≠null 后端误判改动对空串跑格式校验）；②订单级紧急电话 buildEmergencyPhonePayload 原回传 originalEmergencyPhone 明文/脱敏串，用户只改姓名也泄漏脱敏串。修复：TravelerInfoEditor 捕获提交形态基线 baselineTravelerPayload（脱敏字段已省略）+紧急电话「脱敏或与基线一致→null（不改不传）」，buildAdjustmentPeopleUpdate 加 baselineTravelers 对 update 项逐字段 diff「改才传、不改省略」、只剩 id 未改项剔除，toAdjustmentTraveler 防御剔除含「*」的 idCardNo/phone/emergencyPhone；不传基线保持原全量行为向后兼容。order-v2 29 文件 231 用例全绿，checkpoint 全过。"
updated_at: "2026-08-12"
base: "dev-v3"
---

# 调整订单弹窗手机号/证件号脱敏值误回传（前端）

> **页面**：订单 → 调整订单弹窗 → 出行人编辑 → 手机号 / 证件号两列
> **后端**：本条**零改动**。后端契约已支持「不改不传」，问题在前端把脱敏值当成了改动提交。

---

## 一、现象

调整订单弹窗中，出行人的手机号、证件号以**脱敏**形式回显（如手机号 `185****2756`、证件号 `110101****1234`）。用户**没有修改**这两列就提交，后端报错：

- `手机号格式非法（应为 11 位数字）`
- 或 `证件号格式非法`

## 二、根因（前端）

后端判定「某字段是否被修改」的口径是：**值与库里明文比对，不同即视为改动**。脱敏串（`185****2756`）≠ 明文（`18500002756`），前端若把回显的脱敏值原样回传，后端会误判为「用户改了手机号」，进而对脱敏串跑格式校验 → 报格式非法。

## 三、契约（后端已支持，无需改）

`POST /v3/admin/order/{id}/adjustment/submit`，`updates.people.travelers.update[]` 单项（`TravelerEditVO`）：

| 字段 | 不改时 | 要改时 |
|---|---|---|
| `phone` | 传 `null` 或**整个字段省略** → 保留原值 | 传新的完整 11 位明文 |
| `idNo` | 传 `null` 或**整个字段省略** → 保留原值 | 传新的完整明文证件号 |
| 其余字段同理 | null/省略 = 保留 | 传新明文 |

> 后端对每个字段按 `newVal != null && !newVal.equals(oldVal)` 判改动；`null`/省略即跳过该校验与更新。

## 四、前端该做的

1. **未修改的字段不要回传**：手机号/证件号若用户没动，提交时该字段传 `null` 或直接从 `update` 项里省略，**绝不把脱敏回显值回传**。
2. **改动检测以「用户是否输入新值」为准**，不要以「脱敏串 vs 空」判断；只有用户输入了新的完整明文，才放进提交体。
3. **可编辑初始值取明文**：快照 `GET /v3/admin/order/{id}/adjustment/snapshot?scope=PEOPLE` 与订单详情 `customerInfo.travelers` 均返回**明文**（admin 端专用）。若弹窗需要可编辑回填，应取这两个接口的明文，而不是某处的脱敏串——当前弹窗显示脱敏值，说明前端用的不是这两个明文源，需排查取值来源。

## 五、验收

- [ ] 调整订单时只改人数/日期、不动手机号和证件号，提交成功，不报「手机号/证件号格式非法」
- [ ] 显式把手机号改成新的完整 11 位，提交后生效
- [ ] 显式把证件号改成新的完整明文，提交后生效
- [ ] 脱敏回显仍在（不回显明文给用户看），但未改不回传
