文件
hl-api-changelog/changelogs/2026-07/24_5203_出行人资料完整度语义.md
yaosutu 614cad68e6
changelog-filename-gate / validate (push) Successful in 2s
通知小程序出行人资料完整度语义变更
2026-07-24 17:47:04 +08:00

12 KiB

🔧 出行人批量编辑:资料完整度与完成统计统一为订单级手机号语义(#5203)

PR: #5210 Issue: #5203 日期: 2026-07-24 消费端: 一期小程序 MP BFF 接口: POST /mp/v3/order/{id}/traveler/batch-edit

1. 变更背景

出行人资料完整度与订单签约、确认门禁此前存在两套手机号口径:逐人完成状态可能要求每名成人都有手机号,但订单门禁只要求整单至少一名出行人有手机号。

本次统一为:

  • 单名出行人的资料完整度只检查 name、gender、birthday、idType、idNo 五项;
  • phone 不再影响该出行人的完成状态;
  • 订单整体仍必须至少有一名出行人填写手机号;
  • 接口字段名、类型和层级不变,但 completedCount、pendingCount、allCompleted 的统计结果可能变化。

2. 变更接口

接口 方法 路径 变更类型
客户批量补全出行人 POST /mp/v3/order/{id}/traveler/batch-edit 响应字段语义修改

3. 完整接口契约

3.1 调用约束

项目 契约
认证 需要小程序登录态
可编辑订单状态 PENDING_PAY(待支付)、CUSTOMIZING(定制中)
订单归属 只能编辑当前登录用户自己的订单
幂等 同一订单 3 秒内重复提交返回 100502
批量上限 每次 1~30 名出行人
写入语义 id=null 为新增,id 非空为更新;未出现在数组中的已有出行人不会被删除

3.2 路径参数

字段 类型 必填 说明
id Long 是 订单 ID;建议以字符串形式传递,避免大整数精度丢失

3.3 请求体

请求类型:TravelerBatchEditReqVO

字段 类型 必填 约束与语义
travelers TravelerEditItem[] 是 1~30 项
travelers[].id Long / null 否 null 表示新增;非空表示更新,且必须属于路径中的订单
travelers[].name String / null 条件必填 新增项的 name、idType、idNo 至少一项非空;有值时长度 2~30,只允许中文、英文、中点 ·、连字符 -、空格
travelers[].gender String / null 否 0、1、2;该字段为空时资料状态为 PENDING
travelers[].birthday String 是 yyyy-MM-dd,不得晚于当天;用于派生出行人类型
travelers[].idType String / null 条件必填 取值见第 4 节;与 idNo 配套
travelers[].idNo String / null 条件必填 ID_CARD 为 18 位数字或末位 X/x;其他证件为 5~30 位字母、数字或连字符
travelers[].nationality String / null 否 允许不传或传 null,不允许显式传空字符串
travelers[].race String / null 否 允许不传或传 null,不允许显式传空字符串
travelers[].phone String / null 否 有值时必须为 11 位数字;更新时 null 表示保留原值,空字符串表示清空
travelers[].emergencyContact String / null 否 出行人级紧急联系人姓名
travelers[].emergencyPhone String / null 否 有值时必须为 11 位数字
travelers[].roomGroupNo Integer / null 否 最小为 1,最大不超过订单声明总人数

更新已有出行人时,除必填的 birthday 外,其他可选字段传 null 表示保留原值。

3.4 响应

响应类型:Result<TravelerBatchEditRespVO>

统一响应字段:

字段 类型 说明
code Integer 200 表示成功,其他值见第 5 节
message String 响应文案
data Object / null 成功时为批量编辑统计,失败时通常为 null
traceId String / null 链路追踪 ID,可能为空
success Boolean code == 200 时为 true

data 字段:

字段 类型 说明
createdCount Integer 本次请求中 id=null 的新增数量
updatedCount Integer 本次请求中 id 非空的更新数量
completedCount Integer 操作完成后,订单内五项资料均完整的出行人总数
pendingCount Integer 操作完成后,订单内五项资料仍有缺失的出行人总数
allCompleted Boolean 同时满足“订单声明人数大于 0、实际人数等于声明人数、pendingCount=0、整单至少一名出行人有手机号”时为 true

五项资料指:name、gender、birthday、idType、idNo。手机号不计入单名出行人的完成状态,但仍计入 allCompleted 的订单级门禁。

4. 枚举与数据字典

4.1 gender

值 中文 完整度语义
0 未知 有值,满足 gender 完整度
1 男 有值,满足 gender 完整度
2 女 有值,满足 gender 完整度

4.2 资料完成状态

该状态不单独出现在本接口响应中,但直接决定 completedCount 和 pendingCount。

值 中文 判定
COMPLETED 已完善 name/gender/birthday/idType/idNo 五项全部非空
PENDING 待完善 上述五项任一为空

4.3 idType

值 中文
ID_CARD 身份证
PASSPORT 护照
HK_MACAU_PASS 港澳通行证
HONGKONG_RESIDENT_PASS 回乡证
TAIWAN_PASS 台湾通行证
MILITARY_ID 军官证
OTHER 其他

4.4 出行人类型

出行人类型不由请求体传入,而是根据 birthday 自动派生,并用于校验订单各类型人数配额。

年龄 值 中文
未满 2 周岁 BABY 幼童
2~6 周岁 YOUNG_CHILD 小童
7~17 周岁 CHILD 儿童
18 周岁及以上 ADULT 成人

5. 错误码

code message / 含义 触发场景
401 未认证 未携带有效小程序登录态
500 出行人服务不可用,请稍后重试 BFF 无法调用出行人服务
100001 参数非法 travelers 为空、超过 30 项、缺少 birthday、日期格式错误等请求校验失败
100502 出行人补全处理中,请勿重复提交 同一订单 3 秒内重复提交
100503 资源被占用,请稍后重试 同一订单存在并发写入且未能取得操作权
100701 姓名长度异常(2-30字符) 非空姓名长度不在 2~30 字符
100702 姓名含非法字符 姓名包含允许字符集之外的内容
100703 姓名含敏感词 姓名命中敏感词
100704 姓名格式不正确 同一字符连续重复 5 次及以上
581101 12301 必报字段缺失(国籍 / 民族不能为空字符串) nationality 或 race 显式传空字符串
581102 订单不存在,无法编辑出行人 处理过程中订单不存在
581103 性别编码不合法(应为 1=男/2=女/0=未知) 非空 gender 不在 0/1/2
581104 同住分组号超出订单家庭数上限 roomGroupNo < 1 或超过订单声明总人数
581110 出行人 ID 不属于该订单 更新项的 id 不属于路径订单
581111 已签电子合同后禁止修改证件号 已签约记录尝试修改 idNo
581112 证件号格式不合法,请检查证件类型与号码是否匹配 idType 非法或 idNo 格式不匹配
581113 手机号格式非法(应为 11 位数字) 非空 phone 或 emergencyPhone 不是 11 位数字
581114 出生日期不能晚于今天 birthday 为未来日期
581118 新增出行人缺少必填字段 新增项的 name/idType/idNo 全部为空
581119 出行人证件号重复 同一请求或订单内出现重复证件号
581122 订单不属于当前用户 订单不存在或不属于当前登录用户
581145 订单已确认,出行人信息不可再经小程序修改,如需变更请联系定制师 订单状态不在 PENDING_PAY/CUSTOMIZING 白名单
581149 出行人类型人数超出订单人数配置 根据生日派生后的某类出行人数超过订单声明配额

6. 示例

6.1 典型成功:两人五项完整,仅一人有手机号

请求

POST /mp/v3/order/2079576729147338754/traveler/batch-edit
Authorization: Bearer <mp-token>
Content-Type: application/json
{
  "travelers": [
    {
      "id": "2079576729147338801",
      "name": "张三",
      "gender": "1",
      "birthday": "1990-01-01",
      "idType": "PASSPORT",
      "idNo": "P1234567",
      "nationality": "中国",
      "race": "汉族",
      "phone": "13800138000",
      "emergencyContact": null,
      "emergencyPhone": null,
      "roomGroupNo": 1
    },
    {
      "id": "2079576729147338802",
      "name": "李四",
      "gender": "2",
      "birthday": "1992-02-02",
      "idType": "PASSPORT",
      "idNo": "P7654321",
      "nationality": "中国",
      "race": "汉族",
      "phone": "",
      "emergencyContact": null,
      "emergencyPhone": null,
      "roomGroupNo": 1
    }
  ]
}

响应

{
  "code": 200,
  "message": "成功",
  "data": {
    "createdCount": 0,
    "updatedCount": 2,
    "completedCount": 2,
    "pendingCount": 0,
    "allCompleted": true
  },
  "traceId": "a1b2c3d4-e5f6-7890",
  "success": true
}

6.2 边界成功:五项全部完整,但整单没有手机号

假设订单声明人数和实际人数均为 2,且请求将最后一部手机号清空。

请求

POST /mp/v3/order/2079576729147338754/traveler/batch-edit
Authorization: Bearer <mp-token>
Content-Type: application/json
{
  "travelers": [
    {
      "id": "2079576729147338801",
      "name": "张三",
      "gender": "1",
      "birthday": "1990-01-01",
      "idType": "PASSPORT",
      "idNo": "P1234567",
      "phone": ""
    },
    {
      "id": "2079576729147338802",
      "name": "李四",
      "gender": "2",
      "birthday": "1992-02-02",
      "idType": "PASSPORT",
      "idNo": "P7654321",
      "phone": ""
    }
  ]
}

响应

{
  "code": 200,
  "message": "成功",
  "data": {
    "createdCount": 0,
    "updatedCount": 2,
    "completedCount": 2,
    "pendingCount": 0,
    "allCompleted": false
  },
  "traceId": "a1b2c3d4-e5f6-7890",
  "success": true
}

这里 completedCount=2 表示两人的五项资料都完整;allCompleted=false 表示订单级“至少一名出行人有手机号”门禁未满足。

6.3 业务失败:订单已确认

请求

POST /mp/v3/order/2079576729147338754/traveler/batch-edit
Authorization: Bearer <mp-token>
Content-Type: application/json
{
  "travelers": [
    {
      "id": "2079576729147338801",
      "name": "张三",
      "gender": "1",
      "birthday": "1990-01-01",
      "idType": "PASSPORT",
      "idNo": "P1234567",
      "phone": "13800138000"
    }
  ]
}

响应

{
  "code": 581145,
  "message": "订单已确认,出行人信息不可再经小程序修改,如需变更请联系定制师",
  "data": null,
  "traceId": "a1b2c3d4-e5f6-7890",
  "success": false
}

7. 修改前后对比

场景 修改前 修改后
单名成人五项完整但本人无手机号 可能计入 pendingCount 计入 completedCount
同行人已有手机号 仍可能要求每名成人各自填写 整单手机号门禁已满足
五项完整且整单无手机号 逐人完成状态与手机号门禁混合 completedCount 可等于实际人数,但 allCompleted=false
请求 / 响应结构 现有字段 不变

8. 消费注意事项

  • 不要按“每名成人必须有手机号”在本地重算资料完成状态。
  • completedCount 和 pendingCount 是操作后订单内的总量,不是本次请求中发生状态变化的行数。
  • 判断本接口是否已满足整单补全条件,以响应 allCompleted 为准;它已同时包含人数、五项资料和订单级手机号门禁。
  • phone=null 在更新场景表示保留原值;需要清空手机号时传空字符串。

9. 关联