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

106 lines
8.7 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-612
title: AI工场生图运行态分级,保留当前项目非冲突操作
phase: 7
deps: [T-594, T-604, T-608, T-609]
status: DONE
created: 2026-07-13
---
## 问题 / 背景
⑥ AI工场点击「开始生成」或「继续查询任务」后,`ImageStudioTab.start_generation()` / `resume_generation_jobs()` 都经由通用 `_start_worker()` 进入 `_set_running(True)`。当前 `_set_running()` 会同时禁用商品列表、蝦皮原主图、照片池、主图/详情图终选、提示词模板、提示词编辑、生成参数、开始/继续查询、导出和项目操作,只留下「取消」。
这不是 cmhub 网络等待导致 GUI 卡死:网络工作在 `QThread` 中。它是早期把所有 AI工场 worker 当作同一种“全页互斥操作”的保守实现,用来避免:
- 在单一 `_running_worker` / `_running_thread` 模型下同时启动两个耗时 worker;
- 生成回调按 `current_project` 刷新时,用户同时删除项目或开始另一项写操作;
- 用户误以为生成中的提示词或源图变更会影响已经提交给 cmhub 的本轮任务。
但图片生成/继续查询通常持续数分钟,全页变灰妨碍运营在当前商品内浏览照片池、整理终选、修改下一轮提示词。T-608 已经为单张蝦皮原图下载拆除了全页禁用,生图仍沿用旧的全局锁定策略,体验不一致。
## 方案
### 1. 区分操作类型,保留“单一耗时 worker”边界
在 `app/gui/tabs/image_studio.py` 中把通用运行态从单一布尔值扩展为明确的操作类型,例如:`generate`、`resume`、`pull_images`、`export`。运行期间仍只允许一个由 `_start_worker()` 管理的耗时 worker,不能借“局部可用”引入两个生成、轮询、拉图或导出 worker 并发。
- `ImageStudioGenerateJobsWorker` 与 `ImageStudioResumeJobsWorker` 使用“生成运行态”;
- 拉取蝦皮主图、导出终选维持现有较严格的互斥范围;
- T-608 的单张原图下载队列继续使用专用路径,不回退到 `_start_worker()`,不受本任务破坏;
- 线程引用仍只在 `thread.finished` 后释放,继续遵守 T-604 的生命周期修复。
### 2. 生图期间只禁用冲突操作
处于“生成运行态”时:
- **必须禁用**:开始生成、继续查询任务、拉取蝦皮主图、导出终选、删除项目、会启动完整原图下载的原图区操作;这些操作会再启动 worker、改变线上主图快照、移动导出文件或删除当前 worker 仍在写入的项目。
- **保持可用**:当前项目的照片池浏览、源图选择、主图/详情图终选排序、提示词模板切换/编辑/保存、类型/数量/比例的下一轮设置,以及打开当前项目文件夹。
- 当前这一轮的源图、提示词、类型、数量、比例在创建 `ImageStudioGenerateJobsWorker` 时已经快照传入;运行中修改上述控件只影响**下一轮**,不得改变已提交或正在轮询的 cmhub job。
- 在生成设置区显示中文轻量提示,例如「本轮任务已固定;此处修改将在下一轮生成时生效」,避免用户误解。
- 第一版不开放切换商品项目。项目切换会重置缩略图缓存、`current_project`、`selected_source_asset_id` 和列表内容,且现有完成/进度回调仍依赖当前 tab 状态;保留禁用项目列表可避免旧项目的余额、进度或刷新事件显示到新项目。后续若要支持跨项目浏览,必须先让全部回调按启动时捕获的 `project_id` 隔离,再单独立任务。
取消按钮继续始终可用;点击后只请求 worker 在安全边界停止,控件在 worker 正常完成、失败或停止并完成清理后恢复。
### 3. 回调与状态恢复保持幂等
- `_finish_worker()`、`worker.failed`、`worker.finished` 以及 `thread.finished` 的顺序不得导致控件提前恢复或重复恢复;继续复用 T-604 的 `_worker_error_handled` 与线程引用清理规则。
- 生成部分成功、部分失败、用户停止、cmhub 轮询失败和导出/拉图失败后,都按各自操作类型恢复对应控件,而不是无条件套用“生成态”或“全局空闲态”。
- 不在 GUI 主线程等待 cmhub,也不在后台线程直接操作 Qt 控件。
### 4. 文档同步
更新 `docs/routes.md` 中⑥ AI工场的生成运行口径:生图期间禁止新建冲突 worker,但可继续整理当前项目的下一轮设置与终选;原图下载、项目切换、拉取、导出和删除的边界保持明确。
## 验收要点
- 点击「开始生成」或「继续查询任务」后,取消按钮可用,开始/继续查询/拉取/导出/删除项目/原图区下载操作不可用。
- 生图期间,照片池、主图终选、详情图终选、提示词模板、提示词编辑和下一轮类型/数量/比例控件不再整体变灰,可正常操作。
- 运行中修改提示词或参数后,本轮已创建的 worker 仍使用启动时的快照;下一轮生成才读取新值。
- 生图期间不能启动第二个耗时 worker,不能切换或删除项目,不能从原图区触发新的完整原图下载。
- 停止、完成、部分失败和 worker 异常后,控件按空闲态正确恢复;不会出现 QThread 提前释放、重复错误弹窗或残留禁用状态。
- T-608 的单张原图下载仍只局部更新,不会因为本任务重新把 AI工场全页变灰。
- 不改 cmhub submit/poll/download、计费、job 持久化、SQLite schema、CDP、Chrome、蝦皮读取/更新或①至⑤模块。
## 测试要求
更新或新增 `tests/test_gui.py`:
- 覆盖生成运行态下各控件的精确启用/禁用清单;特别断言照片池、终选、提示词和参数可用,而开始/继续查询/拉取/导出/删除/原图区下载不可用。
- 覆盖运行中修改 prompt/参数不会改变已构造 worker 的参数,只影响下一次 `start_generation()`。
- 覆盖取消、成功、失败、`finished(ok=False)` 与 `thread.finished` 各顺序下,运行态和线程引用均正确恢复且错误只处理一次。
- 覆盖原图下载专用队列不受生成运行态重构影响。
验证命令:
```bash
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
```
人工验收:启动一轮等待时间较长的生图,在等待期间编辑下一轮提示词、调整数量、拖动已有候选图到终选并点击取消;确认本轮任务参数不变、下一轮使用新设置,且没有生成第二个后台 worker。
## 边界(不改什么)
- 不实现多项目并行生成、跨项目浏览、多个全局 worker 并发或后台静默重提交流程。
- 不改变单张原图下载的最大并发、重试、项目隔离和关闭清理规则。
- 不改变照片池中失败任务卡的展示语义;该问题由 T-613 单独处理。
- 不增加 cmhub API 字段、重试次数、超时、计费规则、数据库字段或新的设置入口。
- 不改变任何 CDP、Shopee、Chrome 登录或上传逻辑。
## 执行记录
- 2026-07-13:完成 AI工场生图运行态分级。
- `app/gui/tabs/image_studio.py`:为通用 worker 增加 `operation_kind`,区分生成/继续查询、拉主图、导出等操作;生成/继续查询期间保留照片池、终选、提示词模板/编辑和下一轮参数,仍禁用项目切换、原图区下载、拉图、开始/继续查询、导出、删除。
- `app/gui/tabs/image_studio.py`:生成 worker 创建时固定使用当时的源图、提示词和参数;界面显示「本轮任务已固定;此处修改将在下一轮生成时生效」。打开项目文件夹在生成期间仍可用。
- `app/gui/tabs/image_studio.py`:`_start_worker()` 在上一 QThread 尚未发出 `thread.finished` 时拒绝启动下一 worker;拉图、生成、继续查询、导出、删除和移除照片增加运行中保护,避免程序化调用绕过禁用按钮。
- `docs/routes.md`:更新⑥ AI工场的生成运行态边界。
- `tests/test_gui.py`:新增生成态控件清单/参数快照测试,以及线程收尾前禁止启动下一 worker 的测试。
- 验证:
- 主工作区定向 GUI 测试通过:4 项,覆盖生成运行态、参数快照和线程生命周期。
- 主工作区 `python -m ruff check app tests main.py`、`py -3.10 -m compileall app main.py`、`git diff --check` 通过。
- 主工作区全量 unittest 因既有未提交默认提示词文件变更失败 3 项(`papa1` 被乱码默认模板替代),不属于本任务。
- 干净 worktree `D:\chengma\cmshopee-t612-verify` 仅应用本任务差异后通过:`python -m ruff check app tests main.py`、`py -3.10 -m compileall app main.py`、`py -3.10 -m unittest discover -s tests`(389 项)及 `git diff --check`。