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

56 lines
3.8 KiB
Markdown
Raw Normal View History

---
id: T-583
title: ①Excel 导入改为 worker 线程执行,消除 GUI 阻塞与弹窗绘制积压(治本)
phase: 7
deps: [T-582]
status: TODO
created: 2026-07-10
---
## 问题 / 背景
①导入 Excel 目前在 GUI 线程**同步**执行(`app/gui/tabs/collect.py:242` `excel.import_tasks(file_paths, ...)` 在 `import_excel` 按钮 handler 内直接调用)。解析+入库期间**事件循环被阻塞**:界面卡死、重绘积压,紧随其后的完成/错误弹窗容易在积压未冲刷时绘制,导致偶发只显示一半(T-582 分析的根因①之治本项)。
T-582 已用 HiDPI 策略 + 统一弹窗 helper(延迟冲刷 + 屏幕钳制)缓解症状;本任务把导入挪进后台 worker,从根上消除 GUI 阻塞与重绘积压,顺带解决"导入大文件时界面卡死"。
已有可复用范式:①采集本身就是 `CollectWorker` + `run_worker` 线程模型(`collect.py` 已有 `_on_collect_finished`/`finished.connect`/`_forget_*_thread` 一套),导入照搬即可。
## 方案(改哪个文件、改成什么)
### 新增 `ImportWorker`(`app/gui/workers.py`)
- 接收 `file_paths` + `db_path`,在 `run()` 里调 `excel.import_tasks(...)`,通过 `finished` 信号回传 `result`(stats/batch_id/errors)或异常信息;沿用现有 worker 基类/信号约定。
- 不在 worker 线程里碰 Qt 控件;只发信号,GUI 线程收信号后更新。
### 改 `collect.py` `import_excel`
- 选完文件后:置"导入中"状态(禁用导入按钮、状态栏提示"正在导入...")→ 起 `ImportWorker` 线程(复用 `run_worker`/`_forget_*_thread` 模式)→ 立即返回,不阻塞。
- 新增 `_on_import_finished(payload)`:搬迁现同步路径里返回后的逻辑(写 run_log、`has_import_result`/`last_import_stats`/`current_batch_id` 赋值、file_errors/row_errors 落日志、`refresh_tasks`、`_set_status`、错误走 `_show_error`)。弹窗统一走 T-582 的 helper。
- 导入进行中:禁用「导入 Excel...」按钮,防重复导入并发写库;完成/失败后恢复。
### 线程安全 / 边界
- run_log 的写入若在 worker 线程发生,确认 DB 访问与现有 worker 一致(各自连接、不跨线程共享 sqlite 连接)。
- 导入与①采集/删除批次等其它写库操作互斥或至少不并发同一批次(沿用现有 running 守卫思路)。
## 验收要点
- 点「导入 Excel...」选文件后:GUI 不卡死(导入在后台线程),按钮置为导入中/禁用,状态栏提示进行中。
- 导入完成:`_on_import_finished` 更新 stats/batch_id、刷新列表、状态栏汇总,与旧同步路径结果一致(单测:mock `excel.import_tasks` 返回固定 stats,断言完成回调产生同样的 UI 状态/日志)。
- 导入失败:走 `_show_error`(经 T-582 helper)、写失败 run_log/诊断日志,不吞异常。
- 导入进行中「导入 Excel...」按钮禁用,完成后恢复。
- worker 线程内不触碰 Qt 控件(review + 单测 mock 校验信号路径)。
- 大文件导入期间界面可响应(人工验证点,记录到执行记录)。
- 验证命令(unittest,不引入 pytest):
- `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`
## 边界(不改什么)
- 不改 `excel.import_tasks` 解析/入库逻辑本身,只改调用它的线程。
- 不改导入结果的数据结构/stats 字段、批次生成逻辑。
- 不改①采集 `CollectWorker`、③更新、CDP/DB schema/AI/cmhub。
- 弹窗渲染修复本身属于 T-582,本任务只保证导入走 helper。
## 执行记录
(做完在这里写:改了什么文件、跑了什么验证命令及结果、遇到的阻塞、关键决策。)