# C端订单详情页接口变更 — 2026-04-17 > **服务** hl-order-service-v2(端口8094)· **类型** feat > **前端调用路径**: 网关(8080) → hl-mp-service(8085) → hl-order-service-v2(8094) > **前端实际请求前缀**: `GET /mp/order/`(mp-service 需同步新增 BFF 转发层) --- ## 一、已改接口(1个) ### ✏️ `GET /mp/order/{orderId}` — 订单详情 **请求参数**:不变(路径参数 orderId) **返回值变更**:整体结构从 `OrderDetailVO` 改为 `MpOrderDetailVO` #### 新增字段 | 字段 | 类型 | 必有 | 说明 | 示例 | | --- | --- | --- | --- | --- | | `serviceItems` | `List` | ✅ | 服务包含摘要列表,每项含 type/title/summary/clickable | 见下方 | | `notIncluded` | `String` | 否 | 不含说明 | `"往返大交通、个人消费"` | | `priceBreakdown` | `Object` | 否 | 价格明细(新订单有值,历史订单null) | 见下方 | | `balancePayMethodLabel` | `String` | 否 | 尾款方式标签 | `"落地后由领队收取"` | | `refundProgress` | `Object` | 否 | 退款进度(退款中/已取消时有值) | 见下方 | | `tripProgress` | `Object` | 否 | 行程进度(仅行程中状态有值) | 见下方 | | `invoiceStatus` | `String` | ✅ | 发票状态 | `"AFTER_TRIP"` | | `productTypeLabel` | `String` | ✅ | 产品类型中文 | `"核心产品"` | #### 删除的字段(前端不再使用) `totalCost`, `surchargeAmount`, `pendingUpgradeAmount`, `depositRatio`, `balanceProofUrl`, `balancePayMethod`, `remark`, `checklistConfirmed`, `unlockRequestedAt`, `confirmedAt`, `readyAt`, `creatorAdminId`, `creatorName`, `mchId`, `mchName`, `sharerOpenid`, `productSnapshot`, `expiryMinutes`, `timeline`, `processStatus`, `processStatusLabel`, `discountReason`, `discounts`, `surcharges`, `transportSegments`, `roomInfo`, `hotelAssignments`, `hotelAssignmentDetails`, `vehicleInfo`, `refundPolicy`, `refundPolicyId`, `contactName`, `contactPhone` #### 保留不变的字段 `orderId`, `orderNo`, `groupCode`, `productId`, `productName`, `productCoverUrl`, `productType`, `departureDate`, `returnDate`, `tripDays`, `tripNights`, `adultCount`, `childCount`, `youngChildCount`, `babyCount`, `createTime`, `status`, `statusLabel`, `displayStatus`, `displayStatusLabel`, `cancelReason`, `cancelledAt`, `completedAt`, `expiryTime`, `totalPrice`, `depositAmount`, `balanceAmount`, `paidAmount`, `paymentType`, `paymentTypeLabel`, `paidAt`, `payMethodLabel`, `discountAmount`, `refundAmount`, `contracts`, `insurances`, `travelers`, `todos`, `reviewed`, `customizerId`, `customizerName`, `customizerAvatarUrl`, `customizerQrUrl` --- ## 二、新增接口(6个弹窗) > 用户点击 `serviceItems` 列表中某项时按需调用,不需要在详情页一次性请求。 > 每个接口都需要传 userId(mp-service 从 token 中获取后透传)。 ### 🆕 `GET /mp/order/{orderId}/tickets` — 门票清单 **请求参数**:路径参数 `orderId` **返回值** `MpTicketListVO`: | 字段 | 类型 | 说明 | | --- | --- | --- | | `hint` | `String` | 顶部提示语 | | `items` | `List` | 门票列表 | | `items[].seq` | `Integer` | 序号(1开始) | | `items[].scenicName` | `String` | 景点名称 | | `items[].coverUrl` | `String` | 景点封面图(可能为空) | | `items[].dayNumber` | `Integer` | 第几天 | | `items[].originalPrice` | `BigDecimal` | 门票原价/人(可能为null) | | `items[].included` | `Boolean` | 是否已含 | | `totalValue` | `BigDecimal` | 门票总价值/人(可能为null) | | `footerText` | `String` | 底部文案 | **响应示例**: ```json { "code": 200, "data": { "hint": "以下景点门票已包含在套餐内,无需另购", "items": [ { "seq": 1, "scenicName": "莫日格勒河", "coverUrl": null, "dayNumber": 2, "originalPrice": 80.00, "included": true }, { "seq": 2, "scenicName": "根河湿地", "coverUrl": null, "dayNumber": 3, "originalPrice": 120.00, "included": true } ], "totalValue": 200.00, "footerText": "全部已含·无需再付" } } ``` --- ### 🆕 `GET /mp/order/{orderId}/hotels` — 住宿清单 **请求参数**:路径参数 `orderId` **返回值** `MpHotelListVO`: | 字段 | 类型 | 说明 | | --- | --- | --- | | `hint` | `String` | 顶部提示语(如"5晚精选当地酒店") | | `items` | `List` | 酒店列表 | | `items[].hotelName` | `String` | 酒店名称 | | `items[].coverUrl` | `String` | 酒店封面图(可能为空) | | `items[].dayNumber` | `Integer` | 第几天入住 | | `items[].hotelType` | `String` | 酒店类型(如"5星"/"特色民宿",可能为空) | | `items[].roomType` | `String` | 房型(如"大床房",可能为空) | | `footerNote` | `String` | 底部备注 | **响应示例**: ```json { "code": 200, "data": { "hint": "5晚精选当地酒店", "items": [ { "hotelName": "海拉尔铂尔曼大酒店", "coverUrl": null, "dayNumber": 1, "hotelType": "", "roomType": "大床房" } ], "footerNote": "实际入住酒店以出行前确认为准" } } ``` --- ### 🆕 `GET /mp/order/{orderId}/meals` — 餐饮清单 **请求参数**:路径参数 `orderId` **返回值** `MpMealListVO`: | 字段 | 类型 | 说明 | | --- | --- | --- | | `hint` | `String` | 顶部提示语(如"已含5早8正餐") | | `specialMeals` | `List` | 特色正餐列表 | | `specialMeals[].dayNumber` | `Integer` | 第几天 | | `specialMeals[].mealName` | `String` | 餐名 | | `specialMeals[].mealType` | `String` | 餐型(午餐/晚餐) | | `specialMeals[].description` | `String` | 菜品描述 | | `stats` | `Object` | 餐饮统计 | | `stats.breakfast` | `String` | 早餐统计(如"5餐·酒店自助") | | `stats.specialDinner` | `String` | 特色正餐统计(如"3餐") | | `stats.regularDinner` | `String` | 日常正餐统计(如"5餐·当地特色餐厅") | | `footerNote` | `String` | 底部备注 | **响应示例**: ```json { "code": 200, "data": { "hint": "已含1早2正餐", "specialMeals": [ { "dayNumber": 2, "mealName": "手把肉宴", "mealType": "午餐", "description": "含奶茶/手把肉" } ], "stats": { "breakfast": "1餐·酒店自助", "specialDinner": "1餐", "regularDinner": "1餐·当地特色餐厅" }, "footerNote": "对食物有过敏请提前告知领队" } } ``` --- ### 🆕 `GET /mp/order/{orderId}/vehicle` — 用车详情 **请求参数**:路径参数 `orderId` **返回值** `MpVehicleDetailVO`: | 字段 | 类型 | 说明 | | --- | --- | --- | | `hint` | `String` | 顶部提示语 | | `vehicleName` | `String` | 车型名称 | | `coverUrl` | `String` | 车型图片(可能为空) | | `description` | `String` | 车型描述/特点(可能为空) | | `matchRule` | `String` | 匹配规则说明 | **响应示例**: ```json { "code": 200, "data": { "hint": "一家一车不拼团·全程同一辆车", "vehicleName": "商务车", "coverUrl": null, "description": "", "matchRule": "匹配规则:根据出行人数自动配车" } } ``` --- ### 🆕 `GET /mp/order/{orderId}/guide` — 领队详情 **请求参数**:路径参数 `orderId` **返回值** `MpGuideInfoVO`: | 字段 | 类型 | 说明 | | --- | --- | --- | | `name` | `String` | 姓名(可能为null) | | `avatarUrl` | `String` | 头像(可能为null) | | `role` | `String` | 角色标签(固定"主领队"或"领队") | | `phone` | `String` | 电话(可能为null) | | `remark` | `String` | 简介(可能为null) | > ⚠️ 产品服务快照扩展完成前,除 `role` 外所有字段可能为 null --- ### 🆕 `GET /mp/order/{orderId}/photographer` — 摄影详情 **请求参数**:路径参数 `orderId` **返回值** `MpPhotographerInfoVO`: | 字段 | 类型 | 说明 | | --- | --- | --- | | `name` | `String` | 姓名(可能为null) | | `avatarUrl` | `String` | 头像(可能为null) | | `role` | `String` | 角色标签(固定"摄影师") | | `phone` | `String` | 电话(可能为null) | | `remark` | `String` | 简介(可能为null) | > ⚠️ 同领队,产品服务快照扩展完成前字段可能为 null --- ## 三、新增结构体详细说明 ### serviceItems(服务包含摘要) 详情接口返回的 `serviceItems` 是一个数组,每项代表一个服务类别: ```json [ { "type": "HOTEL", "title": "住宿", "summary": "5晚精选当地酒店", "clickable": true }, { "type": "MEAL", "title": "餐饮", "summary": "5早 8正餐", "clickable": true }, { "type": "VEHICLE", "title": "用车", "summary": "专属车辆 + 司机", "clickable": true }, { "type": "GUIDE", "title": "领队", "summary": "全程陪同", "clickable": true }, { "type": "PHOTOGRAPHER", "title": "摄影", "summary": "全程跟拍 + 精修照片", "clickable": true }, { "type": "TICKET", "title": "门票", "summary": "4处景点门票", "clickable": true }, { "type": "INSURANCE", "title": "保险", "summary": "旅行意外险", "clickable": false } ] ``` `clickable=true` 时点击应调用对应弹窗接口:`type=HOTEL` → `GET /mp/order/{orderId}/hotels`,以此类推。 ### priceBreakdown(价格明细) ```json { "items": [ { "label": "成人", "unitPrice": 2300.00, "quantity": 2, "amount": 4600.00 }, { "label": "儿童", "unitPrice": 1800.00, "quantity": 1, "amount": 1800.00 } ], "subtotal": 6400.00, "discounts": [ { "tag": "早鸟优惠", "description": "提前30天", "amount": -400.00 } ], "totalDiscount": -400.00, "totalPayable": 6000.00 } ``` > ⚠️ 仅新创建的订单有值,历史订单为 null,前端需做空判断 ### refundProgress(退款进度) ```json { "steps": [ { "title": "提交退款申请", "description": "用户发起退款", "status": "COMPLETED", "time": "2026-06-25T16:32:00" }, { "title": "商家审核中", "description": "客服正在审核您的退款申请", "status": "ACTIVE", "time": null }, { "title": "退款处理", "description": "原路退回您的微信账户", "status": "PENDING", "time": null }, { "title": "退款到账", "description": "预计1-3个工作日", "status": "PENDING", "time": null } ], "currentStep": 1, "refundAmount": 1000.00, "refundMethod": null, "refundArrivalTime": null } ``` step.status 取值:`COMPLETED`=已完成 / `ACTIVE`=进行中 / `PENDING`=待处理 > ⚠️ 仅退款中/已取消且有退款时有值,其他状态为 null ### tripProgress(行程进度) ```json { "currentDay": 2, "totalDays": 6, "progressPercent": 33, "todayDestination": "莫日格勒河" } ``` > ⚠️ 仅行程中(displayStatus=TRAVELLING)状态有值,其他状态为 null ### invoiceStatus 取值 | 值 | 说明 | | --- | --- | | `ISSUED` | 已开票 | | `PENDING` | 开票中 | | `NOT_ISSUED` | 未开票(已完成订单可申请) | | `AFTER_TRIP` | 出行后可开 | --- ## 四、mp-service BFF 层需同步新增 以上6个弹窗接口目前在 order-service-v2 的 `/internal/mp/order/` 路径下已就绪。 mp-service(hl-mp-service)需要新增对应的 BFF 转发层,路径映射如下: | 前端调用 | mp-service 转发到 | | --- | --- | | `GET /mp/order/{orderId}/tickets` | `GET /internal/mp/order/{orderId}/tickets?userId=xxx` | | `GET /mp/order/{orderId}/hotels` | `GET /internal/mp/order/{orderId}/hotels?userId=xxx` | | `GET /mp/order/{orderId}/meals` | `GET /internal/mp/order/{orderId}/meals?userId=xxx` | | `GET /mp/order/{orderId}/vehicle` | `GET /internal/mp/order/{orderId}/vehicle?userId=xxx` | | `GET /mp/order/{orderId}/guide` | `GET /internal/mp/order/{orderId}/guide?userId=xxx` | | `GET /mp/order/{orderId}/photographer` | `GET /internal/mp/order/{orderId}/photographer?userId=xxx` | > mp-service 从用户 token 中提取 userId,作为查询参数透传给 order-service。