feat: 完成T-303 AI批量生成

- 新增 generate_batch,先并发生成标题再并发生成封面,成功逐条 set_generated 落库

- Tab② 接入开始生成、停止、进度展示和双击新旧封面预览

- 新增 GenerateWorker,通过 worker signal 回传进度与行刷新

- 补充批量生成成功、失败、停止取消和 GUI worker 单元测试

- 同步任务看板、API、路由、当前状态与 progress 文档
This commit is contained in:
chengma
2026-06-27 16:26:08 +08:00
parent fe1e0a7d32
commit 789e82991f
9 changed files with 678 additions and 21 deletions
+10
View File
@@ -499,3 +499,13 @@
- 测试:新增 `tests/test_prompts.py`;`tests/test_gui.py` 覆盖标题回显/保存、封面模板另存/重命名/删除、插入标题与变量预览。
- 文档:`docs/06-tasks.md` 将 T-302p 标为 DONE;同步 `docs/api.md`、`docs/routes.md`、`docs/current-state.md`,下一个可领取任务更新为 T-303。
- 验证:`python -m unittest discover -s tests -p "test_prompts.py"` 通过(3 tests);`python -m unittest discover -s tests -p "test_gui.py"` 通过(21 tests);`python -m compileall app main.py tests` 通过;`python -m unittest discover -s tests` 通过(69 tests);`py -3 -m compileall app main.py tests` 通过;`py -3 -m unittest discover -s tests` 通过(40 tests,skipped=4,py -3 环境缺 openpyxl/PySide6/Pillow,相关测试按设计跳过)。
## 【2026-06-27】T-303 Tab② 开始生成 + 停止 + 进度
- 状态:DONE
- 变更:`app/ai.py` 新增 `generate_batch()` 批量编排,按 `title_concurrency` 先并发生成标题,再按 `image_concurrency` 并发生成封面;封面成功后立即 `db.set_generated()`,标题/封面失败 `db.mark_failed(..., "generate", error)`,失败不阻塞其余任务;`should_stop()` 为真时取消未开始的 Future,被取消任务不记失败。
- GUI:`GenerateTab` 底部接入「开始生成」「停止」和进度标签;开始生成只处理当前筛选结果里 `stage=collected` 的任务;新增 `GenerateWorker` 通过 signal 回传进度、行刷新、完成/取消状态;任务表双击弹窗查看旧封面与新封面对照。
- 测试:`tests/test_ai.py` 覆盖 `generate_batch` 正常落库、单条失败不阻塞、停止前取消且任务保持 collected;`tests/test_gui.py` 覆盖生成控件、双击预览弹窗、`GenerateWorker` 调用 `ai.generate_batch()` 并发出 progress/row_updated。
- 文档:`docs/06-tasks.md` 将 T-303 标为 DONE;同步 `docs/api.md`、`docs/routes.md`、`docs/current-state.md`,下一个可领取任务更新为 T-401。
- 验证:`python -m unittest discover -s tests -p "test_ai.py"` 通过(6 tests);`python -m unittest discover -s tests -p "test_gui.py"` 通过(22 tests);`python -m compileall app main.py tests` 通过;`python -m unittest discover -s tests` 通过(73 tests)。
- 注意:本轮仍为 mock AI 单测,未调用真实 AI 服务;真实生成需在 `config/ai_models.json` 配好可用 text/image 模型后做小样本实测。