15 KiB
15 KiB
schema, ticket, title, consumer, backend, gateway, frontend, base, generated
| schema | ticket | title | consumer | backend | gateway | frontend | base | generated |
|---|---|---|---|---|---|---|---|---|
| hl-changelog/v1 | 5132 | 车务派单详情补全产品、行程节点、出行人与大交通 | admin | verified | verified | pending | dev-v3 | 2026-07-22T10:35:00+08:00 |
【修改接口·前端待处理·管理后台】车务派单详情补全产品、行程节点与出行人
服务: hl-order-service-v3 + hl-fleet-service
日期: 2026-07-22
工单: #5132 影响范围: 管理后台车务管理 / 派车看板 / 派单弹窗 Step1「订单详情」
关键变化
派单弹窗 Step1 不能再只展示人数、日期和每日一句简介。GET /admin/fleet/board/orders/{orderId} 现一次返回:
productName:订单产品名(原字段,前端本次必须展示)。tags[]:订单在order_tag中真实挂载的标签名称与颜色;无标签返回[]。itinerary.days[].nodes[]:每日真实行程节点,含开始时间、时段、时长、名称和简介。travelers[]:出行人脱敏基本信息,不含生日和任何明文字段。transport:抵达、返程及分批大交通信息(原字段,前端本次必须完整展示时间和班次,不能只显示站点)。
行程数据仍以订单当前 order_itinerary_day 和 order_itinerary_node 为权威源,禁止从产品模板反推。
变更接口
GET /admin/fleet/board/orders/{orderId}
响应 VO:BoardOrderDetailVO
新增字段
| 字段 | 类型 | 说明 |
|---|---|---|
tags |
Array | 真实订单标签;无标签返回 [] |
tags[].tagId |
String | 标签雪花 ID,必须按字符串处理 |
tags[].name |
String/null | 标签名称 |
tags[].color |
String/null | 标签颜色,如 #52C41A |
itinerary.days[].nodes |
Array | 当日节点,按 sortOrder 升序;无节点返回 [] |
itinerary.days[].nodes[].nodeId |
String | 节点雪花 ID,必须按字符串处理 |
itinerary.days[].nodes[].nodeType |
String/null | 节点类型,如 SCENIC、RESTAURANT、ACTIVITY、SERVICE、CUSTOM |
itinerary.days[].nodes[].nodeName |
String/null | 节点展示名;节点名为空时后端回退资源名 |
itinerary.days[].nodes[].startTime |
String/null | 开始时间,格式 HH:mm |
itinerary.days[].nodes[].timePeriod |
String/null | 时段,如上午、下午、全天 |
itinerary.days[].nodes[].durationMinutes |
Number/null | 时长,单位分钟 |
itinerary.days[].nodes[].description |
String/null | 节点简介 |
itinerary.days[].nodes[].sortOrder |
Number/null | 同天排序 |
travelers |
Array | 出行人脱敏基本信息;无出行人或下游降级时返回 [] |
travelers[].travelerId |
String | 出行人雪花 ID,必须按字符串处理 |
travelers[].travelerType |
String/null | ADULT / CHILD / YOUNG_CHILD / BABY |
travelers[].travelerTypeName |
String/null | 人员类型中文名,如“成人”“儿童” |
travelers[].nameMasked |
String/null | 脱敏姓名 |
travelers[].gender |
String/null | 性别字典值 |
travelers[].genderName |
String/null | 性别中文名 |
travelers[].ageAtDeparture |
Number/null | 按订单出发日计算的周岁 |
travelers[].idType |
String/null | 证件类型字典值 |
travelers[].idTypeName |
String/null | 证件类型中文名 |
travelers[].idNoMasked |
String/null | 脱敏证件号 |
travelers[].phoneMasked |
String/null | 脱敏手机号 |
travelers[].nationality |
String/null | 国籍 |
travelers[].race |
String/null | 民族 |
travelers[].emergencyContactMasked |
String/null | 脱敏紧急联系人姓名 |
travelers[].emergencyPhoneMasked |
String/null | 脱敏紧急联系人电话 |
travelers[].roomGroupNo |
Number/null | 同住分组号 |
travelers[].transportPlanIds |
String[] | 关联大交通批次 ID,必须按字符串处理 |
travelers[].profileStatus |
String/null | 资料状态:PENDING / COMPLETED |
travelers[].profileStatusName |
String/null | 资料状态中文名 |
productName 是已有字段,结构不变;本次页面必须消费,不再只保存在 normalizeBoardOrder().product 而不展示。
已有但本次必须完整展示的大交通字段
| 字段 | 类型 | 说明 |
|---|---|---|
transport.arrive |
Object/null | 抵达接团段 |
transport.arrive.transportNo |
String/null | 抵达航班号/车次号 |
transport.arrive.time |
String/null | 抵达时间,ISO LocalDateTime |
transport.arrive.station |
String/null | 抵达机场/车站 |
transport.arrive.remark |
String/null | 抵达备注 |
transport.depart |
Object/null | 返程送站段 |
transport.depart.transportNo |
String/null | 返程航班号/车次号 |
transport.depart.time |
String/null | 返程时间,ISO LocalDateTime |
transport.depart.station |
String/null | 返程机场/车站 |
transport.depart.remark |
String/null | 返程备注 |
transport.batches |
Array | 分批接送列表 |
transport.batches[].travelerNames |
String/null | 本批出行人姓名摘要 |
transport.batches[].transportNo |
String/null | 本批航班号/车次号 |
transport.batches[].time |
String/null | 本批抵达/返程时间 |
transport.batches[].station |
String/null | 本批机场/车站 |
transport.transferTimeHint |
String/null | 无任何大交通时间时的后端提示,当前为“暂无接送机时间” |
transport.pickupRequired |
Boolean/null | 是否需要平台派车接送 |
响应示例
{
"code": 200,
"data": {
"orderNo": "HL20260721171011648",
"productName": "草原亲子三日游",
"tags": [
{
"tagId": "9001",
"name": "亲子家庭",
"color": "#52C41A"
}
],
"itinerary": {
"theme": "草原亲子三日游",
"route": null,
"days": [
{
"dayNumber": 1,
"date": "2026-07-29",
"title": "接机",
"detail": "抵达后入住酒店",
"nodes": [
{
"nodeId": "2001",
"nodeType": "SERVICE",
"nodeName": "海拉尔机场接机",
"startTime": "10:30",
"timePeriod": "上午",
"durationMinutes": 60,
"description": "司机举牌接机",
"sortOrder": 1
}
]
}
]
},
"travelers": [
{
"travelerId": "3001",
"travelerType": "ADULT",
"travelerTypeName": "成人",
"nameMasked": "孔**",
"gender": "2",
"genderName": "女",
"ageAtDeparture": 35,
"idType": "ID_CARD",
"idTypeName": "身份证",
"idNoMasked": "150***********1234",
"phoneMasked": "138****1234",
"nationality": "中国",
"race": "蒙古族",
"emergencyContactMasked": "王*",
"emergencyPhoneMasked": "139****5678",
"roomGroupNo": 1,
"transportPlanIds": ["4001"],
"profileStatus": "COMPLETED",
"profileStatusName": "已完善"
}
],
"transport": {
"transferTimeHint": null,
"arrive": {
"transportNo": "CA1234",
"time": "2026-07-29T10:30:00",
"station": "海拉尔东山国际机场",
"remark": "T2 出口举牌接机"
},
"depart": {
"transportNo": "CA5678",
"time": "2026-07-31T17:20:00",
"station": "海拉尔东山国际机场",
"remark": "提前 2 小时送达"
},
"batches": [],
"pickupRequired": true
}
},
"success": true
}
前端页面调整要求
目标文件:src/views/fleet/board/components/Step1OrderDetail.vue。
- 顶部订单摘要展示产品名,读取
order.productName || order.product;产品名为空才显示—。- 当前
Step1OrderDetail.vue中的order.bookingType || '企业包车'是硬编码占位,不是订单标签,必须删除。 - 该位置改为遍历详情响应
tags[],使用name作为文案、color作为颜色;tags=[]时不显示标签,也不回退“企业包车”。
- 当前
- 在顶部订单摘要下增加“大交通”信息卡,抵达与返程分栏展示
transportNo + time + station + remark:- 时间使用完整月日和时分,不只展示日期。
arrive、depart独立判空,只有一段时仍正常展示该段。batches[]非空时增加“分批接送”,展示本批出行人、班次、时间和站点。- 无任何时间时展示
transport.transferTimeHint,不得伪造航班或时间。 - 当前顶部“接送”统计可保留站点摘要,但不能替代大交通详情卡。
- 左侧“每日安排”保留日标题和
detail,并在每一天下面渲染nodes[]:- 时间优先显示
startTime,为空时显示timePeriod,两者都有可组合展示。 startTime和timePeriod都为空时显示“时间待定”,不得根据节点顺序或描述猜测具体时间。- 主文案显示
nodeName。 durationMinutes有值时显示易读时长。description有值且与日简介不重复时显示节点简介。
- 时间优先显示
- 右侧新增“出行人信息”区,默认展示脱敏姓名、人员类型、性别、年龄、国籍/民族、脱敏手机号和资料状态;证件、同住分组、关联大交通批次及紧急联系人可在行内展开或次要信息区展示。
- 年龄文案使用自然表达“年龄 29 岁”,不要显示成“出发时 29岁”。
ageAtDeparture的业务口径仍是按订单出发日计算;如需说明,将“按出发日计算”放在字段提示或帮助文案中,不与年龄值拼成标签。
- 禁止为了展示此页面调用明文接口
POST /admin/fleet/board/orders/{orderId}/travelers/plain。Step1 只使用详情响应中的脱敏travelers[]。 - 空态明确:无节点显示“暂无行程节点”,无出行人显示“暂未填写出行人信息”;不得生成模拟节点或模拟出行人。
- 雪花 ID 禁止
Number()/parseInt(),统一按字符串处理。 - 用车备注与通用特殊诉求必须按字段来源分区展示,不能混在同一个“特殊要求”警示框:
requirementRemark来源于定制师在“调整订单 → 车辆安排 → 备注/其他诉求”填写的自由文本,应显示在“定制师备注”或更准确的“用车备注”卡片中;例如“司机会蒙语”。specialTags[]来源于“通用特殊诉求”的多选标签,只在“特殊要求”区域展示标签;例如“儿童安全座椅”“大行李空间”“中文司机”。plannerNote是订单级定制师备注,与requirementRemark不是同一字段;两者同时存在时分行展示并标明来源,不得互相覆盖。requirements仅作为历史订单兼容文本;当requirementRemark或specialTags[]已有值时,不得把它们重复拼入requirements。
推荐布局:顶部摘要下放横向“大交通”卡;左栏继续承载逐日节点时间线;右栏顺序为“出行人信息 → 客人留言 → 定制师/用车备注 → 特殊要求 → 操作记录”。
兼容与降级
- 仅新增响应字段,不修改请求参数,不影响旧调用方。
- 历史订单无订单标签时
tags=[],禁止使用产品类型、预订类型或固定文案冒充订单标签。 - 历史行程没有节点时
nodes=[],每日标题和简介仍照常返回。 - order-v3 聚合上下文失败并回退 fleet 本地快照时,
relatedDetailReady=false,travelers=[],行程节点不可用;前端显示真实空态。 - 原独立脱敏接口
GET /admin/fleet/board/orders/{orderId}/travelers保留兼容,但此页面无需再发第二次请求。 - 不返回
birthday、明文姓名、明文证件号、明文手机号或明文紧急联系人。
验收清单
- 顶部可看到订单产品名。
- 顶部只展示
tags[]中的真实订单标签;无标签时不显示,“企业包车”硬编码已删除。 - 大交通卡分别展示抵达/返程的班次、完整时间、站点和备注。
- 有分批接送时展示每批出行人、班次、时间和站点;无大交通时间时展示真实空态。
- 每日安排按节点顺序展示时间、节点名、时长和简介。
- 节点无
startTime时可回退显示timePeriod,不会出现undefined。 - 右侧可看到全部出行人的脱敏基本信息。
- 每位出行人以“年龄 N 岁”的自然文案展示年龄,并可查看人员类型、性别、证件、国籍/民族、同住分组、关联大交通及资料状态。
- 无节点/无出行人时展示真实空态,不生成模拟数据。
- 页面 Network 只需现有详情请求,不调用出行人明文接口。
- “备注/其他诉求”读取
requirementRemark并显示在定制师/用车备注卡片;“特殊要求”只展示specialTags[],不会再把备注文本放入警示框。 plannerNote与requirementRemark同时存在时分别展示且不覆盖,历史requirements不造成重复文案。- 现有留言、特殊要求、步骤条和操作记录不受影响。
验证证据
ItineraryServiceTest:覆盖节点名称、开始时间、时段、时长、简介和排序装配。OrderFleetProviderServiceTest:覆盖节点随当前订单日期对齐且出行人脱敏进入聚合上下文。BoardOrderServiceTest:覆盖 shared DTO 到管理端 VO 的节点和出行人映射。BoardControllerTest:覆盖productName、节点时间、String ID 与脱敏出行人的 JSON 契约。OrderFleetProviderServiceTest、BoardOrderServiceTest与BoardControllerTest:覆盖order_tag名称/颜色进入详情响应,标签 ID 按字符串序列化。- 测试环境网关实测订单
HL20260721171011648:HTTP 200,返回 3 个行程日、14 个真实节点和 5 位出行人;5 位出行人均返回ageAtDeparture,且未出现生日、明文姓名、明文证件号或明文手机号。 - 同一实测订单返回 2 个真实订单标签“自动化测试”“房务需求”,均包含颜色,
tagId均为字符串;响应不含bookingType,前端无需也不得使用“企业包车”等硬编码兜底。 - 同一实测订单已返回抵达大交通的班次、抵达时间和站点;该订单无返程段、无分批接送,接口按真实数据返回空值或空数组。
- 该订单 14 个节点的
startTime与timePeriod在订单行程源数据中均为空,接口如实返回null;前端须展示“时间待定”,若要显示具体钟点需先补录订单行程节点时间。 - 测试环境团号
26-7042的调整单中,“备注/其他诉求”为“司机会蒙语”;详情接口已分别返回requirementRemark和specialTags[]。截至v2.1@6e6a11bf,Step1OrderDetail.vue仍使用requirementRemark || requirements渲染“特殊要求”警示框,并仅用plannerNote渲染定制师留言,造成截图中的字段串位;按上方规则调整前端展示即可,后端无需新增字段。 - 网关证据已由
hl task登记,SHA-256:8ff09cc804fb8d72fde6df3f338125b725c857d2c098b59f6b222f460da844a3。
本文是前端接入通知,不代表已修改或发布
mmg/hl-ui。