hl-api-changelog/changelogs/2026-04/2026-04-22_mp-product-detail-order-snapshot.md

4.8 KiB

MP 产品详情接口支持订单快照回显

  • 变更日期: 2026-04-22
  • PR: #1182
  • Closes: #1176
  • 影响面: 小程序端(管理端不涉及)
  • 兼容性: 完全向后兼容,不传 orderId 时行为与改前一致

🎯 业务背景

用户从订单详情页点进产品详情时,应看到下单时冻结的产品快照(非实时最新),避免产品改价/改行程导致历史订单展示混乱。


📡 接口变更:GET /mp/product/{id}

1. 新增可选 Query 参数

参数 类型 必填 说明
orderId Long 订单 ID。传了走快照路径;不传/0/负数走原逻辑(查最新产品)

2. 触发场景(建议前端)

仅在「订单详情页 → 产品卡片/产品详情入口」传 orderId。其它入口(首页搜索、列表、分享链接、退款页等)不传 orderId,避免快照扩散到无必要场景。

3. 请求示例

# 实时路径(原有行为,零变化)
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

前端接入建议

// 从订单详情进产品
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