diff --git a/changelogs/2026-04/2026-04-23_mp-dashboard-endpoints-timing-guide.md b/changelogs/2026-04/2026-04-23_mp-dashboard-endpoints-timing-guide.md new file mode 100644 index 0000000..f6b5ac9 --- /dev/null +++ b/changelogs/2026-04/2026-04-23_mp-dashboard-endpoints-timing-guide.md @@ -0,0 +1,172 @@ +# mp-service: 订单/行程 5 个聚合接口调用时机梳理 + +> **服务**: hl-mp-service(端口 8085)→ 透传 hl-order-service-v2(端口 8094) +> **PR**: -(纯契约梳理,无代码变更) +> **Issue**: - +> **日期**: 2026-04-23 +> **影响范围**: C 端「订单详情页」+「行程 Tab」的 5 个聚合接口 + +--- + +## ⚠️ 关键变化 + +**无接口变更**。本 changelog 是对现有 5 个聚合接口的调用时机/契约关系做一次性梳理,方便前端对照接入。调用顺序、入参、返回 VO 均未调整。 + +--- + +## 一、接口清单 + +| # | 接口 | 方法 | 路径 | 返回 VO | 缓存 TTL | +|---|------|------|------|---------|----------| +| 1 | 订单详情页聚合 | GET | `/mp/order/{orderId}/dashboard` | `MpOrderDashboardVO` | 30s | +| 2 | 行程 Tab 路由决策 | GET | `/mp/trip/tab-state` | `MpTripTabStateVO` | 15s | +| 3 | 行程前·出发准备页聚合 | GET | `/mp/trip/{orderId}/pre-trip-dashboard` | `MpPreTripDashboardVO` | 30s | +| 4 | 行程中·今日页聚合 | GET | `/mp/trip/today-dashboard` | `MpTodayDashboardVO` | 15s | +| 5 | 旅行回忆列表 | GET | `/mp/order/travel-memory` | `PageResult` | 60s | + +所有接口均需登录,`userId` 由 mp-service 从 token 取出后透传给 order-v2。 + +--- + +## 二、两条独立入口 + +### 入口 A:订单详情页(#1) + +来源:我的订单列表点击、支付成功跳转、消息/通知链接。拿到 `orderId` 后直接调 `#1`,与行程 Tab 无关。 + +### 入口 B:行程 Tab(#2 → #3/#4/#5) + +用户切到行程 Tab 时**必须先调 `#2 /mp/trip/tab-state`**,后端根据当前订单情况返回 `state` + `orderId`,前端按 `state` 分支调对应接口。 + +| `state` | 含义 | 下一步接口 | 是否需要前端传 orderId | +|---------|------|-----------|------------------------| +| `NEW` | 从未下过单 | 无(空态) | - | +| `BEFORE_START` | 有订单未出发 | `#3 /mp/trip/{orderId}/pre-trip-dashboard` | ✅ 用 #2 返回的 orderId | +| `IN_PROGRESS` | 行程进行中 | `#4 /mp/trip/today-dashboard` | ❌ 后端从 userId 反查 | +| `RETURNING` | 已完成过行程 | `#5 /mp/order/travel-memory` | ❌ 分页拉列表 | + +未支付订单(`PENDING_PAY`)不计入 `tab-state` 判定。 + +--- + +## 三、接口定位与返回核心字段 + +### 1. `GET /mp/order/{orderId}/dashboard` — 订单管理视角 + +**场景**:用户查看某张订单的履约与售后信息。 + +**返回**:`MpOrderDashboardVO` + +| 字段 | 类型 | 说明 | +|------|------|------| +| `order` | `MpOrderDetailVO` | 订单主体,含 `serviceItems`(服务包含列表)| +| `preTripChecklist` | `MpPreTripChecklistVO` | 出发准备清单(顶部待办徽章用;服务降级时 null)| +| `files` | `FilesVO` | 合同摘要 + 发票摘要 + 保单 PDF 路径 | +| `insurance` | `MpInsuranceDetailVO` | 保险详情(未投保时 null)| +| `refund` | `RefundVO` | 退款详情+进度(仅 CANCELLED/REFUNDING/REFUNDED/REFUND_REJECTED/APPEALING 状态有值,其余 null)| + +内部并行调 6 个 Feign:order(主,失败 500)+ contract + invoice + insurance + refund-detail + refund-progress。contract/invoice/insurance 失败降级 null。 + +> **服务包含列表**位置:`MpOrderDashboardVO.order.serviceItems`(`List`) +> 每项字段:`type`(HOTEL/MEAL/VEHICLE/GUIDE/PHOTOGRAPHER/TICKET/INSURANCE)、`title`、`summary`、`hasDetail`(运行态,是否有子详情页可看) + +--- + +### 2. `GET /mp/trip/tab-state` — 行程 Tab 路由决策 + +**场景**:用户切到行程 Tab 时的第一个调用。 + +**返回**:`MpTripTabStateVO` + +| 字段 | 类型 | 说明 | +|------|------|------| +| `state` | String | `IN_PROGRESS` / `BEFORE_START` / `RETURNING` / `NEW` | +| `stateLabel` | String | 状态中文标签 | +| `orderId` | Long | IN_PROGRESS / BEFORE_START 时有值 | +| `summary` | `Summary` | 产品名/档位/出发日期/距出发天数 等 | + +--- + +### 3. `GET /mp/trip/{orderId}/pre-trip-dashboard` — 行程前·出发准备 + +**场景**:`tab-state` 返回 `BEFORE_START` 时调用,订单已确认尚未出发。 + +**返回**:`MpPreTripDashboardVO`,包含订单头 / 出发准备清单 / 带队团队(领队+摄影师)/ 行程概览 / 客服电话。 + +内部并行调 3 个 Feign:trip + guide + photographer。guide/photographer 失败降级为 null,不影响主清单。 + +--- + +### 4. `GET /mp/trip/today-dashboard` — 行程中·今日页 + +**场景**:`tab-state` 返回 `IN_PROGRESS` 时调用,用户正在行程中。 + +**返回**:`MpTodayDashboardVO` + +| 字段 | 类型 | 说明 | +|------|------|------| +| `today` | `MpTodayVO` | 今日行程主体(无行程中订单时 null)| +| `leader` | `MpGuideInfoVO` | 联系领队卡 | +| `sosContact` | `SosContactVO` | SOS:领队电话 + 客服电话 + 保险客服电话 | +| `weather` | `List` | 今日 + 未来 N 天天气(失败降级 null)| +| `todayProgressPercent` | Integer | 今日进度 0-100(已游览景点 / 总景点)| +| `dayNav` | `List` | DAY 导航,每天标记 DONE/CURRENT/PENDING | +| `todayTimeline` | `MpTodayTimelineVO` | 按当前时间切成 completed/current/next 三段 | +| `todayHotel` | `MpTripHotelArrangementVO` | 今晚住宿(含是否与昨晚换酒店标记)| +| `tomorrow` | `MpTomorrowPreviewVO` | 明日预告(路线摘要+出发时间)| + +**入参仅 userId**(无 orderId),后端自己从 userId 反查进行中订单。无行程中订单时接口正常返回,核心字段全部 null/空列表。 + +内部并行调 guide + weather,两者失败都降级为 null。 + +--- + +### 5. `GET /mp/order/travel-memory` — 回头客态 + +**场景**:`tab-state` 返回 `RETURNING` 时调用。 + +**返回**:`PageResult` — 已完成(COMPLETED)订单分页列表,按出发日倒序。含 `reviewed` / `rating` / `reviewId`(评价服务降级时评分字段为 null)。 + +--- + +## 四、契约约束(正确调用方式) + +### ✅ 行程 Tab 入口 + +| 场景 | 正确调用序列 | +|------|--------------| +| 用户切行程 Tab | **先 `#2`** → 按 state 分支调 `#3` / `#4` / `#5` 之一 | +| state=BEFORE_START | `#2` 返回的 `orderId` 传给 `#3` | +| state=IN_PROGRESS | `#4` 不传 orderId,token 中的 userId 足够 | +| state=RETURNING | 调 `#5` 拉分页 | +| state=NEW | 不再调任何接口 | + +### ❌ 错误调用 + +- 切行程 Tab 直接调 `#3` / `#4`(跳过 `#2`)—— 不要自行根据订单状态/时间判断该渲染哪页 +- 并行调 `#3` 和 `#4` —— 同一时刻用户只可能在其中一个状态 +- `#3` 用自己缓存的 orderId —— 必须用 `#2` 本次返回的 orderId(订单可能已切换) + +### ✅ 订单详情入口(#1)独立 + +从任何订单链接进入都直接调 `#1`,不依赖 `#2`,也不影响行程 Tab 的调用。 + +--- + +## 五、不影响范围 + +- `#1 /mp/order/{orderId}/dashboard` 与 `#3 /mp/trip/{orderId}/pre-trip-dashboard` 字段独立,**不要互相替代** + - `#1` 关注:合同 / 发票 / 保单 / 保险 / 退款(订单管理视角) + - `#3` 关注:准备清单 / 领队+摄影师 / 行程概览(出行准备视角) +- `#3 pre-trip-dashboard` 与 `#4 today-dashboard` 返回 VO 完全不同,**不要通用一套渲染** +- 登录态统一从网关 token 解析,所有接口无需前端额外传 `userId` + +--- + +## 六、相关文档 + +- `MpOrderController.java`、`MpTripController.java`(hl-mp-service) +- VO:`MpOrderDashboardVO` / `MpTripTabStateVO` / `MpPreTripDashboardVO` / `MpTodayDashboardVO` / `MpTravelMemoryVO` +- 关联历史 changelog: + - `2026-04-22_mp-order-detail-service-items-has-detail.md`(#1234 hasDetail 字段) + - `2026-04-23_mp-pre-trip-checklist-split-arrival-departure.md`(#1289 清单拆 ARRIVAL/DEPARTURE)