v106-v109 童装支持 + 标题模板外部化 + 模板导出增强
- 新增男童/女童检测(gender_from_category 优先判童装)与童装场景图生成
(configs/kids_features.yaml:模特/场景/服装风格,同一商品固定同一组)
- 童装 SPU 字段映射:kids_type→SPU商品属性-类型、kids_age→适用年龄段、
target_audience 按性别映射、kids_type_map 女童「上衣」→「针织上衣」
- 标题生成提示词外部化:prompts/title_prompt_{1,2,3}.md + config.yaml 路由表
- 模板多站点匹配:经营站点可配多个,命中任意一个即匹配
- 种草图生成失败自动重试(seed_shot.retries,换场景/模特/风格)
- 模板导出新增 Preview 文件夹(成功产品 _composite.oss.jpg + result.xlsx)
- 修复 SKU 尺码未按从小到大排序(_size_rank 支持单一年龄码 6Y/10Y)
This commit is contained in:
@@ -29,6 +29,38 @@ def _template_out_path(prod_dir: Path, tpl_name: str) -> Path:
|
||||
return prod_dir / f"{tpl_name}_已填写_{int(time.time())}.xlsx"
|
||||
|
||||
|
||||
def _build_preview(output_dir: Path, products: List[Dict[str, Any]]) -> None:
|
||||
"""生成 Preview 文件夹:仅成功导入模板的产品(template_path 已设置),
|
||||
复制其 _composite.oss.jpg(压缩版合成图)到 Preview,并生成 result.xlsx
|
||||
(货号 | 中文标题 | 英文标题 三列)。"""
|
||||
import shutil
|
||||
from openpyxl import Workbook
|
||||
preview_dir = output_dir / "Preview"
|
||||
preview_dir.mkdir(parents=True, exist_ok=True)
|
||||
rows: List[tuple] = []
|
||||
for r in products:
|
||||
if not r.get("template_path"):
|
||||
continue
|
||||
code = str(r.get("img_code") or r.get("oss_code") or "")
|
||||
comp = r.get("composite_path") or r.get("printed_path")
|
||||
if comp:
|
||||
oss_file = Path(comp).with_suffix(".oss.jpg")
|
||||
if oss_file.exists():
|
||||
dst = preview_dir / oss_file.name
|
||||
if not dst.exists():
|
||||
shutil.copy2(oss_file, dst)
|
||||
rows.append((code, r.get("cn_title") or "", r.get("en_title") or ""))
|
||||
if rows:
|
||||
wb = Workbook()
|
||||
ws = wb.active
|
||||
ws.title = "result"
|
||||
ws.append(["货号", "中文标题", "英文标题"])
|
||||
for row in rows:
|
||||
ws.append(list(row))
|
||||
wb.save(str(preview_dir / "result.xlsx"))
|
||||
print(f"[template] Preview 已生成({len(rows)} 个成功产品): {preview_dir}")
|
||||
|
||||
|
||||
@with_fallback("template_export")
|
||||
def template_export_node(state: Dict[str, Any]) -> Dict[str, Any]:
|
||||
products: List[Dict[str, Any]] = state.get("product") or []
|
||||
@@ -68,7 +100,8 @@ def template_export_node(state: Dict[str, Any]) -> Dict[str, Any]:
|
||||
break
|
||||
|
||||
from graph.template_export import (export_products, _resolve_component_map,
|
||||
_resolve_season_map, _resolve_pattern_map)
|
||||
_resolve_season_map, _resolve_pattern_map,
|
||||
_resolve_target_audience_map, _resolve_kids_type_map)
|
||||
tdir = (pcfg.get("template_dir") or "").strip() or str(Path(tp).parent)
|
||||
prod_dir = output_dir / "product"
|
||||
prod_dir.mkdir(parents=True, exist_ok=True)
|
||||
@@ -124,12 +157,15 @@ def template_export_node(state: Dict[str, Any]) -> Dict[str, Any]:
|
||||
component_map=_resolve_component_map(config),
|
||||
season_map=_resolve_season_map(config),
|
||||
pattern_map=_resolve_pattern_map(config),
|
||||
target_audience_map=_resolve_target_audience_map(config),
|
||||
kids_type_map=_resolve_kids_type_map(config),
|
||||
)
|
||||
for r in products:
|
||||
if (r.get("composite_path") or r.get("printed_path")) and (r.get("en_title") or "").strip():
|
||||
r["template_path"] = str(out)
|
||||
exported.append(str(out))
|
||||
print(f"[template] 商品上传模板已生成({len(batch)} 个产品一次合并): {out}")
|
||||
_build_preview(output_dir, products)
|
||||
except Exception as e: # noqa: BLE001
|
||||
errors.append({"node": "template_export", "type": type(e).__name__,
|
||||
"message": f"模板批量导出失败: {e}", "trace": ""})
|
||||
|
||||
Reference in New Issue
Block a user