hl-api-changelog/changelogs-v2/2026-06/19_补全出行信息弹窗三处缺陷-前端待修-管理后台.md
API Changelog Bot b86916bc8c docs(changelog/order-v3): 修正补全弹窗②为紧急联系人必填(后端PR#4041补强581109),原误写非必填
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 11:51:17 +08:00

12 KiB

「补全出行信息」弹窗三处缺陷(回显不全 / 紧急联系人必填 / 保存后不关闭) — 前端待修 + 后端已补强 — 管理后台

变更类型:🐛 前端缺陷(①回显、③保存后不关闭,无后端代码变更)+ 🔧 后端门禁补强②紧急联系人必填,PR #4041,零 DDL、无新增接口;本文档给出前端对接修复方式 + 数据丢失避坑 端类型:管理后台(订单详情页 → 「补全出行信息」弹窗) 日期2026-06-19 服务hl-order-service-v3出行人补全接口已补紧急联系人必填门禁 581109 / 订单详情明文回显接口已上线) 责任端:前端 hl-uimmg,① ③ + ② 配合保持必填);后端 order-v3② 已修,PR #4041 实测样本:测试服网关 9443 + 真实 admin token,订单 HL20260618165816942orderId=2067532338723504130,定制中 / 待补全信息)


⚠️ 关键说明

问题 ① 回显不全、③ 保存后弹窗不关闭为前端侧;问题 ② 紧急联系人必填的后端门禁已补强并部署测试服PR #4041,前端需配合「保持必填 + 处理新错误码」。后端经测试服逐项实测:

  • 后端该出行人的完整明文数据,且已提供明文回显接口(订单详情 overview,#3509
  • 保存接口对「资料齐全」场景返回 HTTP 200 success=true(不是保存失败 → ③ 是前端没关弹窗);
  • 紧急联系人按合同要求必填:后端原先未校验(空值可落库),现已补强制校验(错误码 581109,PR #4041 已合并 dev-v3 + 部署测试服实测)。

🔴 最高优先级警告(修复问题一时必读 §4:补全弹窗里被清空显示的「证件号 / 手机号」,若在保存时以空字符串 "" 回传,后端会把数据库里已有的真实证件号 / 手机号抹掉merge 语义:null 保留原值、"" 覆盖为空)。修回显的同时必须改对保存回传,否则会造成线上数据丢失。


1. 问题一:回显信息不全(证件号 / 手机号 / 备注 显示为空,状态显示「待填」实为「已完成」)

现象:打开弹窗,出行人「王完善」的证件号码、手机号、客户备注均为空,出行人标签显示「待填」。

实测对比(同一订单,后端实际数据 vs 弹窗显示)

字段 后端实际值(订单详情接口明文返回) 弹窗显示
证件号 152522198605311079(明文)
手机号 18547062756(明文)
客户备注 测试测试 哈哈哈哈
profileStatus COMPLETED(已完成) 待填
紧急联系人 name=1 / phone=18547056215 正常显示 ✓

根因:弹窗的回显数据没取自明文源。后端有两个出行人查询口径:

  1. GET /v3/admin/order/{id}/traveler/list —— 脱敏版#2894 PII 应急修复),证件号 / 手机号返回的是 idCardMasked / phoneMasked(形如 152***********1079185****2756)。这种带星号的脱敏值无法放进可编辑输入框,前端只能留空 → 表现为「证件号 / 手机号 空」。
  2. GET /v3/admin/order/{id}(订单详情 overviewoverview.customerInfo.travelers[] —— 明文版TravelerPlainVO,#3509,admin 端业务例外),证件号字段名 idCard、手机号 phone 均为明文。

补全弹窗是从订单详情页打开的,订单详情数据前端已经加载过(含明文出行人 + 紧急联系人 + 客户备注)。弹窗应直接用这份已加载的明文数据回填,而不是再调脱敏的 /traveler/list

修复方式:弹窗回显改用订单详情明文源:

弹窗字段 取自订单详情(GET /v3/admin/order/{id}data.overview
出行人 姓名/性别/生日/证件类型 customerInfo.travelers[].name / gender / birthday / idType
出行人 证件号 customerInfo.travelers[].idCard(明文)
出行人 手机号 customerInfo.travelers[].phone(明文)
出行人 状态标签 customerInfo.travelers[].profileStatus(直接读,COMPLETED=已完成,别再用「输入框是否为空」反推,否则永远显示待填)
紧急联系人 姓名/电话 customerInfo.emergencyContactName / emergencyContactPhone
客户备注 remarkInfo.customerRemark
# 回显数据源:订单详情 overview明文
curl -k "https://api.test.1814.love:9443/v3/admin/order/2067532338723504130" \
  -H "Authorization: Bearer <adminToken>"

实测返回(节选,已上线):

{
  "code": 200,
  "data": {
    "overview": {
      "customerInfo": {
        "emergencyContactName": "1",
        "emergencyContactPhone": "18547056215",
        "travelers": [
          {
            "id": "2067803630752174082",
            "name": "王完善", "gender": "1", "birthday": "1986-05-31",
            "idType": "ID_CARD", "idCard": "152522198605311079", "phone": "18547062756",
            "profileStatus": "COMPLETED", "nationality": "中国", "race": "汉族"
          }
        ]
      },
      "remarkInfo": { "customerRemark": "测试测试 哈哈哈哈" }
    }
  }
}

2. 问题二:紧急联系人必填(合同要求)— 后端已补强制校验

结论:紧急联系人按合同要求必须填写(弹窗副标题「根据合同要求,需填写所有出行人证件号与紧急联系人信息」即此意)。前端保持必填即可。

后端补强PR #4041,已合并 dev-v3 + 部署测试服):此前后端 saveTravelerInfo 对紧急联系人无任何校验,空值提交会成功落库(合同必报字段只靠前端单点拦截不安全)。现已在后端补强制门禁,与前端必填形成双层保障:

场景 后端返回
紧急联系人姓名 / 电话任一为空 581109「紧急联系人姓名和电话必填」,不落库
紧急联系人电话格式非法(非 11 位) 581113「手机号格式非法(应为 11 位数字)」
姓名 + 合法电话齐全 200 正常保存

前端配合

  1. 保持紧急联系人姓名 + 电话的「必填」前端校验(不要去掉),弹窗副标题维持「需填写紧急联系人」。
  2. 透传后端 581109 / 581113message 给用户(用户绕过前端校验或格式不对时的兜底提示)。

3. 问题三:保存成功后弹窗不关闭

现象:点「保存并完成」后弹窗一直不消失。

实测:保存接口 PUT /v3/admin/order/{id}/traveler-info 对该场景返回 HTTP 200

{ "code": 200, "success": true,
  "data": { "createdCount": 0, "updatedCount": 1, "deletedCount": 0,
            "completedCount": 1, "pendingCount": 0, "allCompleted": true } }

保存是成功的,后端无报错。弹窗不关闭是前端没有在成功响应后关闭弹窗 / 刷新页面

修复方式

  1. 保存成功(code===200 && success===true)后:关闭弹窗 + 刷新订单详情(出行人区、流程状态)。
  2. ⚠️ 判成功要看业务字段 code===200 && success===true不能只看 HTTP 状态码。原因:保存接口带幂等保护 @Idempotent同订单 3 秒内重复提交会被拦截,此时 HTTP 仍是 200 但 success=falsecode!=200(实测复现:连续两次提交,第二次 success=false)。前端若只看 HTTP 200 就当成功,会把「被幂等拦截、其实没保存」误判为成功;若据此关弹窗也属误关。正确做法:仅 success===true 关弹窗,success===false 弹出后端 message 提示用户。

4. ⚠️ 数据丢失陷阱(修问题一时必须同步处理)

保存接口的 merge 语义(mergeFromEditItem某字段传 null(或不传该 key= 保留数据库原值;传任何非 null 值(含空字符串 ""= 覆盖

结合问题一的回显修复,存在数据丢失风险链:

  • 出行人「王完善」DB 里证件号 = 152522198605311079、手机号 = 18547062756(已完成);
  • 若弹窗回显仍把证件号 / 手机号显示为空,用户没动这两个框,保存时前端把 idNo:""phone:"" 回传;
  • 后端 "" != null把真实证件号 / 手机号覆盖成空 → 该出行人从 COMPLETED 退回 PENDING证件号 / 手机号永久丢失

前端务必遵守

  1. 优先:按 §1 用明文源回填证件号 / 手机号,用户未修改时原样回传明文值(保存接口字段名是 idNo / phone,注意回显源字段名是 idCard / phone,证件号需做 idCard → idNo 映射)。
  2. 退路:某字段确实没有可回填的值、或不想回传,就传 null / 不带该 key保留原值绝不能传空字符串 ""
  3. 仅当用户主动清空某字段且业务确实要清空时,才传 ""

5. 接口契约速查

回显GET /v3/admin/order/{id}data.overview.customerInfo(明文出行人 + 紧急联系人)+ data.overview.remarkInfo.customerRemark

保存PUT /v3/admin/order/{id}/traveler-info

字段 必填 说明
travelers[] ≤30,非空 全量同步:id=null 新增 / id 非空 更新 / DB 有而本次没提交的 → 删除
travelers[].id 更新必填 回显时务必带上,否则会被当新增 + 旧行被删
travelers[].birthday @NotNull 出生日期,后端按年龄派生出行人类型
travelers[].name / gender / idType 缺则该出行人停留 PENDING
travelers[].idNo 证件号明文回传(回显源字段叫 idCard,注意映射);空串会覆盖,见 §4
travelers[].phone 手机号明文回传;空串会覆盖,见 §4
travelers[].nationality / race 不传后端默认「中国」/「汉族」;传空串 "" 会被拒581101
emergencyContactName / emergencyContactPhone (合同要求,见 §2 订单级紧急联系人;姓名 + 电话必填(任一空 → 581109),电话须合法 11 位(→ 581113
customerRemark 客户备注

幂等:同订单 3 秒窗口重复提交被拒HTTP 200 但 success=false),前端按 §3 判 success


6. 实测确认(测试服 9443 + 真实 admin token,订单 2067532338723504130

  • GET /v3/admin/order/{id}:明文证件号 152522198605311079、手机号 18547062756、备注 测试测试 哈哈哈哈、profileStatus COMPLETED 均正常返回 ✓
  • GET /v3/admin/order/{id}/traveler/list:证件号为脱敏 152***********1079、手机号 185****2756(确认前端用错了脱敏源会留空)✓
  • PUT /v3/admin/order/{id}/traveler-info保留明文值HTTP 200 success=trueallCompleted=true
  • PUT空紧急联系人,PR #4041 部署后):返 581109「紧急联系人姓名和电话必填」、不落库 ✓
  • PUT(紧急联系人电话格式非法):返 581113「手机号格式非法」 ✓
  • PUT(姓名 + 合法电话齐全HTTP 200 success=true 回归正常 ✓
  • 连续两次 PUT:第二次 success=false(确认 3 秒幂等窗口,前端需判 success)✓
  • 测试结束已将订单数据恢复原状(紧急联系人 1/18547056215、证件号、profileStatus 均完好)✓

备注

  • 问题 ①③ 为前端缺陷(无后端代码变更),走本 changelog 通知前端同事,不建工单。
  • 问题 ② 紧急联系人必填后端门禁经 PR #4041 补强(新增错误码 581109,复用 581113无 DDL、无新增接口),已合并 dev-v3 + 部署测试服实测;对应工单 #4040(已关)。
  • 后端明文回显能力(TravelerPlainVO)为 #3509 已上线特性,admin 端业务例外、需 admin 权限,前端可放心使用。