feat(banner): /mp/banner/active 主题补 description + tags (PR #2938 + #2941 Closes #2936)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
这个提交包含在:
API Changelog Bot 2026-05-23 10:39:54 +08:00
父节点 e44bb592ca
当前提交 f026b7fa04

查看文件

@ -0,0 +1,155 @@
# feat(mp/user/product-v2): /mp/banner/active 主题 (PRODUCT_LINE) 补 description + tags 字段
> **仓库**: HL (后端 hl-mp-service + hl-user-service + hl-product-service-v2 + hl-common-feign)
> **关联 PR/Issue**: PR #2938 + PR #2941, Closes #2936
> **日期**: 2026-05-23
> **影响范围**: `/mp/banner/active` 响应新增 `linkTarget` 嵌套对象,内含 description / tags
> **接收方**: mmg (前端)
> **前端**: **需要消费新字段** — banner.linkTarget.description / banner.linkTarget.tags 渲染主题轮播卡片
---
## 🎯 业务背景
呼籁 admin 字典里 `banner_link_type=PRODUCT_LINE` 标签是「主题」,product_line 表面向 C 端就是"主题"概念。
之前 banner 绑定主题 (link_type=PRODUCT_LINE) 时 mp 端拿不到主题的 description 和 tags,前端无法在轮播图卡片展示。
## 改动 (2 个 PR)
### PR #2938 — user-service + product-v2 字段贯通
- `InternalProductLineSimpleVO` (product-v2 + user-service 镜像) 加 `tags: List<String>` 字段
- `BannerLinkTargetVO``description + tags`
- `ProductLineMapper.selectSimpleInfoByIds` `.select()` 列表补 tags 列
- `ProductLineService.selectSimpleByIds` builder 补 `.tags(line.getTags())`
- `BannerService.enrichLinkTarget` PRODUCT_LINE 分支补 `.description(...).tags(...)`
### PR #2941 — mp 端 VO 补 linkTarget 嵌套
- `MpBannerVO` 新增 `linkTarget` 字段(此前精简 VO 没这字段,Feign 反序列化时下游 BannerVO 的 linkTarget 被 Jackson 自动丢弃)
- `MpHomeBannerLinkTargetVO``description + tags` 字段,跟 user-service `BannerLinkTargetVO` 对齐
## API 行为变化
### `GET /mp/banner/active`
每个 banner 现在多一个 `linkTarget` 嵌套对象:
**PRODUCT_LINE (主题) 场景**:
```json
{
"id": 5,
"title": "额吉的故乡",
"linkType": "PRODUCT_LINE",
"linkId": "2045622604613529601",
"linkTarget": {
"type": "PRODUCT_LINE",
"id": "2045622604613529601",
"name": "额吉的故乡v11",
"subtitle": null,
"coverImageUrl": "https://...",
"productType": "CORE",
"seasons": ["winter"],
"lineId": null,
"description": "公司的风格的", // 新字段
"tags": ["限定"] // 新字段
},
...
}
```
**PRODUCT 场景**:
```json
{
"linkType": "PRODUCT",
"linkTarget": {
"type": "PRODUCT",
"name": "...",
"subtitle": "...",
"coverImageUrl": "...",
"productType": "CORE",
"seasons": [...],
"lineId": ...,
"description": null, // PRODUCT 不返,前端可忽略
"tags": null
}
}
```
**其他 linkType / linkId 无效**: `linkTarget = null`
---
## 🚨 前端需要做的事
### 1. 读取新字段
```ts
const banner = response.data[0];
if (banner.linkType === 'PRODUCT_LINE' && banner.linkTarget) {
const desc = banner.linkTarget.description; // 主题描述
const tags = banner.linkTarget.tags; // 主题标签数组
const seasons = banner.linkTarget.seasons; // 季节数组 (本来就有)
}
```
### 2. 兼容性
- 旧前端代码不读 linkTarget 的不受影响 (顶层字段 id/title/imageUrl/linkType 等保持不变)
- linkTarget 可能为 null (其他 linkType 或目标已删除/下架),需做 null 守护
- description 和 tags 仅 PRODUCT_LINE 场景有值,PRODUCT 场景为 null
### 3. 自查
```bash
grep -rE "banner.linkTarget|banner\\.description|banner\\.tags" hl-ui/src
```
---
## 数据流
```
product_line (DB)
↓ ProductLineMapper.selectSimpleInfoByIds (含 tags)
↓ ProductLineService.selectSimpleByIds (含 description + tags)
↓ InternalProductLineSimpleVO (含 description + tags)
↓ user-service BannerService.enrichLinkTarget (PRODUCT_LINE 分支)
↓ user-service BannerLinkTargetVO (含 description + tags)
↓ Feign /internal/mp/banner/active 返回 BannerVO
↓ Jackson 反序列化到 mp MpBannerVO (PR #2941 新增 linkTarget 字段)
↓ MpBannerVO.linkTarget 类型 MpHomeBannerLinkTargetVO (PR #2941 新增 description + tags)
↓ /mp/banner/active 响应给前端
```
---
## 测试服真测记录
部署 user + product-v2 + mp (rolling-deploy 2026-05-23 10:38) 后真测:
```bash
curl https://api.test.1814.love:9443/mp/banner/active
```
| banner | linkType | description | tags |
|---|---|---|---|
| #2033821591988748290 | PRODUCT | null ✅ | null ✅ |
| #5 (额吉的故乡) | PRODUCT_LINE | '公司的风格的' ✅ | ['限定'] ✅ |
单测:
- BannerServiceTest 32 全绿
- ProductLine*Test 80 全绿
- mp Banner + Home 20 全绿
---
## 联系人
后端: wx (呼籁旅行)
前端: mmg
如有疑问可在 [#2936](https://git.1814.love:8443/wx/HL/issues/2936) 评论区留言。