From b92024ad4a2df055a6692f2107068c469be82448 Mon Sep 17 00:00:00 2001 From: chengma Date: Fri, 10 Jul 2026 10:24:44 +0800 Subject: [PATCH] docs(tasks): add T-581 open-image-folder button in tab 2 (cascade select-row/batch/root) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ②筛选行加「打开图片文件夹」按钮:选中行→该账号 slug 图片文件夹(直达 图片)、未选行→当前批次文件夹、全部批次→图片根;目录不存在弹提示不建 目录;跨平台可 mock 打开 helper(Windows os.startfile,Linux 测试不崩)。 Co-Authored-By: Claude Opus 4.8 --- docs/tasks/T-581.md | 74 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 docs/tasks/T-581.md diff --git a/docs/tasks/T-581.md b/docs/tasks/T-581.md new file mode 100644 index 0000000..ebb9319 --- /dev/null +++ b/docs/tasks/T-581.md @@ -0,0 +1,74 @@ +--- +id: T-581 +title: ②AI生成增加「打开图片文件夹」按钮(级联:选中行账号图 / 批次 / 全部批次根) +phase: 7 +deps: [T-566] +status: TODO +created: 2026-07-10 +--- + +## 问题 / 背景 + +运营需要把某商品/某账号/整批的 AI 图片(旧封面、新封面、归档候选)用文件管理器打开,便于打包发给他人做文件级操作。当前②只能在画廊弹窗里看单商品候选(T-567),无法跳到文件夹做批量文件操作。 + +已核事实: +- 图片落盘层级 `///{task_id}_{item_id}_{old|new|new_}.jpg`(`app/image_paths.py`)。slug 文件夹里直接是图片文件(含旧封面、新封面、归档候选);批次文件夹下一层是各账号 slug 子文件夹。 +- `image_root = appconfig.image_dir(config)`(`app/appconfig.py:622`)。 +- ②批次来源 = `batch_filter.currentData()`(`generate.py:1866`,None/"all" 即全部批次);行选中 = 表格 selectionModel。 +- **仓库无任何"打开文件夹"实现**——净新增,需跨平台且 Linux 测试环境不崩(单测在 WSL 跑)。 + +## 方案(改哪个文件、改成什么) + +### 级联打开规则(越具体开越深) + +| 状态 | 打开目录 | +| --- | --- | +| 选中了某行 | `///`(该行任务对应账号的图片,直达图片) | +| 未选行、批次筛选=具体批次 | `//`(整批,含各账号子文件夹,供整批打包) | +| 未选行、批次筛选=全部批次 | `/`(所有批次根) | + +- 选中多行时取第一/当前行的账号 slug(单一目录,不同时开多个)。 +- slug 目录路径复用 `image_paths.task_image_path(image_root, task, account, "new")` 取 `os.path.dirname(...)`,保证与图片实际落盘位置一致;账号解析复用②既有 account 解析(`_account_for_task`/`account_by_alias` 同款)。 + +### `app/gui/tabs/generate.py` — 按钮与布局 + +- 新增 `self.open_image_dir_button = QPushButton("打开图片文件夹")`,放在**筛选行**(`filter_layout`)紧挨 `refresh_button` 右侧(`generate.py:895` 后)。理由:级联依据(批次筛选、选中行)都在这一行,且它是只读导航动作,不与「开始生成/停止/重置生成结果」这类消耗点数/改数据的执行按钮混排。 +- tooltip:「选中某行→打开该账号图片文件夹;未选中→打开当前批次文件夹;全部批次→打开图片根目录」。 +- 点击 handler:按上表算出目标目录 → 若目录**不存在**:弹提示(如「该批次/账号还没有图片」),**不自动创建目录**、不打开 → 存在则调用跨平台打开 helper。 + +### 跨平台打开 helper(可 mock) + +- 新增小工具(如 `app/gui/widgets.py` 或合适模块)`open_in_file_manager(path)`:Windows 用 `os.startfile(path)`;其他平台用 `subprocess.Popen(["xdg-open", path])`/macOS `open`(防御性,产品面向 Windows)。 +- handler 调用该 helper,单测通过 `mock.patch` 断言「用正确目标路径调用了 helper」,**不真正打开**(Linux CI/WSL 不炸)。 + +### 文档同步 + +- `docs/routes.md` / ②相关 UI 文档:登记「打开图片文件夹」按钮及级联规则。 + +## 验收要点 + +- 选中某行 → 用 `///`(= 该行 new 图 dirname)调用打开 helper。 +- 未选行 + 批次筛选具体批次 → 用 `//` 调用。 +- 未选行 + 全部批次 → 用 `/` 调用。 +- 目标目录不存在 → 弹提示、**不调用打开 helper、不创建目录**。 +- 打开 helper 被 mock:单测断言目标路径正确、平台分支正确;不真实执行 `os.startfile`。 +- 按钮位于筛选行、不在生成/重置按钮排;tooltip 说明级联。 +- 生成运行中按钮仍可用(只读动作,不必禁用)。 +- 验证命令(unittest,不引入 pytest): + - `py -3.10 -m unittest tests.test_gui` + - `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` + +## 边界(不改什么) + +- 不改图片落盘路径/层级、`image_paths` 生成逻辑、`image_dir` 配置。 +- 不新建「打包/压缩」功能(只打开文件夹,压缩由用户在文件管理器做)。 +- 不改画廊弹窗(T-567)、生成/重置链路、批次筛选逻辑本身。 +- 不自动创建缺失目录、不删除任何文件。 +- 不改 ③/①/CDP/DB/cmhub。 + +## 执行记录 + +(做完在这里写:改了什么文件、跑了什么验证命令及结果、遇到的阻塞、关键决策。)