notice: 主题列表筛选选小蒙马变空 (前端 BUG, @mmg)

这个提交包含在:
wx 2026-05-07 10:38:00 +08:00
父节点 cc29f8ef91
当前提交 fbf81a10a3

查看文件

@ -0,0 +1,76 @@
# 前端 BUG 通知 — 主题列表「主题类型」筛选选「小蒙马」后列表变空
**日期**: 2026-05-07
**类型**: 前端 BUGadmin 后台 hl-ui
**模块**: 主题管理(产品线 / Product Line
**通知**: @mmg
**后端是否需改动**: 否
---
## 现象
admin 后台「产品 → 主题列表」页面:
- 进入页默认「共 15 条」(与后端实测一致)
- 在「主题类型」下拉框选择「小蒙马」点搜索 → 列表变「暂无主题数据」
- 用户期望:应返回 GROUP 类型的产品线(实测有 3 条)
## 后端 round-trip 实测(已排除后端嫌疑)
测试服 `https://api.test.1814.love:9443/admin-api/admin/product/line/list`,admin/Admin@123456,SUPER_ADMIN
| 请求 | total | records.length | 备注 |
|---|---|---|---|
| 不带 productType | 15 | 12 | PAGE_SIZE=12,分页正常 |
| `productType=GROUP` | **3** | **3** | 与用户描述「0 条」矛盾 → 前端嫌疑 |
| `productType=CORE` | 5 | 5 | |
| `productType=CUSTOM` | 6 | 6 | |
| `productType=ROUTE` | 0 | 0 | 数据本就 0 |
| `productType=小蒙马`(中文 label 当 value 反例) | **0** | **0** | **如果前端误把 label 当 value 传,现象 100% 吻合** |
**结论**:后端 `eqIfPresent(ProductLineDO::getProductType, req.getProductType())` 工作正常;前端选「小蒙马」点搜索后,传给后端的不是字典 value `GROUP`
## 字典对照(`product_type` 字典,已 round-trip 验证)
| label | dictValue |
|---|---|
| 核心产品 | CORE |
| 自驾路书 | ROUTE |
| 私人定制 | CUSTOM |
| **小蒙马** | **GROUP** |
## 根因推断(按概率排序)
### (A) 字典 store localStorage 持久化老数据 ⭐ 最可能
- `hl-ui/src/stores/dict.js:110-114``pinia-plugin-persistedstate` 持久化了 `dictList`
- 用户浏览器 localStorage 里旧版字典可能没有 GROUP 项,导致下拉 option value 错位
- **复现取证步骤**:让 mmg 让用户在 DevTools → Application → Local Storage 查看 `dict` key,看「小蒙马」一项的 `dictValue` 是否为字符串 `"GROUP"`
### (B) 前端把 label 当 value 传给后端
- 检查 `hl-ui/src/views/product/line/index.vue` 的「主题类型」下拉框 v-model 与 `el-option :value` 是否绑定到 `dictValue`(应该是 `GROUP` 字符串)而不是 `dictLabel``小蒙马`
- DevTools → Network 抓搜索后的请求 URL
- 如果是 `?productType=GROUP&...` → 不是这条根因
- 如果是 `?productType=小蒙马&...``?productType=undefined&...` → 就是这条
### (C) 前端打包版本滞后
- 用户访问的静态资源若是某次旧打包,可能还在用老字段名
- 让用户硬刷新Ctrl+Shift+R或退出重登再复现
## 建议修复方向
1. **优先级 1**:让 mmg 在自己浏览器复现一遍,DevTools Network 抓真实请求 URL,定位是 (A) 还是 (B)
2. **如果是 (A)**dict store 加版本号,字典升级后 localStorage 自动失效;或者进入「主题列表」页前强制 `dictStore.refresh()` 拉一次最新
3. **如果是 (B)**:检查筛选区下拉框 `:value` 绑定,确保用 `dict.dictValue` 不是 `dict.dictLabel`
## 涉及文件(仅供前端排查参考)
- 页面:`hl-ui/src/views/product/line/index.vue`(标题「主题管理」)
- 字典 store`hl-ui/src/stores/dict.js:39-50, 110-114`
- API`hl-ui/src/api/product/core.js:49-51` `getProductLinePage`
## 后端代码定位(确认无需改动)
- Controller`hl-product-service-v2/.../admin/AdminProductLineController.java:75-79` `GET /admin/product/line/list`
- VO`ProductLinePageReqVO.java:23` `private String productType;`(字典 product_type
- Service`ProductLineService.java:168-174` `listLines`
- Mapper`ProductLineMapper.java:48-68` `selectPageWithCount``MPJLambdaWrapperX.eqIfPresent(...)`