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

112 lines
13 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-622
title: ⑥用「商品套图」模块替换现有 AI工场(迁移电商图生成器套餐模块)
phase: 7
deps: [T-564]
status: DONE
created: 2026-07-13
---
## 问题 / 背景
顾客不满意最新代码里的 ⑥「AI工场」模块(现有原生 PySide6 实现,后端表 `image_studio_*`)。要求把 `/mnt/d/chengma/虾皮圈电商图生成器源码` 项目里的「商品套图(商品套餐)」模块交互迁移过来,替换现有 ⑥「AI工场」。
已核实的现状事实(落地依据,来自读码):
- cmshopee **全原生 PySide6**,未引入 `QtWebEngine / QWebChannel`;迁移源是 QWebChannel + WebView 单页应用(`web/index.html` + `web/app.js` + `web/style.css`)。
- 现有 ⑥「AI工场」后端分层已完整,可复用:`app/image_studio.py`(领域 Project/Asset/Job/Selection)、`app/image_studio_generation.py`(异步生图)、`app/image_studio_export.py`(导出)、`app/image_studio_images.py`(图片处理)、`app/image_paths.py`;DB 表 `image_studio_projects/assets/jobs/selections`(`app/db.py:293+`);提示词目录 `data/prompts/image_studio/`(`app/appconfig.py:256`)。
- 现有 AI工场 **project 强绑定「账号别名 + 商品ID」**(`app/image_studio.py:148`「缺少账号别名」、`:291`「缺少商品ID」)——顾客不满的是交互/UI,后端契约(绑账号+商品ID、异步生图)保留。
- 异步生图已接:`POST /api/v1/generate/image/tasks` + `Idempotency-Key` + `task_id` 轮询(`app/ai.py:1104+`,T-564 已落地)。
UI 已定稿:`docs/ui/tab6-suite-package-v1.svg`(本仓库家风:`#2b3a55` 头栏 / `#2f6fed` 蓝 / 微软雅黑;已在 `docs/ui/README.md` 登记)。
## 需求定稿(以 SVG 为准)
**整体**
- ⑥ 单一图片类型(**去掉「详情图」**,与套图合并;详情类目可用「自定义分类」加回)。
- 保留**多任务并行**(顶部「套图任务 1 / 2 / +」标签,互不阻塞)。
- **顶部上下文条**:`账号` 下拉 + `商品ID` 输入 + `拉取蝦皮主图` 按钮(右靠、与「打开文件夹」同右边缘);每个套图任务绑定一个账号+商品ID,切换任务随之切换。
- 采用**原生 PySide6 重写 UI**,复用上述 `image_studio_*` 后端与异步生图管线;**不引入 QtWebEngine**。
**左侧配置面板(可滚动区 + 底部固定按钮)**
- 商品原图上传:两行共 **6 张缩略图**(主图 / 参考1..5)+ 添加;支持点击/拖拽/粘贴,或「拉取蝦皮主图」带入;第 1 张为主图,最多 16 张。
- 生成设置:**4 个可切换下拉**(平台=Shopee / 国家地区=中国台湾 / 语言=繁体中文 / 比例=1:1),**不显示 label**(靠位置辨识);+ 复选框「每张上传图分别作为主图生成」。
- 平台/国家/语言当前后端为固定单值,做成下拉是为将来多平台扩展;**选中值须透传进生成提示词上下文**,不得只做装饰。
- 商品卖点与要求:多行输入框(较高)+「✧ AI 帮写」按钮。
- 套图结构配置:默认仅 **3 类**「白底图 / 场景图 / 卖点图」,各带 `− 数量 +` 计数器;`+ 添加自定义分类`(可改名 / 删除)。
- 底部固定「▶ 生成套图(N)」按钮(**在滚动区外,不随滚动**);点击后**同一按钮切换为「■ 停止生成」**(建议危险色);**取消独立「停止」按钮**。按钮下方 label:`建议填写产品名称、核心卖点、目标人群、使用场景与禁用元素`。
- 除「生成套图」按钮外,其余组件同属一个**竖直滚动区**。
**右侧结果区**
- 工具栏:`生成结果` + `共 N 张·成功 M 张` 徽标 + `历史生成` + `打开文件夹`。
- 结果网格:每张卡片显示图片/生成中骨架/失败(带「重试」);右键单图可 预览 / 复制路径 / 重新生成。
- 底部一行(与左侧「生成套图」按钮同高):进度条 + `套图 X/Y(秒)· 失败 N` 汇总。
## 实现决策
1. **技术栈**:采用原生 PySide6 `ProductSuiteTab`,复用现有 `image_studio_*` 后端,不引入 QtWebEngine;旧 `ImageStudioTab` 仅保留内部兼容。
2. **生成上下文**:平台/国家/语言/比例/分类/商品ID/参考图序号统一由 `product_suite.build_suite_prompt()` 写入每个 job prompt;比例另透传到 cmhub `aspect_ratio` 请求字段。
3. **布局**:配置区可滚动,生成按钮固定;缩略图和卖点框设稳定高度,结构分类用常驻 chip + 单项展开计数,基准窗口首屏可见。
## 验收要点
- ⑥ 标签由「AI工场」交互替换为「商品套图」布局,功能对齐 SVG;旧 AI工场入口不再暴露。
- 顶部账号+商品ID 生效:切换任务/账号/商品ID 正确带入;「拉取蝦皮主图」把线上主图拉进「商品原图」。
- 套图结构 3 类默认 + 自定义分类增删改;数量计数正确,合计张数与「生成套图(N)」一致。
- 生成走异步管线(复用 T-564):提交→轮询→逐张落盘;单张失败可重试;「生成⇄停止」toggle 正常;多任务并行互不阻塞。
- 平台/国家/语言/比例选中值确实进入生成上下文(非装饰)。
- 复用现有 `image_studio_*` 表与目录,不新造并行后端;不引入 QtWebEngine。
- 验证:`py -3.10 -m unittest`(相关模块)、`python -m ruff check app tests main.py`、`py -3.10 -m compileall app main.py`、`git diff --check` 全绿。
## 按钮交互清单(每个可点元素 → 行为)
> 行为多数可照迁移源 `web/app.js` 现成实现提炼;标「新增」的是 cmshopee 绑定账号+商品ID 后新增的语义,源里没有。
**顶部上下文条**
- `账号` 下拉(新增):切当前套图任务归属账号;账号变了商品原图/结果按新账号+商品ID 归属,需二次确认是否清空当前未生成配置。
- `商品ID` 输入(新增):当前任务的目标商品;失焦校验(非空、数字/合法 itemid),非法则红框提示,不触发拉取。
- `拉取蝦皮主图`(新增):以 `账号+商品ID` 走 CDP 拉线上主图列表→带入「商品原图」(第 1 张为主图);商品ID 为空/非法则禁用;拉取中转圈、失败给中文提示。
- 任务标签 `套图任务 N`:单击切换任务(`switchTask`,拖拽中禁止切换);`×` 关闭(`closeTask`:生成中先 `confirm「任务生成中,关闭会取消该任务」`,确认才取消并关);`+` 新建(`createTask`,继承当前任务配置)。
**左侧配置面板**
- 商品原图:空位/`添加` → `chooseImages` 选图;整区支持拖拽、粘贴上传;缩略图可拖拽排序(第 1 张=主图),悬停 `×` 删除;超 16 张忽略并提示。
- 4 个下拉(平台/国家/语言/比例):`onchange` 存设置;选中值须进生成上下文(见待决 2)。
- `每张上传图分别作为主图生成` 复选框:`onchange` 存 `suite_per_image_primary`,联动合计张数。
- `✧ AI 帮写`(`startAiWrite`):需先有图,否则提示;冻结当前图+配置提交,按钮变「AI 帮写中… + 计时」且旁边出现「取消」(`cancelAiWrite`);完成后若期间用户改过输入框 → `confirm` 是否用结果覆盖,否则直接填入卖点框;每任务独立、不阻塞切换。
- 套图结构 `− / +`:增减该类张数(最小 0),联动「合计 N 张」与生成按钮 `(N)`。
- `+ 添加自定义分类`:行内输入,Enter 提交,校验 `suiteNameError`(非空、无空格、≤10 字、不重名);分类名双击进入改名;行尾 `×` 删除自定义类。
- `▶ 生成套图(N)`(`startGen`):校验(有图、有卖点、合计≥1);预估 >16 张先 `confirm`;提交后进入生成中,**同按钮变「■ 停止生成」(危险色)**;点停止 → `confirm「确认取消当前任务」`,取消未开始项、已发出的返回后丢弃。
**右侧结果区**
- `历史生成`(`setView('history')`):切历史视图,列往期批次+图片,可刷新、打开生成图片根目录、右键单图预览/删除。
- `打开文件夹`(`openPath`):打开当前批次输出目录。
- 结果卡片:单击预览大图;右键菜单 预览 / 复制路径 / 打开文件夹 / 重新生成该图 / 删除;`×` 删除该图(移废纸篓 + 「撤销」toast);失败卡片 `重试`(`retryAsset`,已有生成任务进行中则提示)。
- `⋯` 更多(`moreMenu`):删除全部(`confirmDeleteAll`,二次确认,移废纸篓)。
## UI/UX 优化项(ui-ux-pro-max 校验后修订,effect 图已落 P1–P4/P5)
> 桌面 PySide6,取可迁移规则(对比度/标签/反馈/层级/空错态/截断),触控类规则不适用。P1–P4 为前几轮「腾纵向空间」引入的回归,已在 `tab6-suite-package-v1.svg` 修正;P5/P6 为实现期加固。
- **P1 核心控制被折叠**(`visual-hierarchy`/`content-priority`/`progressive-disclosure`):卖点框加高曾把「套图结构配置」挤到滚动线下,而它决定生成张数(=按钮 N)。**方案(已落图)**:结构配置压成常驻 chips「白底1 场景2 卖点2 +类」,点分类再展开 −/+(渐进披露),常可见不折叠;卖点框回收到合理高度。
- **P2 去 4 个下拉 label 影响辨识**(`input-labels`/`truncation-strategy`):`1:1` 等脱离 label 难认。**方案(已落图)**:下拉值内联前缀「平台 Shopee / 国家 中国台湾 / 语言 繁体中文 / 比例 1:1」,无独立 label 行也保留语义;实现层另加 `setToolTip`。
- **P3 引导文案字号/对比不足**(`color-contrast` CRITICAL / `contrast-readability`):原 9.5px + `#8a92a0` 属 gray-on-gray。**方案(已落图)**:移到卖点框下方作 helper text,≥11px、`#6b7280`。
- **P4 商品ID 压到 60% 会截断**(`truncation-strategy`/`number-tabular`):Shopee itemid 常 11–13 位,w90 放不下。**方案(已落图)**:恢复到 w140 并用等宽数字;空间靠缩「账号」下拉腾出。
- **P5 空态与失败原因**(`empty-states`/`error-recovery`/`error-clarity`):结果区首次未生成需空态引导「还没有生成,点『生成套图』开始」;失败卡除「重试」外显示简短原因(效果图示「上游超时」,实现取上游 error_type/message 截断)。
- **P6 小控件命中区**(`no-precision-required`,桌面按 ≥24–28px):计数器 −/+、chip 的 ×、缩略图删除,**视觉可小、hit area 放大到 ≥24–28px**;图标按钮补 `accessibleName`/tooltip,Tab 顺序符合视觉顺序(`keyboard-nav`)。
已做对、保持不变:单一蓝色主 CTA(`primary-action`);状态不靠颜色单独表达(打勾/感叹号/转圈,`color-not-only`);生成⇄停止 toggle + 确认 + 撤销 + 重试反馈完整;家风一致、非 emoji 图标。
## 边界(不改什么)
- 不改动 `image_studio.py / image_studio_generation.py / image_studio_export.py` 的后端数据契约与异步生图协议(仅按需扩展字段)。
- 不动 ①~⑤ 既有标签与流程。
- 不引入 `QtWebEngine`(采纳原生重写方案时)。
- 安全红线:不写真实凭证到代码/文档/日志;`config.json`、`cmshopee.db`、`images/` 等不提交;不绕过 Shopee 风控;生成/导出等本地操作不触碰 ③ 的线上提交边界。
## 执行记录
- 2026-07-14:完成第六 Tab 从旧 AI工场入口切换为原生「商品套图」。新增多任务状态、账号+商品ID上下文、16张商品原图导入/拖放/粘贴/排序/后台拉取、结构分类与AI帮写、生成/停止、结果历史、重试、预览、废纸篓删除与撤销;旧 `ImageStudioTab` 保留但主窗口不再创建。
- 2026-07-14:扩展 `image_studio_projects.suite_settings_json` 及原位迁移,新增套图纯逻辑、项目 job 查询/原图排序、本地图片原子导入、生成图废纸篓;cmhub 比例从 UI 真实透传,并以进程级闸门限制多个套图任务合计最多5个在途 job。停止信号在下载前后生效,停止后的临时图片不入资产库。
- 2026-07-14:同步 AI 开发入口、需求、技术栈、架构、API、routes、文档导航与 UI 索引;新增领域、worker、GUI、迁移、图片边界、比例透传和停止清理测试。
- 验证:在只包含 T-622 暂存文件的干净 worktree 中运行 `py -3.10 -m unittest discover -s tests`,459 项全部通过;`python -m ruff check app tests main.py`、`py -3.10 -m compileall app main.py`、`git diff --check` 全部通过。原工作区另有任务开始前即存在的默认封面提示词改名(删除 `papa1.txt`、新增 `默认.txt`),会使3个仍断言 `papa1` 的旧测试失败,该改动未回退、未纳入本任务提交。