Files

136 lines
10 KiB
Markdown
Raw Permalink 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-641
title: 商品套图最近上下文恢复与执行前确认
phase: 7
deps: [T-640]
status: DONE
created: 2026-07-16
---
## 问题 / 背景
⑥「商品套图」当前存在三类容易造成误操作或内容丢失的体验问题:
1. 软件重启后不会恢复最后选择的店铺。`product_suite.last_settings` 目前只保存平台、站点、语言和比例;新建首个任务会回退到账号列表第一项,用户可能在未注意店铺变化时拉取错误商品。
2. 「商品卖点与要求」只有在已经建立正式项目或临时草稿、取得 `project_id` 后才会自动保存到 SQLite。用户只选择店铺并输入卖点、尚未添加图片或拉取主图时,内容仍只在内存中,关闭软件后会丢失。
3. 「拉取蝦皮主图」只有本地已经存在图片时才弹覆盖确认;首次拉取会直接启动。「生成套图」也只有数量超过阈值时才确认。两个操作分别涉及店铺/商品上下文和 cmhub 点数消耗,缺少稳定的执行前复核。
本任务负责最近上下文、未完成草稿和执行前确认;拉取过程中停止、迟到结果隔离及清理本轮图片由 T-642 单独处理。
## 方案
### 1. 持久化最后选择的店铺
修改 `app/appconfig.py`、`app/gui/tabs/product_suite.py` 和 `docs/04-architecture.md`:
- 在 `config.json` 的 `product_suite` 下新增 `last_account_alias`,只保存账号别名,不保存账号密码、Cookie 或登录态。
- 用户完成有效店铺切换后立即保存该别名;被弹窗取消或因项目绑定规则拒绝的切换不得覆盖最近值。
- 软件启动后的第一个新任务优先选择 `last_account_alias`。
- 同一次运行中新建任务继续优先继承当前任务的店铺,保持现有工作流。
- 最近账号已删除、被软删除或不在当前账号列表时,回退到第一个可用账号,并将无效值清理或覆盖。
- 已绑定项目、恢复的临时草稿仍以项目自己的 `account_alias` 为准,不能被全局最近值覆盖。
### 2. 将未绑定卖点保存为可恢复草稿
卖点是商品级业务内容,不能作为全局默认文本复制给其他商品。修改 `app/gui/tabs/product_suite.py`,沿用现有 `image_studio_projects.draft_prompt`:
- 当前任务尚无 `project_id` 时,用户选择了有效店铺且输入的卖点 `strip()` 后非空,沿用现有约 `500ms` 防抖,在文本稳定后创建一次临时草稿并保存 `draft_prompt`。
- 不因第一个字符立即创建项目;连续输入只创建一个草稿、只在防抖稳定后落库。
- 切换任务、关闭任务、关闭软件、开始拉取、添加图片或开始生成前,必须同步刷新卖点;如内容非空且尚无项目,创建草稿并保存,避免用户在防抖到期前关闭造成丢失。
- 空白卖点、无有效店铺或程序化回填不得创建草稿。
- 自动创建的草稿沿用现有恢复机制,重启后恢复为「临时草稿」任务,并显示原店铺与卖点。
- 用户把卖点清空且该草稿没有原图、job、selection 或其他业务内容时,关闭任务可继续使用现有空草稿清理语义,避免积累无内容项目。
- 新建另一个普通任务时卖点默认留空;只有用户明确使用现有“继承当前任务”行为时才允许同一次运行内继承,不能从 `config.json` 全局复制上一个商品卖点。
### 3. 拉取蝦皮主图始终显示上下文确认
修改 `pull_main_images()`:
- 完成店铺、商品 ID、项目绑定和运行状态校验后,无论本地是否已有图片,都必须先弹确认框。
- 确认内容至少包含:
- 店铺显示名与别名;
- 商品 ID;
- 当前可用商品原图数量;
- 操作说明「读取蝦皮主图并在后台下载,不会修改蝦皮线上商品」。
- 当前已有图片时,额外说明蝦皮原图列表会刷新,本地手动添加图片会保留。
- 按钮使用中文「确认拉取」「取消」;用户取消时不得创建 worker、启动 Chrome、打开商品页或修改数据库。
- 不显示账号密码、Cookie、完整本地路径或其他敏感信息。
T-642 完成后,运行中的同一按钮会切换为停止入口;本任务只负责空闲状态下的执行前确认。
### 4. 生成套图始终显示成本与参数确认
修改正常整轮 `start_generation()` 流程:
- 在完成模板校验、项目/原图/卖点校验并构造准确 `specs` 后,创建 job 和启动 worker 前始终弹确认框,不再只对超过数量阈值的任务确认。
- 确认内容至少包含:
- 店铺显示名与别名;
- 商品 ID;临时草稿显示「未绑定商品」;
- 可用商品原图数量;
- 「每张上传图分别作为主图生成」是/否;
- 白底图、场景图、卖点图及自定义分类的生成数量;
- 图片比例与最终生成总数;
- 「本次生成会消耗 cmhub 点数」提示。
- 提示词正文不在确认框完整展示,避免超长文本和敏感业务内容占满弹窗;可显示「商品卖点已填写」或截断摘要。
- 按钮使用中文「确认生成」「返回修改」。
- 用户返回修改时不得创建 job、提交 cmhub 或产生点数消耗。
- T-640 的失败卡片单张「重试」不弹完整套图确认框,继续使用独立重试语义;如后续需要重试扣点确认,应另设简短确认,不复用整轮参数弹窗。
### 5. 配置与文档兼容
- `product_suite.last_settings` 继续只负责平台、站点、语言和比例。
- `last_account_alias` 与 `last_settings` 同级保存,不把商品 ID、卖点、图片路径或密钥写入 `config.json`。
- 旧配置缺少 `last_account_alias` 时保持兼容,不影响启动。
- 同步更新 `docs/04-architecture.md` 中 `product_suite` 配置 schema、最近上下文优先级和草稿保存事实。
## 验收要点
- [ ] 选择店铺后关闭并重启软件,首个新任务恢复最后有效店铺。
- [ ] 最近店铺已删除时自动回退,不出现无效下拉项或启动异常。
- [ ] 已绑定项目和恢复草稿始终显示项目自己的店铺,不被最近店铺覆盖。
- [ ] 未添加图片、未输入商品 ID 时,仅输入非空卖点并关闭软件,重启后可在恢复的临时草稿中看到原卖点。
- [ ] 空白输入和程序化回填不会创建临时草稿;同一次连续输入只创建一个草稿。
- [ ] 新建无关商品任务不会自动带入上一个商品卖点。
- [ ] 首次点击「拉取蝦皮主图」也会显示店铺、商品 ID 和只读操作确认,取消后不启动 worker/Chrome。
- [ ] 有本地图片时确认框说明刷新范围,并明确本地手动添加图片保留。
- [ ] 正常点击「生成套图」始终显示店铺、商品 ID、原图数、每图主图开关、分类数量、比例、总数和点数提示。
- [ ] 取消生成确认后不创建 `image_studio_jobs`,不调用 cmhub。
- [ ] 单张失败重试保持 T-640 行为,不弹整轮生成确认。
- [ ] 所有用户可见文本为中文,日志和弹窗不暴露密钥、Cookie、接口路径或完整提示词。
## 测试
- `tests/test_appconfig.py`:
- `last_account_alias` 默认值、保存、旧配置兼容与无效类型归一化。
- `tests/test_product_suite_gui.py`:
- 最近店铺跨重启恢复、账号失效回退、项目店铺优先;
- 无项目卖点防抖创建草稿、关闭前同步保存、空文本不建草稿、新任务不串卖点;
- 首次/已有图片拉取确认及取消不启动;
- 正常生成确认内容与取消不建 job;
- 单张失败重试不走整轮确认。
- 运行:
```bash
py -3.10 -m unittest tests.test_appconfig 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
```
## 边界(不改什么)
- 不把商品卖点作为全局默认值保存到 `config.json`。
- 不保存账号密码、Cookie、登录态、商品图片路径或 cmhub Key。
- 不修改 SQLite schema,继续复用 `image_studio_projects.draft_prompt` 和现有草稿恢复机制。
- 不实现拉取中停止、下载取消、迟到结果隔离或清理本轮新增图片,这些属于 T-642。
- 不修改 cmhub API、图片生成协议、并发上限、计费规则或单张重试行为。
- 不修改 Shopee/CDP 选择器、商品更新流程、①导入采集、②AI生成、③更新蝦皮、④账号管理或⑤设置。
## 执行记录
- 2026-07-16:`product_suite.last_account_alias` 已加入 `config.json` 归一化与读取 helper。⑥首次新任务会恢复最后有效店铺;同一次运行仍优先继承当前任务;项目/草稿继续使用自己的账号。最近账号失效时回退到第一个可用账号并修正配置,不保存密码、Cookie 或登录态。
- 2026-07-16:卖点防抖沿用现有 500ms。无 `project_id`、店铺有效且卖点非空时自动创建一个静默临时草稿并写入 `draft_prompt`;切换任务、关闭任务和关闭程序前的同步刷新也能补建草稿。仅含卖点的草稿已纳入恢复和 `project_has_content()` 语义;卖点清空且无资产/job 时仍可按空草稿清理。新建不继承任务不会全局带入上一商品卖点。
- 2026-07-16:「拉取蝦皮主图」首次和覆盖拉取均增加上下文确认,展示店铺、商品 ID、当前原图数和只读说明;取消后不创建 worker 或启动 Chrome。「生成套图」在正常整轮构造 specs 后、创建 job 前始终确认,展示原图数、每图主图开关、分类实际数量、比例、总数和 cmhub 点数提示;单张失败重试不走整轮确认。
- 2026-07-16:同步更新架构配置和草稿事实;补齐最近店铺恢复/失效回退、卖点草稿创建与恢复、空文本不建草稿、拉取/生成确认及取消边界测试,并将 T-640 测试中的已销毁 `QThread` 检查改为容忍 Qt 对象已正常释放。相关 73 项通过;商品套图 GUI 36 项在主工作区通过,其余测试文件在短路径隔离 worktree 中逐文件通过,共覆盖 539 项;Ruff、`compileall` 与 `git diff --check` 均通过。