2026-06-15 16:09:32 +08:00
|
|
|
|
# 开发任务清单
|
|
|
|
|
|
|
|
|
|
|
|
## 任务文档说明
|
|
|
|
|
|
|
|
|
|
|
|
本文档用于跟踪自动合成印花服饰效果图工具的整体开发任务。后续 AI 或开发者领取任务前,必须先阅读对应任务的前置文档,并严格遵守 `docs/04-development-rules.md`。
|
|
|
|
|
|
|
|
|
|
|
|
任务状态说明:
|
|
|
|
|
|
|
|
|
|
|
|
- `[x]` 已完成。
|
|
|
|
|
|
- `[ ]` 未开始。
|
|
|
|
|
|
- `[~]` 进行中或部分完成。
|
|
|
|
|
|
|
|
|
|
|
|
## 任务执行顺序
|
|
|
|
|
|
|
|
|
|
|
|
任务编号即建议开发顺序,后续任务依赖前序任务的产出:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
1(基础服务)→ 2(数据模型)→ 3/4(文件/模板服务)
|
2026-06-16 10:53:19 +08:00
|
|
|
|
→ 5(图片合成核心)→ 6(批量任务核心)→ 6.5(低对比组合筛选核心)→ 7(主界面布局)→ 8-13(各 UI 面板)→ 14(微调状态)→ 15(测试)→ 16(打包)
|
2026-06-15 16:09:32 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
任务 1-6 完成前不应开始任务 7 及以后的 UI 任务,否则 UI 层将缺少可依赖的数据模型和服务层。
|
|
|
|
|
|
|
|
|
|
|
|
执行每个「完善 xxx.py」类任务前,必须先读取该文件的当前内容,了解骨架代码现状,再决定新增或修改哪些内容,避免覆盖已有实现。
|
|
|
|
|
|
|
|
|
|
|
|
## 0. 已完成基础工作
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 编写项目愿景文档:`docs/01-product-vision.md`
|
|
|
|
|
|
- [x] 编写 PRD:`docs/02-prd.md`
|
|
|
|
|
|
- [x] 编写技术栈文档:`docs/03-technical-stack.md`
|
|
|
|
|
|
- [x] 编写开发规则文档:`docs/04-development-rules.md`
|
|
|
|
|
|
- [x] 编写项目架构文档:`docs/05-project-architecture.md`
|
|
|
|
|
|
- [x] 编写 UI 效果图提示词:`docs/06-ui-mockup-prompt.md`
|
|
|
|
|
|
- [x] 整理 Claude UI 提示词版本:`docs/06-ui-mockup-prompt-claude.md`
|
|
|
|
|
|
- [x] 保存 UI 效果图设计稿:`docs/ui-v1.html`
|
|
|
|
|
|
- [x] 保存 UI 效果图截图:`docs/ui-v1.png`
|
|
|
|
|
|
- [x] 编写 UI 设计文档:`docs/07-ui-design.md`
|
|
|
|
|
|
- [x] 编写图像编辑器设计文档:`docs/08-image-editor-design.md`
|
|
|
|
|
|
- [x] 编写本地打包发布文档:`docs/09-packaging-release.md`
|
|
|
|
|
|
- [x] 创建 `requirements.txt`
|
|
|
|
|
|
- [x] 创建 `src/version.py`,统一维护 `APP_NAME` 和 `APP_VERSION`
|
|
|
|
|
|
- [x] 创建 `src/main.py` 最小 PySide6 入口
|
|
|
|
|
|
- [x] 创建 `src/app/main_window.py` 最小主窗口
|
|
|
|
|
|
- [x] 创建 `src/app/widgets/` 占位模块
|
|
|
|
|
|
- [x] 创建 `src/core/` 占位模块
|
|
|
|
|
|
- [x] 创建 `src/services/` 占位模块
|
|
|
|
|
|
- [x] 创建 `src/resources/` 资源目录
|
|
|
|
|
|
- [x] 创建 `tests/` 测试目录
|
|
|
|
|
|
- [x] 验证本机 Python 版本为 `3.7.9`
|
|
|
|
|
|
- [x] 验证 PySide6 版本为 `6.5.3`
|
|
|
|
|
|
- [x] 通过 `python -m py_compile` 语法检查
|
|
|
|
|
|
- [x] 验证最小 PySide6 窗口可以创建并关闭
|
|
|
|
|
|
- [x] 已提交文档规划代码
|
|
|
|
|
|
- [x] 已提交 PySide6 工程骨架代码
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 工程基础完善
|
|
|
|
|
|
|
|
|
|
|
|
### 1.1 日志服务
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/04-development-rules.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-15 16:33:33 +08:00
|
|
|
|
- [x] 先读取 `src/services/log_service.py` 现有内容
|
|
|
|
|
|
- [x] 完善 `src/services/log_service.py`
|
|
|
|
|
|
- [x] 启动时创建 `logs/` 目录
|
|
|
|
|
|
- [x] 日志文件按启动时间或日期命名
|
|
|
|
|
|
- [x] 日志格式包含时间、模块、级别、消息
|
|
|
|
|
|
- [x] 在 `src/main.py` 中初始化日志
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-15 16:33:33 +08:00
|
|
|
|
- [x] 启动程序后生成日志文件
|
|
|
|
|
|
- [x] 程序启动信息写入日志
|
|
|
|
|
|
- [x] 不使用 `print` 作为正式日志
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
### 1.2 路径与资源服务
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/04-development-rules.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
- `docs/09-packaging-release.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-15 16:48:37 +08:00
|
|
|
|
- [x] 在 `src/services/file_service.py` 中新增路径辅助函数(不单独建模块)
|
|
|
|
|
|
- [x] 实现 `get_app_dir()`:返回程序根目录,兼容开发环境和 PyInstaller 打包环境
|
|
|
|
|
|
- [x] 实现 `get_resource_path(relative_path)`:返回资源文件绝对路径
|
|
|
|
|
|
- [x] 实现 `get_config_path(relative_path)`:返回配置文件绝对路径
|
|
|
|
|
|
- [x] 实现 `get_log_dir()`:返回日志目录路径
|
|
|
|
|
|
- [x] 实现 `get_output_dir()`:返回默认输出目录路径
|
|
|
|
|
|
- [x] 保证 Windows 中文路径可用
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-15 16:48:37 +08:00
|
|
|
|
- [x] 路径函数不使用开发机绝对路径
|
|
|
|
|
|
- [x] 程序目录下缺少 `logs/` 或 `output/` 时可自动创建
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
### 1.3 配置服务
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/04-development-rules.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-15 16:51:46 +08:00
|
|
|
|
- [x] 先读取 `src/services/config_service.py` 现有内容
|
|
|
|
|
|
- [x] 完善 `src/services/config_service.py`
|
|
|
|
|
|
- [x] 定义默认配置
|
|
|
|
|
|
- [x] 支持读取 JSON 配置
|
|
|
|
|
|
- [x] 支持保存 JSON 配置
|
|
|
|
|
|
- [x] 配置损坏时使用安全默认值并记录日志
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-15 16:51:46 +08:00
|
|
|
|
- [x] 缺少配置文件时程序可启动
|
|
|
|
|
|
- [x] 配置文件损坏时程序可启动并记录日志
|
|
|
|
|
|
- [x] 不会无提示清空用户配置
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 2. 核心数据模型
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`
|
|
|
|
|
|
- `docs/04-development-rules.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
- `docs/08-image-editor-design.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-15 16:56:36 +08:00
|
|
|
|
- [x] 先读取 `src/core/models.py` 现有内容
|
|
|
|
|
|
- [x] 完善 `src/core/models.py`
|
|
|
|
|
|
- [x] 定义 `ImageAsset`
|
|
|
|
|
|
- [x] 定义 `TransformState`
|
|
|
|
|
|
- [x] 定义 `Template`
|
|
|
|
|
|
- [x] 定义 `ExportOptions`
|
|
|
|
|
|
- [x] 定义 `BatchOptions`
|
|
|
|
|
|
- [x] 定义 `ComposeResult`
|
|
|
|
|
|
- [x] 定义 `BatchResult`
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-15 16:56:36 +08:00
|
|
|
|
- [x] `models.py` 不依赖 PySide6 UI 控件
|
|
|
|
|
|
- [x] 变换状态包含 `x/y/width/height/rotation/keep_aspect_ratio`
|
|
|
|
|
|
- [x] 模型可以被 core、services 和 UI 层复用
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 3. 文件扫描与素材导入
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`
|
|
|
|
|
|
- `docs/04-development-rules.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
- `docs/07-ui-design.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-15 16:58:44 +08:00
|
|
|
|
- [x] 先读取 `src/services/file_service.py` 现有内容
|
|
|
|
|
|
- [x] 完善 `src/services/file_service.py`
|
|
|
|
|
|
- [x] 支持递归扫描衣服图片文件夹
|
|
|
|
|
|
- [x] 支持递归扫描印花图片文件夹
|
|
|
|
|
|
- [x] 支持格式:PNG、JPG、JPEG、WEBP
|
|
|
|
|
|
- [x] 忽略不支持格式并记录日志
|
|
|
|
|
|
- [x] 保留来源子文件夹信息
|
|
|
|
|
|
- [x] 生成安全输出文件名
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-15 16:58:44 +08:00
|
|
|
|
- [x] 可以扫描包含子文件夹的中文路径
|
|
|
|
|
|
- [x] 不修改原始素材文件
|
|
|
|
|
|
- [x] 不支持文件格式不会导致扫描失败
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 4. 模板服务
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`
|
|
|
|
|
|
- `docs/04-development-rules.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-15 17:01:40 +08:00
|
|
|
|
- [x] 先读取 `src/services/template_service.py` 现有内容
|
|
|
|
|
|
- [x] 完善 `src/services/template_service.py`
|
|
|
|
|
|
- [x] 定义内置模板
|
|
|
|
|
|
- [x] 支持读取自定义模板 JSON
|
|
|
|
|
|
- [x] 支持保存自定义模板 JSON
|
|
|
|
|
|
- [x] 支持新增、重命名、删除自定义模板
|
|
|
|
|
|
- [x] 校验模板字段
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-15 17:01:40 +08:00
|
|
|
|
- [x] 内置模板和自定义模板可区分
|
|
|
|
|
|
- [x] 单个模板损坏不影响全部模板加载
|
|
|
|
|
|
- [x] UI 不直接操作模板 JSON 文件
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 5. 图片合成核心
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`
|
|
|
|
|
|
- `docs/04-development-rules.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
- `docs/08-image-editor-design.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-15 17:28:02 +08:00
|
|
|
|
- [x] 先读取 `src/core/composer.py` 现有内容
|
|
|
|
|
|
- [x] 完善 `src/core/composer.py`
|
|
|
|
|
|
- [x] 使用 Pillow 读取衣服底图和印花图
|
|
|
|
|
|
- [x] 支持透明 PNG alpha 合成
|
|
|
|
|
|
- [x] 支持按 `TransformState` 缩放印花
|
|
|
|
|
|
- [x] 支持按 `TransformState` 旋转印花
|
|
|
|
|
|
- [x] 支持旋转后按中心点对齐粘贴
|
|
|
|
|
|
- [x] 支持 PNG 导出
|
|
|
|
|
|
- [x] 支持 JPG 导出
|
|
|
|
|
|
- [x] 输出文件名避免默认覆盖
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-15 17:28:02 +08:00
|
|
|
|
- [x] 合成逻辑不依赖 PySide6 UI 控件
|
|
|
|
|
|
- [x] 输出尺寸默认与衣服底图一致
|
|
|
|
|
|
- [x] 透明 PNG 不出现黑底或白底
|
|
|
|
|
|
- [x] 印花部分超出画布时不会报错
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 6. 批量任务核心
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`
|
|
|
|
|
|
- `docs/04-development-rules.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-15 17:55:55 +08:00
|
|
|
|
- [x] 先读取 `src/core/batch.py` 现有内容
|
|
|
|
|
|
- [x] 完善 `src/core/batch.py`
|
|
|
|
|
|
- [x] 支持多衣服 × 单印花
|
|
|
|
|
|
- [x] 支持单衣服 × 多印花
|
|
|
|
|
|
- [x] 支持一一匹配
|
|
|
|
|
|
- [x] 支持全组合
|
|
|
|
|
|
- [x] 复用 `core/composer.py`
|
|
|
|
|
|
- [x] 单个任务失败时继续处理剩余任务
|
|
|
|
|
|
- [x] 汇总成功数量、失败数量和失败原因
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-15 17:55:55 +08:00
|
|
|
|
- [x] 不复制第二套合成算法
|
|
|
|
|
|
- [x] 单张失败不会中断整个批量任务
|
|
|
|
|
|
- [x] 失败原因可供 UI 和日志使用
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
2026-06-16 10:53:19 +08:00
|
|
|
|
## 6.5 低对比组合筛选核心
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`
|
|
|
|
|
|
- `docs/04-development-rules.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
- `docs/08-image-editor-design.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-16 11:21:21 +08:00
|
|
|
|
- [x] 定义可见度状态:`正常`、`偏低`、`不明显`、`无法判断`
|
|
|
|
|
|
- [x] 新增低对比分析核心函数,位置应符合架构分层,不能写进 UI 事件
|
|
|
|
|
|
- [x] 基于当前模板或 `TransformState` 获取衣服目标区域
|
|
|
|
|
|
- [x] 只分析衣服目标区域颜色,不使用整张衣服图判断
|
|
|
|
|
|
- [x] 只统计印花 alpha 有效像素,例如 `alpha > 20`
|
|
|
|
|
|
- [x] 计算 RGB 颜色距离
|
|
|
|
|
|
- [x] 计算亮度差
|
|
|
|
|
|
- [x] 根据阈值输出可见度状态和评分
|
|
|
|
|
|
- [x] 单个组合分析失败时返回 `无法判断`,不得中断整个队列
|
|
|
|
|
|
- [x] 为后续队列项保存可见度结果预留字段或结果结构
|
2026-06-16 10:53:19 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-16 11:21:21 +08:00
|
|
|
|
- [x] 白色衣服配浅色印花时可标记为 `偏低` 或 `不明显`
|
|
|
|
|
|
- [x] 深色衣服配深色印花时可标记为 `偏低` 或 `不明显`
|
|
|
|
|
|
- [x] 透明 PNG 的透明区域不参与印花颜色判断
|
|
|
|
|
|
- [x] 低对比分析不修改原始衣服图片和原始印花图片
|
|
|
|
|
|
- [x] 分析逻辑不依赖 PySide6 UI 控件
|
|
|
|
|
|
- [x] 失败项不会中断批量队列生成或导出流程
|
2026-06-16 10:53:19 +08:00
|
|
|
|
|
2026-06-15 16:09:32 +08:00
|
|
|
|
## 7. 主界面布局
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/04-development-rules.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
- `docs/07-ui-design.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-15 18:04:29 +08:00
|
|
|
|
- [x] 先读取 `src/app/main_window.py` 现有内容
|
|
|
|
|
|
- [x] 将 `src/app/main_window.py` 从最小窗口扩展为主布局
|
2026-06-17 09:05:47 +08:00
|
|
|
|
- [x] ~~实现顶部标题和版本号~~(后移除内容区自绘标题栏:与系统窗口标题重复,名称/版本改由系统标题栏显示,见 17.7)
|
2026-06-15 18:04:29 +08:00
|
|
|
|
- [x] 实现流程页签区域
|
|
|
|
|
|
- [x] 实现左侧素材栏容器
|
|
|
|
|
|
- [x] 实现中间预览区容器
|
|
|
|
|
|
- [x] 实现右侧参数栏容器
|
|
|
|
|
|
- [x] 实现底部合成队列容器
|
|
|
|
|
|
- [x] 实现底部状态栏
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-15 18:04:29 +08:00
|
|
|
|
- [x] 窗口标题显示 `APP_NAME` 和 `APP_VERSION`
|
|
|
|
|
|
- [x] UI 布局接近 `docs/ui-v1.png`
|
|
|
|
|
|
- [x] 不把所有业务逻辑塞进 `main_window.py`
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 8. 素材列表 UI
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
- `docs/07-ui-design.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-16 08:44:17 +08:00
|
|
|
|
- [x] 先读取 `src/app/widgets/image_list_panel.py` 现有内容
|
|
|
|
|
|
- [x] 实现衣服图片列表
|
|
|
|
|
|
- [x] 实现印花图片列表
|
|
|
|
|
|
- [x] 实现打开文件夹按钮
|
|
|
|
|
|
- [x] 实现全选和取消全选
|
|
|
|
|
|
- [x] 实现单张勾选和取消勾选
|
|
|
|
|
|
- [x] 显示已选数量和总数量(例如:`含子文件夹 · 共 12`)
|
|
|
|
|
|
- [x] 显示来源子文件夹标签和文件名
|
|
|
|
|
|
- [x] 实现排序选择器(默认按文件夹+名称排序)
|
|
|
|
|
|
- [x] 点击素材后更新当前预览选择
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-16 08:44:17 +08:00
|
|
|
|
- [x] 支持递归导入素材
|
|
|
|
|
|
- [x] 当前预览选中态和批量勾选态可区分
|
|
|
|
|
|
- [x] 不在 UI 层重复实现文件扫描规则
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 9. 图像预览编辑器
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/04-development-rules.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
- `docs/07-ui-design.md`
|
|
|
|
|
|
- `docs/08-image-editor-design.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-16 09:01:15 +08:00
|
|
|
|
- [x] 先读取 `src/app/widgets/image_canvas.py` 现有内容
|
|
|
|
|
|
- [x] 使用 `QGraphicsView / QGraphicsScene`
|
|
|
|
|
|
- [x] 显示衣服底图(scene 坐标与原图像素坐标保持一致)
|
|
|
|
|
|
- [x] 显示印花图层
|
|
|
|
|
|
- [x] 实现印花拖动
|
|
|
|
|
|
- [x] 实现缩放控制点(至少四角)
|
|
|
|
|
|
- [x] 实现旋转控制点(顶部中心外侧)
|
|
|
|
|
|
- [x] 实现预览缩放(通过 `QGraphicsView` view transform,不修改 scene 内容)
|
|
|
|
|
|
- [x] 实现预览顶部栏:显示当前底图文件名、印花文件名、操作模式按钮(移动/缩放/旋转)、缩放比例控制
|
|
|
|
|
|
- [x] 实现画布操作提示 Overlay(拖动移动 / 四角缩放 / 顶部旋转 / Shift 锁比例)
|
|
|
|
|
|
- [x] 将交互结果同步为 `TransformState`
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-16 09:01:15 +08:00
|
|
|
|
- [x] 预览缩放不改变真实合成参数
|
|
|
|
|
|
- [x] 拖动后坐标为衣服原图像素坐标
|
|
|
|
|
|
- [x] 缩放后宽高同步
|
|
|
|
|
|
- [x] 旋转后角度同步
|
|
|
|
|
|
- [x] 不使用截图作为导出结果
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 10. 参数面板 UI
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
- `docs/07-ui-design.md`
|
|
|
|
|
|
- `docs/08-image-editor-design.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-16 09:06:24 +08:00
|
|
|
|
- [x] 先读取 `src/app/widgets/transform_panel.py` 现有内容
|
|
|
|
|
|
- [x] 完善 `src/app/widgets/transform_panel.py`
|
|
|
|
|
|
- [x] 实现 X/Y 坐标输入
|
|
|
|
|
|
- [x] 实现宽度/高度输入
|
|
|
|
|
|
- [x] 实现锁定宽高比例
|
|
|
|
|
|
- [x] 实现角度输入
|
|
|
|
|
|
- [x] 实现左旋 90 度和右旋 90 度按钮
|
|
|
|
|
|
- [x] 与 `ImageCanvas` 双向同步 `TransformState`
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-16 09:06:24 +08:00
|
|
|
|
- [x] 参数输入后预览同步更新
|
|
|
|
|
|
- [x] 预览交互后参数输入框同步更新
|
|
|
|
|
|
- [x] 程序化更新输入框不会造成信号循环
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 11. 模板面板 UI
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
- `docs/07-ui-design.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-16 09:15:33 +08:00
|
|
|
|
- [x] 先读取 `src/app/widgets/template_panel.py` 现有内容
|
|
|
|
|
|
- [x] 完善 `src/app/widgets/template_panel.py`
|
|
|
|
|
|
- [x] 显示模板下拉框
|
|
|
|
|
|
- [x] 支持选择模板
|
|
|
|
|
|
- [x] 支持保存模板
|
|
|
|
|
|
- [x] 支持另存为模板
|
|
|
|
|
|
- [x] 支持重置为模板
|
|
|
|
|
|
- [x] 通过 `template_service` 操作模板
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-16 09:15:33 +08:00
|
|
|
|
- [x] 选择模板后更新预览和参数面板
|
|
|
|
|
|
- [x] UI 不直接修改模板 JSON
|
|
|
|
|
|
- [x] 自定义模板重启后仍可用
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 12. 导出面板 UI
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
- `docs/07-ui-design.md`
|
|
|
|
|
|
- `docs/09-packaging-release.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-16 09:18:39 +08:00
|
|
|
|
- [x] 先读取 `src/app/widgets/export_panel.py` 现有内容
|
|
|
|
|
|
- [x] 完善 `src/app/widgets/export_panel.py`
|
|
|
|
|
|
- [x] 实现输出目录选择
|
|
|
|
|
|
- [x] 实现输出格式选择
|
|
|
|
|
|
- [x] 实现质量选择
|
|
|
|
|
|
- [x] 实现导出当前单张
|
2026-06-16 17:01:58 +08:00
|
|
|
|
- [x] ~~实现应用为模板入口~~(后移除:与模板区域「另存为」重复,见 17.3)
|
|
|
|
|
|
- [x] ~~实现重置为模板入口~~(后移除:与模板区域「重置为模板」重复,见 17.3)
|
2026-06-16 09:18:39 +08:00
|
|
|
|
- [x] 显示当前操作影响范围提示
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-16 09:18:39 +08:00
|
|
|
|
- [x] 缺少衣服或印花时导出按钮禁用
|
|
|
|
|
|
- [x] 输出目录不可写时提示用户并记录日志
|
|
|
|
|
|
- [x] 单张导出调用 `core/composer.py`
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 13. 合成队列 UI
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
- `docs/07-ui-design.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-16 09:25:45 +08:00
|
|
|
|
- [x] 实现底部合成队列表格(建议使用 `QTableView` + 模型视图结构)
|
|
|
|
|
|
- [x] 实现队列头部批量模式切换:多衣服×单印花 / 单衣服×多印花 / 一一匹配 / 全组合(矩阵)
|
|
|
|
|
|
- [x] 实现队列统计显示(共 N 项 · 完成 · 进行 · 失败 · 待导出)
|
|
|
|
|
|
- [x] 实现「重置全部」按钮
|
|
|
|
|
|
- [x] 实现「导出选中」按钮
|
|
|
|
|
|
- [x] 实现「开始批量导出」按钮(导出中切换为停止/暂停)
|
|
|
|
|
|
- [x] 实现队列折叠/展开
|
|
|
|
|
|
- [x] 显示任务状态(已完成 / 待导出 / 导出中 / 失败)
|
|
|
|
|
|
- [x] 导出中任务显示进度条
|
|
|
|
|
|
- [x] 显示失败原因
|
|
|
|
|
|
- [x] 支持选中队列项并更新预览区和参数面板
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-16 09:25:45 +08:00
|
|
|
|
- [x] 队列统计显示总数、完成、进行、失败、待导出
|
|
|
|
|
|
- [x] 导出中任务显示进度条
|
|
|
|
|
|
- [x] 失败行显示可理解原因
|
|
|
|
|
|
- [x] 选中队列项可以加载对应状态
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 14. 微调状态
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/07-ui-design.md`
|
|
|
|
|
|
- `docs/08-image-editor-design.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-16 09:31:16 +08:00
|
|
|
|
- [x] 定义队列项微调状态
|
|
|
|
|
|
- [x] 手动调整队列项后标记为 `已微调`
|
|
|
|
|
|
- [x] 微调项保存独立 `TransformState`
|
|
|
|
|
|
- [x] 批量导出时微调项使用自己的参数
|
|
|
|
|
|
- [x] 未微调项使用模板参数
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-16 09:31:16 +08:00
|
|
|
|
- [x] 已微调项不会被无提示覆盖
|
|
|
|
|
|
- [x] 队列表格能显示 `模板` 和 `已微调`
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 15. 测试
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/04-development-rules.md`
|
|
|
|
|
|
- `docs/05-project-architecture.md`
|
|
|
|
|
|
- `docs/08-image-editor-design.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-16 09:38:06 +08:00
|
|
|
|
- [x] 编写 `tests/test_composer.py`
|
|
|
|
|
|
- [x] 编写 `tests/test_templates.py`
|
|
|
|
|
|
- [x] 测试透明 PNG 合成
|
|
|
|
|
|
- [x] 测试缩放参数
|
|
|
|
|
|
- [x] 测试旋转中心
|
|
|
|
|
|
- [x] 测试文件扫描
|
|
|
|
|
|
- [x] 测试模板读写
|
|
|
|
|
|
- [x] 测试批量任务生成
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
2026-06-16 09:38:06 +08:00
|
|
|
|
- [x] 核心逻辑测试不依赖 GUI
|
|
|
|
|
|
- [x] 测试可在 Python 3.7 环境运行
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
## 16. 打包
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/03-technical-stack.md`
|
|
|
|
|
|
- `docs/04-development-rules.md`
|
|
|
|
|
|
- `docs/09-packaging-release.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
2026-06-16 11:49:25 +08:00
|
|
|
|
- [x] 创建打包脚本
|
|
|
|
|
|
- [x] 验证 PyInstaller `onedir` 打包
|
|
|
|
|
|
- [x] 打包资源文件
|
|
|
|
|
|
- [x] 打包默认配置和模板
|
|
|
|
|
|
- [x] 验证打包后程序启动
|
|
|
|
|
|
- [x] 验证标题栏版本号
|
|
|
|
|
|
- [x] 验证单张导出
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 打包产物可在无 Python 环境的 Windows 电脑启动
|
2026-06-16 11:49:25 +08:00
|
|
|
|
- [x] 发布包不包含源代码、缓存、测试输出和私人配置
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
2026-06-16 17:01:58 +08:00
|
|
|
|
## 17. 体验优化(持久化与独立重置)
|
|
|
|
|
|
|
|
|
|
|
|
第二阶段根据实际使用反馈新增。
|
|
|
|
|
|
|
|
|
|
|
|
### 17.1 用户偏好持久化
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`(6.6 模板选择、6.9 批量合成导出、9 数据与文件结构)
|
|
|
|
|
|
- `docs/05-project-architecture.md`(4.12 config_service)
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 先读取 `src/services/config_service.py` 与 `src/app/main_window.py` 现有内容
|
|
|
|
|
|
- [ ] 在 `main_window` 启动时调用 `load_config()` 并把初值分发给各面板(集中管理,不让控件各自读写)
|
|
|
|
|
|
- [ ] 在 `config_service` 默认配置中新增 `last_template`、`last_batch_mode`
|
|
|
|
|
|
- [ ] 记住并在启动时恢复上次选择的模板;自定义模板已删除时回退到第一个内置模板
|
|
|
|
|
|
- [ ] 记住并在启动时恢复上次选择的批量模式;持久化值非法时回退默认(全组合)
|
|
|
|
|
|
- [ ] 面板选择变化时「改一次存一次」回写配置
|
|
|
|
|
|
- [ ] `template_panel` 增加模板选择变化信号(携带模板名)
|
|
|
|
|
|
- [ ] `queue_panel` 增加 `set_batch_mode()` 与批量模式变化信号
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 重启后自动恢复上次选择的模板和批量模式
|
|
|
|
|
|
- [ ] 自定义模板被删除或批量模式值非法时安全回退,不报错
|
|
|
|
|
|
- [ ] UI 控件不直接读写配置文件
|
|
|
|
|
|
|
|
|
|
|
|
### 17.2 位置 / 尺寸 / 旋转独立重置
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/07-ui-design.md`(7 右侧参数栏、10 视觉规范)
|
|
|
|
|
|
- `docs/08-image-editor-design.md`
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 先读取 `src/app/widgets/transform_panel.py` 现有内容
|
|
|
|
|
|
- [ ] 在 `位置` / `尺寸` / `旋转` 三个分区标题右侧各加一个独立 `重置` 按钮
|
|
|
|
|
|
- [ ] 各重置只把对应参数还原为当前选中模板的值,互不影响(位置→仅 X/Y;尺寸→仅宽/高,位置不变;旋转→仅角度)
|
|
|
|
|
|
- [ ] 移除合并的 `重置位置 / 尺寸 / 角度` 按钮与角度旁的 `归零` 按钮
|
|
|
|
|
|
- [ ] 重置按钮采用幽灵样式(静止灰、悬停蓝、按下深蓝、禁用更灰),不使用红色
|
|
|
|
|
|
- [ ] 未选模板或未加载衣服/印花时三个按钮置灰
|
|
|
|
|
|
- [ ] 由 `main_window` 取模板换算值并按项合并进当前 `TransformState`
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 位置、尺寸、旋转可分别独立重置,互不影响
|
|
|
|
|
|
- [ ] 尺寸重置只改变宽 / 高,不改变位置 X / Y
|
|
|
|
|
|
- [ ] 按钮视觉层级符合 `docs/07-ui-design.md` 第 10 节
|
|
|
|
|
|
|
|
|
|
|
|
### 17.3 按钮去重(导出面板模板入口)
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/07-ui-design.md`(7.1 模板区域、7.7 操作按钮)
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 移除导出面板的 `应用为模板` 与 `重置为模板` 按钮(与模板区域的 `另存为` / `重置为模板` 是同一动作的重复入口)
|
|
|
|
|
|
- [ ] 模板相关操作统一留在模板区域,导出面板只负责输出与导出
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 同一个动作在界面上只出现一次,命名一致
|
|
|
|
|
|
- [ ] 导出面板仅保留输出设置与 `导出当前单张`
|
|
|
|
|
|
|
2026-06-16 17:45:09 +08:00
|
|
|
|
### 17.4 「重置为模板」归位并更名为「位置尺寸旋转重置为当前模板」
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/07-ui-design.md`(7 右侧参数栏、10 视觉规范)
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 把模板区域的 `重置为模板` 按钮移出,移到参数栏底部(旋转分区下方)
|
|
|
|
|
|
- [ ] 更名为 `位置尺寸旋转重置为当前模板`,与三个分项 `↺ 重置` 构成「全部 + 分项」两级
|
|
|
|
|
|
- [ ] 还原逻辑改为把位置/尺寸/旋转整体设为模板值,并与分项重置同走 `_apply_preview_transform`
|
|
|
|
|
|
- [ ] 与三个分项重置一起受「未加载图片时置灰」控制
|
|
|
|
|
|
- [ ] 采用安静、全宽、悬停出强调色的样式(不使用红色)
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 模板区域只剩 `保存` / `另存为`,不含整体重置
|
|
|
|
|
|
- [ ] `位置尺寸旋转重置为当前模板` 在旋转分区下方,未加载图片时置灰
|
|
|
|
|
|
- [ ] 点击后位置、尺寸、旋转一并还原为当前选中模板
|
|
|
|
|
|
|
|
|
|
|
|
### 17.5 模板删除按钮
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/07-ui-design.md`(7.1 模板区域)
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 在模板区域增加 `删除` 按钮(复用 `template_service.delete_template`)
|
|
|
|
|
|
- [ ] `删除` 仅对自定义模板可用,选中内置模板时隐藏(与 `保存` 一致)
|
|
|
|
|
|
- [ ] 删除前弹二次确认对话框;确认后才删除
|
|
|
|
|
|
- [ ] 删除后刷新下拉框并回选第一个内置模板,同步持久化选择
|
|
|
|
|
|
- [ ] `删除` 用红色文字提示危险但保持安静样式
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 可在界面上删除自定义模板,无需手改 `templates.json`
|
|
|
|
|
|
- [ ] 内置模板不显示 `删除`
|
|
|
|
|
|
- [ ] 删除有二次确认,取消则不删
|
|
|
|
|
|
|
|
|
|
|
|
### 17.6 参数/导出面板紧凑化与命名
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/07-ui-design.md`(7.2 位置区域、7.3 尺寸区域、7.5 输出设置区域)
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 「位置」的 X、Y 输入框放在同一行(标签简化为 `X` / `Y`)
|
|
|
|
|
|
- [ ] 「尺寸」的宽、高输入框放在同一行(标签简化为 `宽` / `高`),`锁定宽高比例` 在其下方
|
|
|
|
|
|
- [ ] 导出面板「格式」「质量」放在同一行
|
|
|
|
|
|
- [ ] 底部整体重置按钮更名为 `位置尺寸旋转重置为当前模板`
|
|
|
|
|
|
- [ ] 仅改布局/文案,不动同步与导出逻辑
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] X/Y 一行、宽/高一行、格式/质量一行,界面更紧凑
|
|
|
|
|
|
- [ ] 拖动/缩放预览后输入框仍正常同步
|
|
|
|
|
|
- [ ] 质量仍仅在 JPG 时可用
|
|
|
|
|
|
|
2026-06-17 09:05:47 +08:00
|
|
|
|
### 17.7 移除重复的自绘标题栏与无效「设置」按钮
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/07-ui-design.md`(3 整体布局、4.1 标题栏)
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 移除标题栏里点了无反应的占位「设置」按钮
|
|
|
|
|
|
- [x] 移除内容区自绘标题栏(与系统窗口标题重复),名称/版本由系统标题栏(`setWindowTitle`)显示
|
|
|
|
|
|
- [x] 同步清理相关样式与未用常量
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 界面不再出现重复的软件名称/版本号
|
|
|
|
|
|
- [x] 系统窗口标题仍显示 `APP_NAME` 与 `APP_VERSION`
|
|
|
|
|
|
- [x] 工作区因移除标题栏而获得更多纵向空间
|
|
|
|
|
|
|
2026-06-17 15:13:01 +08:00
|
|
|
|
### 17.8 加载文件夹后默认预览第一张
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/07-ui-design.md`(5.1 衣服图片面板)
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 衣服、印花面板加载文件夹后,自动选中并预览第一张(按当前排序)
|
|
|
|
|
|
- [x] 空文件夹不选;把选中逻辑抽成按行选择以复用
|
|
|
|
|
|
- [x] 与现有「模板粘性」衔接:自动选印花后按当前模板落位
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 加载文件夹后画布不再为空、无需手动点选
|
|
|
|
|
|
- [x] 两个文件夹加载顺序无关,最终都能得到合成预览
|
|
|
|
|
|
|
|
|
|
|
|
### 17.9 输出按「时间戳 → 印花」分组到子文件夹
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`(6.8 单张合成导出、9 数据与文件结构)
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] `make_safe_output_path` 输出到 `<输出目录>/<印花文件名>/<衣服文件名>.<扩展名>`
|
|
|
|
|
|
- [x] 新增 `timestamped_run_dir(base)`,每次导出运行在输出目录下新建时间戳文件夹
|
|
|
|
|
|
- [x] 一次导出运行(批量/单张)共用同一个时间戳;批量在开始时计算一次
|
|
|
|
|
|
- [x] 单张导出、队列导出、`core.batch.run_batch` 均接入时间戳层
|
|
|
|
|
|
- [x] 子文件夹由 `composer.compose` 保存时自动创建;重名仍追加 `_1`/`_2`
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 路径形如 `输出目录/<时间戳>/<印花文件名>/<衣服文件名>.<扩展名>`
|
|
|
|
|
|
- [x] 重复运行落在不同时间戳文件夹,互不覆盖
|
|
|
|
|
|
- [x] 一次批量运行内所有图片共用同一个时间戳文件夹
|
|
|
|
|
|
|
|
|
|
|
|
### 17.10 记住上次的衣服/印花文件夹
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`(6.1 图片加载、9 数据与文件结构)
|
|
|
|
|
|
- `docs/05-project-architecture.md`(4.12 config_service)
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] `_AssetPanel` 打开对话框时定位到上次目录(`set_start_dir`),并在选中后发 `folder_opened` 信号
|
|
|
|
|
|
- [x] `ImageListPanel` 暴露 `set_garment_start_dir` / `set_print_start_dir` 与 `garment_folder_opened` / `print_folder_opened`
|
|
|
|
|
|
- [x] `main_window` 启动恢复 `last_garment_dir` / `last_print_dir`,并在打开文件夹时「改一次存一次」回写
|
|
|
|
|
|
- [x] UI 不直接读写配置,统一经主窗口
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 重启后打开「打开文件夹」对话框定位到上次的衣服/印花目录
|
|
|
|
|
|
- [x] 目录已不存在时安全回退,不报错
|
|
|
|
|
|
|
|
|
|
|
|
### 17.11 修复:批量导出忽略所选输出格式/质量/目录
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/07-ui-design.md`(7.5 输出设置区域、8 底部合成队列)
|
|
|
|
|
|
|
|
|
|
|
|
问题:
|
|
|
|
|
|
|
|
|
|
|
|
- `queue_panel.set_export_options()` 从未被调用,导出面板也无「选项变化」信号,导致队列始终使用默认 `ExportOptions`(PNG、默认目录),批量导出无视 UI 所选格式/质量/目录。
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 导出面板新增 `export_options_changed` 信号与公开 `current_options()`
|
|
|
|
|
|
- [x] 格式/质量/输出目录任一变化即发出当前 `ExportOptions`
|
|
|
|
|
|
- [x] `main_window` 接到 `queue_panel.set_export_options`,并在启动时同步一次
|
|
|
|
|
|
- [x] 单张导出 `_do_export` 改用同一 `current_options()` 来源
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 选 JPG 后批量导出的文件为 `.jpg` 且按 JPEG 保存
|
|
|
|
|
|
- [x] 批量导出跟随所选输出目录与质量
|
|
|
|
|
|
|
2026-06-17 15:51:52 +08:00
|
|
|
|
### 17.12 合并图文件名加上印花名
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`(6.8 单张合成导出、9 数据与文件结构)
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] `make_safe_output_path` 的文件名由 `<衣服文件名>` 改为 `<衣服文件名>_<印花文件名>`
|
|
|
|
|
|
- [x] 目录分组结构不变(仍 `输出目录/<时间戳>/<印花文件名>/`)
|
|
|
|
|
|
- [x] 重名仍追加 `_1`/`_2` 避免覆盖
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 输出文件形如 `输出目录/<时间戳>/TY030/1_TY030.png`
|
|
|
|
|
|
- [x] 单张导出与批量导出一致
|
|
|
|
|
|
|
|
|
|
|
|
### 17.13 隐藏「导出当前单张」按钮
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/07-ui-design.md`(7.7 操作按钮、10 视觉规范)
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 隐藏导出面板的 `导出当前单张` 按钮(`setVisible(False)`)
|
|
|
|
|
|
- [x] 保留按钮与 `_do_export` 逻辑,便于后续需要时再显示
|
|
|
|
|
|
- [x] 导出统一经底部合成队列完成
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 导出面板不再显示 `导出当前单张`,只剩输出设置
|
|
|
|
|
|
- [x] 队列的批量/选中导出不受影响
|
|
|
|
|
|
|
|
|
|
|
|
### 17.14 修复:选中未微调队列项时预览未按模板落位
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`(6.6 模板选择)
|
|
|
|
|
|
- `docs/07-ui-design.md`(12.4 选中队列项)
|
|
|
|
|
|
|
|
|
|
|
|
问题:
|
|
|
|
|
|
|
|
|
|
|
|
- `_on_queue_item_activated` 仅在 `item.transform` 存在(已微调)时覆盖画布变换;未微调项保留 `load_print` 的写死默认(印花≈衣服宽 40%、居中),预览尺寸与选中模板不一致——「模板粘性」在队列项激活路径的遗漏分支。
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 选中队列项且 `item.transform` 为空时,调用 `template_panel.apply_current()` 按当前模板落位
|
|
|
|
|
|
- [x] 仍在 `_loading_queue_item` 保护下,避免被误标为「已微调」
|
|
|
|
|
|
- [x] 与预览流程(`_on_print_preview`)行为一致
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 点击未微调队列项,预览印花为选中模板要求的大小/位置
|
|
|
|
|
|
- [x] 已微调项仍显示其自身参数,不被覆盖
|
|
|
|
|
|
|
2026-06-17 16:42:20 +08:00
|
|
|
|
### 17.15 修复:批量导出对未微调项复用单个像素变换
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/02-prd.md`(6.6 模板选择)
|
|
|
|
|
|
- `docs/08-image-editor-design.md`(变换状态)
|
|
|
|
|
|
|
|
|
|
|
|
问题:
|
|
|
|
|
|
|
|
|
|
|
|
- `QueuePanel` 用单个像素级 `TransformState`(`_template_transform`,来自 `template_applied`,按「当时画布那张衣服/印花尺寸」算出)作为所有未微调项的回退变换。
|
|
|
|
|
|
- `TransformState` 是「衣服原图像素坐标」,对尺寸不同的衣服/印花原样复用会错位、错尺寸(如 1000×1000 算出的 x=400/w=250 套到 2000×3000 上,印花跑到左上、尺寸只剩一半)。
|
|
|
|
|
|
- 影响批量导出与「导出选中」中所有未微调项。
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 队列改存模板对象(比例坐标 `Template`)而非单个像素变换:`set_template()` 取代 `set_transform()`
|
|
|
|
|
|
- [x] 导出时按每项自身衣服/印花尺寸现算:抽纯函数 `core.composer.resolve_transform()`(已微调项用自身变换,否则 `template.to_transform_state(gw,gh,pw,ph)`)
|
|
|
|
|
|
- [x] widget 仅负责读图尺寸(`core.composer.image_size()`,只读 header)+ 单次运行内缓存
|
|
|
|
|
|
- [x] `main_window` 在 `template_changed`/`template_applied` 时把模板推给队列,并在启动时初始同步
|
|
|
|
|
|
- [x] 新增 4 个纯函数单测覆盖:已微调优先、不同尺寸各自换算、空模板/空尺寸返回 None
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 一个批次内含不同尺寸的衣服/印花时,未微调项各自按模板正确落位
|
|
|
|
|
|
- [ ] GUI 实测:混合尺寸批量导出,结果图印花位置/大小均正确
|
|
|
|
|
|
|
2026-06-17 17:05:46 +08:00
|
|
|
|
### 17.16 局域网更新 · 阶段②:启动时检测并通知
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/10-lan-update.md`(§7 更新源、§8 流程、§16 阶段②)
|
|
|
|
|
|
- `docs/02-prd.md`(app_config 的 `update_source`)
|
|
|
|
|
|
|
|
|
|
|
|
说明:
|
|
|
|
|
|
|
|
|
|
|
|
- 阶段①(数据目录分离)已在 commit `76f2c6d` 完成。本任务实现阶段②「只读通知」,不自动安装。
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 配置项 `update_source`(空 = 不检查)写入 `DEFAULT_CONFIG`
|
|
|
|
|
|
- [x] `services/update_service.py`:`parse_version` / `is_newer` / `check_for_update`,读取 `<source>/manifest.json`,任何不可达/损坏/非更新一律返回 None(不抛错、不阻塞)
|
|
|
|
|
|
- [x] 主窗口顶部通知横幅(默认隐藏):「发现新版本 vX.Y.Z」+「打开更新目录」+ 关闭
|
|
|
|
|
|
- [x] 检查在后台守护线程进行,经 Qt 队列信号回主线程显示横幅(更新源不可达不卡启动)
|
|
|
|
|
|
- [x] 「打开更新目录」用 `QDesktopServices` 打开 `manifest.source`
|
|
|
|
|
|
- [x] 15 个纯函数单测覆盖版本比较与 `check_for_update` 各分支
|
|
|
|
|
|
|
|
|
|
|
|
验收:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 单测通过;更新源为空/不可达时静默跳过
|
2026-06-17 17:17:47 +08:00
|
|
|
|
- [x] GUI 实测:配置可达更新源 + 高版本 manifest → 启动后显示横幅,点击打开目录
|
2026-06-17 17:12:43 +08:00
|
|
|
|
- [x] GUI 实测:更新源不可达 → 正常启动、无横幅、无卡顿
|
2026-06-17 17:05:46 +08:00
|
|
|
|
|
2026-06-17 17:29:56 +08:00
|
|
|
|
### 17.17 局域网更新 · 阶段③:自动安装启动器(脚本)
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/10-lan-update.md`(§3 架构、§8 流程、§16 阶段③)
|
|
|
|
|
|
|
|
|
|
|
|
说明:
|
|
|
|
|
|
|
|
|
|
|
|
- 实现 PowerShell 启动器 `scripts/update.ps1`,跑通「检查 → staging → 校验 → 原子切换 → 启动 → 降级」整条链路。先以脚本验证流程,后续再决定是否编译为 `Launcher.exe`。
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] `scripts/update.ps1`:读 `current.txt` 与 `data\config\app_config.json` 的 `update_source`
|
|
|
|
|
|
- [x] 读远端 `manifest.json`、语义化版本比较,仅当远端更高才更新
|
|
|
|
|
|
- [x] robocopy 拷到 `staging\<ver>.tmp` → 校验 `marker` → 重命名进 `versions\<ver>` → 原子写 `current.txt`(ascii 无 BOM)
|
|
|
|
|
|
- [x] 启动 `versions\<current>\CMBot.exe` 并设 `CMBOT_DATA_DIR`
|
|
|
|
|
|
- [x] 降级:源不可达 / robocopy 失败 / marker 缺失 / 坏 manifest 一律启动本地现版本
|
|
|
|
|
|
- [x] 假版本目录验证 6 个用例(更新、幂等、源不可达、未配置源、下载损坏、坏 manifest)全过
|
|
|
|
|
|
- [ ] 接入真实安装结构:`build.ps1` 或新增安装步骤产出 `%LOCALAPPDATA%\CMBot\versions\<ver>\` 版本并排布局
|
2026-06-18 08:54:16 +08:00
|
|
|
|
- [ ] 真实双机实测
|
|
|
|
|
|
|
|
|
|
|
|
### 17.18 更新传输统一改为 HTTP
|
|
|
|
|
|
|
|
|
|
|
|
前置阅读:
|
|
|
|
|
|
|
|
|
|
|
|
- `docs/10-lan-update.md`(已整体改为 HTTP:§7 源、§8 流程、§14 安全、§16 阶段)
|
|
|
|
|
|
- `docs/02-prd.md`(`update_source` / `update_user` / `update_pass`)
|
|
|
|
|
|
|
|
|
|
|
|
背景:
|
|
|
|
|
|
|
|
|
|
|
|
- 更新源改为 HTTP(S) 文件服务(已部署 gohttpserver + nginx,HTTP Basic Auth,示例 `http://cm.xiapi.com/`)。§17.16/§17.17 的本地文件版与 UNC/robocopy 版作为历史保留,本任务把传输统一到 HTTP。
|
|
|
|
|
|
|
|
|
|
|
|
任务:
|
|
|
|
|
|
|
|
|
|
|
|
- [x] 文档:`docs/10` 由 UNC/robocopy 全面改为 HTTP(源/清单/流程/安全/阶段);`docs/02`、`docs/05` 同步配置项
|
2026-06-18 09:43:23 +08:00
|
|
|
|
- [x] 配置项 `update_user` / `update_pass` 写入 `DEFAULT_CONFIG`
|
|
|
|
|
|
- [x] `update_service.check_for_update` 支持 `http(s)://` 源 + Basic Auth(当前仅 `open()` 本地文件,填 URL 静默返回 None),补单测
|
|
|
|
|
|
- [x] 启动器 `update.ps1` 改 HTTP:带凭据下载 zip → 校验 SHA-256 → 解压到 `staging\app.new` → `app/app.old` 切换回滚
|
|
|
|
|
|
- [x] manifest 字段由 `source`/`files`/`marker` 改为 `url`/`sha256`/`size`
|
2026-06-18 08:54:16 +08:00
|
|
|
|
- [ ] 发布流程脚本:build → 打 zip → 算 SHA-256 → 写 manifest → 上传
|
|
|
|
|
|
- [ ] 生产前将更新源切到 HTTPS、客户端改用只读账号
|
|
|
|
|
|
- [ ] 真实环境端到端实测
|
2026-06-17 17:29:56 +08:00
|
|
|
|
|
2026-06-16 17:01:58 +08:00
|
|
|
|
## 18. 后续暂缓任务
|
2026-06-15 16:09:32 +08:00
|
|
|
|
|
|
|
|
|
|
以下任务第一阶段暂不做,后续需要时再新增设计文档:
|
|
|
|
|
|
|
|
|
|
|
|
- [ ] 局域网分发
|
|
|
|
|
|
- [ ] 自动更新
|
|
|
|
|
|
- [ ] 多版本启动器
|
|
|
|
|
|
- [ ] 按电脑名控制版本
|
|
|
|
|
|
- [ ] AI 穿搭
|
|
|
|
|
|
- [ ] 导出上架流程
|
|
|
|
|
|
- [ ] 自动抠图
|
|
|
|
|
|
- [ ] 自动识别衣服区域
|
|
|
|
|
|
- [ ] 移动端应用
|