docs(tasks): refine T-582 import error dialog scope
This commit is contained in:
+24
-15
@@ -1,6 +1,6 @@
|
||||
---
|
||||
id: T-582
|
||||
title: 修复①导入 Excel 后完成弹窗偶发只显示一半(延迟一拍弹窗 + 可选 HiDPI 一行)
|
||||
title: 修复①导入 Excel 失败通知弹窗偶发只显示一半(延迟一拍弹窗)
|
||||
phase: 7
|
||||
deps: []
|
||||
status: TODO
|
||||
@@ -9,28 +9,34 @@ created: 2026-07-10
|
||||
|
||||
## 问题 / 背景
|
||||
|
||||
用户反馈:①采集导入 Excel 后的完成/错误弹窗**偶发只显示一半、显示不全**。**界面本身不卡死**——导入通常很快、无可感知冻结,纯粹是弹窗画不全。「偶尔」也排除纯 HiDPI 缩放(那会稳定半截),指向绘制时序竞态。
|
||||
用户反馈:①采集导入 Excel 后的通知弹窗**偶发只显示一半、显示不全**。**界面本身不卡死**——导入通常很快、无可感知冻结,纯粹是弹窗画不全。「偶尔」也排除纯 HiDPI 缩放(那会稳定半截),更像绘制时序竞态。
|
||||
|
||||
已核代码事实:①导入返回后在**同一调用栈**里紧接 `refresh_tasks()`(整表重绘)后立即 `exec()` 弹窗(`app/gui/tabs/collect.py:242` 起)。模态框在这次整表重绘尚未画完时就打开,首帧几何/内容没算稳 → 偶发只画一半。**与导入是否耗时无关**:只要弹窗在待处理重绘之前 `exec()` 就可能半截,所以修法不是"别阻塞",而是"让弹窗晚一拍、等重绘画完再开"。
|
||||
已核代码事实:
|
||||
- 当前 `CollectTab.import_excel()` **成功导入后没有完成弹窗**,只是在 `refresh_tasks()` 后调用 `_set_status("导入完成...")` 更新左下角状态栏。因此本任务不得新增“导入成功”弹窗,否则会变成新需求。
|
||||
- 当前导入失败路径在 `except` 中写 run log / 诊断日志后直接调用 `_show_error(safe_error)`;`_show_error()` 立即执行 `QMessageBox.warning(self, "导入采集", str(message))`。
|
||||
- 失败弹窗可能在同一调用栈内、界面刷新/状态更新还未完成时立即进入模态 `exec()`,首帧几何/内容没算稳 → 偶发只画一半。修法不是“把导入改慢/改 worker”,而是“让通知弹窗晚一拍,等当前事件循环先把待处理绘制冲刷完”。
|
||||
|
||||
范围收敛:本任务**只修导入这一处弹窗**,不建统一弹窗 helper、不重构其它 `QMessageBox` 调用点、不改导入线程模型(导入 worker 化不在本任务)。
|
||||
范围收敛:本任务**只修①导入 Excel 失败通知弹窗**,不建统一弹窗 helper、不重构其它 `QMessageBox` 调用点、不改导入线程模型(导入 worker 化不在本任务)。
|
||||
|
||||
## 方案(改哪个文件、改成什么)
|
||||
|
||||
### 1. 让导入完成/错误弹窗晚一拍弹(`app/gui/tabs/collect.py`)
|
||||
- 导入返回后,把该路径上的弹窗(`_show_error` 失败框、账号未就绪 warning、导入结果通知框等**导入链路**的通知类弹窗)改为用 `QTimer.singleShot(0, lambda: <弹窗>)` 推迟显示——让紧邻的整表重绘(`refresh_tasks`)先在事件循环里冲刷完,再打开模态框。
|
||||
- 只改导入链路的通知类弹窗;不动 question/确认类(导入链路本身无需返回值的确认)。
|
||||
- 仅 collect.py 导入相关处,不外扩。
|
||||
### 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`)
|
||||
- `QApplication` 创建前设 `QGuiApplication.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)`(`main()` 里 `app = QApplication.instance() or QApplication(sys.argv)` 之前;实例已存在时跳过避免告警)。
|
||||
- 零风险、对整体弹窗清晰度有益;如实现时评估有副作用可省略,验收不强制。
|
||||
### 2. 本任务不做 HiDPI 全局设置
|
||||
- 先不在 `app/gui/__init__.py` 增加 `QGuiApplication.setHighDpiScaleFactorRoundingPolicy(...)`。该设置影响全局窗口缩放,且当前问题是“偶发”,优先按事件循环时序修复。
|
||||
- 如果后续能稳定复现 HiDPI 缩放导致的弹窗裁切,再另立任务处理全局缩放策略。
|
||||
|
||||
## 验收要点
|
||||
- 导入完成/失败后的通知类弹窗经 `QTimer.singleShot(0, ...)` 延迟显示(单测:mock `QTimer.singleShot` 断言被用于导入完成/错误弹窗路径;不真正弹窗)。
|
||||
- 导入结果/错误的既有行为(stats 更新、run_log、状态栏文案、`_show_error` 内容)不回归。
|
||||
- 若采纳 HiDPI 行:启动设置在 QApplication 创建前、不回归启动。
|
||||
- 未改动导入链路以外的弹窗调用点(`git diff` 范围仅 collect.py 导入链路 +(可选)__init__.py 一行)。
|
||||
- `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`
|
||||
@@ -41,6 +47,9 @@ created: 2026-07-10
|
||||
## 边界(不改什么)
|
||||
- 不建统一弹窗 helper、不收敛/替换其它模块的 `QMessageBox` 调用。
|
||||
- 不把①导入改成 worker 线程(如后续要治界面卡死另立任务/backlog)。
|
||||
- 不新增导入成功弹窗;成功导入仍只用状态栏提示。
|
||||
- 不改 `_show_account_guide()` 账号未就绪弹窗;它属于采集链路,不属于导入 Excel 链路。
|
||||
- 不做 HiDPI 全局缩放策略调整。
|
||||
- 不改弹窗文案/业务语义、不改 `excel.import_tasks` 解析入库逻辑。
|
||||
- 不改 CDP/DB/AI/cmhub、主窗口尺寸逻辑。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user