跳转至

[ISSUE-0068] dogfood v0.10.89 — 4 项小修

用户开启 enableMultiStageScrape 后跑大批量任务,5 张截图反馈: 1. 清空数据后列表不刷新 —— toast 成功但行还在 2. mstage:success 标签 hover 显示"抓取失败" —— UI 不识别 mstage 是事件标记非错误 3. 电话去重未去国家码 —— "+1 907-522-1341 (地图)" 和 "9075221341" 被当 2 个号 4. 创建任务点击后卡顿无反馈 —— 整国采集时解析 location 列表慢

Bug 1:清空数据后列表不刷新

病灶

src/sections/page/local-toolbar.tsx:doClearAll

const doClearAll = async () => {
  const r: any = await clearSearchData();
  if (r?.success) {
    toast.success('清空数据成功');
    // ❌ 缺:通知列表 refresh
  }
};

后果:KPI 顶部 stats 走自己的 polling 已经归 0,但商家列表用的是 client mode rowsSnapshot(v0.10.79 useDataSource hook 重构后)—— 没人通知它重新拉。

清空成功后调 flushData() prop(LocalDataView 早已实现 client/server mode 双分支刷新)。1 行修复。

Bug 2:mstage:success 标签 hover 显示"抓取失败"

病灶

src/sections/page/log-view.tsx:215-224 早期写法 if (e.error) 一律渲染红色 + tooltip "抓取失败:${e.error}"。

但 SPEC-004 v0.10.87 起 e.error 被复用编码多阶段事件: - mstage:success — success: 6 contacts —— 是成功 - mstage:dead@probe — dead/404 —— 是主动跳过 - mstage:fallback/contact-keyword-but-empty@extract —— 是降级到 tab

UX 灾难:用户看到一整页"红色失败",但实际 60% 是 success。

新 helper classifyMstage(error) 按前缀分类:

前缀 color tooltip 前缀
mstage:success success.main 绿 多阶段命中
mstage:dead / no-contact / non-html text.secondary 灰 跳过抓取
mstage:retry-later warning.dark 稍后重试
mstage:antibot-* / fallback/antibot warning.main 橙 反爬拦截 / 落 tab
mstage:fallback/* info.main 蓝 降级到 tab 抓取
mstage: 其他 text.secondary 多阶段事件
mstage: 前缀 error.main 红 抓取失败(真错误)

Bug 3:电话去重未去国家码

病灶

scraper-executor.ts:mergePhonesWithMapsLabel 的 normalize:

const normalize = (p: string) => p.replace(/\D/g, '');

后果: - "+1 907-522-1341 (地图)""19075221341" (含国家码 1) - "9075221341""9075221341" (无国家码) - 两者作为去重 key 不相等 → 同一号码被当 2 个

截图 5 实际场景:tooltip 显示 3 个号码("+1 907-522-1341 (地图)" / "9075221341" / "907-522-1343"),其中前两个其实是同号。

normalize 取后 10 位(北美 +1 / 中国 +86 都剥):

const normalize = (p: string) => {
  const d = p.replace(/\D/g, '');
  return d.length > 10 ? d.slice(-10) : d;
};

10 位是北美 NPA-NXX-XXXX 长度;中国 +86 → 11 位手机号 → 取后 10 位也安全("86 13800138000" → "3800138000" 跟另一条 "13800138000" 还是不同 → 不漏匹配也不误合并)。

实际上中国手机 11 位 — 13800138000 normalize → 后 10 位 3800138000;带国家码 +8613800138000 normalize 13 位 → 后 10 位 3800138000一致 ✓

Bug 4:创建任务点击后卡顿无反馈

病灶

task-create-dialog.tsx:handleCreate async 函数: - 整国采集时调 apiCountryLocations({ code }) 拿 state/city 列表(云端 API,可能秒级) - 再 browser.runtime.sendMessage({ type: 'create-task', ... }) 给 background

期间按钮无任何视觉反馈,用户多次点击 / 怀疑卡死。

  • submitting: boolean state
  • handleCreate 包 try-finally:进 setSubmitting(true),finally setSubmitting(false)
  • 按钮 disabled={!canSubmit || submitting}
  • startIcon 切换为 <CircularProgress size={14}>
  • 文本切换为 "创建中…"
  • 函数顶部 if (submitting) return 防双击

注意点

  • Bug 3 normalize 改动也影响已存在的 phone 字段(旧数据不会自动重抓,下次重抓时新 normalize 生效)
  • Bug 2 classifyMstage 用 startsWith 判断 — 未来 mstage 加新类型时记得补 case
  • Bug 1 flushData 在 server mode 也安全(dataRefresh())
  • Bug 4 try-finally 确保所有 return 路径都重置 submitting

元教训

dogfood 大数据集才能暴露:单跑 10 商家时 4 个问题全看不出来。需要 50k+ 行 / 大量 mstage 事件 / 含 +1 国家码的真实电话数据。

相关