Files

5.4 KiB
Raw Permalink Blame History

id, title, phase, deps, status, created
id title phase deps status created
T-568 ②封面画廊单任务重新生成与并发守卫 7
T-567
DONE 2026-07-09

问题 / 背景

T-567 只提供候选封面查看与保存。运营在对比时仍需要对当前商品单独再生成一张新封面,并在画廊中立即看到新候选。该能力涉及 AI 点数、DB 归档、任务状态和后台 worker 并发,必须单独拆出,避免 T-567 弹窗基础功能过大。

方案(改哪个文件、改成什么)

重新生成按钮

  • 在 T-567 的封面画廊弹窗底部新增「重新生成」按钮。
  • 点击后弹确认框:
    • 文案说明将重新生成当前商品封面,可能消耗 cmhub 点数;
    • 用户取消则无副作用。
  • 用户确认后:
    1. 调用 db.reset_generated(task_id, reset_title=False, reset_cover=True),由 T-566 归档当前 new_cover_path 并清空封面指针;
    2. reset 成功后必须重新 db.get_task(task_id) 获取最新任务对象,不能复用弹窗打开时的旧 task(旧对象可能还带旧 new_cover_path,导致 generate_batch() 判断无需补封面);
    3. 启动单任务 GenerateWorker([fresh_task]),沿用当前②页面的提示词、cmhub配置、生成参数和“生成封面图片”语义,但本任务强制只补当前任务缺失封面,不重生标题;
    4. 弹窗左下状态 label 显示“开始重新生成商品 <item_id> 的封面图片”。

完成/失败刷新

  • 单任务生成完成:
    • 刷新②列表该行;
    • 重新调用 list_task_cover_candidates() 刷新画廊;
    • 新生成的规范名 _new.jpg 应成为 DB 当前 new_cover_path,画廊默认选中它;
    • 状态 label 显示“封面重新生成完成”。
  • 失败:
    • 保留已归档旧图;
    • 列表按既有生成失败口径显示;
    • 状态 label 显示失败摘要;
    • 画廊继续显示历史候选,允许用户选择历史图保存。
  • 若 reset_generated() 因 Windows 文件占用导致归档改名失败:
    • 中止重新生成;
    • 不启动 GenerateWorker;
    • 弹中文提示“请先关闭正在查看的封面图片再重试”。

并发守卫

  • ②批量生成运行中时,画廊「重新生成」按钮禁用,并显示 tooltip。
  • 画廊单任务重新生成运行中时,②主界面「开始生成」按钮也应禁用或阻断,避免两个 GenerateWorker 同时写同一 DB/图片目录。
  • 同一画廊弹窗运行中再次点击「重新生成」无效。
  • 本任务不新增 cmhub cancel 接口;关闭弹窗时若单任务仍在运行,只允许隐藏/关闭视图,不强杀服务端任务,遵守 T-564 续查语义。

验收要点

  • 重新生成确认取消 → 不归档、不启动 worker、不改 DB。
  • 确认后先归档旧图,再用 fresh task 启动单任务生成;不会因旧 task 对象残留 new_cover_path 而跳过封面生成。
  • 成功后画廊出现新图并默认选中;②列表刷新为新封面路径。
  • 失败后历史候选仍可选择保存。
  • 归档改名失败时不清 DB 指针、不启动 worker。
  • 批量生成和单任务重生互斥,不允许两个 GenerateWorker 并行。
  • 验证命令:
    • py -3.10 -m unittest tests.test_gui tests.test_db
    • 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

边界(不改什么)

  • 不改 T-566 数据层契约。
  • 不改 cmhub submit/poll/download 逻辑。
  • 不做上一条/下一条切换和未保存拦截(T-569)。
  • 不改 ③更新/Excel/CDP/Shopee。

执行记录

  • 2026-07-09 完成 T-568。
  • 修改 app/gui/tabs/generate.py:
    • 在 T-567 封面画廊底部新增「重新生成」按钮;点击后先弹中文确认,说明会重新生成当前商品封面并可能消耗 cmhub 点数。
    • 确认后调用 db.reset_generated(task_id, reset_title=False, reset_cover=True),由 T-566 归档当前新封面并清空封面指针;随后重新 db.get_task() 获取 fresh task,再启动单任务 GenerateWorker([fresh_task]),避免旧 task 残留 new_cover_path 导致跳过生图。
    • 单任务重生使用当前②页面传入的标题/封面提示词和配置,但只在 worker 配置副本中强制 ai.generate_cover=True,不保存到设置,确保只补缺失封面、不重生标题。
    • worker 完成后刷新②列表与画廊候选;成功时新 _new.jpg 默认选中;失败时保留已归档旧图并允许选择历史候选保存;归档改名失败时弹中文错误并不启动 worker。
    • 增加并发守卫:②批量生成运行中时画廊「重新生成」禁用并显示 tooltip;画廊单任务重生运行中时②主界面「开始生成」和「重置生成结果」禁用/阻断。
  • 修改 tests/test_gui.py:
    • 用 fake GenerateWorker/thread 覆盖重新生成确认取消、fresh task 启动、临时强制 generate_cover=True、成功刷新并选中新图、失败后历史候选可保存、归档失败不启动 worker、批量生成与单任务重生互斥、主界面启动阻断。
  • 验证通过:
    • py -3.10 -m unittest tests.test_gui
    • py -3.10 -m unittest tests.test_gui tests.test_db
    • python -m ruff check app tests main.py
    • py -3.10 -m compileall app main.py
    • py -3.10 -m unittest discover -s tests(297 tests;PySide6 字体目录警告不影响结果)
    • git diff --check