docs(tasks): plan suite generation confirmation safeguards
This commit is contained in:
@@ -0,0 +1,97 @@
|
|||||||
|
---
|
||||||
|
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:根据商品套图生成前的数量、逐图主图和预计扣点确认需求创建任务。待实现。
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
---
|
||||||
|
id: T-652
|
||||||
|
title: 商品套图生成设置下拉框防滚轮误改
|
||||||
|
phase: 7
|
||||||
|
deps: []
|
||||||
|
status: TODO
|
||||||
|
created: 2026-07-17
|
||||||
|
---
|
||||||
|
|
||||||
|
## 问题 / 背景
|
||||||
|
|
||||||
|
⑥「商品套图」左侧生成设置的「平台、站点、语言、比例」目前使用普通 `QComboBox`。鼠标指针停在下拉框上时,用户滚动滚轮想浏览配置区页面,会触发 Qt 默认行为并直接修改当前选项,可能导致平台、输出语言或图片比例在未察觉时变化。
|
||||||
|
|
||||||
|
这些参数会影响套图提示词和生图请求,属于影响生成结果与成本的设置。滚轮悬停改值不符合用户的显式操作预期。
|
||||||
|
|
||||||
|
## 方案
|
||||||
|
|
||||||
|
### 1. 只限制⑥生成设置的闭合下拉框滚轮行为
|
||||||
|
|
||||||
|
- 仅处理 `ProductSuiteTab` 的平台、站点、语言、比例四个生成设置下拉框;不全局修改所有 `QComboBox`,不影响账号选择、历史店铺筛选、设置页模型别名等其他业务控件;
|
||||||
|
- 下拉框处于闭合状态时,忽略鼠标滚轮导致的选项切换,并将滚动事件交给外层配置滚动区,使页面继续自然上下滚动;
|
||||||
|
- 下拉列表已展开时,滚轮只用于浏览下拉选项列表,不能在未点击/未明确键盘确认的情况下静默提交新的当前值;
|
||||||
|
- 保留鼠标点击选择、`Alt+↓` 打开、方向键/回车等明确键盘操作;不得通过 `Qt.NoFocus` 粗暴禁用焦点,避免破坏键盘操作和无障碍能力;
|
||||||
|
- 使用局部 `QComboBox` 子类或只安装在这四个控件上的事件过滤器,避免散落的重复条件判断。
|
||||||
|
|
||||||
|
### 2. 保持设置持久化和生成语义
|
||||||
|
|
||||||
|
- 滚轮被忽略时不得触发 `_on_settings_changed()`、不写项目设置、不改变生成数量、提示词预览、历史或当前任务状态;
|
||||||
|
- 用户通过鼠标/键盘明确选中后,沿用现有设置归一化、项目保存和新任务最近设置记忆逻辑;
|
||||||
|
- 不改变平台、站点、语言、比例的可选值、默认值、布局、提示词变量或 cmhub 请求参数。
|
||||||
|
|
||||||
|
### 3. 测试与文档
|
||||||
|
|
||||||
|
- `tests/test_product_suite_gui.py`:向四个闭合下拉框发送 wheel event,断言当前值不变且外层 `suiteConfigScroll` 可继续滚动;鼠标选择和键盘选择仍会改变值并按原逻辑持久化;
|
||||||
|
- 覆盖下拉展开时滚轮仅浏览候选项、不因悬停静默提交的行为;
|
||||||
|
- 同步更新 `docs/routes.md` 的⑥生成设置交互说明;无需新增 SVG 效果图;
|
||||||
|
- 运行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
py -3.10 -m unittest tests.test_product_suite_gui
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
## 验收要点
|
||||||
|
|
||||||
|
- [ ] 鼠标悬停在平台、站点、语言、比例任一下拉框上滚动页面时,当前选项不改变。
|
||||||
|
- [ ] 外层配置区仍可正常滚动,不出现滚轮失效或页面卡住。
|
||||||
|
- [ ] 展开下拉后可正常滚动浏览选项,鼠标点击或明确键盘确认后才改变设置。
|
||||||
|
- [ ] 鼠标点击、键盘选择、项目保存和最近设置记忆不回归。
|
||||||
|
- [ ] 账号选择、历史筛选、⑤设置和其他 Tab 的下拉框滚轮行为不受影响。
|
||||||
|
- [ ] 不影响套图生成、AI帮写、cmhub、SQLite、历史、导出、Shopee CDP、采集或更新蝦皮。
|
||||||
|
|
||||||
|
## 边界(不改什么)
|
||||||
|
|
||||||
|
- 不全局重写 Qt 滚轮事件,不新增全局 event filter。
|
||||||
|
- 不修改平台、站点、语言、比例的选项、默认值、提示词结构、生成数量、模型选择或价格逻辑。
|
||||||
|
- 不修改其他 Tab 的下拉框、快捷键、鼠标选择、账号管理或设置模块。
|
||||||
|
|
||||||
|
## 执行记录
|
||||||
|
|
||||||
|
- 2026-07-17:根据生成设置下拉框滚轮误改问题创建任务。待实现。
|
||||||
Reference in New Issue
Block a user