跳转至

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.tsxsrc/sections/page/local-data-view.tsxsrc/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'

验证方式

  1. 进入数据 → 商家列表
  2. 点「有邮箱」chip → 表格条数应变为 967(不是 19137)
  3. 取消 chip / 点「全部」 → 应恢复 19137
  4. 其它 4 个 chip 逐个测:有网址 / 高评分 / 已挖掘 / 待挖掘
  5. chip 间切换:选了 A 再选 B 应只显示 B(不累加)

如何避免再犯

  • UI 状态与数据查询必须有明确的依赖链:state 改 → useEffect/useQuery 重跑 → 数据更新
  • 任何"过滤器选项"加完后必须实测,不能只看 chip 视觉
  • 测试矩阵:每个独立筛选 + 多 chip 组合 + 切换 + 取消 都要过一遍

相关问题