Files
cmshoppe/docs/tasks/T-582.md
T

59 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: T-582
title: 修复①导入 Excel 失败通知弹窗偶发只显示一半(延迟一拍弹窗)
phase: 7
deps: []
status: TODO
created: 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、主窗口尺寸逻辑。
## 执行记录
(做完在这里写:改了什么文件、跑了什么验证命令及结果、遇到的阻塞、关键决策。)