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

153 lines
7.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-603
title: ②AI生成封面重置计数与商品ID警示色
phase: 7
deps: [T-511, T-534, T-554, T-566, T-577]
status: DONE
created: 2026-07-11
---
## 问题 / 背景
②AI生成模块里,用户可以通过顶部「重置生成结果」或封面画廊「重置图片」重置某条记录的封面。T-566 已经让重置封面时把旧 `new_cover_path` 归档,因此同一商品后续可能有多张生成图片候选可查看和恢复。
当前缺口是:`tasks` 表里没有“这条记录封面曾经重置过”的业务事实;②列表也只给「标题状态 / 图片状态」上色,商品ID列没有特殊颜色。用户回到列表后,不能直接判断哪些商品可能有多张候选图,需要双击逐条打开画廊确认。
本任务目标:**记录封面重置历史,并在②AI生成列表用商品ID列 warning 色提醒用户“这条商品封面重置过,可能有多张候选图”。**
## 方案
### 1. DB 增加封面重置历史字段
在 `tasks` 表做兼容迁移,新增字段:
- `cover_reset_count INTEGER NOT NULL DEFAULT 0`
- `cover_reset_at TEXT`
同步更新:
- `SCHEMA_SQL`
- 旧库启动时的 ad-hoc 迁移
- `Task` dataclass
- row → `Task` 映射
- DB 单测
字段语义:
- `cover_reset_count > 0` 表示该商品封面曾经被人工重置过,可能存在多张封面候选图。
- `cover_reset_at` 记录最近一次封面重置时间,用于 tooltip 和诊断。
- 这不是失败状态,也不是待生成状态;它是“有重置历史/可重点查看候选图”的业务标记。
### 2. 统一在 `db.reset_generated()` 里记录
只在 `reset_cover=True` 且重置前 `before.new_cover_path` 非空时记录封面重置历史:
- `cover_reset_count = cover_reset_count + 1`
- `cover_reset_at = now`
原因:
- 顶部「重置生成结果」和封面画廊「重置图片」都会走 `db.reset_generated()`,统一在这里记录不会漏。
- 如果只重置标题(`reset_title=True, reset_cover=False`),不改 `cover_reset_count`,避免误导用户“有多张图片”。
- 如果任务本来没有 `new_cover_path`,即使传入 `reset_cover=True`,也不增加计数,避免空重置造成误标。
明确不清除:
- `db.update_generated_cover()` 不清 `cover_reset_count`。用户从历史候选图保存回当前封面后,这条记录仍属于“曾经重置过/有候选图历史”。
- `db.set_generated()` 新生成封面成功后也不清 `cover_reset_count`。新图成功后更需要保留提示,方便用户知道可打开画廊比较多张候选图。
- 第一版不提供“清除重置历史”入口;后续如果用户需要,可另做独立任务。
### 3. ②商品ID列语义色
在 `GenerateTaskTableModel.data()` 中增加商品ID列(列 1)的 `Qt.ForegroundRole`:
- 若 `task.cover_reset_count > 0`,商品ID显示为 warning/琥珀色。
- 颜色复用 T-511/T-543 语义色板中的 `COLOR_WARNING`,不要新增硬编码颜色。
- 不使用红色;红色保留给失败。
- 不使用绿色;绿色保留给成功。
- 不刷整行背景,避免与失败、选中态、状态列颜色冲突。
tooltip:
- 商品ID列若 `cover_reset_count > 0`,显示:
- `该商品封面已重置 2 次,可能有多张候选图,双击可查看封面画廊`
- 如果同一行还有 `last_error`,商品ID列优先显示封面重置提示;状态列/其它列继续保留原失败 tooltip 即可。
### 4. 不用扫描候选图数量作为主判断
不要把 `image_paths.list_task_cover_candidates()` 或目录扫描结果作为商品ID变色的唯一依据。
原因:
- 图片文件可能被用户移动、清理或被杀毒软件隔离。
- 旧版本路径兼容、归档文件名、业务目录迁移都可能影响扫描稳定性。
- “封面重置过”是业务事实,应该存在 SQLite 里。
可以在未来增强 tooltip 时辅助显示“当前扫描到 X 张候选图”,但本任务第一版只依赖 `cover_reset_count` 决定商品ID颜色。
## 验收要点
- 重置某条封面后,刷新②AI生成列表,该行商品ID变成 warning/琥珀色。
- 批量重置封面时,多行商品ID都变色。
- 只重置标题时,商品ID不变色。
- 如果任务没有 `new_cover_path`,重置封面不增加 `cover_reset_count`,商品ID不误变色。
- 双击变色商品仍能进入封面画廊查看候选图。
- 从候选图里保存某张图为当前封面后,商品ID仍保持 warning 色,因为它仍有重置历史。
- 重新生成封面成功后,商品ID仍保持 warning 色,提示用户可打开画廊比较候选图。
- 程序重启后颜色仍保留。
- ③更新蝦皮逻辑不受影响;③列表不因为 `cover_reset_count` 改颜色。
- 失败行仍按现有状态列/图片状态列显示 danger;商品ID warning 只表示“封面重置历史”,不是失败。
## 测试要求
- `tests/test_db.py`
- 覆盖新字段 schema 和旧库迁移。
- 覆盖 `reset_generated(reset_cover=True)` 增加 `cover_reset_count/cover_reset_at`。
- 覆盖只重置标题不增加计数。
- 覆盖没有 `new_cover_path` 的空封面重置不增加计数。
- 覆盖 `update_generated_cover()` 和 `set_generated()` 不清除计数。
- `tests/test_gui.py`
- 覆盖 `GenerateTaskTableModel` 商品ID列 `Qt.ForegroundRole` 返回 warning 色。
- 覆盖商品ID列 tooltip 显示重置次数和画廊提示。
- 覆盖标题状态/图片状态列原有颜色不回归。
验证命令:
```bash
python -m ruff check app tests main.py
py -3.10 -m compileall app main.py
py -3.10 -m unittest discover -s tests
git diff --check
```
## 边界(不改什么)
- 不改 AI/cmhub 请求、并发、重试、下载保存逻辑。
- 不改封面画廊候选图枚举规则。
- 不改 ③更新蝦皮/CDP/Shopee 流程。
- 不新增 Excel 字段,不把重置次数回写 Excel。
- 不新增“只看重置过”筛选。
- 不用目录扫描结果替代 SQLite 业务标记。
- 不让标题重置触发商品ID变色。
## 执行记录
- 2026-07-11:已完成。
- 代码:
- `app/db.py`:`tasks` 新增 `cover_reset_count INTEGER NOT NULL DEFAULT 0` 与 `cover_reset_at TEXT`,补 `init_db()` 兼容迁移、`Task` dataclass 字段和旧库迁移路径。
- `db.reset_generated()`:仅在 `reset_cover=True` 且重置前 `new_cover_path` 非空时累加 `cover_reset_count` 并写最近重置时间;只重置标题、空封面重置不计数。`update_generated_cover()` 与 `set_generated()` 不清除该历史。
- `app/gui/models.py`:② `GenerateTaskTableModel` 商品ID列在 `cover_reset_count > 0` 时使用 `COLOR_WARNING`,tooltip 显示“该商品封面已重置 X 次,可能有多张候选图,双击可查看封面画廊”;标题/图片状态列原有颜色不变。
- 测试:
- `tests/test_db.py`:覆盖新字段初始化、旧库迁移、封面重置计数、只重置标题不计数、空封面重置不计数、选择候选图/重新生成后不清除计数。
- `tests/test_gui.py`:覆盖②商品ID列 warning 色、tooltip 和状态列颜色不回归。
- 验证:
- 当前主工作区全量 unittest 会被既有未提交默认提示词文件影响(`papa1` 与 `默认.txt` 差异),该问题不属于 T-603。
- 在临时干净 worktree 中仅应用本任务 diff 后验证通过:
- `python -m ruff check app tests main.py`
- `py -3.10 -m compileall app main.py`
- `py -3.10 -m unittest discover -s tests`(338 tests)
- `git diff --check`
- 主工作区定向验证通过:
- `py -3.10 -m unittest tests.test_db`
- `py -3.10 -m unittest tests.test_gui.GuiTests.test_generate_table_marks_cover_reset_history_on_item_id_column tests.test_gui.GuiTests.test_generate_table_splits_title_and_cover_statuses_and_widths`