5 个 fix PR 合并 dev,已部署待运维同步测试服: - PR #1803 (Closes #1787) order-v2/work-order: 工单创建漏 setWorkOrderNo/setOrderNo - PR #1804 (Closes #1791) order-v2/order+refund: 列表日期范围筛选三层补字段 - PR #1805 (Closes #1789) order-v2/insurance: 投保人证件号字段名 + JsonAlias 兼容 - PR #1806 (Closes #1793) hl-user-service/explore-category: 详情 VO 缺 status - PR #1807 (Closes #1794, #1795) hl-resource-service: 景区下架引用校验 + 服务人员手机号格式 @mmg 看到请同步前端: - 工单列表/详情新增 workOrderNo + orderNo 字段 - 订单/退款列表查询参数 createTimeStart/createTimeEnd - 保险投保 idCardType/idCardNo 字段名(V1 契约,@JsonAlias 兼容) - 探索分类详情 status 字段(去掉 ?? 1 默认值) - 景区下架 errorCode SCENIC_DISABLE_IN_USE 含产品名 需重启服务:hl-order-service-v2、hl-user-service、hl-resource-service
5.3 KiB
订单出行人证件验证: admin 端补接口 + 前端必须改 URL/method/参数
服务: hl-order-service-v2 (端口 8084) PR: #1798 (已合并 dev, 待部署 prod) Issue: #1797 日期: 2026-05-07 影响范围: 管理后台 出行人证件验证弹窗(蒋雨莲所在订单页) @ 前端: mmg
⚠️ 关键变化(必须改前端)
prod 弹窗 "证件验证未通过 · 蒋雨莲:接口不存在: POST /admin/auth/cert/validate" 是因为 POST /admin/auth/cert/validate 后端从未实现过(五重证据:代码 0 命中 / git 全历史 0 命中 / changelog 0 命中 / 需求文档 0 命中 / AuthController 全部 13 个 mapping 无 cert)。
后端新增正确接口:
GET /admin/order/{orderId}/travelers/validate
前端必须把"逐个 traveler 调 cert/validate"的循环逻辑整段删掉,改为按 orderId 一次性校验:URL 变 / method 由 POST 改 GET / 参数由 traveler body 改 path orderId。
一、背景
弹窗触发动作(疑似锁单/支付/确认行程前置校验)应该一次性把订单内全部出行人验证一次,而不是循环逐人。后端早就有 GET /internal/order/traveler/validate/{orderId} 给 payment-service Feign 调,本次只是在 admin 端薄包装一层让前端可以直调。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 校验订单出行人证件信息 | GET | /admin/order/{orderId}/travelers/validate |
新增 | 替换前端误调的 POST /admin/auth/cert/validate |
三、接口详情
1. 校验订单出行人证件信息 GET /admin/order/{orderId}/travelers/validate
Service: 复用已有 OrderTravelerService.validateAndReturnVO(orderId)(与 internal 接口完全对齐)
VO: TravelerValidationVO
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| orderId | Path | Long | ✅ | 雪花 ID | 订单 ID |
出参 Result<TravelerValidationVO>
| 字段 | 类型 | 说明 |
|---|---|---|
| valid | Boolean | 全部出行人证件信息是否合规 |
| travelerCount | Integer | 出行人数量 |
| errors | List<String> |
校验失败明细(中文消息),合规时为空数组 |
请求示例
GET /admin/order/123456789/travelers/validate
Authorization: Bearer <admin_token>
响应示例(合规)
{
"code": 200,
"message": "成功",
"data": {
"valid": true,
"travelerCount": 2,
"errors": []
},
"success": true
}
响应示例(不合规)
{
"code": 200,
"message": "成功",
"data": {
"valid": false,
"travelerCount": 2,
"errors": [
"蒋雨莲:身份证号格式错误",
"张三:护照有效期已过"
]
},
"success": true
}
四、契约约束与正确调用方式
✅ 正确 / ❌ 错误 调用对照
| 场景 | 调用 |
|---|---|
| ✅ 一次性按订单校验全部出行人 | GET /admin/order/{orderId}/travelers/validate |
| ❌ 循环逐人调 cert/validate | POST /admin/auth/cert/validate × N(接口不存在 404) |
前端代码改动指引
旧代码(删除):
for (const t of travelers) {
await http.post('/admin/auth/cert/validate', t) // ❌ 接口不存在
}
新代码:
const { data } = await http.get(`/admin/order/${orderId}/travelers/validate`)
if (!data.valid) {
// 弹窗显示 data.errors 即可
showCertValidationDialog(data.errors)
}
错误明细 errors: List<String> 已经包含中文姓名 + 错误原因,前端不需要再拼姓名前缀。
五、数据库行为
只读校验,不写库。
六、边界行为
- orderId 不存在 → 服务端 BusinessException →
Result.code != 200+ 中文 message - 订单存在但 0 个出行人 →
valid=false, travelerCount=0, errors=["订单尚未添加出行人"] - 未登录 → 网关 401 拦截
- 下游服务降级 → 暂不需要 fallback,service 内部不依赖外部服务
七、不影响范围
- 仅影响: 管理后台出行人证件验证弹窗(前端 hl-ui mmg 维护)
- 零影响:
- 小程序端出行人列表 / 添加 / 编辑
- admin 端出行人增删改 (
/admin/order/{orderId}/travelers/**) - payment-service 内部 Feign 调用的
/internal/order/traveler/validate/{orderId}保持不变 - 历史数据零变更
八、测试环境已验证
后端单测 3 用例全绿(mockMvc 真路径 dispatch):
validate_orderComplete_returnsSuccessVO✓validate_orderIncomplete_returnsIncompleteVO✓validate_invalidOrderId_serviceThrows_exposedAsBusinessError✓
测试服 admin token round-trip:待 PR #1798 部署到测试服后 /@qa 角色验证(24h 内回贴 curl 输出)。
九、相关历史 PR
| PR | Issue | 说明 | 是否仍有效 |
|---|---|---|---|
| 无 | 无 | 后端从未约定 POST /admin/auth/cert/validate 接口 |
-- |
| 本 PR #1798 | #1797 | 新增 GET /admin/order/{orderId}/travelers/validate |
✅ 最新 |
十、相关文档
- 关联 Issue: wx/HL#1797
- 关联 PR: wx/HL#1798