docs(mp): /mp/banner/active 响应新增 linkTarget 嵌套对象
PR #890 合并说明,含产品线季节、封面等展示字段 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
这个提交包含在:
父节点
ec1d0cfab3
当前提交
f8e9410ed2
@ -0,0 +1,118 @@
|
||||
# 小程序首页 Banner - 响应新增 linkTarget 嵌套对象
|
||||
|
||||
- **日期**: 2026-04-19
|
||||
- **PR**: [#890](https://git.1814.love:8443/wx/HL/pulls/890) (Closes #889)
|
||||
- **类型**: FEATURE
|
||||
- **状态**: 已合并到 dev + 测试环境部署完成
|
||||
- **服务**: hl-user-service + hl-product-service-v2
|
||||
- **接口**: `GET /mp/banner/active`
|
||||
- **兼容性**: **向后兼容**(仅新增字段,旧字段全部保留)
|
||||
|
||||
---
|
||||
|
||||
## 一、背景
|
||||
|
||||
小程序拿到 `/mp/banner/active` 列表后,当用户点到某条 Banner,前端还要再发一次产品/产品线详情请求才能展示封面、季节、产品类型,白屏等待感明显。
|
||||
|
||||
后端一把返回 Banner 展示所需的关联目标轻量信息,前端零二次请求。
|
||||
|
||||
---
|
||||
|
||||
## 二、响应新增字段
|
||||
|
||||
### 顶层新增 `linkTarget`
|
||||
|
||||
Banner 列表每个元素在原有字段基础上新增:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"id": "1",
|
||||
"title": "小蒙马亲子专题",
|
||||
"imageUrl": "https://cdn.example.com/banner1.jpg",
|
||||
"linkType": "PRODUCT_LINE",
|
||||
"linkId": "1001",
|
||||
"linkTargetType": "GROUP", // 保留,兼容旧前端
|
||||
"linkTargetName": "小蒙马亲子", // 保留,admin 填的展示名
|
||||
|
||||
// ⬇⬇⬇ 新增嵌套对象
|
||||
"linkTarget": {
|
||||
"type": "PRODUCT_LINE",
|
||||
"id": 1001,
|
||||
"name": "小蒙马亲子",
|
||||
"subtitle": null,
|
||||
"coverImageUrl": "https://cdn.example.com/line-cover.jpg",
|
||||
"productType": "GROUP",
|
||||
"seasons": ["SPRING", "SUMMER"],
|
||||
"lineId": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `linkTarget` 字段明细
|
||||
|
||||
| 字段 | 类型 | 说明 | 产品线 | 产品 |
|
||||
|------|------|------|--------|------|
|
||||
| `type` | string | `PRODUCT` \| `PRODUCT_LINE` | ✅ | ✅ |
|
||||
| `id` | long | 目标 ID(产品 ID 或产品线 ID) | ✅ | ✅ |
|
||||
| `name` | string | 名称 | ✅ | ✅ |
|
||||
| `subtitle` | string \| null | 副标题 | null | ✅ |
|
||||
| `coverImageUrl` | string \| null | 封面图 URL | ✅ | ✅ |
|
||||
| `productType` | string | `CORE` / `GROUP` / `CUSTOM` | ✅ | ✅ |
|
||||
| `seasons` | string[] | 适用季节,字典 `season`:`SPRING` / `SUMMER` / `AUTUMN` / `WINTER` | ✅ | ✅ |
|
||||
| `lineId` | long \| null | 所属产品线 ID | null | ✅ |
|
||||
|
||||
### `linkTarget=null` 的情况
|
||||
|
||||
以下场景 `linkTarget` 整体为 `null`,前端按「无卡片详情可展示」处理即可(原有字段 `title` / `imageUrl` / `linkType` / `linkId` 照常渲染和跳转):
|
||||
|
||||
- `linkType` 不是 `PRODUCT` 或 `PRODUCT_LINE`(例如 `SCENIC` / `PAGE` / `WEBVIEW` / `NONE`)
|
||||
- 关联目标已被删除或下架
|
||||
- 后端 Feign 降级(产品服务短暂不可用)
|
||||
|
||||
---
|
||||
|
||||
## 三、前端集成建议
|
||||
|
||||
### 卡片展示
|
||||
|
||||
```js
|
||||
// 列表渲染时
|
||||
banners.forEach(banner => {
|
||||
const target = banner.linkTarget;
|
||||
if (target) {
|
||||
// 可直接用 target.name / target.coverImageUrl / target.seasons 渲染副卡
|
||||
renderTargetCard({
|
||||
cover: target.coverImageUrl,
|
||||
title: target.name,
|
||||
subtitle: target.subtitle,
|
||||
tags: target.seasons, // ['SPRING', 'SUMMER']
|
||||
});
|
||||
} else {
|
||||
// 仅渲染 Banner 主图,点击跳 linkType + linkId
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 季节文案映射(前端字典)
|
||||
|
||||
```js
|
||||
const SEASON_LABEL = {
|
||||
SPRING: '春季',
|
||||
SUMMER: '夏季',
|
||||
AUTUMN: '秋季',
|
||||
WINTER: '冬季',
|
||||
};
|
||||
// target.seasons.map(s => SEASON_LABEL[s]) → ['春季', '夏季']
|
||||
```
|
||||
|
||||
### 跳转路径
|
||||
|
||||
跳转规则**不变**:继续用外层的 `linkType` + `linkId` 决定跳转目标路由。`linkTarget` 只用于 Banner 上的视觉展示。
|
||||
|
||||
---
|
||||
|
||||
## 四、其它说明
|
||||
|
||||
- **旧字段全部保留**:`linkType` / `linkId` / `linkTargetType` / `linkTargetName` 行为不变,前端原有兼容逻辑不用动
|
||||
- **缓存**:Banner 列表带 30 分钟 Redis 缓存 + 事务提交后自动 evict,管理员改完 Banner 小程序下次拉取就能看到最新 `linkTarget`
|
||||
- **admin 管理端接口未受影响**:banner 创建/编辑/列表接口未变(admin 只用 `linkTargetType` 做合法性提示,不返回 `linkTarget`)
|
||||
正在加载...
x
在新工单中引用
屏蔽一个用户