Files

6.3 KiB
Raw Permalink Blame History

id, title, phase, deps, status, created
id title phase deps status created
T-582 修复①导入 Excel 失败通知弹窗偶发只显示一半(延迟一拍弹窗) 7
DONE 2026-07-10

问题 / 背景

用户反馈:①采集导入 Excel 后的通知弹窗偶发只显示一半、显示不全。界面本身不卡死——导入通常很快、无可感知冻结,纯粹是弹窗画不全。「偶尔」也排除纯 HiDPI 缩放(那会稳定半截),更像绘制时序竞态。

已核代码事实:

  • 当前 CollectTab.import_excel() 成功导入后没有完成弹窗,只是在 refresh_tasks() 后调用 _set_status("导入完成...") 更新左下角状态栏。因此本任务不得新增“导入成功”弹窗,否则会变成新需求。
  • 当前导入失败路径在 except 中写 run log / 诊断日志后直接调用 _show_error(safe_error);_show_error() 立即执行 QMessageBox.warning(self, "导入采集", str(message))。
  • 失败弹窗可能在同一调用栈内、界面刷新/状态更新还未完成时立即进入模态 exec(),首帧几何/内容没算稳 → 偶发只画一半。修法不是“把导入改慢/改 worker”,而是“让通知弹窗晚一拍,等当前事件循环先把待处理绘制冲刷完”。

范围收敛:本任务只修①导入 Excel 失败通知弹窗,不建统一弹窗 helper、不重构其它 QMessageBox 调用点、不改导入线程模型(导入 worker 化不在本任务)。

方案(改哪个文件、改成什么)

1. 让导入失败通知弹窗晚一拍弹(app/gui/tabs/collect.py)

  • 把 _show_error(message) 改为:先同步更新状态栏 _set_status(str(message), level="danger" 或现有口径);再用 QTimer.singleShot(0, lambda: QMessageBox.warning(...)) 延迟显示导入失败通知。
  • 这样导入失败路径原有 run log、diagnostic log、状态栏错误信息仍在当前调用栈完成;真正的模态弹窗等当前事件循环下一拍再打开,降低首帧绘制不完整概率。
  • 只改 _show_error() 这一处导入失败通知;不改 import_excel() 成功路径,不新增导入成功弹窗。
  • 不改 _show_account_guide():它属于采集前账号就绪引导,不是导入 Excel 完成链路;本任务不外扩到采集链路。
  • 不改 QMessageBox.question / 删除批次确认等需要立即返回用户选择的确认类弹窗。

2. 本任务不做 HiDPI 全局设置

  • 先不在 app/gui/__init__.py 增加 QGuiApplication.setHighDpiScaleFactorRoundingPolicy(...)。该设置影响全局窗口缩放,且当前问题是“偶发”,优先按事件循环时序修复。
  • 如果后续能稳定复现 HiDPI 缩放导致的弹窗裁切,再另立任务处理全局缩放策略。

验收要点

  • excel.import_tasks() 抛异常时,导入失败通知经 QTimer.singleShot(0, ...) 延迟显示;单测 mock QTimer.singleShot 断言被调用,不真正弹窗。
  • excel.import_tasks() 抛异常时,不再在同一调用栈直接调用 QMessageBox.warning;可通过 mock QMessageBox.warning 断言在执行 singleShot 回调前未被直接调用。
  • 导入失败既有行为不回归:run log 标记 failed、诊断日志写入、状态栏显示脱敏错误文案、_show_error 的窗口标题/正文仍为中文导入失败提示。
  • 导入成功路径不新增 QMessageBox;仍然刷新列表、更新 summary、写状态栏“导入完成...”。
  • 未改动导入链路以外的弹窗调用点(git diff 范围仅 app/gui/tabs/collect.py + 对应 tests/test_gui.py)。
  • 验证命令(unittest,不引入 pytest;GUI 测试用 offscreen):
    • py -3.10 -m unittest tests.test_gui
    • python -m ruff check app tests main.py
    • py -3.10 -m compileall app main.py
    • py -3.10 -m unittest discover -s tests
    • git diff --check

边界(不改什么)

  • 不建统一弹窗 helper、不收敛/替换其它模块的 QMessageBox 调用。
  • 不把①导入改成 worker 线程(如后续要治界面卡死另立任务/backlog)。
  • 不新增导入成功弹窗;成功导入仍只用状态栏提示。
  • 不改 _show_account_guide() 账号未就绪弹窗;它属于采集链路,不属于导入 Excel 链路。
  • 不做 HiDPI 全局缩放策略调整。
  • 不改弹窗文案/业务语义、不改 excel.import_tasks 解析入库逻辑。
  • 不改 CDP/DB/AI/cmhub、主窗口尺寸逻辑。

执行记录

  • 2026-07-10:已实现 _show_error() 延迟弹出导入失败通知:状态栏仍同步显示错误,QMessageBox.warning(self, "导入采集", text) 改为经 QTimer.singleShot(0, ...) 下一拍执行,降低刷新/绘制同栈内立即弹模态框导致首帧显示不完整的概率。
  • 2026-07-10:未改导入成功路径;成功导入仍只刷新列表、更新 summary、状态栏显示“导入完成...”,不新增成功弹窗。未改 _show_account_guide()、删除批次确认框、HiDPI 全局设置、导入解析入库逻辑。
  • 2026-07-10:补 tests/test_gui.py:成功导入断言不会调用 QTimer.singleShot 和弹窗;导入异常时断言 QTimer.singleShot(0, callback) 被调用、回调执行前不直接弹窗、run log/脱敏错误/弹窗标题正文不回归。
  • 当前工作区验证通过:
    • py -3.10 -m unittest tests.test_gui.GuiTests.test_collect_tab_import_button_imports_excel_and_refreshes_tasks tests.test_gui.GuiTests.test_collect_tab_import_error_dialog_is_delayed_one_event_loop tests.test_gui.GuiTests.test_collect_tab_import_excel_writes_diagnostic_run_log
    • python -m ruff check app tests main.py
    • py -3.10 -m compileall app main.py
    • git diff --check(仅输出当前工作区既有 CRLF 提示,无空白错误)
  • 当前工作区直接运行 py -3.10 -m unittest tests.test_gui 失败 2 项,原因是本任务开始前已有未提交改动把默认封面提示词从 papa1 改成「默认」,导致两个旧断言仍期望 papa1;该提示词改名不属于 T-582,本次未处理、未提交。提交后需用干净 worktree 验证本次提交本身。
  • 提交后在干净 worktree D:\chengma\cmshopee_verify_t582 验证本次 T-582 提交:python -m ruff check app tests main.py 通过,py -3.10 -m compileall app main.py 通过,git diff --check 通过,py -3.10 -m unittest tests.test_gui 通过 145 项,py -3.10 -m unittest discover -s tests 通过 325 项。