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

122 lines
8.5 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-646
title: 商品套图全局历史生成列表与按轮导出
phase: 7
deps: [T-643, T-644]
status: TODO
created: 2026-07-17
---
## 问题 / 背景
T-644 已把⑥「商品套图」的「历史生成」改为弹窗,但弹窗只读取当前 `project_id`。用户需要回看近期为不同店铺、不同商品生成过的套图,并能在不重新输入商品 ID 的情况下定位、预览和导出之前的结果。
现有数据已通过项目、生成轮次、job 和 asset 持久化:
- 一个商品项目可有多轮正常生成;每次再次点击「生成套图」会产生新的 `generation_round_key`;
- 单张失败后的「重试」沿用原轮次和槽位,不应被误认为新的整轮;
- 主结果区只显示当前轮,历史数据仍保留在 SQLite 中;
- 当前历史弹窗按项目内轮次倒序展示,无法用于跨商品回看。
产品目标是把顶部「历史生成」改为全局历史入口:用户打开后先看到最近的套图生成记录,按时间倒序逐行浏览;一行对应一次生成轮次,显示该轮所属店铺、商品 ID 和生成图片缩略图。双击可查看该轮生成图片的原始尺寸预览,并可导出该轮已成功的结果图片。
## 方案
### 1. 历史入口改为全局只读窗口
修改 `app/gui/tabs/product_suite.py` 及必要的新对话框/模型组件:
- 点击⑥顶部「历史生成」打开非模态的「套图历史生成记录」窗口,不再要求当前已绑定商品项目;
- 窗口默认查询所有未软删除商品项目的生成轮次,按轮次创建时间倒序;同一时间使用稳定 ID 作为次序补充;
- 当前任务已绑定商品时,窗口提供「仅当前商品」快捷筛选,但默认值为“全部商品”,不能把用户重新限制到当前项目;
- 重复点击复用并聚焦同一个全局窗口;关闭⑥任务页或切换商品不能关闭全局历史窗口;应用退出时正常释放窗口资源;
- 无任何历史时显示中文空态,不打开空白或报错窗口。
### 2. 一轮一行的时间倒序列表
列表的事实单位是“一次整轮生成”,不是“一个商品所有历史合并成一行”:
- 正常生成每个 `generation_round_key` 一行;同轮的单张重试只更新该槽位的当前有效图片和重试次数,不能新增一行;
- 每行固定高度,左侧显示生成时间、店铺/账号别名、商品 ID;中部显示固定尺寸的横向缩略图条;右侧显示成功/失败/取消数量和「导出本轮」命令;
- 缩略图按该轮稳定槽位顺序展示,最多直显 5 张,剩余以 `+N` 表示;图片文件缺失时显示中文不可用占位,不删除数据库记录;
- 临时草稿项目明确显示“临时草稿”,不伪造商品 ID;已软删除项目不进入列表;
- 对无可靠轮次边界的旧版记录,沿用 T-643 的“旧版历史记录”语义,不按文件时间差、目录名或图片数量猜测、拆分或合并轮次;
- 列表首屏和后续翻页只读取必要的轮次摘要与缩略图,不能一次加载全部原图到内存。
### 3. 查询、筛选和性能边界
在 `app/image_studio.py` 增加结构化的跨项目历史查询 API,SQLite 仍是唯一事实来源:
- 返回轮次摘要及其项目上下文:项目 ID、店铺/账号、商品 ID、轮次 key、创建时间、当前轮标记、各终态数量、缩略图对应的当前有效 job/asset;
- 支持 `limit` / `offset` 分页,默认首屏不超过 30 行;
- 至少支持店铺/账号和商品 ID 关键字筛选;筛选在数据库查询层完成,不先加载全量再在 GUI 过滤;
- 新增适当索引前先核实现有 `image_studio_projects` / `image_studio_jobs` 索引,避免无必要 schema 迁移;如确需索引,迁移必须幂等;
- 仍按项目和 job 归属隔离数据,不能把不同商品、店铺或草稿的图片串行展示;
- 缩略图使用受限尺寸缓存或可见区延迟加载;切换筛选、刷新和加载更多时不阻塞正在运行的生图 worker。
### 4. 原图预览与导出
- 双击行内任一生成缩略图,打开已有自适应预览能力的轮次浏览窗口;被双击图片为首张,用户可在该轮所有当前有效生成图片间前后切换;
- 双击没有图片的行、或缺失文件占位时仅给出中文提示,不伪造预览;
- 「导出本轮」只导出该行轮次中本地存在且成功的生成图片;由用户选择目标目录,导出目录名使用安全的店铺/商品 ID/生成时间组合;
- 同名文件不得静默覆盖,采用确定性的去重命名;导出失败要汇总中文结果并保留可成功导出的其他图片;
- 导出是复制操作,不移动、重命名或删除内部 asset 文件,不导出 API Key、提示词全文、图片 URL、Cookie 或诊断日志;
- 本任务第一版不提供“导出全部历史”、批量选择多轮、删除历史、恢复历史轮为当前轮或从历史直接再次生成。
### 5. 现有当前商品历史兼容
- 现有 T-644 的项目内轮次、当前轮标签、单槽位重试和文件缺失语义必须保留;
- 全局窗口不修改主结果区当前轮、生成轮次提升、计费、任务恢复或图片保存流程;
- 若现有用户需要只看当前商品,可使用「仅当前商品」快捷筛选;不得再单独维护两套历史数据或扫描生成文件夹;
- 所有按钮、状态、空态和错误提示使用中文,且不暴露本地完整路径、接口 URL、模型别名、Key 或 Provider 原始错误。
同步更新 `docs/04-architecture.md`、`docs/api.md`、`docs/routes.md`;如 UI 结构变化需要效果图,保存到 `docs/ui/` 并登记 `docs/ui/README.md`。
## 验收要点
- [ ] 点击「历史生成」后能打开全局套图历史窗口,即使当前没有输入商品 ID 或未绑定商品项目。
- [ ] 默认按生成时间倒序一轮一行展示不同店铺、不同商品的历史记录。
- [ ] 同一商品再次正常生成会出现新行;单张失败重试不会产生新行。
- [ ] 每行显示店铺、商品 ID、时间、状态统计和固定尺寸缩略图;最多 5 张,余量显示 `+N`。
- [ ] 双击缩略图可以在轮次浏览窗口查看该轮所有可用生成图片的原始尺寸,并从被双击图片开始切换。
- [ ] 旧版历史、临时草稿、文件缺失、全失败轮次和软删除项目分别遵守既有语义,不跨项目串数据。
- [ ] 支持店铺/账号、商品 ID 和“仅当前商品”筛选;刷新和加载更多保持稳定排序。
- [ ] 「导出本轮」只复制成功且存在的输出图;不覆盖外部同名文件,不修改内部资产。
- [ ] 历史数量较多时首屏、滚动、筛选和预览不造成明显 GUI 冻结,且不影响正在运行的套图生成任务。
- [ ] 不影响 cmhub 调用、提示词组装、图片下载、生成轮次、重试、当前结果、Shopee CDP 或其他模块。
## 测试
- `tests/test_image_studio.py`:
- 跨项目轮次查询的倒序、分页、店铺/商品筛选和软删除隔离;
- 同轮单槽位重试去重、当前有效 job/asset 选择、旧版历史和缺失 asset;
- 项目上下文、临时草稿和轮次状态统计正确。
- `tests/test_product_suite_gui.py` 或新增独立测试:
- 无当前项目时可打开全局窗口、重复点击窗口复用;
- 一轮一行、缩略图上限和 `+N`、筛选、刷新、分页及中文空态;
- 双击从指定图片打开轮次预览并在同轮切换;
- 导出本轮的目标目录、重复命名、部分失败和不修改源文件;
- 生成进行中打开/刷新历史不影响 worker。
- 运行:
```bash
py -3.10 -m unittest discover -s tests
py -3.10 -m ruff check app tests main.py
py -3.10 -m compileall app main.py
git diff --check
```
- 人工在至少两个店铺、三个商品、包含多轮正常生成、单张重试、失败轮和缺失文件的测试数据上检查 Windows 100% / 125% / 150% 缩放下的行高、缩略图、预览、筛选和导出。
## 边界(不改什么)
- 不扫描文件夹、目录名、文件名或时间差推断历史轮次。
- 不删除、移动、重命名内部历史 asset、job、轮次或项目记录。
- 不实现批量导出全部历史、批量选择多轮、历史删除、恢复历史轮、历史重跑或直接更新蝦皮。
- 不修改 cmhub API、模型别名、图片理解、生图并发、超时、轮询、下载或计费逻辑。
- 不修改 Shopee CDP、商品采集、AI生成、更新蝦皮、账号管理或设置模块。
## 执行记录
- 2026-07-17:根据产品讨论创建任务。待实现。