docs(mp-product): 产品详情接口支持订单快照回显 (#1182)

这个提交包含在:
API Changelog Bot 2026-04-22 17:00:52 +08:00
父节点 6093ec52cf
当前提交 7edd339569

查看文件

@ -0,0 +1,139 @@
# MP 产品详情接口支持订单快照回显
- **变更日期**: 2026-04-22
- **PR**: #1182
- **Closes**: #1176
- **影响面**: 小程序端(管理端不涉及)
- **兼容性**: **完全向后兼容**,不传 `orderId` 时行为与改前一致
---
## 🎯 业务背景
用户从订单详情页点进产品详情时,应看到下单时冻结的产品快照(非实时最新),避免产品改价/改行程导致历史订单展示混乱。
---
## 📡 接口变更:`GET /mp/product/{id}`
### 1. 新增可选 Query 参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `orderId` | Long | 否 | 订单 ID。传了走快照路径;不传/0/负数走原逻辑(查最新产品) |
### 2. 触发场景(建议前端)
**仅在**「订单详情页 → 产品卡片/产品详情入口」传 `orderId`。其它入口(首页搜索、列表、分享链接、退款页等)**不传 orderId**,避免快照扩散到无必要场景。
### 3. 请求示例
```http
# 实时路径(原有行为,零变化)
GET /mp/product/1001
Authorization: Bearer <token>
# 快照路径(新增)
GET /mp/product/1001?orderId=99988
Authorization: Bearer <token>
```
---
## 📦 响应 VO 变更:`MpProductDetailRespVO` 新增 3 字段
所有字段都是 **Boolean/Long 类型,可空**,旧前端代码不读时零影响。
| 字段 | 类型 | 说明 |
|---|---|---|
| `isSnapshot` | Boolean | `true`=快照数据(冻结版本);`false`/null=实时数据 |
| `snapshotOrderId` | Long | 快照来源的订单 ID仅 isSnapshot=true 时有值)|
| `snapshotFallback` | Boolean | `true`=原本想返回快照但降级到了实时(订单异常/快照空/Feign 失败等);`false`=正常快照;null=原路径未涉及 |
### 响应三态对照
| 请求 | isSnapshot | snapshotOrderId | snapshotFallback | 含义 |
|---|---|---|---|---|
| 不传 orderId | null/false | null | null | 原逻辑实时数据 |
| 传 orderId一切正常| **true** | 99988 | **false** | 返回订单快照,前端可打「订单快照」标识 |
| 传 orderId降级| false | 99988 | **true** | 快照出问题降级实时了,前端可提示「当前为最新版本,下单时数据已不可查」 |
---
## 🔻 错误码 / 降级行为
| 场景 | 行为 |
|---|---|
| 不传 orderId | 原逻辑,查最新产品5min Redis 缓存)|
| 传 orderId=0 或负数 | 同「不传 orderId」 |
| 传的 orderId 不存在 / 非本人 / 已软删 | **统一降级到实时路径** + `snapshotFallback=true`,不抛错(防 orderId 枚举攻击)|
| 快照字段为空(历史订单)/ JSON 解析失败 | 降级实时 + `snapshotFallback=true` |
| 快照正常但对应产品已下架 | 返回快照 + `productDeleted=true`(前端可提示「该产品已下架」)|
| Feign 超时 / order 服务不可达 | 降级实时 + `snapshotFallback=true` |
| `productId` 与快照里的不匹配(防串号)| HTTP 200 + 业务错误码 400 + msg「产品与订单不匹配」|
---
## 🧩 MP 独有字段(不走快照,走实时)
下列字段**永远实时查**,即使走快照路径也会实时补齐(因为这些是用户预期会更新的数据):
- `reviewSummary`(评价摘要)
- `earlyBirdTip` / `earlyBirdLadder`(早鸟方案)
- `DayInfo.gatherPlace` / `dismissalPlace` / `quoteText`(集合/解散地、引言)
- `NodeInfo.resourceCover` / `resourceImages` / `resourceAddress` / `resourceDescription` / `resourceTags`(资源详情)
- `TierPriceInfo.depositAmount`(按比例算)
- `refundPolicy`(退款政策)
这些字段在快照路径下也正常返回,前端不用关心差异。
---
## 🔒 鉴权
- 小程序 token登录态必传。网关从 token 解析 `X-User-Id` Header 注入,后端据此校验订单归属
- 未登录token 缺失)时走实时路径 + `snapshotFallback=true`
---
## ✅ 前端接入建议
```js
// 从订单详情进产品
const resp = await request({
url: `/mp/product/${productId}?orderId=${orderId}`,
});
if (resp.data.isSnapshot === true) {
// 显示角标:订单快照版本
showBadge('订单快照');
} else if (resp.data.snapshotFallback === true) {
// 提示:原订单数据已不可查,显示最新
showTip('当前为最新版本,下单时数据已不可查');
}
if (resp.data.productDeleted === true) {
// 产品已下架,仅展示模式
disableActions();
showTip('该产品已下架');
}
```
其他入口调用方式不变。
---
## 📌 非变更项(确保前端无需额外改动)
- 其他返回字段id/name/tiers/itinerary/tierPrices/...)语义不变
- Header、认证方式、Base URL 均不变
- 其他接口(`/mp/product/list``/admin/product/**` 等)零影响
---
## 🔗 相关
- 工单:#1176
- PR#1182
- 部署:合并到 dev 后由 Deploy Panel 同步部署 `hl-order-service-v2` + `hl-product-service-v2`
- 测试环境:`https://api.test.1814.love:9443`