Files

8.7 KiB
Raw Permalink Blame History

id, title, phase, deps, status, created
id title phase deps status created
T-612 AI工场生图运行态分级,保留当前项目非冲突操作 7
T-594
T-604
T-608
T-609
DONE 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 各顺序下,运行态和线程引用均正确恢复且错误只处理一次。
  • 覆盖原图下载专用队列不受生成运行态重构影响。

验证命令:

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。