title: [ISSUE-0006]「有邮箱」chip 选中但表格未过滤 description: "选有邮箱,但是这边还是所有的,其他是不是也是呢?" tags: [issue, ui] created: 2026-05-26 updated: 2026-05-26 type: issue status: fixed severity: critical
[ISSUE-0006]「有邮箱」chip 选中但表格未过滤¶
相关源码:
src/sections/page/merchant-quick-filters.tsx、src/sections/page/local-data-view.tsx、src/sections/page/local-table.tsx
用户感知的现象¶
"选有邮箱,但是这边还是所有的,其他是不是也是呢?"
商家列表上方有 5 个快速筛选 chip(有邮箱 / 有网址 / 高评分 / 已挖掘 / 待挖掘)。用户点「有邮箱 967」chip → chip 视觉变蓝色(选中态)→ 但下方表格仍显示全部 19137 条。
用户合理怀疑其他 chip 也有同样问题。
根因分析¶
local-data-view.tsx:267:
const quickFilterAsFilters = (qf) => {
if (qf === 'has-email') return []; // TODO: jsstore 无法直接查 array.length>0,暂留空
...
};
「有邮箱」chip 的 filter 转换函数留了 TODO,返回空数组。chip 视觉受 quickFilter state 控制变蓝,但下推到 jsstore 的 filter 是 [] = 不过滤。
根本困难:emails 字段是 DATA_TYPE.Array,jsstore 不支持「数组长度 > 0」查询。
修复方案¶
JS 端 post-filter 旁路:
// api/search.ts
if (hasEmailOnly) {
const big = await getListByQuery(baseQuery, 1, 50_000, sort);
const filtered = big.list.filter(r => Array.isArray(r.emails) && r.emails.length > 0);
const start = (current - 1) * pageSize;
return { list: filtered.slice(start, start + pageSize), total: filtered.length, ... };
}
// local-data-view.tsx
dataRun({
...,
hasEmailOnly: quickFilter === 'has-email', // 旁路参数
});
性能:50k 行 JS filter ≈ 5-10ms,merchant-stats.ts 已验证可接受。
改动文件¶
| 文件 | 改了什么 |
|---|---|
src/api/search.ts |
apiLocalDataList 加 hasEmailOnly 参数 + JS post-filter 分支 |
src/sections/page/local-data-view.tsx |
dataRun 调用传 hasEmailOnly: true 当 quickFilter === 'has-email' |
验证方式¶
- 进入数据 → 商家列表
- 点「有邮箱」chip → 表格条数应变为 967(不是 19137)
- 取消 chip / 点「全部」 → 应恢复 19137
- 其它 4 个 chip 逐个测:有网址 / 高评分 / 已挖掘 / 待挖掘
- chip 间切换:选了 A 再选 B 应只显示 B(不累加)
如何避免再犯¶
- UI 状态与数据查询必须有明确的依赖链:state 改 → useEffect/useQuery 重跑 → 数据更新
- 任何"过滤器选项"加完后必须实测,不能只看 chip 视觉
- 测试矩阵:每个独立筛选 + 多 chip 组合 + 切换 + 取消 都要过一遍
相关问题¶
- 无