docs(tasks): add product suite drag sorting task

This commit is contained in:
chengma
2026-07-23 08:44:33 +08:00
parent 01b4a05c26
commit 7d31578e8b
+58
View File
@@ -0,0 +1,58 @@
---
id: T-691
title: 商品套图原图真实拖放排序修复
phase: 7
deps: [T-688]
status: TODO
created: 2026-07-23
---
## 问题 / 背景
商品套图的商品原图列表已显示“拖动到第一位即可设为主图”,但用户无法把参考图拖到第一张位置。列表开启了 `QListWidget.InternalMove`,真实原图项却只具备拖拽源标记,没有 `Qt.ItemIsDropEnabled`;拖到已有第一张图片时不是合法的内部放置目标,Qt 不会触发可用的排序结果和 `orderChanged` 回写。列表默认 drop action 仍为复制,也没有明确表达内部排序必须移动。
此前 T-688 的测试只直接调用 `reorder_originals()`,验证了 SQLite 排序持久化,未覆盖实际 Qt 拖放事件,因此没有发现界面手势失效。
拉取蝦皮主图尚未完全结束(含后台下载)或正在生成时,排序仍应锁定,这是既有并发保护,不属于本 bug;界面必须继续给出明确原因。
## 方案
### 1. 修复真实内部拖放条件
- 创建真实商品原图项时,显式保留可选中、可勾选、可拖动并增加 `Qt.ItemIsDropEnabled`,使任意原图都能作为内部排序的放置目标。
- 原图列表明确将内部 drop action 设为 `Qt.MoveAction`;外部本地文件 URL 拖入仍沿用既有导入路径,不能被内部排序逻辑误处理。
- 内部 drop 只在 Qt 已接受移动后发出 `orderChanged`,避免无效 drop、锁定状态或外部拖入触发错误的数据库排序。
### 2. 保留安全边界与用户反馈
- 生成中、拉取 URL 或拉取图片下载尚未完成时继续禁用原图内部排序;完成后自动恢复可拖放状态。
- 排序成功继续复用 `reorder_originals()` 的单事务服务写入和“已更新商品原图顺序,第一张图片为主图”提示;第一项的主图文字、粗体和语义色按刷新后的顺序更新。
- 不改历史 job 的 `source_asset_id/reference_asset_ids` 快照;排序只影响之后新建的生成轮次。
### 3. 自动回归
- 增加 Qt 级回归,构造原图列表并模拟已接受的内部移动结果,验证第二张变为第一张时 `orderChanged` 只发出一次、顺序正确且服务层写回 SQLite。
- 覆盖原图 item flags 含拖动/放置、默认 action 为移动、外部文件 URL 拖入仍仅走 `filesDropped`,以及拉取锁定时不触发排序。
## 验收要点
- 非生成、非拉取状态下,用户可将任意参考图拖到第一张位置,刷新后该图显示“主图”,数据库 `source_order` 同步更新。
- 拖到其它位置也可正常重排;无效 drop 不写数据库、不提示排序成功。
- 外部图片拖入继续进入“添加商品原图”,不被当作内部排序。
- 生成中或拉取未完成时仍不能排序,并保留中文原因提示;任务结束后可立即排序。
- 自动验证:
- `py -3.10 -m unittest tests.test_product_suite_gui tests.test_image_studio tests.test_product_suite`
- `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`
## 边界(不改什么)
- 不改 SQLite schema、商品套图任务/历史轮次、提示词、cmhub 生图、下载并发或 Shopee CDP。
- 不解除生成中或拉取未完成时的排序锁定,不增加新的主图选择按钮。
- 不影响①至⑤模块及商品原图的删除、预览、勾选和外部文件导入语义。
## 执行记录
- 待实现。