# 【前端】小程序产品线详情页: 没有产品的类目 tab 应隐藏

> **类型**: 前端渲染修复(notice,后端无改动)
> **服务**: hl-product-service-v2(数据已就绪,无需改后端)
> **日期**: 2026-05-28
> **影响范围**: 小程序「产品线详情页」顶部类目 tab(全部 / 亲子游 / 蜜月旅行 / 摄影之旅 …)
> **归属**: 前端(mmg)。后端不建工单,本条仅同步现状 + 修法。

---

## ⚠️ 问题

产品线详情页顶部那排类目 tab 当前**把 `product_category` 字典的全部 5 个类目都渲染出来了**,不管该产品线下有没有这个类目的产品 → 出现"点进去空的"类目 tab。

**用户要求:没有产品的类目隐藏掉**,只显示该产品线下实际有产品的类目(再加一个「全部」)。

### 实测复现(测试服)

产品线「额吉的故乡v11」(lineId=`2045622604613529601`)下 4 个已上架产品的 `category` 分布:

| 产品 | category |
|------|----------|
| 额吉的故乡 6天5晚草原版 | `family`(亲子游) |
| 额吉的故乡(蜜月) | `honeymoon`(蜜月旅行) |
| 额吉的故乡 6天5晚 | `family` |
| 额吉的故乡(亲子) | `family` |

→ 该线**只有 `family`(亲子游) + `honeymoon`(蜜月旅行)** 两个类目有产品。
但页面 tab 还显示了「摄影之旅」(`photography`)等**没有产品**的类目 → 这就是 bug。

---

## 一、根因

- 类目 tab 不是后端某个接口返回的"类目列表",而是前端按 `product_category` 字典(共 5 项)**全量渲染**的,跟"该线是否有此类目产品"无关。
- 后端**没有**也不需要专门的"类目 tab 列表"接口。
- 但前端要判断"哪些类目有产品"所需的数据,后端**已经全量提供**:`GET /mp/product-line/{lineId}/products` 返回该线**全部已上架产品**(不分页),每个产品都带 `category` 字段。

---

## 二、前端修法(推荐,后端零改动)

1. 进入产品线详情页时调 `GET /mp/product-line/{lineId}/products`(不带 category 参数)拿到该线全部已上架产品。
2. 对返回列表的 `category` 字段做去重(去掉 null/空)→ 得到"该线实际有产品的类目集合"。
3. tab 只渲染这个集合里的类目(顺序可按字典 `dict_sort`),最前面保留「全部」。
4. 由于该接口不分页、返回全量产品,所以 distinct 出来的类目就是完整的非空类目集,无遗漏。

### 字典 `product_category` 码 → 中文(渲染 tab 文案用)

| code | 文案 |
|------|------|
| family | 亲子游 |
| honeymoon | 蜜月旅行 |
| photography | 摄影之旅 |
| experience | 深度体验 |
| driving | 自驾越野 |

---

## 三、可选: 如果前端希望后端直接给"非空类目列表"

若前端架构上更希望后端直接返回该线的非空类目(免去前端 distinct,并统一码→中文映射 + 排序),可告知后端,我们在产品线详情 `MpProductLineRespVO` 加一个 `categories`(code+label,仅含有产品的类目)字段。**当前默认不加,优先按上面的前端修法。** 需要就说一声。

---

## 四、相关接口(均已上线,无变更)

| 接口 | 方法 | 路径 | 说明 |
|------|------|------|------|
| 产品线下产品列表 | GET | `/mp/product-line/{lineId}/products` | 返回该线全部已上架产品,每项含 `category`(本次修复的数据来源) |
| 产品线详情 | GET | `/mp/product-line/{lineId}` | 头部信息(名称/封面/tags/起步价),`tags` 是产品线自由标签,**与类目 tab 是两个概念,别混用** |
