feat(export): 批量导出后生成 AI 穿搭 Excel,每印花子目录一行 (§17.23)

添加印花批量导出完成后,自动在输出目录生成与时间戳目录同名的 xlsx
文件(docs/02 §6.12);每个有效印花子目录一行,C 列指向该子目录路径,
AI 穿搭页直接选取即可触发目录扇出逻辑(§19.12),无需手工填写 Excel。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-23 09:33:28 +08:00
co-authored by Claude Sonnet 4.6
parent e83dd07dc0
commit a3f4c39821
5 changed files with 144 additions and 3 deletions
+48
View File
@@ -138,6 +138,54 @@ class TestOutfitExcelService(unittest.TestCase):
with self.assertRaises(ExcelInUseError):
ensure_excel_writable(self.excel_path)
# -- write_outfit_source_excel (docs/02 §6.12) ----------------------------
def test_write_outfit_source_excel_header_and_rows(self):
"""One row per (print_name, subdir_path); header + A/B/C values correct."""
import os
from services.excel_service import write_outfit_source_excel
p = self.tmp / "batch.xlsx"
rows = [
("floral", r"D:\out\20260623\floral" + os.sep),
("stripe", r"D:\out\20260623\stripe" + os.sep),
]
write_outfit_source_excel(p, rows)
wb = load_workbook(str(p))
ws = wb.active
try:
self.assertEqual(
[ws.cell(1, c).value for c in range(1, 7)],
["标题", "货号", "衣服图路径", "生成结果图片路径", "完成状态", "失败原因"],
)
self.assertEqual(ws.max_row, 3) # 1 header + 2 data
self.assertEqual(ws.cell(2, 1).value, "floral")
self.assertIsNone(ws.cell(2, 2).value) # 货号留空
self.assertIn("floral", ws.cell(2, 3).value)
self.assertTrue(ws.cell(2, 3).value.endswith(os.sep))
self.assertEqual(ws.cell(3, 1).value, "stripe")
for col in (4, 5, 6): # D/E/F 留空
self.assertIsNone(ws.cell(2, col).value)
finally:
wb.close()
def test_write_outfit_source_excel_ai_outfit_can_read_it(self):
"""AI穿搭 read_all_rows picks up the generated Excel as a directory row."""
import os
from services.excel_service import read_all_rows, write_outfit_source_excel
subdir = self.tmp / "floral"
subdir.mkdir()
p = self.tmp / "batch.xlsx"
write_outfit_source_excel(p, [("floral", str(subdir) + os.sep)])
rows = read_all_rows(p)
self.assertEqual(len(rows), 1)
self.assertEqual(rows[0].title, "floral")
self.assertEqual(rows[0].product_id, "")
self.assertTrue(rows[0].garment_path.endswith(os.sep))
if __name__ == "__main__":
unittest.main()