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
+3 -1
View File
@@ -175,7 +175,9 @@ class _TitleWorker(QObject):
try:
ensure_excel_writable(self._excel_path)
rows = read_all_rows(self._excel_path)
# 标题生成的行来源只要求 原始图片路径(C) 非空,标题(A) 可空——A 正是
# 要填的列;否则 A 空的印花表会被误判为无行(§19.27)。
rows = read_all_rows(self._excel_path, require_title=False)
except Exception as exc: # noqa: BLE001 - report to UI
self.failed.emit(str(exc))
return
+9 -5
View File
@@ -115,13 +115,17 @@ def load_outfit_tasks(excel_path, retry_failed=False):
workbook.close()
def read_all_rows(excel_path):
def read_all_rows(excel_path, require_title=True):
"""Return an OutfitTask for every valid data row, ignoring E-column status.
Unlike load_outfit_tasks (which filters for *processable* rows), this returns
all rows whose 标题 + 衣服图路径 are filled — including 「完成」/「失败」, and
regardless of 货号 (which is optional, docs/11 §4) — for preview/sample purposes
only (docs/11 §10.3). Rows missing title/garment are skipped.
all rows whose 衣服图路径 is filled — including 「完成」/「失败」, and regardless
of 货号 (optional, docs/11 §4) — for preview/sample purposes (docs/11 §10.3).
require_title (docs/11 §17.1 / §19.27): when True (default) a row also needs
标题(A) non-empty (preview / image-gen input). 标题生成 passes False because
its very job is to FILL A, so rows with an empty 标题 must NOT be skipped —
only 原始图片路径(C) is required.
"""
path = Path(excel_path)
workbook = load_workbook(str(path))
@@ -132,7 +136,7 @@ def read_all_rows(excel_path):
title = sheet.cell(row_index, COL_TITLE).value
product_id = sheet.cell(row_index, COL_PRODUCT_ID).value
garment_path = sheet.cell(row_index, COL_GARMENT_PATH).value
if _is_empty(title) or _is_empty(garment_path): # 货号可空
if _is_empty(garment_path) or (require_title and _is_empty(title)):
continue
raw_status = sheet.cell(row_index, COL_STATUS).value
rows.append(