From 03b9bbab78ca13ddd9673bdc8ec17f67eb75a843 Mon Sep 17 00:00:00 2001 From: chengma Date: Thu, 23 Jul 2026 09:32:15 +0800 Subject: [PATCH] docs(tasks): add product suite drag lifecycle fix --- docs/tasks/T-693.md | 61 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 docs/tasks/T-693.md diff --git a/docs/tasks/T-693.md b/docs/tasks/T-693.md new file mode 100644 index 0000000..47cb715 --- /dev/null +++ b/docs/tasks/T-693.md @@ -0,0 +1,61 @@ +--- +id: T-693 +title: 商品套图连续拖放丢失显示修复 +phase: 7 +deps: [T-692] +status: TODO +created: 2026-07-23 +--- + +## 问题 / 背景 + +T-692 已避免 Qt 默认内部投放复制同一图片项,但用户连续把参考1、参考2、参考3、参考4等图片拖到第一位时,商品原图列表仍可能突然看不到“参考1”,后续拖放也不能稳定写入排序。 + +现场 SQLite 检查确认相关项目的原图记录、状态和本地文件路径仍完整,未执行删除;异常属于 GUI 列表状态失配。当前 `ProductOriginalList._move_dragged_item_to()` 在 `dropEvent()` 尚未退出时同步发送 `orderChanged`,槽函数 `ProductSuiteTab.reorder_originals()` 随即写库并调用 `_refresh_originals()`,通过 `clear()` 删除全部旧 `QListWidgetItem` 后重新创建。此时 Qt 的 `QDrag` 仍持有本轮拖拽源和模型状态,连续拖动会让旧拖拽对象与新列表项发生重入,出现缩略图临时消失、标签缺位或后续排序未提交。 + +“主图 / 参考1 / 参考2”仍是当前位置标签,不是图片永久名称;每次排序后应连续重编号。只要原图不少于两张,界面刷新后必须存在“参考1”。 + +## 方案 + +### 1. 拖拽结束后再提交顺序 + +- `startDrag()` 开始前保存唯一的拖拽项和排序快照,并清空上一轮待提交状态。 +- `dropEvent()` 只用 T-692 的受控 `takeItem()` + `insertItem()` 完成当前列表内移动;不在该事件内发送 `orderChanged`,也不触发列表刷新。 +- 移动成功后仅保存待提交的唯一 asset ID 顺序;原地释放、无效目标、跨列表、锁定状态或重复 ID 不建立待提交顺序。 +- 等 `super().startDrag()` 返回,确认 Qt 拖拽事务完全结束后,再清理拖拽上下文并发送一次 `orderChanged`。不使用固定毫秒延时猜测拖拽完成。 + +### 2. 保存、失败恢复与显示一致性 + +- `ProductSuiteTab.reorder_originals()` 继续复用 `image_studio.reorder_original_assets()` 的 SQLite 单事务写入和唯一性校验;成功或失败后的完整刷新发生在拖拽事务之外。 +- 写库成功后按数据库顺序重建列表,并连续显示“主图、参考1、参考2……”;保留勾选状态、图片 ID 和缩略图。 +- 写库失败时重新读取数据库恢复原顺序并显示中文错误,不保留仅存在于 GUI 的临时顺序。 +- 不删除、复制或新增原图资产,不修改本地文件;现有删除确认、生成/拉取锁定及历史 job 快照保持不变。 + +### 3. 回归测试 + +- 扩展 `ProductOriginalList` Qt 测试,验证 `dropEvent()` 阶段只记录待提交顺序,不发送 `orderChanged`;拖拽结束后只发送一次。 +- 连续模拟把不同参考图移到第一位,接收排序后重建列表,验证每轮图片数量不变、asset ID 唯一且集合不变,标签始终连续包含“主图、参考1……”;最终顺序与 SQLite 一致。 +- 覆盖原地释放、重复 ID、无拖拽源和被锁定时不提交;外部文件 URL 拖入仍只走 `filesDropped`。 + +## 验收要点 + +- 对同一商品连续把参考1、参考2、参考3、参考4拖到第一位,每次均只改变顺序,不丢失或复制任何缩略图。 +- 原图不少于两张时,每轮刷新后都显示“参考1”,其余参考图按位置连续编号。 +- 每次有效拖拽只写库一次;无效拖拽不写库、不显示成功。 +- 切换商品或重启程序后,SQLite 中原图数量、图片 ID 集合和最终顺序与界面一致。 +- 自动验证: + - `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、蝦皮 CDP 或①至⑤模块。 +- 不改变“主图 / 参考N”按当前位置动态编号的产品语义,不给图片增加永久参考编号。 +- 不放宽服务层对重复 ID、缺失 ID 和跨项目 ID 的校验,不实现跨列表或多项拖放。 + +## 执行记录 + +- 待实现。