v92-v105 多国适配 + 模板导出增强 + 生图可靠性优化

- 新增韩国(KR)适配:countries/pinterest 种子词、K-pop 提示词、UI 国家列表
- 爬虫跨运行持久化已采集 URL(.collected_urls.json),同关键词重复搜索采新图
- 模板导出增强:SPU 商品属性列名前缀剥离匹配、尺码下拉框 INDIRECT 动态引用、
  SPU 字段映射(袖长/门襟/胸垫等)、季节/印花图案女装映射、建议售价统一必填、
  SKU 分类/数量/单位直接填默认值
- 自定义模式:多模态提示词独立(custom_analyze_*)、生图提示词模板可配置
- Pinterest:空选品守卫、连续空分析保护(max_empty_analyze)、flat_prompt 配置覆盖
- 生图可靠性:开始/完成进度日志、异步任务轮询超时 60s→300s
This commit is contained in:
2026-08-31 18:35:51 +08:00
parent 71a48e4ed5
commit 3dc594cf57
29 changed files with 1369 additions and 321 deletions
+18 -6
View File
@@ -81,6 +81,12 @@ def _pinterest_route(state: Dict[str, Any]) -> str:
if max_rounds <= 0:
max_rounds = max(target * 2, 5)
# 简报已达目标 → 停止补分析,直接收尾出模板(即使用户图池还有未消费图片也不再分析,
# 避免目标简报数的小任务把整池图分析成冗余简报、浪费配额)
if len(briefs) >= target:
print(f"[pinterest_route] 简报已达目标 {len(briefs)}/{target},停止补分析,结束(将收尾出模板)")
return "done"
# 简报池还有待处理/在途简报 → 先让后台消化,不分析新图也不采集
if pipe is not None and hasattr(pipe, "pending_count"):
pending = pipe.pending_count()
@@ -88,7 +94,7 @@ def _pinterest_route(state: Dict[str, Any]) -> str:
# 日志由 pinterest_wait 节点进入时统一打印(阻塞等待消化,避免此处高频刷屏)
return "wait"
# 简报池空闲 → 检查图池还有未消费图片 → 补分析(不管简报离目标差多少,先把这批用完
# 简报池空闲 + 简报未达标 + 图池还有未消费图片 → 补分析(缺口批大小由 analyze_node 按 target 收敛
try:
from graph.pinterest import load_image_pool, load_used_images, pool_unused_images
pool = load_image_pool(str(state.get("output_dir") or ""), state.get("country") or "")
@@ -96,16 +102,22 @@ def _pinterest_route(state: Dict[str, Any]) -> str:
unused = pool_unused_images(pool, used)
except Exception: # noqa: BLE001
unused = []
# 连续多轮图片分析无新增简报(分析失败 / 图片均不适合印花)→ 视为无法生成,
# 直接收尾,避免"取下一张参考图"式无限空转
max_empty = int(pcfg.get("max_empty_analyze") or 0)
if max_empty <= 0:
max_empty = max(target + 2, 3)
empty = int(state.get("pinterest_empty_rounds") or 0)
if empty >= max_empty:
print(f"[pinterest_route] 连续 {empty} 轮图片分析无新增简报(目标 {len(briefs)}/{target} 条简报未达标),"
f"无法生成 → 放弃补分析,直接收尾(不再逐一取下一张参考图)")
return "done"
if unused:
print(f"[pinterest_route] 简报池空闲,图池还有 {len(unused)} 张未消费图片,补分析"
f"(简报 {len(briefs)}/{target}")
return "analyze"
# 简报池空闲 + 图池空 → 检查简报是否已达标
if len(briefs) >= target:
print(f"[pinterest_route] 图池已空,简报已达目标 {len(briefs)}/{target},结束")
return "done"
# 简报池空闲 + 图池空 + 简报不达标 → 新一轮搜索采集
if rounds >= max_rounds:
print(f"[pinterest_route] 已达最大轮次 {max_rounds},图池已空,简报 {len(briefs)}/{target},按现有结果继续")