fix(ai-outfit): 标题生成对「标题(A)空」的印花表不再误报无行 (§19.27)

catch-22:「生成标题」用 read_all_rows 取行,而它要求 标题(A)+原始图片路径(C)
都非空;但标题生成的目的就是填 A。印花导出表若 A 空(被清空/早期导出),
所有行被跳过 → 误报「该表没有可处理的行」。实测 output/20260623_094529.xlsx:
A 全空、C 是印花子目录。

- excel_service.read_all_rows 增 require_title=True 开关:False 时只在
  原始图片路径(C) 空时跳过、允许 标题(A) 空;默认 True 行为不变(预览/
  无待处理统计/图片生成 load_outfit_tasks 仍要求 A)
- ai_outfit_panel._TitleWorker.run 改调 read_all_rows(..., require_title=False)

测试:A 空+C 有的行 require_title=False 收录、默认跳过;C 空两种都跳过。
全套 py37 通过(test_config_service 的 packaging 模板失败属并行 §19.13,无关)。
离屏冒烟:真表 20260623_094529.xlsx 默认 0 行→require_title=False 加载 6 行;
worker 把 6 条标题按序回填 A、C(印花目录)不动。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-23 17:35:13 +08:00
co-authored by Claude Opus 4.8
parent be1eb9ee36
commit a9360f9421
5 changed files with 59 additions and 8 deletions
+23
View File
@@ -126,6 +126,29 @@ class TestOutfitExcelService(unittest.TestCase):
self.assertEqual(tasks[0].product_id, "")
self.assertEqual([r.row_index for r in read_all_rows(p)], [2])
def test_read_all_rows_require_title_false_keeps_empty_title_rows(self):
"""§19.27: 标题生成的行来源——A 空、C 非空的行 require_title=False 收录,
默认(True)跳过;C 空的行两种都跳过。"""
from services.excel_service import read_all_rows
p = self.tmp / "notitle.xlsx"
wb = Workbook()
ws = wb.active
ws.append(["标题", "商品id", "原始图片路径", "结果", "状态", "原因"])
ws.append([None, None, "D:\\out\\TY030\\", "", "", ""]) # A空、C有(印花表)
ws.append([None, None, "D:\\out\\TY037\\", "", "", ""]) # A空、C有
ws.append([None, None, "", "", "", ""]) # C空 → 两种都跳过
wb.save(str(p))
wb.close()
# 默认要求标题 → A 全空 → 跳过印花行(旧 catch-22 现象)
self.assertEqual([r.row_index for r in read_all_rows(p)], [])
# require_title=False → A 空也收录,只按 C 过滤
rows = read_all_rows(p, require_title=False)
self.assertEqual([r.row_index for r in rows], [2, 3])
self.assertEqual(rows[0].title, "") # A 留空(待生成)
self.assertTrue(rows[0].garment_path.endswith("TY030" + "\\"))
def test_write_title_result_updates_a_only_and_saves(self):
"""标题生成回填只改 A 列,不动 D/E/F(docs/11 §17)。"""
from services.excel_service import write_title_result