fix(ai-outfit): 货号(B列)改为可选,空货号不再跳过整行 (§19.14)

用户表的「商品id(货号)」整列为空时,行有效性判定(标题+货号+图三者非空)
把每一行都判为不完整 → read_all_rows 与 load_outfit_tasks 都返回 0:预览下拉
只剩占位符,且「开始生成」也判定无待处理行。货号不进提示词、目录行输出名沿用
源图名,对该用法是多余约束。

- excel_service.py: read_all_rows / load_outfit_tasks 完整性判定改为只要求
  标题 + 衣服图路径 非空,货号可空(状态过滤不变)
- core/ai_outfit.py: 单文件行货号为空时输出名回退 Path(garment).stem
  (货号非空仍用 货号.jpg);目录行不变
- ai_outfit_panel.py: 样本下拉标签货号为空显示「(无货号)」
- tests: 空货号行被 read_all_rows/load_outfit_tasks 收录、单文件空货号按源图名命名
- docs/11 §4(表+规则)/§9(命名回退)、tasks.md §19.14

离屏冒烟:标题填/货号空/C=目录 → 预览下拉有行、生成产出到子目录、E=完成;
全套测试在 Python 3.7 全绿(test_config_service 的失败属并行的出厂模板工作,与本次无关)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 17:15:05 +08:00
co-authored by Claude Opus 4.8
parent abe46c4aeb
commit 9a61a432d9
7 changed files with 65 additions and 13 deletions
+4 -4
View File
@@ -55,8 +55,8 @@ services/excel_service:把结果写回 Excel(D 新图路径 / E 状态 / F
| 列 | 含义 | 读/写 |
|---|---|---|
| A | 标题 | 读 |
| B | 货号(商品 ID) | 读 |
| C | 衣服图路径(本机绝对路径) | 读 |
| B | 货号(商品 ID,**可空**) | 读 |
| C | 衣服图路径(本机绝对路径,文件或目录) | 读 |
| D | 生成结果图片路径 | 写回 |
| E | 完成状态:`完成` / `失败`(空=未处理) | 写回 |
| F | 失败原因(仅人工查看) | 写回 |
@@ -65,7 +65,7 @@ services/excel_service:把结果写回 Excel(D 新图路径 / E 状态 / F
- 默认读第一个工作表,第 1 行表头,从第 2 行开始。
- **跳过 E=`完成` 的行**;是否处理 E=`失败` 的行由界面「重试失败行」决定(勾选则处理「空白 + 失败」,否则只处理「空白」)。
- 标题/货号/衣服图任一为空 → 跳过该行,不写状态、不中断。
- **行有效性只看「标题 + 衣服图路径」两者非空**;**货号(B 列)可空**——它不进提示词,仅用于单文件行的输出命名(见 §9),为空时命名回退用源图名,因此不应再因缺货号而跳过整行。标题或衣服图为空 → 跳过该行,不写状态、不中断。
- 字段按原样读取,不清理空格、不回写清理值。
- **开始前检测 Excel 是否被占用**(Office 打开会锁文件,openpyxl 无法写回)→ 提示「请关闭 Excel 后再开始」。
- **每处理完一行即保存 Excel**(降低崩溃丢结果风险)。
@@ -174,7 +174,7 @@ Excel 行 → `OutfitTask` 列表的转换由 `excel_service` 完成;核心只
- 格式 JPG,1:1,压缩到 ≤2MB;质量三档(小文件 75 / 均衡 85 / 高清 92)。
- 默认输出目录沿用 cmbot `get_output_dir()`(程序旁的「合并后的图片」,见 `docs/10` §5),界面可改。
- 命名:`货号.jpg`,重名自动 `_1`/`_2`,非法字符替换为 `_`(不改 Excel 原始货号)。
- 命名:`货号.jpg`,重名自动 `_1`/`_2`,非法字符替换为 `_`(不改 Excel 原始货号)。**货号为空时命名回退用源图名**(`<源图名>.jpg`,与目录行一致)。
- 成功后把**实际新图绝对路径**写回 Excel D 列。
### 9.1 目录行的输出(多图 → 同名子目录)