From 231f2e0411294274fe36ba082bd24af9d814210d Mon Sep 17 00:00:00 2001 From: yaosutu <770858045@qq.com> Date: Tue, 11 Aug 2026 17:40:23 +0800 Subject: [PATCH] =?UTF-8?q?changelog(#5855):=20=E5=87=BA=E8=A1=8C=E4=BA=BA?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E6=96=B0=E5=A2=9E"=E8=87=B3=E5=B0=91?= =?UTF-8?q?=E4=B8=80=E5=90=8D=E6=88=90=E4=BA=BA=E5=BF=85=E9=A1=BB=E5=A1=AB?= =?UTF-8?q?=E6=89=8B=E6=9C=BA=E5=8F=B7"=E6=9C=8D=E5=8A=A1=E7=AB=AF?= =?UTF-8?q?=E7=A1=AC=E6=A0=A1=E9=AA=8C=EF=BC=88PR=20#5858=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 涉及 PUT traveler-info / POST batch-edit / POST add 三个保存入口, 新增错误码 581136;validate 接口 blockReasons 文案同步收紧为"成人"。 入参/出参结构无变化,前端按 code!=200 toast 约定即可兼容。 --- ...存校验至少一成人填手机号-修改接口-管理后台.md | 160 ++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 changelogs-v2/2026-08/11_5855_出行人保存校验至少一成人填手机号-修改接口-管理后台.md diff --git a/changelogs-v2/2026-08/11_5855_出行人保存校验至少一成人填手机号-修改接口-管理后台.md b/changelogs-v2/2026-08/11_5855_出行人保存校验至少一成人填手机号-修改接口-管理后台.md new file mode 100644 index 0000000..141d782 --- /dev/null +++ b/changelogs-v2/2026-08/11_5855_出行人保存校验至少一成人填手机号-修改接口-管理后台.md @@ -0,0 +1,160 @@ +--- +schema: "hl-changelog/v2" +ticket: "5855" +title: "出行人保存新增「至少一名成人必须填手机号」服务端硬校验(新增错误码 581136)" +consumer: "admin" +change_type: "修改接口" +author: "yst" +backend_status: "deployed" +gateway_status: "not_required" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "" +status_note: "" +updated_at: "2026-08-11" +base: "dev-v3" +--- + +# 出行人保存新增「至少一名成人必须填手机号」服务端硬校验(#5855 / PR #5858) + +## 1. 接口背景 + +电子合同签署要求订单中至少有一名成人出行人预留手机号(用于接收签署短信)。此前该约束只在 `traveler/validate` 校验接口里做软提示,保存接口本身不拦截,导致可以保存出"无成人有手机号"的订单,后续签约环节才暴露问题。本次在出行人保存链路上补齐服务端硬校验:保存时若"最终生效的出行人集合"中没有任何一名成人填写手机号,整个保存请求被拒绝(不写库),并返回新增错误码 `581136`。 + +## 2. 变更清单 + +| # | 接口 | 变更类型 | 说明 | +|---|------|----------|------| +| 1 | `PUT /v3/admin/order/{id}/traveler-info` | 新增服务端校验 | 补全出行信息(全量同步)保存时新增硬校验,触发返回 581136 | +| 2 | `POST /v3/admin/order/{id}/traveler/batch-edit` | 新增服务端校验 | 批量编辑出行人保存时新增硬校验,触发返回 581136 | +| 3 | `POST /v3/admin/order/{id}/traveler/add` | 新增服务端校验 | 单个新增出行人时新增硬校验,触发返回 581136 | +| 4 | `GET /v3/admin/order/{id}/traveler/validate` | 出参文案收紧 | `blockReasons[]` 文案由"至少需要一名出行人填写手机号"收紧为"至少需要一名成人出行人填写手机号",判定口径同步收紧 | + +> 说明:删除出行人接口**不**加此校验。入参 / 出参结构、字段名、类型均无变化。 + +## 3. 接口详情 + +| 项 | 值 | +|---|---| +| 方法 + 路径 | `PUT /v3/admin/order/{id}/traveler-info`;`POST /v3/admin/order/{id}/traveler/batch-edit`;`POST /v3/admin/order/{id}/traveler/add`;`GET /v3/admin/order/{id}/traveler/validate` | +| 使用场景 | 管理后台订单详情 - 出行人 Tab:补全出行信息 / 批量编辑 / 单个新增 / 保存前校验 | +| 认证 | 管理后台 JWT(admin 端) | +| 幂等性 | PUT traveler-info 为全量同步天然幂等;batch-edit / add 为普通写操作 | +| 限流 | 无特殊限流 | + +## 4. 接口入参 + +入参结构**无变化**,此处仅强调与本校验相关的字段语义。 + +### 4.1 路径参数 + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| id | Long | 是 | 订单 ID | + +### 4.2 请求体关键字段(出行人行) + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| travelerType | String | 是 | 出行人类型,`ADULT`=成人;本校验只统计成人行 | +| phone | String | 否 | 手机号。更新时传 `null`=保留原值(不修改),传 `""` 空串=清空;若清空后无任何成人有手机,触发 581136 | + +## 5. 出参字段 + +三个保存接口出参结构**无变化**,仍为统一 `Result`: + +| 字段 | 类型 | 说明 | +|------|------|------| +| code | Integer | `200`=成功;`581136`=本次新增的"无成人有手机号"业务错误 | +| success | Boolean | 成功 true / 失败 false | +| message | String | 失败时为错误文案,前端直接 toast | +| data | T | 成功时的业务数据(结构不变) | + +`GET /traveler/validate` 出参 `blockReasons[]`(String 数组)中文案变化: + +| 原来 | 现在 | +|------|------| +| 至少需要一名出行人填写手机号用于合同签署 | 至少需要一名**成人**出行人填写手机号用于合同签署 | + +## 6. 枚举 / 数据字典 + +| 枚举 | 取值 | 说明 | +|------|------|------| +| travelerType | `ADULT` | 成人,本校验的统计对象 | +| travelerType | 其他(儿童等) | 不计入"是否有手机"判定 | + +## 7. 错误码 + +| code | message | 触发条件 | +|------|---------|----------| +| 581136 | 至少需要一名成人出行人填写手机号用于合同签署 | 保存后"最终生效的出行人集合"中没有任何一名成人(travelerType=ADULT)填写手机号;整个请求被拒,不写库 | + +## 8. 示例 + +### 8.1 典型成功(至少 1 名成人有手机) + +请求 `PUT /v3/admin/order/123/traveler-info`,出行人中含成人且至少一名成人 phone 非空: + +```json +{ + "code": 200, + "success": true, + "message": "success", + "data": { } +} +``` + +### 8.2 边界(成人 phone 传 null 保留原值) + +更新出行人时成人行 `phone: null` 表示保留原手机号不修改,只要原有数据里仍有成人有手机即通过校验,响应同 8.1。 + +### 8.3 业务失败(无任何成人有手机 → 581136) + +请求 `PUT /v3/admin/order/123/traveler-info`,提交的所有成人 phone 均为空(或清空): + +```json +{ + "code": 581136, + "success": false, + "message": "至少需要一名成人出行人填写手机号用于合同签署", + "data": null +} +``` + +出行人**未落库**,前端按 Result 约定 `code != 200` toast `message` 即可。 + +## 9. 业务边界 + +- 适用:订单出行人的补全 / 批量编辑 / 单个新增保存。 +- 不适用:删除出行人接口(删除不加此校验,即使删完后无成人有手机也不拦截删除动作本身)。 +- 特殊边界:校验看的是"保存后最终生效的集合",不是单条提交行——例如 batch-edit 把唯一有手机的成人 phone 清空,即使其他行不变也会触发 581136。 + +## 10. 修改前后对比 + +| 维度 | 原来 | 现在 | +|------|------|------| +| 保存接口校验 | 不校验"成人是否有手机",可保存出无成人手机号的订单 | 保存时硬校验,无成人有手机则整单拒存,返回 581136 | +| validate 判定口径 | 任意出行人有手机即通过 | 必须是**成人**有手机才通过 | +| validate blockReasons 文案 | 至少需要一名出行人填写手机号用于合同签署 | 至少需要一名成人出行人填写手机号用于合同签署 | +| 入参 / 出参结构 | — | 无变化 | + +## 11. 影响评估 / 回滚 + +- 破坏兼容:否。入参 / 出参结构不变,仅新增一个业务错误码与文案收紧。 +- 前端同步上线:非强制。前端按现有 `code != 200` toast 约定即可天然兼容;建议在补全 / 编辑出行人表单对成人行补充"至少一名成人需填手机号"的提示,提升体验。 +- 回滚方案:后端回滚 PR #5858 即恢复原行为,前端无需改动。 + +## 12. 注意事项 + +- 581136 通过 HTTP 200 + `code=581136` 返回(Result 约定),**不是** HTTP 4xx/5xx,前端拦截器按业务 code 处理。 +- `phone` 字段更新语义:`null`=保留原值,`""`=清空。前端表单回显时注意区分"未改动"与"主动清空"。 +- 删除出行人不受此校验约束。 + +## 13. 关联 / 联系人 + +- Issue: https://git.1814.love:8443/wx/HL/issues/5855 +- PR: https://git.1814.love:8443/wx/HL/pulls/5858 +- Commit: https://git.1814.love:8443/wx/HL/commit/06f03e40c3 +- 后端负责人:腰苏图(yst)