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

136 lines
10 KiB
Markdown
Raw Normal View History

---
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` 均通过。