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

98 lines
6.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-651
title: 商品套图生成前的数量与预计扣点确认
phase: 7
deps: [T-650]
status: TODO
created: 2026-07-17
---
## 问题 / 背景
⑥「商品套图」正常点击「生成套图」后,当前已有「确认生成商品套图」弹窗。它会显示店铺、商品 ID、可用原图数量、各分类实际生成张数、比例、总张数和“本次生成会消耗 cmhub 点数”。但用户看不到当前配置下的预计单张/总扣点,也无法清晰区分“每张上传图分别作为主图生成”对各分类数量的实际影响。
实际生成数量不是简单的原图数量:`product_suite.build_job_specs()` 先按分类数量规划 job;开启逐图主图时,场景图、卖点图等非白底分类按每张可用原图展开,白底图仍只使用第一张原图。当前确认文字只有“是/否”,可能让用户误以为白底图也会按每张原图重复生成。
T-650 将提供图片理解价格确认所需的短期 cmhub 模型目录缓存和安全价格读取边界;套图正式生图应复用同一份模型目录缓存,不能重复设计另一套价格来源。
## 方案
### 1. 基于实际 job 规划计算可确认的预估价格
- 继续先完成现有模板、项目、原图、卖点和数量校验,并构建最终 `specs`;确认框中的分类数量和总数必须来自 `specs`,不是从界面文字或原图数量猜测;
- 复用 T-650 的进程内 cmhub 模型目录缓存和后台刷新机制,按当前 `image_alias` 查找可用的正式生图模型价格;缓存键、脱敏、失效和线程管理遵守 T-650,不另存 API Key、价格或模型目录;
- 只有模型目录能明确给出每个正式生图 job 的唯一、无条件歧义 `points_cost` 时,才计算「预计单张扣点」与「预计总扣点」。总点数等于该确认框中 `len(specs)` 个 planned job 的单价合计;不得按上传原图数量、勾选数量或“前8张”规则自行倍乘;
- 若价格与分辨率、质量档或其他服务器条件相关而无法唯一确定,或目录不可用/未定价/字段缺失,则不显示数字总价,只显示「本次会消耗 cmhub 点数,暂时无法取得预计扣点,实际以网关返回为准」;不得取最低价、最高价、平均价或沿用过期未知价格;
- 预估价格仅供确认,不预扣余额、不写 SQLite/Excel/运行日志、不影响 job 成功失败。每个 job 完成后仍以 cmhub 返回的 `points_cost`/`points_balance` 作为实际计费事实。
### 2. 优化正式生成确认弹窗内容
在既有「确认生成商品套图」弹窗中保留并整理为清晰的中文分组:
```text
店铺:...
商品ID:...
可用商品原图:N 张
逐图主图:已开启
说明:白底图只使用第一张原图;场景图、卖点图和自定义分类会按每张原图分别生成。
白底图:1 张
场景图:6 张
卖点图:6 张
图片比例:1:1
本次生成总数:13 张
预计单张扣点:2 点
预计总扣点:26 点
实际扣点以 cmhub 返回为准。
```
- 逐图主图关闭时,明确说明所有分类均只使用第一张可用原图;
- 分类行只显示本次实际存在的类别,保持 `product_suite.category_order()` 顺序,自定义分类追加在后;
- 不显示模型别名、API URL、图片路径、Key、原始上游错误或内部 task ID;
- 按钮继续使用「确认生成」和「返回修改」,默认/关闭/Esc 均不提交生成;价格读取阶段需要后台处理,不得卡住 GUI 或提前创建 `ProductSuiteGenerateWorker`。
### 3. 与历史确认、取消和并发的顺序
- 已有成功套图时,先保留 T-648 的“查看历史 / 继续生成新一轮 / 取消”确认;只有用户选择继续后,才进入包含数量和预计扣点的正式生成确认;
- 价格读取、确认框和最终提交之间必须防重复点击。用户取消、关闭、切换任务或关闭任务时,不创建正式生成 worker、不写 job、不调用 cmhub 生图;
- 最终确认前重新核对当前任务、原图和 `specs` 仍有效。若配置或原图在等待价格期间已变化,取消旧确认并重新计算,不可用旧数量或旧价格提交;
- 单张失败图片的“重新生成”和恢复未完成任务沿用现有语义,不强行套用整轮批量确认;如后续需要显示单图预估扣点,另行设计,不在本任务扩展。
### 4. 测试与文档
- `tests/test_product_suite_gui.py`:覆盖逐图主图开/关时确认文案、白底图例外、分类实际数量、确定价格的单价/总价、未知价格降级、取消不创建 worker、确认只创建一次 worker、已有历史的两段确认顺序;
- `tests/test_product_suite.py` / `tests/test_ai.py`:覆盖 `specs` 数量与预估总价只按 planned job 计算,多个条件价格或无价格时不产生数字估算;
- 同步更新 `docs/04-architecture.md`、`docs/api.md`、`docs/routes.md`,说明正式套图生成的确认、逐图主图例外和预估/实际扣点边界;
- 运行:
```bash
py -3.10 -m unittest tests.test_ai tests.test_product_suite tests.test_product_suite_gui tests.test_workers
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
```
## 验收要点
- [ ] 正常点击「生成套图」在真正提交前显示基于最终 `specs` 的分类数量、总张数和逐图主图说明。
- [ ] 开启逐图主图时明确白底图只使用第一张原图,其余分类按每张原图展开;关闭时明确所有分类只使用第一张原图。
- [ ] 已知唯一 per-job 价格时显示预计单张扣点和预计总扣点,且总价只按 planned job 数量计算。
- [ ] 价格未知或有歧义时不显示伪造数字,用户仍可明确选择确认或返回修改。
- [ ] 历史确认、价格读取、正式确认和 worker 启动顺序正确,取消不会创建 job 或产生生图请求。
- [ ] 实际扣点仍由 cmhub 响应决定,不预扣、不改变余额或计费协议。
- [ ] 不影响 AI帮写、②AI生成、历史、单图重试、导出、Shopee CDP、采集、更新蝦皮、账号管理或设置模块。
## 边界(不改什么)
- 不修改 cmhub 生图接口、模型别名、超时、轮询、下载、重试、并发或点数协议。
- 不新增余额硬阻断、自动充值、批量预算、价格持久化或“不再确认”开关。
- 不修改 `build_job_specs()` 的实际生成规则、分类数量、提示词、原图排序或白底图使用第一张原图的既有语义。
- 不改变单张失败重试、恢复未完成任务或历史导出的确认路径。
## 执行记录
- 2026-07-17:根据商品套图生成前的数量、逐图主图和预计扣点确认需求创建任务。待实现。