hl-api-changelog/changelogs-v2/2026-07/24_5203_出行人手机号订单级门禁-修改接口-管理后台.md
Mimingguang f4ed055581
一些检查失败了
changelog-filename-gate / validate (push) Failing after 1s
chore(changelog): 标记前端已领取 #5203
修改原因:hl-ui changelog loop 需要把前端消费进度回写到契约源,避免领取、实现状态与实际交付脱节。

修改内容:将 frontend_status 与已有 legacy frontend 同步为 claimed,记录负责人 hl-ui-codex,实现引用保持为空;发布和验收字段保持不变。

实际验证:回写器已校验目标文件、状态单调性、提交范围和 Front Matter 内容,提交只包含当前 changelog。

Frontend-Status: tools/mcp-api-sync/.changelog-repo/changelogs-v2/2026-07/24_5203_出行人手机号订单级门禁-修改接口-管理后台.md
2026-07-24 17:48:11 +08:00

35 KiB

schema, ticket, title, consumer, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
schema ticket title consumer change_type backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at status_note updated_at base
hl-changelog/v2 5203 出行人手机号改为订单级门禁 admin 修改接口 deployed verified claimed hl-ui-codex 后端新语义已发布;前端需按逐人五项资料和订单级手机号门禁消费 2026-07-24T09:48:11.001Z dev-v3

🔧【修改接口·管理后台】出行人手机号改为订单级门禁(#5203

PR: #5210 服务: hl-order-service-v3 更新时间: 2026-07-24 影响范围: 订单详情、出行人维护/校验、确认订单前置检查与确认提交

1. 接口背景

出行人逐人资料状态与订单签约门禁原来使用了冲突口径:成人没有手机号时,逐人的 profileStatus 会是 PENDING;但确认订单只需要整单至少一名出行人提供手机号。

本次统一为两层规则:

  1. 逐人资料完整度只检查 namegenderbirthdayidTypeidNo 五项。
  2. 手机号是订单级门禁:整单至少一名出行人填写手机号,才允许校验通过、自动推进和确认行程。

手机号字段本身没有删除,所有请求和响应结构保持不变;变化的是 profileStatus、完成数统计、missingFields 和确认门禁的字段语义。

变更接口

# 接口 方法 路径 变更类型 本次变化
1 订单详情 GET /v3/admin/order/{id} 出参语义修改 overview.customerInfo.travelers[].profileStatus 改用逐人五项资料判断
2 出行人列表 GET /v3/admin/order/{id}/traveler/list 出参语义修改 profileStatus 改用逐人五项资料判断
3 批量编辑出行人 POST /v3/admin/order/{id}/traveler/batch-edit 出参语义修改 完成数与 allCompleted 不再逐人要求手机号;自动推进仍要求整单至少一部手机号
4 单个新增出行人 POST /v3/admin/order/{id}/traveler/add 出参语义修改 无手机号但五项资料齐全时返回 COMPLETED
5 补全出行信息 PUT /v3/admin/order/{id}/traveler-info 出参语义修改 完成数与 allCompleted 改用逐人五项资料判断;自动推进仍保留订单级手机号门禁
6 智能批量解析 POST /v3/admin/order/{id}/traveler/smart-parse 出参语义修改 预览和入库结果的 profileStatus 改用逐人五项资料判断
7 出行人信息校验 GET /v3/admin/order/{id}/traveler/validate 出参枚举语义修改 missingFields 删除 phone,增加 genderbirthday;无任何手机号改由 blockReasons 表达
8 确认订单前置检查 GET /v3/admin/order/{id}/confirm-checklist 出参语义修改 TRAVELER_COMPLETE 先检查逐人五项,再检查整单至少一部手机号
9 确认行程 POST /v3/admin/order/{id}/confirm-itinerary 行为修改 每人无须都有手机号;整单完全无手机号仍返回 581036

3. 接口详情

所有接口均使用管理后台 JWT。除批量编辑、单个新增、补全出行信息外,接口没有额外幂等窗口。 公共响应包装为:

字段 类型 说明
code Integer 200 表示成功;业务失败返回业务错误码
message String 响应说明
data 见各接口 业务数据;失败时通常为 null
success Boolean 是否成功

3.1 订单详情

  • 方法/路径: GET /v3/admin/order/{id}
  • 使用场景: 打开订单详情,读取主单、标签和概览中的出行人。
  • 幂等性: 是,只读。
  • 路径参数:
字段 类型 必填 说明
id Long 订单 ID
  • 响应: Result<OrderDetailRespVO>
字段 类型 说明
data.main OrderMainVO 订单主单、进度和各 Tab 状态;本次字段结构未变
data.tags[] TagVO[] 标签列表;每项含 namecolorcreator
data.overview.customerInfo CustomerInfoVO 客户信息
data.overview.customerInfo.contactName String/null 联系人
data.overview.customerInfo.contactPhone String/null 联系电话
data.overview.customerInfo.agencyName String/null 商户名
data.overview.customerInfo.consultantName String/null 定制师姓名
data.overview.customerInfo.peopleSummary String/null 人数摘要
data.overview.customerInfo.adultCount Integer 成人数
data.overview.customerInfo.childCount Integer 儿童数
data.overview.customerInfo.youngChildCount Integer 小童数
data.overview.customerInfo.babyCount Integer 幼童数
data.overview.customerInfo.createTime String/null 创建时间,格式 yyyy-MM-ddTHH:mm:ss
data.overview.customerInfo.emergencyContactName String/null 订单紧急联系人姓名
data.overview.customerInfo.emergencyContactPhone String/null 订单紧急联系人电话
data.overview.customerInfo.travelers[] TravelerPlainVO[] 出行人列表;字段见下表
data.overview.remarkInfo.customerRemark String/null 客户备注
data.overview.remarkInfo.consultantRemark String/null 定制师备注
data.overview.remarkInfo.hotelRemark String/null 用房备注
data.overview.remarkInfo.vehicleRemark String/null 用车备注
data.unreadMessageCount Integer 联系房务未读数;无会话或降级时为 0

TravelerPlainVO 完整字段:

字段 类型 说明
id Long 出行人 ID
orderId Long 订单 ID
travelerType String 出行人类型
travelerTypeName String/null 出行人类型中文名
name String/null 姓名
gender String/null 性别
birthday String/null 出生日期,yyyy-MM-dd
idType String/null 证件类型
idTypeName String/null 证件类型中文名
idCard String/null 证件号
nationality String/null 国籍
race String/null 民族
phone String/null 出行人手机号
emergencyContact String/null 紧急联系人姓名
emergencyPhone String/null 紧急联系人电话
roomGroupNo Integer/null 同住分组号
profileStatus String PENDING / COMPLETED;本次语义见第 6 节
transportPlanIds[] Long[] 关联大交通批次 ID
  • 错误码: 581007 订单不存在;581045 房务角色无权查看订单详情。
  • 业务边界: 出行人没有手机号但五项资料齐全时,profileStatus=COMPLETED
  • 典型示例:

请求

GET /v3/admin/order/2079576729147338754
Authorization: Bearer <admin-token>

响应

{
  "code": 200,
  "message": "success",
  "data": {
    "main": {
      "id": "2079576729147338754",
      "orderNo": "HL202607240001",
      "orderStatus": "CUSTOMIZING",
      "flowStatus": "AWAITING_CONFIRM"
    },
    "tags": [],
    "overview": {
      "customerInfo": {
        "contactName": "张三",
        "adultCount": 2,
        "childCount": 0,
        "youngChildCount": 0,
        "babyCount": 0,
        "travelers": [
          {
            "id": "2079576729147338801",
            "name": "张三",
            "gender": "1",
            "birthday": "1990-01-01",
            "idType": "ID_CARD",
            "idCard": "110101199001011234",
            "phone": "13800138000",
            "profileStatus": "COMPLETED",
            "transportPlanIds": []
          },
          {
            "id": "2079576729147338802",
            "name": "李四",
            "gender": "2",
            "birthday": "1992-02-02",
            "idType": "ID_CARD",
            "idCard": "110101199202021235",
            "phone": null,
            "profileStatus": "COMPLETED",
            "transportPlanIds": []
          }
        ]
      },
      "remarkInfo": {
        "customerRemark": null,
        "consultantRemark": null,
        "hotelRemark": null,
        "vehicleRemark": null
      }
    },
    "unreadMessageCount": 0
  },
  "success": true
}

3.2 出行人列表

  • 方法/路径: GET /v3/admin/order/{id}/traveler/list
  • 使用场景: 加载出行人 Tab。
  • 幂等性: 是,只读。
  • 路径参数: id,Long,必填,订单 ID。
  • 响应: Result<List<TravelerVO>>

TravelerVO 完整字段:

字段 类型 说明
idorderId Long 出行人 ID、订单 ID
travelerTypetravelerTypeName String/null 出行人类型及中文名
name String/null 姓名
gender String/null 性别
birthday String/null 出生日期
idTypeidTypeName String/null 证件类型及中文名
idCardMasked String/null 脱敏证件号
idProvinceCodeidProvinceName String/null 大陆身份证省级代码及名称
nationalityrace String/null 国籍、民族
phoneMasked String/null 脱敏手机号
emergencyContact String/null 紧急联系人姓名
emergencyPhoneMasked String/null 脱敏紧急联系电话
roomGroupNo Integer/null 同住分组号
profileStatus String PENDING / COMPLETED
transportPlanIds[] Long[] 关联大交通批次 ID
  • 错误码: 581102 订单不存在。
  • 业务边界: 空列表返回 data=[];手机号为空不再单独令 profileStatus 变成 PENDING
  • 典型示例:

请求

GET /v3/admin/order/2079576729147338754/traveler/list
Authorization: Bearer <admin-token>

响应

{
  "code": 200,
  "message": "success",
  "data": [
    {
      "id": "2079576729147338802",
      "orderId": "2079576729147338754",
      "travelerType": "ADULT",
      "travelerTypeName": "成人",
      "name": "李四",
      "gender": "2",
      "birthday": "1992-02-02",
      "idType": "ID_CARD",
      "idTypeName": "身份证",
      "idCardMasked": "110***********1235",
      "idProvinceCode": "11",
      "idProvinceName": "北京市",
      "nationality": "中国",
      "race": "汉族",
      "phoneMasked": null,
      "emergencyContact": null,
      "emergencyPhoneMasked": null,
      "roomGroupNo": 1,
      "profileStatus": "COMPLETED",
      "transportPlanIds": []
    }
  ],
  "success": true
}

3.3 批量编辑出行人

  • 方法/路径: POST /v3/admin/order/{id}/traveler/batch-edit
  • 使用场景: 一次新增或更新最多 30 名出行人。
  • 幂等性: 同一订单 3 秒内重复提交会被拒绝。
  • 路径参数: id,Long,必填,订单 ID。
  • 请求体: TravelerBatchEditReqVO
字段 类型 必填 约束
travelers TravelerEditItem[] 130 项
travelers[].id Long/null null 新增;非空更新且必须属于本订单
travelers[].name String/null 条件必填 新增项 name/idType/idNo 至少一项非空
travelers[].gender String/null 0 / 1 / 2
travelers[].birthday String 不得晚于今天;用于派生人群类型
travelers[].idType String/null 条件必填 取值见第 6 节
travelers[].idNo String/null 条件必填 与证件类型匹配
travelers[].nationality String/null 不可传空字符串
travelers[].race String/null 不可传空字符串
travelers[].phone String/null 有值时必须为 11 位数字
travelers[].emergencyContact String/null 出行人级紧急联系人
travelers[].emergencyPhone String/null 有值时必须为 11 位数字
travelers[].roomGroupNo Integer/null 不得超过订单家庭数上限
  • 响应: Result<TravelerBatchEditRespVO>
字段 类型 说明
data.createdCount Integer 本次新增数
data.updatedCount Integer 本次更新数
data.completedCount Integer 操作后五项资料完整的出行人数
data.pendingCount Integer 操作后五项资料不完整的出行人数
data.allCompleted Boolean 所有出行人的五项资料是否完整;不表示整单手机号门禁已通过
  • 错误码: 581101581102581103581104581105581110581111581112581113581114581118581119581146581147581148581149
  • 业务边界: 两人五项资料齐全且仅一人有手机号时, completedCount=2pendingCount=0allCompleted=true,同时满足订单级手机号门禁。
  • 典型示例:

请求

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

响应

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

3.4 单个新增出行人

  • 方法/路径: POST /v3/admin/order/{id}/traveler/add
  • 使用场景: 在订单声明人数尚未补齐时新增一名出行人。
  • 幂等性: 同一订单 3 秒内重复提交会被拒绝。
  • 路径参数: id,Long,必填,订单 ID。
  • 请求体:
字段 类型 必填 约束
name String/null 姓名
gender String/null 0 / 1 / 2
birthday String 不得晚于今天
idType String/null 证件类型
idNo String/null 证件号
nationalityrace String/null 默认中国、汉族
phone String/null 有值时 11 位数字
emergencyContactemergencyPhone String/null 出行人级紧急联系人
roomGroupNo Integer/null 同住分组号
  • 响应: Result<TravelerVO>,完整字段同 3.2。
  • 错误码: 581102581103581104581112581113581114581115581116581119581146581147581148581149
  • 业务边界: 五项资料齐全、phone=null 时,新行可返回 profileStatus=COMPLETED; 若订单其他出行人也都没有手机号,整单仍不能通过订单级门禁。
  • 典型示例:

请求

POST /v3/admin/order/2079576729147338754/traveler/add
Authorization: Bearer <admin-token>
Content-Type: application/json
{
  "name": "李四",
  "gender": "2",
  "birthday": "1992-02-02",
  "idType": "ID_CARD",
  "idNo": "110101199202021235",
  "nationality": "中国",
  "race": "汉族",
  "phone": null,
  "roomGroupNo": 1
}

响应

{
  "code": 200,
  "message": "success",
  "data": {
    "id": "2079576729147338802",
    "orderId": "2079576729147338754",
    "travelerType": "ADULT",
    "name": "李四",
    "gender": "2",
    "birthday": "1992-02-02",
    "idType": "ID_CARD",
    "idCardMasked": "110***********1235",
    "phoneMasked": null,
    "profileStatus": "COMPLETED",
    "transportPlanIds": []
  },
  "success": true
}

3.5 补全出行信息

  • 方法/路径: PUT /v3/admin/order/{id}/traveler-info
  • 使用场景: 全量同步出行人,并保存订单级紧急联系人和客户备注。
  • 幂等性: 同一订单 3 秒内重复提交会被拒绝。
  • 路径参数: id,Long,必填,订单 ID。
  • 请求体:
字段 类型 必填 约束
travelers TravelerEditItem[] 全量列表,130 项;单项字段同 3.3
emergencyContactName String 订单级紧急联系人姓名
emergencyContactPhone String 11 位数字
customerRemark String/null 客户备注
  • 响应:
字段 类型 说明
data.createdCount Integer 新增数
data.updatedCount Integer 更新数
data.deletedCount Integer 原有但未出现在本次全量列表中的删除数
data.completedCount Integer 五项资料完整人数
data.pendingCount Integer 五项资料不完整人数
data.allCompleted Boolean 所有人五项资料是否完整;不等同于手机号门禁通过
  • 错误码: 581102581103581104581109581110581111581112581113581114581118581119581146581147581148581149
  • 业务边界: travelers 为全量数据;五项资料全部完整但整单没有任何出行人手机号时, allCompleted=true,但流程不会自动越过订单级手机号门禁。
  • 典型示例:

请求

PUT /v3/admin/order/2079576729147338754/traveler-info
Authorization: Bearer <admin-token>
Content-Type: application/json
{
  "travelers": [
    {
      "id": "2079576729147338801",
      "name": "张三",
      "gender": "1",
      "birthday": "1990-01-01",
      "idType": "ID_CARD",
      "idNo": "110101199001011234",
      "phone": "13800138000"
    },
    {
      "id": "2079576729147338802",
      "name": "李四",
      "gender": "2",
      "birthday": "1992-02-02",
      "idType": "ID_CARD",
      "idNo": "110101199202021235",
      "phone": null
    }
  ],
  "emergencyContactName": "王五",
  "emergencyContactPhone": "13900139000",
  "customerRemark": null
}

响应

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

3.6 智能批量解析

  • 方法/路径: POST /v3/admin/order/{id}/traveler/smart-parse
  • 使用场景: 将多行“姓名、身份证、手机号”文本解析为出行人,可预览或直接保存。
  • 幂等性/限流: 每名管理员每分钟最多 10 次;dryRun=true 只读。
  • 请求体:
字段 类型 必填 约束
rawText String 非空,最多 20000 字符
dryRun Boolean 默认 falsetrue 仅预览
  • 响应:
字段 类型 说明
data.successCount Integer 成功解析行数
data.failCount Integer 失败行数
data.successList[] TravelerVO[] 成功结果,字段同 3.2;预览时 id 可为 null
data.failures[].lineIndex Integer 原文有效行序号,从 1 起
data.failures[].maskedSnippet String 脱敏原文片段
data.failures[].reason String 中文失败原因
  • 错误码: 100501 调用过于频繁;581102 订单不存在;581131 原文超长; 581132 原文为空或全行无法解析;581134 当前订单状态不允许批量导入。
  • 业务边界: 成功行五项资料齐全时,即使没有解析到手机号也返回 profileStatus=COMPLETED;整单手机号门禁仍在校验和确认阶段单独判断。
  • 典型示例:

请求

POST /v3/admin/order/2079576729147338754/traveler/smart-parse
Authorization: Bearer <admin-token>
Content-Type: application/json
{
  "rawText": "李四 110101199202021235",
  "dryRun": true
}

响应

{
  "code": 200,
  "message": "success",
  "data": {
    "successCount": 1,
    "failCount": 0,
    "successList": [
      {
        "id": null,
        "name": "李四",
        "gender": "2",
        "birthday": "1992-02-02",
        "idType": "ID_CARD",
        "phoneMasked": null,
        "profileStatus": "COMPLETED"
      }
    ],
    "failures": []
  },
  "success": true
}

3.7 出行人信息校验

  • 方法/路径: GET /v3/admin/order/{id}/traveler/validate
  • 使用场景: 保存后检查人数、逐人五项资料和订单级手机号门禁。
  • 幂等性: 是,只读。
  • 路径参数: id,Long,必填,订单 ID。
  • 响应:
字段 类型 说明
data.passed Boolean 人数一致、逐人五项完整且 blockReasons 为空时为 true
data.declaredCount Integer 订单声明总人数
data.actualCount Integer 当前实际出行人数
data.countMismatch Boolean 声明人数与实际人数是否不一致
data.incompleteList[] IncompleteTravelerVO[] 五项资料不完整的出行人
data.incompleteList[].travelerId Long 出行人 ID
data.incompleteList[].name String/null 脱敏姓名
data.incompleteList[].missingFields[] String[] 只可能是 name/gender/birthday/idType/idNo
data.blockReasons[] String[] 订单级阻断原因;整单无手机号时包含固定文案
  • 错误码: 581102 订单不存在。
  • 业务边界:
    • 两人五项资料齐全,仅一人有手机号:passed=true
    • 每人五项资料齐全,但所有人都无手机号:incompleteList=[]blockReasons 包含“至少需要一名出行人填写手机号用于合同签署”,passed=false
  • 典型示例:

请求

GET /v3/admin/order/2079576729147338754/traveler/validate
Authorization: Bearer <admin-token>

响应

{
  "code": 200,
  "message": "success",
  "data": {
    "passed": true,
    "declaredCount": 2,
    "actualCount": 2,
    "countMismatch": false,
    "incompleteList": [],
    "blockReasons": []
  },
  "success": true
}

3.8 确认订单前置检查

  • 方法/路径: GET /v3/admin/order/{id}/confirm-checklist
  • 使用场景: 打开确认订单弹框前检查五项门禁。
  • 幂等性: 是,只读。
  • 路径参数: id,Long,必填,订单 ID。
  • 响应:
字段 类型 说明
data.allPassed Boolean 五项是否全部通过
data.items[] ChecklistItemVO[]/null 未全部通过时返回;全部通过时为 null
data.items[].code String 检查项代码
data.items[].checkName String 中文名称
data.items[].passed Boolean 是否通过
data.items[].failReason String/null 失败原因
data.preview PreviewVO/null 全部通过时返回;未通过时为 null
data.preview.departureDate String/null 出发日期
data.preview.totalPeopleCount Integer 总人数
data.preview.driverName String/null 司机姓名
data.preview.driverPhoneMasked String/null 脱敏司机手机号
data.preview.hotels[] HotelSummaryVO[] 酒店摘要,含 cityNamehotelName
data.preview.staffs[] StaffItemVO[] 人员摘要
data.preview.staffs[].assignmentId String 分配记录 ID
data.preview.staffs[].staffId String 员工 ID
data.preview.staffs[].staffName String/null 员工姓名
data.preview.staffs[].staffPhone String/null 脱敏手机号
data.preview.staffs[].staffRole String 人员角色
data.preview.staffs[].staffRoleName String/null 角色中文名
data.preview.staffs[].isPrimaryReporter Boolean 是否主报账人
data.preview.contractAutoAction Object/null 合同动作,含 planNameautoSign
data.preview.insuranceAutoAction Object/null 保险动作,含 planNamepeopleCounteffectiveDescription
  • 错误码: 581007 订单不存在;581045 房务角色无权查看。
  • 业务边界: TRAVELER_COMPLETE 通过必须同时满足: 所有出行人的五项资料均完整,且整单至少一人有手机号。
  • 典型示例:

请求

GET /v3/admin/order/2079576729147338754/confirm-checklist
Authorization: Bearer <admin-token>

响应

{
  "code": 200,
  "message": "success",
  "data": {
    "allPassed": false,
    "items": [
      {
        "code": "PAYMENT_OK",
        "checkName": "订单款项",
        "passed": true,
        "failReason": null
      },
      {
        "code": "TRAVELER_COMPLETE",
        "checkName": "出行人信息",
        "passed": false,
        "failReason": "至少需要一名出行人填写手机号用于合同签署"
      }
    ],
    "preview": null
  },
  "success": true
}

3.9 确认行程

  • 方法/路径: POST /v3/admin/order/{id}/confirm-itinerary
  • 使用场景: 五项 checklist 全部通过后确认行程。
  • 幂等性: 状态机约束;成功后重复确认会因状态不匹配失败。
  • 路径参数: id,Long,必填,订单 ID。
  • 请求体: 可不传。
字段 类型 必填 说明
reporterAssignmentId Long/null 新主报账人 assignmentId;不传沿用当前主报账人
  • 响应:
字段 类型 说明
data.success Boolean 是否成功
data.oldStatus String 变更前粗状态
data.newStatus String 变更后粗状态
data.oldFlowStatus String 变更前细状态
data.newFlowStatus String 变更后细状态
data.triggeredEvents[] String[] 触发的后续事件代码
  • 错误码: 581007 订单不存在;581009 状态不允许;581036 前置 checklist 未通过; 581045 房务角色无权查看;581046 主报账人 ID 格式非法。
  • 业务边界: 多名出行人不要求每人都有手机号;整单完全没有手机号时, TRAVELER_COMPLETE 不通过,本接口返回 581036
  • 典型示例:

请求

POST /v3/admin/order/2079576729147338754/confirm-itinerary
Authorization: Bearer <admin-token>
Content-Type: application/json
{
  "reporterAssignmentId": "2072930844657283074"
}

响应

{
  "code": 200,
  "message": "success",
  "data": {
    "success": true,
    "oldStatus": "CUSTOMIZING",
    "newStatus": "PENDING_DEPARTURE",
    "oldFlowStatus": "AWAITING_CONFIRM",
    "newFlowStatus": "PENDING_DEPARTURE",
    "triggeredEvents": [
      "ASYNC_CONTRACT_GENERATE",
      "ASYNC_INSURANCE_ISSUE"
    ]
  },
  "success": true
}

4. 接口入参汇总

本次没有新增、删除或改名请求字段。需要注意:

  • phone 仍可在批量编辑、单个新增、补全出行信息和智能解析中提交。
  • phone 允许单人为空,但整单至少一人必须填写。
  • genderbirthday 原本已存在;本次只将二者纳入逐人资料完整度。
  • 批量编辑和补全出行信息的 allCompleted 只代表逐人五项资料,不代表订单级手机号门禁。

5. 出参汇总

字段 改前 改后
profileStatus 成人通常还需手机号才为 COMPLETED 五项资料齐全即为 COMPLETED,与手机号无关
completedCount / pendingCount 受逐人手机号影响 只按逐人五项资料统计
allCompleted 可能因某个成人没手机号为 false 只表示所有人五项资料完整
incompleteList[].missingFields[] name/idType/idNo/phone name/gender/birthday/idType/idNo
blockReasons[] 手机号与逐人缺失字段存在语义重叠 整单无手机号时统一返回固定订单级阻断原因
checklist TRAVELER_COMPLETE 逐人状态可能要求成人各自有手机号 所有人五项完整,并且整单至少一人有手机号

6. 枚举 / 数据字典

6.1 profileStatus

中文 判定
PENDING 待完善 name/gender/birthday/idType/idNo 任一为空
COMPLETED 已完善 上述五项全部非空;不检查该出行人的手机号

6.2 missingFields

中文 说明
name 姓名 姓名为空
gender 性别 性别为空;本次新增为缺失项
birthday 出生日期 出生日期为空;本次新增为缺失项
idType 证件类型 证件类型为空
idNo 证件号 证件号为空

phone 已从此列表删除,改由订单级 blockReasons 表达。

6.3 gender

中文 说明
0 未知 有值,满足逐人完整度
1 有值,满足逐人完整度
2 有值,满足逐人完整度

6.4 travelerType

中文
ADULT 成人
CHILD 儿童
YOUNG_CHILD 小童
BABY 幼童

6.5 idType

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

6.6 checklist code

中文
PAYMENT_OK 订单款项
TRAVELER_COMPLETE 出行人信息
HOTEL_DONE 用房准备
VEHICLE_DONE 用车准备
CONTRACT_TEMPLATE_OK 合同方案

7. 错误码

本次没有新增错误码。与本次语义直接相关的错误:

code 含义 触发场景
581036 确认订单前置校验未通过,请先补全所有必填项 确认行程时整单无手机号,或其他 checklist 项未通过
581102 订单不存在,无法编辑出行人 出行人查询、编辑或校验的订单不存在
581103 性别编码不合法 gender 不是 0/1/2
581112 证件号格式不合法 idTypeidNo 不匹配
581113 手机号格式非法 非空手机号不是 11 位数字
581114 出生日期不能晚于今天 birthday 为未来日期
581119 出行人证件号重复 同订单出现重复证件号
581149 出行人类型人数超出订单配置 按生日派生的人群类型超过订单声明配额

固定订单级阻断文案为:

至少需要一名出行人填写手机号用于合同签署

8. 示例

8.1 典型成功:两名成人仅一人有手机号

前置数据:两人五项资料均完整,第一人有手机号,第二人没有手机号。

{
  "profileStatuses": [
    "COMPLETED",
    "COMPLETED"
  ],
  "validate": {
    "passed": true,
    "incompleteList": [],
    "blockReasons": []
  },
  "checklistTravelerComplete": {
    "passed": true,
    "failReason": null
  }
}

8.2 边界:五项完整但整单无手机号

{
  "profileStatuses": [
    "COMPLETED",
    "COMPLETED"
  ],
  "validate": {
    "passed": false,
    "incompleteList": [],
    "blockReasons": [
      "至少需要一名出行人填写手机号用于合同签署"
    ]
  },
  "checklistTravelerComplete": {
    "passed": false,
    "failReason": "至少需要一名出行人填写手机号用于合同签署"
  }
}

8.3 异常:缺性别并确认行程

先调用校验接口:

{
  "code": 200,
  "message": "success",
  "data": {
    "passed": false,
    "declaredCount": 1,
    "actualCount": 1,
    "countMismatch": false,
    "incompleteList": [
      {
        "travelerId": "2079576729147338801",
        "name": "张*",
        "missingFields": [
          "gender"
        ]
      }
    ],
    "blockReasons": []
  },
  "success": true
}

继续提交确认行程会失败:

{
  "code": 581036,
  "message": "确认订单前置校验未通过,请先补全所有必填项",
  "data": null,
  "success": false
}

9. 业务边界

  • 逐人五项资料是:姓名、性别、出生日期、证件类型、证件号。
  • 手机号不属于逐人 missingFields,不影响单人的 profileStatus
  • gender=0 是有效枚举值,不等于字段缺失;gender=null 或空值才缺失。
  • 订单至少需要一名出行人有手机号;可以不是每名成人都有手机号。
  • allCompleted=true 只说明五项资料完整。需要判断订单能否确认时,应读取 traveler/validatepassed/blockReasonsconfirm-checklistallPassed/items
  • 确认行程仍会服务端复检,不能仅凭前端本地判断绕过。

10. 修改前后对比

10.1 字段级

字段 修改前 修改后
missingFields 可选值 name/idType/idNo/phone name/gender/birthday/idType/idNo
blockReasons 手机号语义 与逐人 phone 缺失可能重叠 统一表达整单手机号门禁

10.2 行为级

场景 修改前 修改后
成人五项完整、本人无手机号、同行人有手机号 本人可能为 PENDING 本人为 COMPLETED,整单可通过
五项完整、整单无手机号 逐人状态与订单门禁混在一起 每人可 COMPLETED,但校验与确认被订单级门禁阻断
只缺性别或出生日期 可能不进入 missingFields 精确返回 genderbirthday

11. 影响评估 / 回滚

  • 是否破坏向后兼容: 字段名、类型和层级不变,但枚举集合与字段语义变化;依赖旧 missingFields=phone 或自行按“每人必须有手机号”判断的前端逻辑需要调整。
  • 前端是否必须同步上线: 是。应删除逐人手机号必填对 profileStatus 的本地推断, 并使用 blockReasons / checklist 表达订单级阻断。
  • 回滚影响: 若接口语义回滚,旧逻辑会再次把部分无手机号成人标为 PENDING; 前端不应在本地固化任一后端历史口径。

12. 注意事项

  • 不要用“手机号输入框是否为空”自行重算 profileStatus
  • 不要再判断 missingFields 是否包含 phone;该值已从允许集合删除。
  • allCompleted=true 不等于可确认订单;确认按钮的权威结果是 confirm-checklist.allPassed
  • 手机号格式校验仍存在:非空时必须是 11 位数字。
  • GET order detail 的出行人字段与 GET traveler/list 的敏感字段展示口径不同, 但两者的 profileStatus 语义完全一致。

验证证据

  • 两名成人五项资料齐全、仅一人有手机号:两行均为 COMPLETED,校验通过。
  • 成人五项资料齐全且本人无手机号:订单详情、列表、智能解析均返回 COMPLETED
  • 所有人均无手机号:逐人状态仍为 COMPLETED,校验返回订单级阻断原因,确认行程返回 581036
  • 只缺 gender 或只缺 birthday:逐人状态为 PENDINGmissingFields 精确返回对应字段。
  • PR 验证结果Order + MP 聚焦测试 165 个通过;全量 Reactor 8420 个测试通过;本次增量行与分支覆盖率均为 100%。

13. 关联 / 联系人