修复种草图生成:以三合一主图为参考 img2img 生成,按颜色分配(每色优先、超出随机补足);新增 BR/CA/DE/ES/IT/PL/SA 七国配置与提示词;删除验证用测试脚本

This commit is contained in:
2026-08-24 14:02:19 +08:00
parent f493bde8a9
commit 3c341d2e78
51 changed files with 2571 additions and 514 deletions
+1
View File
@@ -1,4 +1,5 @@
# 构建产物 # 构建产物
dist/
dist_*/ dist_*/
build*/ build*/
build_clean*/ build_clean*/
+7 -1
View File
@@ -4,7 +4,13 @@
a = Analysis( a = Analysis(
['ui_app.py'], ['ui_app.py'],
pathex=[], pathex=[],
binaries=[], # 显式指定 conda 的 OpenSSL DLL3.5.6,与 _ssl.pyd 匹配)。
# 若不指定,PyInstaller 会从 PATH 找到 MySQL Server 8.0 自带的 OpenSSL 3.0.15
# 导致 _ssl 加载失败:DLL load failed while importing _ssl。
binaries=[
('C:\\Users\\Admin\\miniconda3\\Library\\bin\\libssl-3-x64.dll', '.'),
('C:\\Users\\Admin\\miniconda3\\Library\\bin\\libcrypto-3-x64.dll', '.'),
],
datas=[('config.yaml', '.'), ('configs', 'configs'), ('prompts', 'prompts'), datas=[('config.yaml', '.'), ('configs', 'configs'), ('prompts', 'prompts'),
('templates', 'templates'), ('basemap', 'basemap'), ('templates', 'templates'), ('basemap', 'basemap'),
('material_library', 'material_library')], ('material_library', 'material_library')],
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

+30 -11
View File
@@ -1,12 +1,19 @@
# ===== POD 热点抓取 Agent 配置(LangGraph 工程化版)===== # ===== POD 热点抓取 Agent 配置(LangGraph 工程化版)=====
# 目标国家(Google Trends 地区代码:US / GB / JP / AU / MX ... # 目标国家(Google Trends 地区代码:US / GB / JP / AU / MX / DE / BR / SA / PL / ES / IT / CA ...
countries: countries:
- US - US
- GB - GB
- JP - JP
- AU - AU
- MX - MX
- DE
- BR
- SA
- PL
- ES
- IT
- CA
# —— 可插拔数据源 —— # —— 可插拔数据源 ——
# 在 graph/sources/ 注册表里登记;这里列出要启用的。 # 在 graph/sources/ 注册表里登记;这里列出要启用的。
@@ -22,8 +29,7 @@ sources:
# static: 仅用 yaml 写死种子,零动态(保留兼容,UI 未列出)。 # static: 仅用 yaml 写死种子,零动态(保留兼容,UI 未列出)。
seed_provider: mock seed_provider: mock
seed_provider_cfg: seed_provider_cfg:
max_style_seeds: 12 # style 种子总数上限(动态分配:固定种子优先 → 节日/月份主题 → 动态补位 max_seeds: 24 # 种子总数上限(不再按类型分:从全部种子词统一池随机抽取,均分 style/related
max_related_seeds: 12 # related 种子总数上限(同上)
trending_context_limit: 15 trending_context_limit: 15
history_limit: 20 history_limit: 20
@@ -88,7 +94,7 @@ llm_screen:
provider: openai # openai(真 LLM,需 key/ mock(无 key 启发式兜底) provider: openai # openai(真 LLM,需 key/ mock(无 key 启发式兜底)
api_key: "sk-ws-H.EPXPIER.vRMT.MEUCIQDji_AHGl-EekYOftdLxEvFl2ZqCNtLDSp3Bqnaz0SRpgIgI4qPeVyIMMzutl9JakuYRv3zmFxkwc12c4aBcIL1gqE" # 留空则自动读取环境变量 LLM_API_KEY / OPENAI_API_KEY(推荐,避免密钥入库) api_key: "sk-ws-H.EPXPIER.vRMT.MEUCIQDji_AHGl-EekYOftdLxEvFl2ZqCNtLDSp3Bqnaz0SRpgIgI4qPeVyIMMzutl9JakuYRv3zmFxkwc12c4aBcIL1gqE" # 留空则自动读取环境变量 LLM_API_KEY / OPENAI_API_KEY(推荐,避免密钥入库)
base_url: "https://ws-5rfjflubus647o7t.cn-beijing.maas.aliyuncs.com/compatible-mode/v1" # 自定义网关地址,也可用环境变量 LLM_BASE_URL 覆盖 base_url: "https://ws-5rfjflubus647o7t.cn-beijing.maas.aliyuncs.com/compatible-mode/v1" # 自定义网关地址,也可用环境变量 LLM_BASE_URL 覆盖
model: "qwen3.7-max-preview" # 自定义模型名(任意 OpenAI 兼容模型) model: "qwen3.7-plus-2026-05-26" # 自定义模型名(任意 OpenAI 兼容模型)
temperature: 0.6 temperature: 0.6
max_topics_per_call: 12 max_topics_per_call: 12
min_score: 0.0 min_score: 0.0
@@ -122,6 +128,20 @@ DESIGN CONTENT: {motif}, {art_style}, {color_palette}, {composition}."
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, AU-market aesthetic: laid-back coastal and outdoor vibe, nature-inspired, bright fresh energy, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a small slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names" image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, AU-market aesthetic: laid-back coastal and outdoor vibe, nature-inspired, bright fresh energy, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a small slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
MX: MX:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, MX-market aesthetic: vibrant mexican folk art, sugar skull / loteria / aztec motifs, fiesta colors, festive cultural pride mood, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a Spanish slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names" image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, MX-market aesthetic: vibrant mexican folk art, sugar skull / loteria / aztec motifs, fiesta colors, festive cultural pride mood, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a Spanish slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
DE:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, DE-market aesthetic: bavarian-alpine folk charm, berlin street-art edge, bauhaus minimalism, cozy beer-garden and christmas-market mood, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a German slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
BR:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, BR-market aesthetic: vibrant tropical carnival energy, samba rhythm, football passion, bold beach and street-art colors, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a Portuguese slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
SA:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, SA-market aesthetic: elegant desert minimalism, arabian geometric patterns, falconry and starry-night calm, refined and conservative mood, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or an Arabic slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
PL:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, PL-market aesthetic: highland folk embroidery charm, wycinanki paper-cut patterns, slavic forest mystique, retro polish poster mood, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a Polish slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
ES:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, ES-market aesthetic: flamenco passion, andalusian tile patterns, mediterranean sunshine, festive fiesta energy, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a Spanish slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
IT:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, IT-market aesthetic: renaissance elegance, roman heritage, tuscan countryside warmth, la dolce vita retro charm, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or an Italian slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
CA:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, CA-market aesthetic: maple-leaf pride, northern-lights wonder, rocky-mountain outdoors, cozy cottage and hockey spirit, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a French slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
# —— 第三阶段 compose:生成纯印花设计稿 + 导出简报包(在 product 之前)—— # —— 第三阶段 compose:生成纯印花设计稿 + 导出简报包(在 product 之前)——
# 用前 N 个 safe 简报的 image_prompt 调图像后端文生图,产物 output/<country>/designs/ # 用前 N 个 safe 简报的 image_prompt 调图像后端文生图,产物 output/<country>/designs/
@@ -146,15 +166,14 @@ oss:
oss_key_secret: "2Q25JohOI4GmovszvIw1NuVvUzM6PB" oss_key_secret: "2Q25JohOI4GmovszvIw1NuVvUzM6PB"
enabled: true # false = 跳过上传(本地仅压缩或完全跳过) enabled: true # false = 跳过上传(本地仅压缩或完全跳过)
# —— 第六阶段 seed_shot:种草图生成(在 oss_upload 之后)—— # —— 第六阶段 seed_shot:种草图选取(在 oss_upload 之后)——
# 模板:configs/seed_shot_templates.yaml(提示词,占位符 [商品名称]/[材质]/[模特特征],可自定义添加) # 种草图不再用 AI 重新生成,而是从 product 已生成的三合一主图(每颜色一张)中按 count 随机选取:
# 模特特征:configs/model_features.yaml(随机取一条,可自定义添加 # - count <= 颜色数:随机取 count 个不同颜色(优先保证每色主图都有一张
# [商品名称] ← product 的 cn_title[材质] ← db SPU.material[模特特征] ← yaml 随机 # - count > 颜色数:每色一张 + 从全部主图中随机补足(可重复)
# 种草图同样压缩上传 OSS(货号计数与 oss_upload 共用续接)。 # 选取的种草图压缩上传 OSS(货号计数与 oss_upload 共用续接)URL 写入模板「详情图文」列
seed_shot: seed_shot:
enabled: true enabled: true
count: 1 # 每个产品生成几张种草图(传入数量即可) count: 1 # 每个产品选取几张种草图(从三合一主图中随机取,传入数量即可)
size: "1536×2048" # 种草图尺寸(统一读取此配置,不再硬编码)
# —— 第四阶段 product:热点 → SPU/颜色选品 → 底图 → 三图合成(图1模特+图2设计稿+图3底图)→ 模板 —— # —— 第四阶段 product:热点 → SPU/颜色选品 → 底图 → 三图合成(图1模特+图2设计稿+图3底图)→ 模板 ——
# 数据关系:SPU.code=款号,SKU.code="款号-颜色编码"(如 DG004-BL01), # 数据关系:SPU.code=款号,SKU.code="款号-颜色编码"(如 DG004-BL01),
+64 -5
View File
@@ -1,8 +1,6 @@
# 澳大利亚专属数据源配置
trending: trending:
enabled: true enabled: true
limit: 40 limit: 40
style: style:
enabled: true enabled: true
seeds: seeds:
@@ -18,7 +16,59 @@ style:
- paw prints - paw prints
- moon and stars - moon and stars
- cozy vibes - cozy vibes
- kangaroo
- koala
- aussie slang
- vegemite
- barbecue
- reef coral
- bush walk
- wattle
- cricket
- footy
- sundowner
- boomerang
- farm life
- seagull
- lamington
- pavlova
- op shop retro
- uluru
- sydney opera house
- sydney harbour bridge
- bondi beach
- great barrier reef
- wombat
- platypus
- echidna
- dingo
- emu
- kookaburra
- cockatoo
- fairy penguin
- sea turtle
- whale shark
- saltwater crocodile
- meat pie
- sausage roll
- fairy bread
- anzac biscuit
- damper
- billy tea
- akubra hat
- afl
- rugby league
- surf lifesaving
- beach cricket
- snorkelling
- sailing
- eucalyptus
- gum tree
- bottlebrush
- waratah
- kangaroo paw
- frangipani
- southern cross
related: related:
enabled: true enabled: true
seed_keywords: seed_keywords:
@@ -28,5 +78,14 @@ related:
- beach art - beach art
- retro travel - retro travel
- floral - floral
- aussie wildlife
timeframe: "today 3-m" - outback art
- retro australia
- surf retro
- coastal art
- australian food
- native plants
- beach retro
- sydney art
- reef art
timeframe: today 3-m
+95
View File
@@ -0,0 +1,95 @@
# 巴西专属数据源配置(configs/countries/BR.yaml
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- tropical
- amazon rainforest
- samba
- carnival
- rio de janeiro
- copacabana
- beach sunset
- surf
- football fan
- jiu jitsu
- capoeira
- parrot
- toucan
- macaw
- jaguar
- sloth
- capybara
- pineapple
- coconut palm
- acai bowl
- caipirinha
- street art
- graffiti
- bossa nova
- forro
- tropical flowers
- hibiscus
- palm trees
- samba dancer
- carnival mask
- confetti
- favela art
- amazon river
- jungle wildlife
- hummingbird
- sunset beach
- brazilian coffee
- brigadeiro
- ipanema
- sugarloaf mountain
- christ the redeemer
- iguaçu falls
- pantanal
- pink river dolphin
- anaconda
- piranha
- blue morpho butterfly
- poison dart frog
- caiman
- pão de queijo
- feijoada
- churrasco
- coxinha
- pastel
- tapioca
- acarajé
- moqueca
- maracujá
- passion fruit
- mango tree
- banana leaf
- monstera
- orchids
- festa junina
- sertanejo
- funk carioca
- pandeiro
- berimbau
related:
enabled: true
seed_keywords:
- tropical vintage
- brazilian street art
- samba pattern
- rio retro
- amazon wildlife
- beach vibes
- brazilian food
- carnival colors
- jungle leaves
- sunset palm
- brazilian wildlife
- rio de janeiro art
- brazilian music
- tropical leaves
- festa junina
- brazilian retro
timeframe: today 3-m
+95
View File
@@ -0,0 +1,95 @@
# 加拿大专属数据源配置(configs/countries/CA.yaml
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- maple leaf
- maple syrup
- moose
- beaver
- polar bear
- northern lights
- aurora borealis
- rocky mountains
- banff
- lake louise
- pine forest
- canoe
- kayak
- camping
- hiking
- snowboarding
- skiing
- hockey
- ice skating
- winter
- snowflake
- log cabin
- poutine
- butter tart
- canadian wildlife
- loon
- whale
- orca
- salmon
- french canada
- quebec
- old quebec
- montreal
- toronto skyline
- cn tower
- vancouver
- pacific coast
- lobster
- fishing
- cottage
- lake life
- fall colors
- autumn leaves
- hockey stick
- ice fishing
- snowmobile
- lumberjack
- plaid
- flannel
- mountie
- snowy owl
- bald eagle
- puffin
- beluga
- narwhal
- caribou
- muskox
- arctic fox
- niagara falls
- jasper
- moraine lake
- whistler
- tofino
- vancouver island
- st lawrence river
- sugar shack
- maple taffy
- curling
related:
enabled: true
seed_keywords:
- canadian wildlife
- northern lights
- maple leaf
- rocky mountains
- cottage country
- winter sports
- canadian retro
- french canada
- autumn leaves
- lake life
- canadian birds
- winter wonderland
- canadian food
- mountain lakes
- east coast art
- maple syrup art
timeframe: today 3-m
+95
View File
@@ -0,0 +1,95 @@
# 德国专属数据源配置(configs/countries/DE.yaml
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- lederhosen
- bavarian
- alpine
- black forest
- cuckoo clock
- pretzel
- german beer
- bratwurst
- sauerkraut
- berlin street art
- bauhaus
- industrial minimal
- german typography
- gothic
- medieval castle
- neuschwanstein
- viking
- nordic
- forest hiking
- mountain lake
- cycling
- football fan
- christmas market
- stollen
- dirndl
- edelweiss
- techno music
- berlin wall
- east berlin retro
- trabi car
- ampelmann
- german shepherd
- schnauzer
- wild boar
- red fox
- autumn forest
- river rhine
- harbor lighthouse
- stork
- bavarian alps
- zugspitze
- beer garden
- weisswurst
- currywurst
- schnitzel
- spätzle
- apfelstrudel
- black forest cake
- marzipan
- lebkuchen
- glühwein
- nutcracker
- brandenburg gate
- fernsehturm
- cologne cathedral
- hamburg harbor
- heidelberg castle
- romantic road
- dachshund
- great dane
- deer stag
- lynx
- wolf
- black eagle
- fraktur
- german expressionism
- krautrock
- oompah band
related:
enabled: true
seed_keywords:
- bavarian pattern
- alpine vintage
- german humor
- berlin retro
- retro gdr
- nordic minimal
- german food
- mountain hiking
- medieval knight
- christmas market
- german wildlife
- bavarian alps
- berlin art
- german castle
- autobahn retro
- beer garden
timeframe: today 3-m
+95
View File
@@ -0,0 +1,95 @@
# 西班牙专属数据源配置(configs/countries/ES.yaml
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- flamenco
- flamenco dress
- andalusia
- seville
- azulejo
- spanish tile
- gaudi
- barcelona
- sagrada familia
- tapas
- paella
- jamon
- olive
- olive tree
- bull
- castanets
- spanish guitar
- siesta
- fiesta
- tomato festival
- carnival
- valencia
- mediterranean
- costa brava
- ibiza
- flamenco dancer
- mantilla
- hand fan
- moorish
- alhambra
- gothic
- renaissance
- sangria
- churros
- siesta cat
- mediterranean coast
- spanish villa
- orange tree
- bullring
- sevillanas
- granada
- cordoba
- ronda
- white villages
- park guell
- casa batllo
- las ramblas
- tortilla espanola
- patatas bravas
- croquetas
- gazpacho
- salmorejo
- pulpo
- calamares
- manchego
- chorizo
- empanada
- turron
- polvorones
- iberian lynx
- spanish ibex
- flamingo
- imperial eagle
- griffon vulture
- sunflower fields
- almond blossom
- olive grove
- vineyard
related:
enabled: true
seed_keywords:
- spanish tile pattern
- flamenco art
- mediterranean vibes
- andalusian pattern
- spanish food
- gaudi style
- costa del sol
- spanish retro
- olive branch
- fiesta colors
- spanish wildlife
- mediterranean coast art
- spanish architecture
- tapas art
- iberian nature
- spanish vintage
timeframe: today 3-m
+64 -5
View File
@@ -1,8 +1,6 @@
# 英国专属数据源配置
trending: trending:
enabled: true enabled: true
limit: 40 limit: 40
style: style:
enabled: true enabled: true
seeds: seeds:
@@ -18,7 +16,59 @@ style:
- paw prints - paw prints
- moon and stars - moon and stars
- cozy vibes - cozy vibes
- heritage
- london skyline
- britpop
- mod style
- tea time
- pub sign
- coastal britain
- canal narrowboat
- classic british cars
- seaside pier
- english garden
- countryside walk
- tartan plaid
- victorian pattern
- fish and chips
- rainy day humor
- morris dancing
- big ben
- tower bridge
- red double decker bus
- london taxi
- queen's guard
- buckingham palace
- stonehenge
- scottish highlands
- loch ness
- edinburgh castle
- welsh dragon
- afternoon tea
- scones
- full english breakfast
- sunday roast
- yorkshire pudding
- bangers and mash
- shepherd's pie
- thatched cottage
- country pub
- rose garden
- lavender field
- corgi
- bulldog
- robin
- red squirrel
- hedgehog
- badger
- white cliffs of dover
- lake district
- cotswolds
- cornwall coast
- bonfire night
- fireworks
- christmas pudding
- red telephone box
related: related:
enabled: true enabled: true
seed_keywords: seed_keywords:
@@ -28,5 +78,14 @@ related:
- skull head - skull head
- england retro - england retro
- retro shirt - retro shirt
- british wildlife
timeframe: "today 3-m" - london retro
- union jack pattern
- english garden art
- seaside retro
- pub sign art
- royal heritage
- countryside art
- britpop retro
- tea time art
timeframe: today 3-m
+95
View File
@@ -0,0 +1,95 @@
# 意大利专属数据源配置(configs/countries/IT.yaml
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- italian renaissance
- rome
- colosseum
- venice
- gondola
- canals
- tuscany
- tuscan hills
- cypress
- sunflower
- pizza
- pasta
- spaghetti
- espresso
- italian coffee
- gelato
- tiramisu
- limoncello
- amalfi coast
- lemon
- lemon tree
- vesuvius
- pompeii
- la dolce vita
- italian sports car
- opera
- venetian mask
- carnival of venice
- italian mosaic
- roman mosaic
- gladiator
- roman soldier
- laurel wreath
- olive branch
- mediterranean
- italian riviera
- portofino
- sicily
- trulli
- leaning tower
- florence
- italian typography
- vintage italy
- retro italian
- pantheon
- trevi fountain
- spanish steps
- roman forum
- aqueduct
- centurion
- st mark's square
- rialto bridge
- murano glass
- burano
- chianti
- san gimignano
- siena
- val d'orcia
- lasagna
- ravioli
- tortellini
- risotto
- carbonara
- pesto
- mozzarella
- burrata
- prosciutto
- panettone
related:
enabled: true
seed_keywords:
- italian vintage
- venetian mask
- tuscan countryside
- italian food
- roman empire
- mediterranean coast
- renaissance art
- espresso culture
- italian retro
- amalfi coast
- italian wildlife
- italian architecture
- dolce vita art
- italian wine
- mediterranean art
- italian design
timeframe: today 3-m
+65 -5
View File
@@ -1,8 +1,6 @@
# 日本专属数据源配置
trending: trending:
enabled: true enabled: true
limit: 40 limit: 40
style: style:
enabled: true enabled: true
seeds: seeds:
@@ -18,7 +16,60 @@ style:
- paw prints - paw prints
- moon and stars - moon and stars
- cozy vibes - cozy vibes
- shiba inu
- sakura
- ukiyo e
- torii gate
- maneki neko
- daruma
- koi fish
- bonsai
- origami
- ramen
- sushi
- matcha
- zen minimal
- japanese calligraphy
- yokai
- festival matsuri
- tanuki
- onsen
- mount fuji
- bullet train
- japanese garden
- bamboo forest
- momiji
- kimono
- yukata
- samurai
- ninja
- geisha
- kabuki
- sumo
- karate
- tempura
- okonomiyaki
- takoyaki
- udon
- mochi
- taiyaki
- green tea
- wagashi
- akita
- red-crowned crane
- kitsune
- kappa
- sumi-e
- manga
- chibi
- harajuku
- pagoda
- kinkakuji
- himeji castle
- tokyo skyline
- shibuya crossing
- hanami
- fireworks hanabi
related: related:
enabled: true enabled: true
seed_keywords: seed_keywords:
@@ -28,5 +79,14 @@ related:
- anime tee - anime tee
- minimalist art - minimalist art
- floral - floral
- japanese retro
timeframe: "today 3-m" - ukiyo e art
- japanese food
- zen art
- sakura art
- japanese wildlife
- torii gate art
- manga art
- japanese pattern
- retro japan
timeframe: today 3-m
+63 -5
View File
@@ -1,8 +1,6 @@
# 墨西哥专属数据源配置
trending: trending:
enabled: true enabled: true
limit: 40 limit: 40
style: style:
enabled: true enabled: true
seeds: seeds:
@@ -16,7 +14,62 @@ style:
- mexican folk art - mexican folk art
- chicano - chicano
- cactus - cactus
- alebrije
- papel picado
- talavera
- agave
- fiesta
- sombrero
- folk embroidery
- huarache
- quetzal
- maracas
- charro
- mexican flowers
- colorful birds
- mercado
- catrina
- marigold
- cempasuchil
- ofrenda
- pan de muerto
- aztec calendar
- mayan pyramid
- chichen itza
- teotihuacan
- quetzalcoatl
- jaguar
- feathered serpent
- luchador
- wrestling mask
- serape
- poncho
- rebozo
- taco
- burrito
- enchilada
- quesadilla
- tamale
- pozole
- mole
- elote
- churro
- concha
- horchata
- nopal
- saguaro
- prickly pear
- pitaya
- avocado
- guacamole
- otomi pattern
- huichol art
- axolotl
- xoloitzcuintli
- monarch butterfly
- iguana
- hummingbird
- sea turtle
related: related:
enabled: true enabled: true
seed_keywords: seed_keywords:
@@ -30,5 +83,10 @@ related:
- aztec calendar - aztec calendar
- alebrijes - alebrijes
- lowrider - lowrider
- mexican wildlife
timeframe: "today 3-m" - mexican art
- day of the dead art
- mexican retro
- aztec art
- mexican nature
timeframe: today 3-m
+95
View File
@@ -0,0 +1,95 @@
# 波兰专属数据源配置(configs/countries/PL.yaml
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- highland folklore
- podhale
- goral
- folk embroidery
- wycinanki
- paper cutout
- amber
- european bison
- white eagle
- forest
- lake
- mazury
- baltic sea
- seagull
- pierogi
- oscypek
- tatra mountains
- mountain hiking
- medieval castle
- knight
- slavic mythology
- wawel dragon
- krakow old town
- retro poland
- polish poster
- typography
- mushroom
- wildflowers
- cornflower
- folk pattern
- embroidery pattern
- christmas eve
- gingerbread
- stork
- wolf
- elk
- river vistula
- old town square
- amber jewelry
- folk dance
- zakopane
- highland hut
- sheep
- bryndza
- krakowiak
- polonaise
- mazurka
- boleslawiec pottery
- sea glass
- wisent
- moose
- brown bear
- lynx
- wild boar
- hare
- beaver
- swan
- crane
- kingfisher
- bigos
- żurek
- gołąbki
- kotlet schabowy
- sernik
- makowiec
- paczki
- toruń gingerbread
- kielbasa
related:
enabled: true
seed_keywords:
- polish folk art
- highland pattern
- slavic retro
- amber jewelry
- tatra mountains
- polish food
- folk embroidery
- medieval knight
- baltic coast
- forest wildlife
- polish wildlife
- slavic mythology art
- zakopane style
- baltic amber
- polish retro
- folk pattern art
timeframe: today 3-m
+96
View File
@@ -0,0 +1,96 @@
# 沙特阿拉伯专属数据源配置(configs/countries/SA.yaml
# 保守市场:避免宗教符号/人物形象/酒精/猪/国旗国徽/王室;主打自然、几何、文化氛围。
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- desert
- sand dunes
- camel
- arabian horse
- falcon
- arabic calligraphy
- geometric pattern
- palm tree
- date palm
- oasis
- oud
- arabic coffee
- dates
- bedouin tent
- starry desert night
- red sea
- coral reef
- scuba diving
- riyadh skyline
- futuristic city
- desert fox
- arabian oryx
- gazelle
- falconry
- incense
- henna pattern
- arabic lantern
- arabian nights
- mosaic
- desert rose
- sand art
- dune buggy
- desert sunset
- camel caravan
- star map
- astronomy
- constellation
- desert wildflowers
- alula
- hegra
- edge of the world
- diriyah
- jeddah corniche
- neom
- arabesque
- islamic geometry
- zellige
- mashrabiya
- horseshoe arch
- gahwa
- cardamom
- saffron
- rose water
- mint tea
- kunafa
- baklava
- luqaimat
- kabsa
- shawarma
- falafel
- hummus
- bakhoor
- amber
- jasmine
- flying carpet
- magic lamp
- spice market
- sand cat
related:
enabled: true
seed_keywords:
- arabic geometric
- desert sunset
- camel silhouette
- arabian horse
- falcon art
- henna pattern
- arabic lantern
- oasis palm
- red sea coral
- starry desert
- saudi wildlife
- arabic coffee
- desert art
- red sea life
- arabian nights art
- traditional pattern
timeframe: today 3-m
+63 -6
View File
@@ -1,9 +1,6 @@
# 美国专属数据源配置(覆盖全局默认)
# 种子词已换成短而热门、且贴近 POD 的词,related_queries 才能返回数据。
trending: trending:
enabled: true enabled: true
limit: 40 limit: 40
style: style:
enabled: true enabled: true
seeds: seeds:
@@ -21,7 +18,58 @@ style:
- paw prints - paw prints
- moon and stars - moon and stars
- cozy vibes - cozy vibes
- western cowboy
- coastal cowgirl
- y2k
- retro gaming
- psychedelic
- tie dye
- 90s nostalgia
- minimalist typography
- hand drawn doodle
- botanical line art
- mountain adventure
- camping outdoors
- space astronomy
- astrology zodiac
- surf beach
- art deco
- national parks
- vintage racing
- skater culture
- boho
- bald eagle
- american bison
- grizzly bear
- raccoon
- blue jay
- route 66
- grand canyon
- yellowstone
- new york skyline
- las vegas neon
- cowboy boots
- rodeo
- sheriff star
- wild west saloon
- covered wagon
- baseball
- basketball
- american football
- hot dog
- burger
- apple pie
- retro diner
- neon sign
- road trip
- camper van
- muscle car
- rock and roll
- jazz blues
- country music
- vinyl record
- thanksgiving turkey
- pumpkin patch
related: related:
enabled: true enabled: true
seed_keywords: seed_keywords:
@@ -31,5 +79,14 @@ related:
- anime tee - anime tee
- retro band tee - retro band tee
- skull art - skull art
- american retro
timeframe: "today 3-m" - national park art
- western art
- vintage travel
- retro sports
- diner sign
- american wildlife
- stars and stripes
- road trip art
- coastal retro
timeframe: today 3-m
+39 -49
View File
@@ -1,4 +1,4 @@
# 种草图提示词模板库 —— 跨境电商详情页专用版(正面印花完整展示版) # 种草图提示词模板库 —— 跨境电商详情页专用版(稳定出图+零遮挡强约束版)
# 占位符:[商品名称]、[材质]、[模特特征]、[服装风格] # 占位符:[商品名称]、[材质]、[模特特征]、[服装风格]
# 摄影参数说明:35mm/50mm镜头控制自然透视,f/1.4-f/2.8控制景深虚化,8k强化面料细节,3:4符合电商标准长图比例。 # 摄影参数说明:35mm/50mm镜头控制自然透视,f/1.4-f/2.8控制景深虚化,8k强化面料细节,3:4符合电商标准长图比例。
@@ -8,175 +8,165 @@ seed_shot_templates:
# ========================================== # ==========================================
- name: "纯白背景正面全展示" - name: "纯白背景正面全展示"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在纯白无缝背景纸前,身体正对镜头微侧15度,双手自然下垂,眼神直视镜头,整体呈现[服装风格]的调性,完整展示衣服正面的印花图案与[材质]面料的垂坠感。采用电商标准的高亮柔光,左右各一盏柔光箱消除杂乱阴影,光线均匀分布。画面比例为3:4。商业白底图摄影,50mm镜头,f/2.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特站在纯白无缝背景纸前,身体正对镜头微侧15度,眼神直视镜头,整体呈现[服装风格]的调性,完整展示衣服正面的印花图案与[材质]面料的垂坠感。采用电商标准的高亮柔光,左右各一盏柔光箱消除杂乱阴影,光线均匀分布。画面比例为3:4。商业白底图摄影,50mm镜头,f/2.8光圈,8k分辨率。
- name: "高级浅灰背景全展示" - name: "高级浅灰背景全展示"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在高级浅灰背景纸前,身体正对镜头,双手插兜或自然下垂,姿态略微随性,整体呈现[服装风格]的调性,完整展示衣服正面印花与[材质]的挺括度。采用影棚标准柔光与边缘光结合,背景为干净的低饱和灰色。画面比例为3:4。商业白底摄影,50mm镜头,f/2.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂或单手插兜,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特站在高级浅灰背景纸前,身体正对镜头,姿态略微随性,整体呈现[服装风格]的调性,完整展示衣服正面印花与[材质]的挺括度。采用影棚标准柔光与边缘光结合。画面比例为3:4。商业白底摄影,50mm镜头,f/2.8光圈,8k分辨率。
- name: "纯白背景双手展示下摆" - name: "纯白背景双手展示下摆"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中近景半身构图,模特站在纯白背景纸前,双手捏住衣服下摆两侧向下轻拉展平,确保正面印花完整无遮挡,眼神直视镜头,整体呈现[服装风格]的调性,画面聚焦展示衣服正面印花图案与下摆的缝线工艺。采用影棚高显色柔光箱,突出印花色彩与[材质]的紧密编织纹理。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.0光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须背在身后或自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中近景半身构图,模特站在纯白背景纸前,眼神直视镜头,整体呈现[服装风格]的调性,画面聚焦展示衣服正面印花图案与下摆的缝线工艺。采用影棚高显色柔光箱,突出印花色彩与[材质]的紧密编织纹理。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.0光圈,8k分辨率。
- name: "低饱和克莱因蓝背景棚拍" - name: "低饱和克莱因蓝背景棚拍"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特在低饱和克莱因蓝的无缝背景纸前摆出具有张力的站姿,身体正对镜头,双手自然下垂,整体呈现[服装风格]的调性,突出衣服正面印花图案的视觉冲击力与剪裁,展示[材质]的独特纹理。光线采用双灯硬光与柔光箱结合,形成干净分明的明暗对比。画面比例为3:4。极简主义商业摄影,85mm镜头,f/2.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特在低饱和克莱因蓝的无缝背景纸前摆出具有张力的站姿,身体正对镜头,整体呈现[服装风格]的调性,突出衣服正面印花图案的视觉冲击力与剪裁,展示[材质]的独特纹理。光线采用双灯硬光与柔光箱结合,形成干净分明的明暗对比。画面比例为3:4。极简主义商业摄影,85mm镜头,f/2.8光圈,8k分辨率。
- name: "纯白背景微动态走动展示" - name: "纯白背景微动态走动展示"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在纯白无缝背景纸前,呈现正对镜头的动态走动状态,单手插兜,整体呈现[服装风格]的调性,展示衣服正面印花在动态下的视觉效果与[材质]面料的动态垂坠感。采用影棚高亮柔光,光比干净分明。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂或单手插兜,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特站在纯白无缝背景纸前,呈现正对镜头的动态走动状态,整体呈现[服装风格]的调性,展示衣服正面印花在动态下的视觉效果与[材质]面料的动态垂坠感。采用影棚高亮柔光,光比干净分明。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.8光圈,8k分辨率。
# ========================================== # ==========================================
# 二、 面料与印花特写区(打消购买顾虑) # 二、 面料与印花特写区(打消购买顾虑)
# ========================================== # ==========================================
- name: "纯白背景领口细节特写" - name: "纯白背景领口细节特写"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中近景构图,模特站在纯白背景纸前,双手自然下垂不遮挡印花,整体呈现[服装风格]的调性,画面聚焦展示衣服的领口、袖口等工艺细节与[材质]面料的紧密编织纹理。采用影棚标准高显色柔光箱,光线均匀且突出材质的高密度纹理与亲肤特性。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.0光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中近景构图,模特站在纯白背景纸前,整体呈现[服装风格]的调性,画面聚焦展示衣服的领口、袖口等工艺细节与[材质]面料的紧密编织纹理。采用影棚标准高显色柔光箱,光线均匀且突出材质的高密度纹理与亲肤特性。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.0光圈,8k分辨率。
- name: "逆光面料透气质感展示" - name: "逆光面料透气质感展示"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特在黄昏时分的空旷天台逆光站立,发丝被风吹起,双手插兜,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服在逆光强光下展现出的[材质]面料透光性与柔软质感。光线为日落黄金时刻逆光,边缘形成强烈的轮廓光发丝发亮。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂或单手插兜,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中景半身构图,模特在黄昏时分的空旷天台逆光站立,发丝被风吹起,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服在逆光强光下展现出的[材质]面料透光性与柔软质感。光线为日落黄金时刻逆光,边缘形成强烈的轮廓光发丝发亮。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8光圈,8k分辨率。
- name: "双手拉扯领口弹性展示" - name: "双手拉扯领口弹性展示"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中近景构图,模特站在纯色背景前,双手拉扯衣服领口向下或向两侧拉伸,展示衣服的弹力与防变形属性,整体呈现[服装风格]的调性,凸显[材质]面料的回弹性与结实度。采用高亮柔光,突出面料拉伸时的纹理张力。画面比例为3:4。商业电商摄影,50mm镜头,f/2.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手捏住领口两侧向外轻拉,展示衣服的弹力与防变形属性,绝对不可将手放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中近景构图,模特站在纯色背景前,凸显[材质]面料的回弹性与结实度。采用高亮柔光,突出面料拉伸时的纹理张力。画面比例为3:4。商业电商摄影,50mm镜头,f/2.8光圈,8k分辨率。
- name: "低头凝视正面印花特写" - name: "低头凝视正面印花特写"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特站在纯白背景纸前,微微低头凝视衣服胸前的印花图案,双手自然下垂,整体呈现[服装风格]的调性,画面以斜俯视角度聚焦展示正面印花的色彩细节与[材质]面料的质感。采用影棚顶部柔光与正面补光,突出印花图案的清晰度。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.0光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中景半身构图,模特站在纯白背景纸前,微微低头凝视衣服胸前的印花图案,整体呈现[服装风格]的调性,画面以斜俯视角度聚焦展示正面印花的色彩细节与[材质]面料的质感。采用影棚顶部柔光与正面补光,突出印花图案的清晰度。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.0光圈,8k分辨率。
# ========================================== # ==========================================
# 三、 居家生活场景区(营造松弛感与舒适度) # 三、 居家生活场景区(营造松弛感与舒适度)
# ========================================== # ==========================================
- name: "居家沙发慵懒场景" - name: "居家沙发慵懒场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中远景全身构图,模特慵懒地靠在现代极简风格的客厅布艺沙发上,身体正对镜头微侧,姿态松弛,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的舒适度。室内采用柔和的漫反射自然光,背景为高度虚化的居家环境。画面比例为3:4。柯达Portra 400胶片质感,色彩柔和,35mm镜头,f/2.0光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中远景全身构图,模特慵懒地靠在现代极简风格的客厅布艺沙发上,身体正对镜头微侧,姿态松弛,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的舒适度。室内采用柔和的漫反射自然光,背景为高度虚化的居家环境。画面比例为3:4。柯达Portra 400胶片质感,色彩柔和,35mm镜头,f/2.0光圈,8k分辨率。
- name: "居家落地窗自然光展示" - name: "居家落地窗自然光展示"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特站在高层公寓的落地窗前,单手轻触玻璃,身体正前方对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]亲肤舒适属性。采用日落前的柔和逆光,形成强烈的轮廓光发丝发亮。背景为大虚化的城市楼宇剪影与暖色光晕。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中景半身构图,模特站在高层公寓的落地窗前,单手轻触玻璃,身体正前方对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]亲肤舒适属性。采用日落前的柔和逆光,形成强烈的轮廓光发丝发亮。背景为大虚化的城市楼宇剪影与暖色光晕。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8光圈,8k分辨率。
- name: "周末清晨床头场景" - name: "周末清晨床头场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景构图,模特坐在柔软的双人床上伸懒腰,旁边有凌乱的白色枕头,展现周末清晨的松弛感,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的亲肤无拘束感。室内采用清晨柔和的侧向自然光,背景为高度虚化的卧室家具。画面比例为3:4。日系胶片质感,柯达Portra 400色彩预设,40mm镜头,f/2.0光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂或撑在身后,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中景构图,模特坐在柔软的双人床上伸懒腰,展现周末清晨的松弛感,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的亲肤无拘束感。室内采用清晨柔和的侧向自然光,背景为高度虚化的卧室家具。画面比例为3:4。日系胶片质感,柯达Portra 400色彩预设,40mm镜头,f/2.0光圈,8k分辨率。
- name: "居家厨房烹饪场景" - name: "居家厨房烹饪场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中远景全身构图,模特站在现代开放式厨房的中岛台前切水果,身体正对镜头微侧,姿态放松自然,整体呈现[服装风格]的调性,展示衣服正面印花在居家生活中的百搭属性与[材质]面料的舒适耐穿度。室内采用明亮的漫反射自然光与暖色室内灯,背景为高度虚化的厨房台面与绿植。画面比例为3:4。清透氧气感色彩,索尼A7R4画质,50mm镜头,f/1.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂或单手操作厨具,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中远景全身构图,模特站在现代开放式厨房的中岛台前切水果,身体正对镜头微侧,姿态放松自然,整体呈现[服装风格]的调性,展示衣服正面印花在居家生活中的百搭属性与[材质]面料的舒适耐穿度。室内采用明亮的漫反射自然光与暖色室内灯,背景为高度虚化的厨房台面与绿植。画面比例为3:4。清透氧气感色彩,索尼A7R4画质,50mm镜头,f/1.8光圈,8k分辨率。
- name: "周末居家阅读场景" - name: "周末居家阅读场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特盘腿坐在卧室的羊毛地毯上,身体正对镜头微侧,双手捧着一本书但不遮挡胸口印花,整体呈现[服装风格]的调性,展示衣服正面印花图案与[材质]面料的柔软亲肤感。室内采用柔和的窗光侧逆光,背景为高度虚化的卧室床铺与暖色氛围灯。画面比例为3:4。日系胶片质感,柯达Portra 400色彩预设,40mm镜头,f/2.0光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须捧书放在腿上,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中景半身构图,模特盘腿坐在卧室的羊毛地毯上,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花图案与[材质]面料的柔软亲肤感。室内采用柔和的窗光侧逆光,背景为高度虚化的卧室床铺与暖色氛围灯。画面比例为3:4。日系胶片质感,柯达Portra 400色彩预设,40mm镜头,f/2.0光圈,8k分辨率。
# ========================================== # ==========================================
# 四、 户外休闲/运动场景区(展现百搭与透气) # 四、 户外休闲/运动场景区(展现百搭与透气)
# ========================================== # ==========================================
- name: "阳光草坪户外实拍" - name: "阳光草坪户外实拍"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身动态抓拍构图,模特单手插兜,行走在阳光斑驳的城市林荫道上,身体正对镜头微侧,微微低头微笑,呈现不经意的随性状态,整体展现[服装风格]的氛围,凸显[材质]在自然行动中的透气与百搭。午后阳光透过树叶洒下丁达尔光斑与树影,背景为高度虚化的过往行人与都市街景。画面比例为3:4。徕卡Q2摄影质感,高对比度色彩,35mm镜头,f/1.7大光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂或单手插兜,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身动态抓拍构图,模特行走在阳光斑驳的城市林荫道上,身体正对镜头微侧,微微低头微笑,呈现不经意的随性状态,整体展现[服装风格]的氛围,凸显[材质]在自然行动中的透气与百搭。午后阳光透过树叶洒下丁达尔光斑与树影,背景为高度虚化的过往行人与都市街景。画面比例为3:4。徕卡Q2摄影质感,高对比度色彩,35mm镜头,f/1.7大光圈,8k分辨率。
- name: "都市街头OOTD穿搭展示" - name: "都市街头OOTD穿搭展示"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在现代商业街区或美术馆外墙前,单手拿着外带咖啡杯放在胸前不遮挡印花,身体正对镜头微靠在墙上,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的抗皱性。采用午后天光与建筑反射光,画面明亮通透,背景为高度虚化的都市街景与阳光光斑。画面比例为3:4。清透氧气感色彩,索尼A7R4画质,50mm镜头,f/1.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂或单手拿咖啡杯放在腰侧,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特站在现代商业街区或美术馆外墙前,身体正对镜头微靠在墙上,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的抗皱性。采用午后天光与建筑反射光,画面明亮通透,背景为高度虚化的都市街景与阳光光斑。画面比例为3:4。清透氧气感色彩,索尼A7R4画质,50mm镜头,f/1.8光圈,8k分辨率。
- name: "天台蓝天白云清透场景" - name: "天台蓝天白云清透场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在无遮挡的空旷天台上,背景是大面积的蓝天白云,模特双手自然下垂或交叉抱胸但不遮挡印花,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的透气感。正午明亮的顺光,无死角的展现服装颜色,背景为高饱和的纯蓝天空。画面比例为3:4。徕卡Q2摄影质感,35mm镜头,f/2.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特站在无遮挡的空旷天台上,背景是大面积的蓝天白云,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的透气感。正午明亮的顺光,无死角的展现服装颜色。画面比例为3:4。徕卡Q2摄影质感,35mm镜头,f/2.8光圈,8k分辨率。
- name: "自然公园休闲外景" - name: "自然公园休闲外景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在阳光充足的公园草坪前,微风吹拂发丝,微微仰头感受自然,身体正对镜头微侧,双手自然下垂,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的透气性与轻盈感。光线为明亮的顺光搭配自然反光,画面明亮通透,背景为大面积虚化的鲜绿植被与光斑。画面比例为3:4。清透氧气感色彩,索尼A7R4画质,85mm镜头,f/1.8光圈,清新高调摄影,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特站在阳光充足的公园草坪前,微风吹拂发丝,微微仰头感受自然,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的透气性与轻盈感。光线为明亮的顺光搭配自然反光,画面明亮通透,背景为大面积虚化的鲜绿植被与光斑。画面比例为3:4。清透氧气感色彩,索尼A7R4画质,85mm镜头,f/1.8光圈,清新高调摄影,8k分辨率。
- name: "街头滑板运动场景" - name: "街头滑板运动场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身动态抓拍构图,模特单脚踩着滑板停在滑板公园的U型池边缘,身体正对镜头,微风吹拂发丝,双手自然下垂,呈现不经意的随性状态,整体展现[服装风格]的氛围,展示衣服正面印花与[材质]的运动属性。午后强烈的阳光形成侧逆光,背景为高度虚化的水泥滑板池与涂鸦墙。画面比例为3:4。徕卡Q2摄影质感,35mm镜头,f/1.7光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身动态抓拍构图,模特单脚踩着滑板停在滑板公园的U型池边缘,身体正对镜头,微风吹拂发丝,呈现不经意的随性状态,整体展现[服装风格]的氛围,展示衣服正面印花与[材质]的运动属性。午后强烈的阳光形成侧逆光,背景为高度虚化的水泥滑板池与涂鸦墙。画面比例为3:4。徕卡Q2摄影质感,35mm镜头,f/1.7光圈,8k分辨率。
- name: "阳光林荫道骑行场景" - name: "阳光林荫道骑行场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身动态抓拍构图,模特骑着一辆复古自行车停在两旁长满梧桐树的林荫小道上,单脚点地,转头看向镜头微笑,身体正对镜头,双手握把不遮挡印花,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的透气性。午后阳光透过树叶洒下丁达尔光斑,背景为高度虚化的树干与光斑。画面比例为3:4。日系胶片质感,柯达Portra 400色彩预设,40mm镜头,f/2.0光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须握把且手肘外展不遮挡胸口,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身动态抓拍构图,模特骑着一辆复古自行车停在两旁长满梧桐树的林荫小道上,单脚点地,转头看向镜头微笑,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的透气性。午后阳光透过树叶洒下丁达尔光斑,背景为高度虚化的树干与光斑。画面比例为3:4。日系胶片质感,柯达Portra 400色彩预设,40mm镜头,f/2.0光圈,8k分辨率。
- name: "海边漫步度假场景" - name: "海边漫步度假场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身动态抓拍构图,模特走在细软的沙滩上,海风吹起衣摆,双手自然张开,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的轻盈与夏日属性。光线为正午强烈的顺光,画面明亮高调,背景为高度虚化的蔚蓝海水、白沙滩与远处海平线。画面比例为3:4。索尼A7R4画质,35mm镜头,f/2.0光圈,高饱和度清透色彩,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然张开或下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身动态抓拍构图,模特走在细软的沙滩上,海风吹起衣摆,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的轻盈与夏日属性。光线为正午强烈的顺光,画面明亮高调,背景为高度虚化的蔚蓝海水、白沙滩与远处海平线。画面比例为3:4。索尼A7R4画质,35mm镜头,f/2.0光圈,高饱和度清透色彩,8k分辨率。
- name: "露营帐篷森系户外场景" - name: "露营帐篷森系户外场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特坐在森林空地的露营椅上,旁边有燃烧的篝火和搭好的金字塔帐篷,双手端着搪瓷杯放在腿上不遮挡印花,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的保暖性。采用黄昏暖色篝火光与天光交织,背景为高度虚化的茂密松林与烟雾。画面比例为3:4。复古胶片质感,35mm镜头,f/1.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须端着搪瓷杯放在腿上,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特坐在森林空地的露营椅上,旁边有燃烧的篝火和搭好的金字塔帐篷,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的保暖性。采用黄昏暖色篝火光与天光交织,背景为高度虚化的茂密松林与烟雾。画面比例为3:4。复古胶片质感,35mm镜头,f/1.8光圈,8k分辨率。
- name: "海风度假场景展示" - name: "海风度假场景展示"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特赤脚走在浅水沙滩上,海风吹起衣摆,双手自然张开,笑容明朗,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的轻盈与飘逸感。光线为正午到下午的明亮阳光,海面反光形成自然补光,背景为高度虚化的蔚蓝大海、白沙滩与天空。画面比例为3:4。夏日清透色彩,高饱和度,35mm镜头,f/2.0光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然张开,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特赤脚走在浅水沙滩上,海风吹起衣摆,笑容明朗,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的轻盈与飘逸感。光线为正午到下午的明亮阳光,海面反光形成自然补光,背景为高度虚化的蔚蓝大海、白沙滩与天空。画面比例为3:4。夏日清透色彩,高饱和度,35mm镜头,f/2.0光圈,8k分辨率。
- name: "热带绿植温室场景" - name: "热带绿植温室场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在长满大型龟背竹与天堂鸟的植物园温室中,手指轻轻触碰绿叶,笑容明朗,身体正对镜头,双手自然下垂,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的轻盈与透气感。光线为穿透植物叶片的柔和自然光,形成斑驳的树影打在衣服上,背景为高度虚化的茂密绿植与光斑。画面比例为3:4。富士Provia 400X色彩预设,35mm镜头,f/1.4大光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特站在长满大型龟背竹与天堂鸟的植物园温室中,手指轻轻触碰绿叶,笑容明朗,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的轻盈与透气感。光线为穿透植物叶片的柔和自然光,形成斑驳的树影打在衣服上,背景为高度虚化的茂密绿植与光斑。画面比例为3:4。富士Provia 400X色彩预设,35mm镜头,f/1.4大光圈,8k分辨率。
- name: "阴天极简冷淡风外景" - name: "阴天极简冷淡风外景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特背靠在粗犷的混凝土墙面或现代美术馆外墙前,眼神冷酷,身体正对镜头微侧,双手自然下垂,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]的街头属性。采用阴天柔和的漫反射自然冷光,背景为低饱和的莫兰迪灰调与几何阴影,画面干净清冷。画面比例为3:4。极简主义商业摄影,55mm镜头,f/2.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特背靠在粗犷的混凝土墙面或现代美术馆外墙前,眼神冷酷,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]的街头属性。采用阴天柔和的漫反射自然冷光,背景为低饱和的莫兰迪灰调与几何阴影,画面干净清冷。画面比例为3:4。极简主义商业摄影,55mm镜头,f/2.8光圈,8k分辨率。
- name: "山顶自然风光征服场景" - name: "山顶自然风光征服场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在山顶的岩石上,双手叉腰但不遮挡印花,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花图案与[材质]面料在户外的耐穿与透气属性。采用傍晚日落前的逆光与山顶漫反射光,背景为高度虚化的连绵山脉与云海。画面比例为3:4。电影级情绪摄影,35mm镜头,f/2.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须叉腰但不遮挡胸口,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特站在山顶的岩石上,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花图案与[材质]面料在户外的耐穿与透气属性。采用傍晚日落前的逆光与山顶漫反射光,背景为高度虚化的连绵山脉与云海。画面比例为3:4。电影级情绪摄影,35mm镜头,f/2.8光圈,8k分辨率。
# ========================================== # ==========================================
# 五、 工作/通勤场景区(展现日常实用度) # 五、 工作/通勤场景区(展现日常实用度)
# ========================================== # ==========================================
- name: "办公场景商务休闲展示" - name: "办公场景商务休闲展示"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特坐在极简办公桌前,单手托腮或敲击键盘,身体正对镜头微侧,展现干练气质,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的抗皱与挺括感。室内采用明亮的现代白光照明,背景为高度虚化的电脑屏幕与办公桌绿植,画面通透干净。画面比例为3:4。商业电商摄影,50mm镜头,f/2.0光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须撑在下巴上且不遮挡胸口,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中景半身构图,模特坐在极简办公桌前,身体正对镜头微侧,展现干练气质,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的抗皱与挺括感。室内采用明亮的现代白光照明,背景为高度虚化的电脑屏幕与办公桌绿植,画面通透干净。画面比例为3:4。商业电商摄影,50mm镜头,f/2.0光圈,8k分辨率。
- name: "咖啡馆周末休闲场景" - name: "咖啡馆周末休闲场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特坐在极简风格咖啡馆的窗边座位上,单手端着陶瓷咖啡杯放在嘴边不遮挡印花,身体正对镜头微侧,姿态慵懒松弛,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的柔软垂坠感。晨间自然光从大窗户斜射进来形成柔和侧逆光,背景为高度虚化的木质室内装潢、绿植与朦胧的咖啡蒸汽。画面比例为3:4。日系胶片质感,富士Provia 400X色彩预设,35mm镜头,f/1.8大光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,单手端着陶瓷咖啡杯放在嘴边不遮挡印花,另一只手自然下垂,绝对不可双手交叉抱胸。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中景半身构图,模特坐在极简风格咖啡馆的窗边座位上,身体正对镜头微侧,姿态慵懒松弛,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的柔软垂坠感。晨间自然光从大窗户斜射进来形成柔和侧逆光,背景为高度虚化的木质室内装潢、绿植与朦胧的咖啡蒸汽。画面比例为3:4。日系胶片质感,富士Provia 400X色彩预设,35mm镜头,f/1.8大光圈,8k分辨率。
- name: "书店翻阅书籍场景" - name: "书店翻阅书籍场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特站在高大的木质书架前翻阅一本精装书,眼神专注,身体正对镜头微侧,双手捧书放在腰间不遮挡胸口印花,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的挺括与质感。书店采用暖色调的钨丝灯点光源,背景为高度虚化的书脊与暖色光斑。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8大光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须捧书放在腰间不遮挡胸口,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中景半身构图,模特站在高大的木质书架前翻阅一本精装书,眼神专注,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的挺括与质感。书店采用暖色调的钨丝灯点光源,背景为高度虚化的书脊与暖色光斑。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8大光圈,8k分辨率。
- name: "复古家具店探店场景" - name: "复古家具店探店场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在摆满上世纪老物件的中古家具店内,手指轻抚一把复古单椅,眼神安静,身体正对镜头微侧,双手自然下垂,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的质感。店内采用暖色调的钨丝灯漫反射,背景为高度虚化的胡桃木柜子与老式台灯。画面比例为3:4。富士Provia 400X色彩预设,35mm镜头,f/1.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特站在摆满上世纪老物件的中古家具店内,手指轻抚一把复古单椅,眼神安静,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的质感。店内采用暖色调的钨丝灯漫反射,背景为高度虚化的胡桃木柜子与老式台灯。画面比例为3:4。富士Provia 400X色彩预设,35mm镜头,f/1.8光圈,8k分辨率。
- name: "艺术画廊看展高级场景" - name: "艺术画廊看展高级场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在灯光柔和的现代艺术画廊内,侧身凝视一幅巨大的抽象画后转过头来正对镜头,双手自然下垂,气质疏离高级,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]的高级调性。画廊专业的顶光灯打出柔和的漫反射,背景为高度虚化的洁白墙面与画框。画面比例为3:4。索尼A7R4画质,35mm镜头,f/1.8大光圈,清冷调高级感,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特站在灯光柔和的现代艺术画廊内,侧身凝视一幅巨大的抽象画后转过头来正对镜头,气质疏离高级,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]的高级调性。画廊专业的顶光灯打出柔和的漫反射,背景为高度虚化的洁白墙面与画框。画面比例为3:4。索尼A7R4画质,35mm镜头,f/1.8大光圈,清冷调高级感,8k分辨率。
- name: "超市货架色彩碰撞场景" - name: "超市货架色彩碰撞场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特推着购物车或站在摆满色彩鲜艳饮料的超市货架前,身体正对镜头,双手推车不遮挡印花,姿态俏皮个性,整体呈现[服装风格]的调性,展示衣服正面印花图案与背景色彩的碰撞感及[材质]的日常实穿度。货架顶部的冷光源打亮环境,背景为高度虚化的彩色商品与灯轨。画面比例为3:4。赛博潮流摄影,35mm镜头,f/1.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须推车不遮挡印花,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特推着购物车或站在摆满色彩鲜艳饮料的超市货架前,身体正对镜头,姿态俏皮个性,整体呈现[服装风格]的调性,展示衣服正面印花图案与背景色彩的碰撞感及[材质]的日常实穿度。货架顶部的冷光源打亮环境,背景为高度虚化的彩色商品与灯轨。画面比例为3:4。赛博潮流摄影,35mm镜头,f/1.8光圈,8k分辨率。
# ========================================== # ==========================================
# 六、 情绪氛围与夜景场景区(提升品牌调性) # 六、 情绪氛围与夜景场景区(提升品牌调性)
# ========================================== # ==========================================
- name: "工业风工作室背景展示" - name: "工业风工作室背景展示"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在工业风loft工作室的水泥墙前,单手插兜不遮挡印花,眼神清冷,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的硬挺与廓形。采用顶部的冷色聚光灯与微弱的暖色环境光对比,背景为高度虚化的昏暗通道与反光地面。画面比例为3:4。赛博潮流电商摄影,55mm镜头,f/2.0光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂或单手插兜,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特站在工业风loft工作室的水泥墙前,眼神清冷,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的硬挺与廓形。采用顶部的冷色聚光灯与微弱的暖色环境光对比,背景为高度虚化的昏暗通道与反光地面。画面比例为3:4。赛博潮流电商摄影,55mm镜头,f/2.0光圈,8k分辨率。
- name: "录音棚音乐人场景" - name: "录音棚音乐人场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景构图,模特戴着监听耳机站在专业麦克风前调音,眼神专注,身体正对镜头微侧,双手调音不遮挡胸口印花,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的挺括廓形。采用录音棚特有的暖色小聚光灯与整体冷色调对比,背景为高度虚化的吸音棉墙面与调音台。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须调音不遮挡胸口,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中景构图,模特戴着监听耳机站在专业麦克风前调音,眼神专注,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的挺括廓形。采用录音棚特有的暖色小聚光灯与整体冷色调对比,背景为高度虚化的吸音棉墙面与调音台。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8光圈,8k分辨率。
- name: "微醺暖光清吧场景" - name: "微醺暖光清吧场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特坐在氛围感清吧的吧台前,单手把玩着威士忌酒杯放在吧台上不遮挡印花,眼神微醺迷离,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]在暖光下的质感。采用暖黄色的点光源与背景微弱的蓝光对比,背景为高度虚化的酒瓶阵列与杯光交错。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.4大光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须把玩酒杯放在吧台上不遮挡印花,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中景半身构图,模特坐在氛围感清吧的吧台前,眼神微醺迷离,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]在暖光下的质感。采用暖黄色的点光源与背景微弱的蓝光对比,背景为高度虚化的酒瓶阵列与杯光交错。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.4大光圈,8k分辨率。
- name: "夜晚霓虹街头场景" - name: "夜晚霓虹街头场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特夜晚倚靠在城市天桥栏杆旁,眼神清冷,身体正对镜头微侧,双手插兜不遮挡印花,整体呈现[服装风格]的调性,展示衣服正面印花在夜色下的视觉效果与[材质]的质感与垂感。采用强烈的边缘光与城市霓虹灯的彩色反光(青蓝与橘红对比),背景为高度虚化的车流光轨与霓虹灯牌。画面比例为3:4。赛博朋克潮流摄影,35mm镜头,f/1.4大光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须插兜不遮挡印花,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特夜晚倚靠在城市天桥栏杆旁,眼神清冷,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花在夜色下的视觉效果与[材质]的质感与垂感。采用强烈的边缘光与城市霓虹灯的彩色反光(青蓝与橘红对比),背景为高度虚化的车流光轨与霓虹灯牌。画面比例为3:4。赛博朋克潮流摄影,35mm镜头,f/1.4大光圈,8k分辨率。
- name: "复古旱冰场霓虹场景" - name: "复古旱冰场霓虹场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特穿着旱冰鞋在复古旱冰场滑行,姿态灵动,身体正对镜头微侧,双手自然摆动不遮挡印花,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的随性与飘逸。霓虹紫粉色调与射灯打在模特身上,背景为高度虚化的霓虹灯带与溜冰场护栏。画面比例为3:4。复古胶片质感,35mm镜头,f/1.4大光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然摆动,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特穿着旱冰鞋在复古旱冰场滑行,姿态灵动,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的随性与飘逸。霓虹紫粉色调与射灯打在模特身上,背景为高度虚化的霓虹灯带与溜冰场护栏。画面比例为3:4。复古胶片质感,35mm镜头,f/1.4大光圈,8k分辨率。
- name: "地下车库工业风场景" - name: "地下车库工业风场景"
prompt: | prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特背靠在粗犷的地下车库水泥柱上,眼神冷酷,身体转回正对镜头,双手自然下垂,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的耐穿属性。采用顶部的冷色聚光灯与微弱的暖色环境光对比,背景为高度虚化的昏暗车库通道与反光地面。画面比例为3:4。赛博朋克潮流摄影,55mm镜头,f/2.0光圈,8k分辨率。 【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口。【动作硬约束】模特动作必须确保正面印花100%完整可见,双手必须自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特背靠在粗犷的地下车库水泥柱上,眼神冷酷,身体转回正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的耐穿属性。采用顶部的冷色聚光灯与微弱的暖色环境光对比,背景为高度虚化的昏暗车库通道与反光地面。画面比例为3:4。赛博朋克潮流摄影,55mm镜头,f/2.0光圈,8k分辨率。
- name: "美式复古街道场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特走在有复古拱门和石板路的欧式街道上,手里拿着一束鲜花放在胸前不遮挡印花,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的垂感。清晨柔和的漫反射自然光,画面充满复古氛围,背景为高度虚化的古典建筑与梧桐树。画面比例为3:4。柯达Portra 400胶片质感,色彩柔和低饱和,50mm镜头,f/2.0光圈,8k分辨率。
- name: "长途自驾车窗场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特坐在汽车副驾驶位上,单手将手肘搭在车窗上,看着镜头,微风吹拂发丝,身体正对镜头微侧,另一只手自然放在腿上不遮挡印花,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的随性质感。光线为穿透车窗的柔和侧逆光,背景为高度虚化的公路与掠过的树影。画面比例为3:4。电影级情绪摄影,柯达Portra 400色彩预设,40mm镜头,f/2.0光圈,8k分辨率。
BIN
View File
Binary file not shown.
+4
View File
@@ -135,8 +135,12 @@ class MockBackend:
related += history[:6] related += history[:6]
related += trending[4:8] related += trending[4:8]
max_seeds = int(context.get("max_seeds") or 0)
max_style = int(context.get("max_style_seeds", 10) or 10) max_style = int(context.get("max_style_seeds", 10) or 10)
max_related = int(context.get("max_related_seeds", 10) or 10) max_related = int(context.get("max_related_seeds", 10) or 10)
if max_seeds > 0:
# 不再按类型分:总量均分到 style/related
max_style = max_related = (max_seeds + 1) // 2
return { return {
"style_seeds": _dedup_limit(style, max_style), "style_seeds": _dedup_limit(style, max_style),
"related_seeds": _dedup_limit(related, max_related), "related_seeds": _dedup_limit(related, max_related),
+25
View File
@@ -64,4 +64,29 @@ def filter_node(state: Dict[str, Any]) -> Dict[str, Any]:
kept = validate_rows(kept, "filter") kept = validate_rows(kept, "filter")
stats = dict(state.get("stats") or {}) stats = dict(state.get("stats") or {})
stats["filter"] = {"kept": len(kept), "dropped": dropped_total} stats["filter"] = {"kept": len(kept), "dropped": dropped_total}
# 把过滤后的热点写入 collected_keywords.json(前台显示完整热点池用):
# 完整流水线(run_country)也会写,保证运行后前台能看到所有未用热点,
# 而不是只显示简报(design_briefs 仅含本次限量生成的热点)。
if kept:
try:
import json as _json
from pathlib import Path as _Path
p = _Path(state.get("cache_dir") or state.get("output_dir", "")) / "collected_keywords.json"
p.parent.mkdir(parents=True, exist_ok=True)
kws = [{"topic": r.get("topic", ""), "source": r.get("source", ""),
"kind": r.get("kind", ""), "raw_score": r.get("raw_score")} for r in kept]
p.write_text(_json.dumps({"country": country,
"collected_at": _datetime_now(),
"keywords": kws}, ensure_ascii=False, indent=2),
encoding="utf-8")
print(f"[filter] 已写入采集缓存 {len(kws)} 条(collected_keywords.json")
except Exception as e: # noqa: BLE001
print(f"[filter] 写入采集缓存失败: {e}")
return {"filtered_rows": kept, "stats": stats} return {"filtered_rows": kept, "stats": stats}
def _datetime_now() -> str:
import time
return time.strftime("%Y-%m-%dT%H:%M:%S")
+9 -3
View File
@@ -221,6 +221,7 @@ def _process_spu(
# 6) 模板选择按 SPU.mark 决定: # 6) 模板选择按 SPU.mark 决定:
# mark==1 → 新三图合成模板 MODEL_WEAR_PROMPT(图1模特 + 图2印花设计 + 图3底图) # mark==1 → 新三图合成模板 MODEL_WEAR_PROMPT(图1模特 + 图2印花设计 + 图3底图)
# mark!=1 → 旧两图合成模板 composite_prompt(底图 + 印花设计) # mark!=1 → 旧两图合成模板 composite_prompt(底图 + 印花设计)
# mark==1 统一只做三合一:无模特图时跳过合成,不再回退两图合成(印花+底图)
if int(spu.get("mark") or 0) == 1: if int(spu.get("mark") or 0) == 1:
print(f"{tag} SPU {spu['code']} mark=1 → 使用三图合成模板(图1模特+图2印花+图3底图)") print(f"{tag} SPU {spu['code']} mark=1 → 使用三图合成模板(图1模特+图2印花+图3底图)")
if model_img is not None: if model_img is not None:
@@ -231,13 +232,14 @@ def _process_spu(
result["model_folder"] = model_img.parent.name result["model_folder"] = model_img.parent.name
print(f"{tag} 模特图(任务级分配,{model_img.parent.name}/: {model_copy}") print(f"{tag} 模特图(任务级分配,{model_img.parent.name}/: {model_copy}")
else: else:
print(f"{tag} material_library 无模特图,回退两图合成(composite_prompt") print(f"{tag} material_library 无模特图,mark=1 统一只做三合一,跳过合成")
else: else:
print(f"{tag} SPU {spu['code']} mark={spu.get('mark')} → 使用两图合成模板 composite_prompt(底图+印花)") print(f"{tag} SPU {spu['code']} mark={spu.get('mark')} → 使用两图合成模板 composite_prompt(底图+印花)")
# 7) 合成: # 7) 合成:
# 有模特图 → 三图合成(图1=模特 / 图2=印花设计 / 图3=底图) # 有模特图 → 三图合成(图1=模特 / 图2=印花设计 / 图3=底图)
# 无模特图 → 两图合成平铺服装图(图3=底图 + 图2=印花设计 # mark=1 无模特图 → 跳过合成(统一只做三合一,不做印花+底图两图合成
# mark!=1 无模特图 → 两图合成平铺服装图(图3=底图 + 图2=印花设计)
if "design_path" not in result: if "design_path" not in result:
print(f"{tag} 无设计稿,跳过合成") print(f"{tag} 无设计稿,跳过合成")
elif model_img is not None: elif model_img is not None:
@@ -266,10 +268,14 @@ def _process_spu(
errors.append({"node": "product", "type": type(e).__name__, "message": f"模特合成失败(重试仍失败): {e}", "trace": ""}) errors.append({"node": "product", "type": type(e).__name__, "message": f"模特合成失败(重试仍失败): {e}", "trace": ""})
print(f"{tag} 三图合成重试仍失败 → 跳过该产品(不生成标题/不写模板): {e}") print(f"{tag} 三图合成重试仍失败 → 跳过该产品(不生成标题/不写模板): {e}")
return None return None
else:
# mark=1 无模特图 → 统一只做三合一,不做印花+底图两图合成
if int(spu.get("mark") or 0) == 1:
print(f"{tag} mark=1 无模特图,跳过合成(统一只做三合一)")
else: else:
printed_path = str(prod_dir / f"{img_code}_printed.png") printed_path = str(prod_dir / f"{img_code}_printed.png")
try: try:
# 两图合成(无模特):用平铺印图文案(wearable_prompt),回退旧 composite_prompt # 两图合成(无模特mark!=1):用平铺印图文案(wearable_prompt),回退旧 composite_prompt
flat_prompt = (brief.get("wearable_prompt") or "").strip() or brief.get("composite_prompt", "") flat_prompt = (brief.get("wearable_prompt") or "").strip() or brief.get("composite_prompt", "")
ib.print(flat_prompt, str(basemap_img), printed_path, ib.print(flat_prompt, str(basemap_img), printed_path,
brief.get("composite_negative", ""), brief.get("composite_negative", ""),
+4 -1
View File
@@ -34,7 +34,7 @@ def _cache_key(country: str, provider: str, cfg: Dict[str, Any]) -> str:
避免命中旧参数生成的种子;旧文件保留(不删缓存,取最新)。""" 避免命中旧参数生成的种子;旧文件保留(不删缓存,取最新)。"""
fp = hashlib.md5( fp = hashlib.md5(
json.dumps( json.dumps(
{k: cfg.get(k) for k in ("max_style_seeds", "max_related_seeds", {k: cfg.get(k) for k in ("max_seeds", "max_style_seeds", "max_related_seeds",
"trending_context_limit", "history_limit")}, "trending_context_limit", "history_limit")},
sort_keys=True, ensure_ascii=False, sort_keys=True, ensure_ascii=False,
).encode("utf-8") ).encode("utf-8")
@@ -72,6 +72,7 @@ def seed_node(state: Dict[str, Any]) -> Dict[str, Any]:
cfg = config.get("seed_provider_cfg") or {} cfg = config.get("seed_provider_cfg") or {}
trending_limit = int(cfg.get("trending_context_limit", 15)) trending_limit = int(cfg.get("trending_context_limit", 15))
history_limit = int(cfg.get("history_limit", 20)) history_limit = int(cfg.get("history_limit", 20))
max_seeds = int(cfg.get("max_seeds", 0))
max_style = int(cfg.get("max_style_seeds", 12)) max_style = int(cfg.get("max_style_seeds", 12))
max_related = int(cfg.get("max_related_seeds", 12)) max_related = int(cfg.get("max_related_seeds", 12))
guard = COMMON_RISK_WORDS + [b.lower() for b in (config.get("blacklist") or [])] guard = COMMON_RISK_WORDS + [b.lower() for b in (config.get("blacklist") or [])]
@@ -84,6 +85,7 @@ def seed_node(state: Dict[str, Any]) -> Dict[str, Any]:
res = cached res = cached
context: Dict[str, Any] = { context: Dict[str, Any] = {
"country": country, "country": country,
"max_seeds": max_seeds,
"max_style_seeds": max_style, "max_style_seeds": max_style,
"max_related_seeds": max_related, "max_related_seeds": max_related,
} }
@@ -91,6 +93,7 @@ def seed_node(state: Dict[str, Any]) -> Dict[str, Any]:
# 1) 收集上下文 # 1) 收集上下文
context: Dict[str, Any] = { context: Dict[str, Any] = {
"country": country, "country": country,
"max_seeds": max_seeds,
"max_style_seeds": max_style, "max_style_seeds": max_style,
"max_related_seeds": max_related, "max_related_seeds": max_related,
} }
+60 -11
View File
@@ -1,14 +1,20 @@
"""节点 8/8:种草图生成(seed_shot)——在 oss_upload 之后。 """节点 8/8:种草图生成(seed_shot)——在 oss_upload 之后。
对每个 product 的合成图(图1),按 seed_shot_templates.yaml 模板 + model_features.yaml 随机模特特征 种草图用 img2img 真正生成(不是复用主图):从 product 已生成的三合一主图
生成 N 张种草图(config.seed_shot.count,默认 1): color_composites,每颜色一张)中按分配规则选参考图,以该图提取衣服颜色并作为
参考图,按 seed_shot_templates.yaml 模板 + model_features.yaml 随机模特特征生成新图:
- [商品名称] ← product 的 cn_title(上一节点多模态生成) - [商品名称] ← product 的 cn_title(上一节点多模态生成)
- [材质] ← 数据库 SPU.material 字段 - [材质] ← 数据库 SPU.material 字段
- [模特特征] ← model_features.yaml 随机一条 - [模特特征] ← model_features.yaml 随机一条
种草图同样压缩上传到 OSS(货号计数与 oss_upload 共用 state["oss_seq"] 续接)。 分配规则(config.seed_shot.count):
- count <= 颜色数:随机取 count 个不同颜色,各生成 1 张
- count > 颜色数:每个颜色至少 1 张,剩余随机补足(可重复)
种草图同样压缩上传到 OSS(货号计数与 oss_upload 共用 state["oss_seq"] 续接),
URL 写入 r["seed_shot_urls"],供 template_export 插入模板详情图文列。
未配置图像后端 / 无合成图 / count=0 时跳过,不中断。 未配置图像后端 / 无三合一主图 / count=0 时跳过,不中断。
""" """
import random
import time import time
from pathlib import Path from pathlib import Path
from typing import Any, Dict, List from typing import Any, Dict, List
@@ -16,6 +22,34 @@ from typing import Any, Dict, List
from graph.validate import with_fallback from graph.validate import with_fallback
def _plan_seed_shots(comps: List[Dict[str, Any]], count: int) -> List[tuple]:
"""按颜色分配种草图数量:count <= 颜色数 → 随机取 count 个不同颜色各 1 张;
count > 颜色数 → 每色 1 张 + 随机补足(可重复)。返回 [(composite, n)]。"""
if count <= 0 or not comps:
return []
if len(comps) >= count:
picked = random.sample(comps, count)
return [(cc, 1) for cc in picked]
plan: List[tuple] = [(cc, 1) for cc in comps] # 每色至少 1 张
for _ in range(count - len(comps)):
cc = random.choice(comps) # 随机补足(可重复)
for i, (c, n) in enumerate(plan):
if c is cc:
plan[i] = (c, n + 1)
break
return plan
def _color_tag(cc: Dict[str, Any], idx: int) -> str:
"""种草图文件名里的颜色标识:优先 sku_code 的颜色段,回退颜色名/序号。"""
sku = str(cc.get("sku_code") or "")
if "-" in sku:
tag = sku.split("-", 1)[1]
else:
tag = str(cc.get("color") or "") or f"c{idx}"
return "".join(ch for ch in tag if ch.isalnum() or ch in "-_") or f"c{idx}"
@with_fallback("seed_shot") @with_fallback("seed_shot")
def seed_shot_node(state: Dict[str, Any]) -> Dict[str, Any]: def seed_shot_node(state: Dict[str, Any]) -> Dict[str, Any]:
products: List[Dict[str, Any]] = state.get("product") or [] products: List[Dict[str, Any]] = state.get("product") or []
@@ -47,7 +81,6 @@ def seed_shot_node(state: Dict[str, Any]) -> Dict[str, Any]:
material_map: Dict[str, str] = {} material_map: Dict[str, str] = {}
try: try:
from graph.product import list_spus from graph.product import list_spus
import yaml
dbp = (config.get("product") or {}).get("db_path", "db/spu_sku.db") dbp = (config.get("product") or {}).get("db_path", "db/spu_sku.db")
p = Path(dbp) p = Path(dbp)
if not p.is_absolute(): if not p.is_absolute():
@@ -71,6 +104,7 @@ def seed_shot_node(state: Dict[str, Any]) -> Dict[str, Any]:
seq = int(state.get("oss_seq") or 0) seq = int(state.get("oss_seq") or 0)
oss_cfg = config.get("oss") or {} oss_cfg = config.get("oss") or {}
oss_enabled = bool(oss_cfg.get("enabled", True)) and bool(oss_cfg.get("oss_bucket")) oss_enabled = bool(oss_cfg.get("enabled", True)) and bool(oss_cfg.get("oss_bucket"))
size = str(ss_cfg.get("size") or "1504x2000")
all_shots: List[Dict[str, Any]] = [] all_shots: List[Dict[str, Any]] = []
shot_dir = output_dir / "seed_shots" shot_dir = output_dir / "seed_shots"
@@ -83,16 +117,31 @@ def seed_shot_node(state: Dict[str, Any]) -> Dict[str, Any]:
def _shot_one(r: Dict[str, Any]): def _shot_one(r: Dict[str, Any]):
"""单个产品的种草图生成+上传(每产品独立线程)。""" """单个产品的种草图生成+上传(每产品独立线程)。"""
nonlocal seq nonlocal seq
base = r.get("composite_path") or r.get("printed_path") # 三合一主图:多色用 color_composites;单色回退 composite_path
if not base or not Path(base).exists(): comps = r.get("color_composites") or []
print(f"[seed_shot] {r.get('spu_code', '')} 无合成图,跳过种草图") if not comps and r.get("composite_path") and Path(r["composite_path"]).exists():
comps = [{"sku_code": r.get("sku_code"), "color": r.get("color", ""),
"composite_path": r["composite_path"]}]
if not comps:
print(f"[seed_shot] {r.get('spu_code', '')} 无三合一主图,跳过种草图")
return None return None
plan = _plan_seed_shots(comps, count)
cn = (r.get("cn_title") or "").strip() or r.get("topic", "") cn = (r.get("cn_title") or "").strip() or r.get("topic", "")
material = material_map.get(r.get("spu_code", ""), "") material = material_map.get(r.get("spu_code", ""), "")
paths = generate_seed_shots(ib, base, cn, material, count, str(shot_dir), base_prefix = r.get("img_code") or r.get("oss_code") or ""
paths: List[str] = []
for ci, (cc, n) in enumerate(plan, start=1):
base = cc.get("composite_path")
if not base or not Path(base).exists():
print(f"[seed_shot] {r.get('spu_code', '')} 参考图缺失({base}),跳过该颜色种草图")
continue
tag = _color_tag(cc, ci)
pfx = f"{base_prefix}_{tag}" if base_prefix else f"seed_{tag}"
generated = generate_seed_shots(ib, base, cn, material, n, str(shot_dir),
r.get("composite_negative", ""), r.get("composite_negative", ""),
size=str((config.get("seed_shot") or {}).get("size") or "1504x2000"), size=size, prefix=pfx)
prefix=r.get("img_code") or r.get("oss_code") or "") paths.extend(generated)
if not paths: if not paths:
return None return None
r["seed_shot_paths"] = paths r["seed_shot_paths"] = paths
+11 -2
View File
@@ -8,7 +8,8 @@
4. 用完全用:池中种子数 ≤ 需要数时全部使用(不再随机限量/截断); 4. 用完全用:池中种子数 ≤ 需要数时全部使用(不再随机限量/截断);
5. 每个国家独立配置:configs/countries/<country>.yaml 的 style.seeds / related.seed_keywords。 5. 每个国家独立配置:configs/countries/<country>.yaml 的 style.seeds / related.seed_keywords。
limit 由 seed_node 从 context 注入max_style_seeds / max_related_seeds0 或缺失=不限)。 limit 由 seed_node 从 context 注入max_seeds(单一总量,不再按类型分,从统一池随机抽后均分
style/related);兼容旧参数 max_style_seeds / max_related_seeds0 或缺失=不限)。
LLM 后端生成失败时自动回退到静态+节日主题,保证不中断。 LLM 后端生成失败时自动回退到静态+节日主题,保证不中断。
""" """
import random import random
@@ -87,10 +88,18 @@ class DynamicStrategy(SeedStrategy):
add(dyn_related, 1.0, "dynamic") add(dyn_related, 1.0, "dynamic")
items = list(pool.values()) items = list(pool.values())
limit_total = int(context.get("max_seeds") or 0)
limit_style = int(context.get("max_style_seeds") or 0) limit_style = int(context.get("max_style_seeds") or 0)
limit_related = int(context.get("max_related_seeds") or 0) limit_related = int(context.get("max_related_seeds") or 0)
# 2) 每次随机取(加权,不重复);池不足 → 全部用 if limit_total > 0:
# 不再按类型分:从统一池随机抽 max_seeds 个,均分到 style/related(各约一半)
pick = _weighted_sample(items, limit_total)
half = (len(pick) + 1) // 2
style_pick = pick[:half]
related_pick = pick[half:]
else:
# 兼容旧参数(max_style_seeds / max_related_seeds 分别限量)
style_pick = _weighted_sample(items, limit_style) style_pick = _weighted_sample(items, limit_style)
style_keys = {id(it) for it in style_pick} style_keys = {id(it) for it in style_pick}
remaining = [it for it in items if id(it) not in style_keys] remaining = [it for it in items if id(it) not in style_keys]
+71
View File
@@ -101,6 +101,74 @@ _HOLIDAYS_BY_COUNTRY: Dict[str, List[tuple]] = {
("Boxing Day", 12, 26, None, 21), ("Boxing Day", 12, 26, None, 21),
("Halloween", 10, 31, None, 21), ("Halloween", 10, 31, None, 21),
], ],
"DE": [
("New Year", 1, 1, None, 14),
("Valentine's Day", 2, 14, None, 21),
("Easter", 0, 0, "easter", 21),
("Oktoberfest", 9, 21, "third_saturday", 30), # 啤酒节(9 月第三个周六)
("German Unity Day", 10, 3, None, 21),
("Halloween", 10, 31, None, 30),
("Advent Season", 11, 30, None, 30),
("Christmas", 12, 25, None, 30),
("Boxing Day", 12, 26, None, 14),
],
"BR": [
("New Year", 1, 1, None, 14),
("Carnival", 2, 15, None, 30), # 狂欢节(浮动,2 月近似)
("Easter", 0, 0, "easter", 21),
("Tiradentes Day", 4, 21, None, 14),
("Independence Day (BR)", 9, 7, None, 21),
("Children's Day (BR)", 10, 12, None, 21),
("Halloween", 10, 31, None, 30),
("Christmas", 12, 25, None, 30),
("New Year Eve", 12, 31, None, 14),
],
"SA": [
("New Year", 1, 1, None, 14),
("Saudi Founding Day", 2, 22, None, 21),
("Saudi National Day", 9, 23, None, 30),
("Winter Season", 12, 1, None, 30),
],
"PL": [
("New Year", 1, 1, None, 14),
("Valentine's Day", 2, 14, None, 21),
("Easter", 0, 0, "easter", 21),
("Constitution Day (PL)", 5, 3, None, 21),
("Halloween", 10, 31, None, 30),
("Independence Day (PL)", 11, 11, None, 21),
("Christmas", 12, 25, None, 30),
("Boxing Day", 12, 26, None, 14),
],
"ES": [
("Three Kings Day", 1, 6, None, 14),
("Valentine's Day", 2, 14, None, 21),
("Easter (Semana Santa)", 0, 0, "easter", 21),
("Feria de Abril", 4, 15, None, 21),
("La Tomatina", 8, 27, None, 21),
("Halloween", 10, 31, None, 30),
("Christmas", 12, 25, None, 30),
("New Year Eve", 12, 31, None, 14),
],
"IT": [
("New Year", 1, 1, None, 14),
("Epiphany", 1, 6, None, 14),
("Valentine's Day", 2, 14, None, 21),
("Carnevale", 2, 15, None, 21),
("Easter", 0, 0, "easter", 21),
("Ferragosto", 8, 15, None, 21),
("Halloween", 10, 31, None, 30),
("Christmas", 12, 25, None, 30),
],
"CA": [
("New Year", 1, 1, None, 14),
("Valentine's Day", 2, 14, None, 21),
("Easter", 0, 0, "easter", 21),
("Canada Day", 7, 1, None, 21),
("Thanksgiving (CA)", 10, 12, None, 21), # 10 月第 2 周一(近似固定日)
("Halloween", 10, 31, None, 30),
("Christmas", 12, 25, None, 30),
("Boxing Day", 12, 26, None, 14),
],
} }
@@ -147,6 +215,9 @@ def _resolve(name: str, month: int, day: int, rule, year: int) -> Optional[datet
if rule == "labor": if rule == "labor":
first = datetime.date(year, month, 1) first = datetime.date(year, month, 1)
return first + datetime.timedelta(days=(0 - first.weekday()) % 7) return first + datetime.timedelta(days=(0 - first.weekday()) % 7)
if rule == "third_saturday":
first = datetime.date(year, month, 1)
return first + datetime.timedelta(days=(5 - first.weekday()) % 7 + 2 * 7)
return None return None
+4
View File
@@ -13,6 +13,10 @@ class AgentState(TypedDict, total=False):
country_config: Dict[str, Any] # 该国合并后的配置(全局 + configs/countries/*.yaml + prompts/<country>/aesthetics.yaml country_config: Dict[str, Any] # 该国合并后的配置(全局 + configs/countries/*.yaml + prompts/<country>/aesthetics.yaml
prompts_dir: str # prompts/<country> 绝对路径 prompts_dir: str # prompts/<country> 绝对路径
output_dir: str # output/<country> 绝对路径 output_dir: str # output/<country> 绝对路径
cache_dir: str # output/<country> 根目录(采集缓存/去重/简报缓存)
task_timestamp: str # 任务开始时间戳(OSS 路径段 / 产物文件夹名)
oss_seq: int # 货号计数(000 起,最多 999)
base_image: str # 平铺衣服底图路径(可选,印图用)
# —— 流水线数据(逐节点累积)—— # —— 流水线数据(逐节点累积)——
raw_rows: List[Dict[str, Any]] # fetch 产出:各源原始行(统一格式) raw_rows: List[Dict[str, Any]] # fetch 产出:各源原始行(统一格式)
+48
View File
@@ -199,6 +199,54 @@ COUNTRY_AESTHETICS: Dict[str, Dict[str, str]] = {
"art_style": "sunny laid-back coastal illustration, relaxed", "art_style": "sunny laid-back coastal illustration, relaxed",
"palette": "sunny coastal palette: sky blue, sand beige, coral, sun-bleached white, turquoise", "palette": "sunny coastal palette: sky blue, sand beige, coral, sun-bleached white, turquoise",
}, },
"MX": {
"label": "墨西哥",
"style_hint": "Vibrant Mexican folk art; Day of the Dead / calavera / Loteria / Aztec / Talavera motifs; fiesta colors.",
"art_style": "vibrant mexican folk art illustration, festive",
"palette": "fiesta palette: marigold orange, magenta, deep purple, black, gold",
},
"DE": {
"label": "德国",
"style_hint": "Bavarian-Alpine folk charm, Berlin street-art edge, Bauhaus minimalism, cozy beer-garden and Christmas-market mood.",
"art_style": "bavarian folk or bauhaus minimal illustration, clean",
"palette": "bavarian palette: bavarian blue, white, golden yellow, alpine green, red",
},
"BR": {
"label": "巴西",
"style_hint": "Vibrant tropical carnival energy, samba rhythm, football passion, bold beach and street-art colors.",
"art_style": "vibrant tropical carnival illustration, bold",
"palette": "tropical carnival palette: hot pink, turquoise, gold, lime green, purple",
},
"SA": {
"label": "沙特阿拉伯",
"style_hint": "Elegant desert minimalism, arabian geometric patterns, falconry and starry-night calm, refined and conservative.",
"art_style": "elegant desert geometric illustration, refined",
"palette": "desert palette: warm sand, terracotta, deep amber, teal, cream",
},
"PL": {
"label": "波兰",
"style_hint": "Highland folk embroidery charm, wycinanki paper-cut patterns, slavic forest mystique, retro polish poster mood.",
"art_style": "highland folk or retro polish poster illustration",
"palette": "folk palette: rust red, forest green, cream, amber gold, black",
},
"ES": {
"label": "西班牙",
"style_hint": "Flamenco passion, andalusian tile patterns, mediterranean sunshine, festive fiesta energy.",
"art_style": "flamenco or andalusian tile illustration, vibrant",
"palette": "flamenco palette: flamenco red, black, gold, cobalt blue, cream",
},
"IT": {
"label": "意大利",
"style_hint": "Renaissance elegance, roman heritage, tuscan countryside warmth, la dolce vita retro charm.",
"art_style": "renaissance or tuscan countryside illustration, elegant",
"palette": "tuscan palette: terracotta, olive green, golden wheat, cream, gold",
},
"CA": {
"label": "加拿大",
"style_hint": "Maple-leaf pride, northern-lights wonder, rocky-mountain outdoors, cozy cottage and hockey spirit.",
"art_style": "maple or rocky-mountain outdoor illustration, clean",
"palette": "canadian palette: maple red, aurora green, pine green, snow white, lake blue",
},
} }
+54 -8
View File
@@ -21,6 +21,38 @@ from graph.product import _connect
_CAROUSEL_KW = ("轮播", "carousel", "カルーセル") _CAROUSEL_KW = ("轮播", "carousel", "カルーセル")
def _size_rank(size) -> tuple:
"""把尺码字符串转成可排序 rank(从小到大)。
优先级:数字码(90/100...) < 字母码(XS/S/M/L/XL/XXL/3XL...) < 童装年龄码(0/3M、1-2Y...)
< 尺寸规格(30*40...) < 未知(字典序兜底) < 均码/Onesize(最后)。
"""
s = str(size or "").strip().upper()
if not s:
return (9, 0, "")
if s in ("ONESIZE", "ONE SIZE", "FREESIZE", "FREE SIZE", "均码"):
return (8, 0, s)
if s == "XS":
return (2, 0, s)
if s in ("S", "M", "L"):
return (2, {"S": 1, "M": 2, "L": 3}[s], s)
m = re.fullmatch(r"(X+)(L)", s) # XL/XXL/XXXL/XXXXL/XXXXXL
if m:
return (2, 3 + len(m.group(1)), s)
m = re.fullmatch(r"(\d+)XL", s) # 3XL/4XL/5XL
if m:
return (2, 3 + int(m.group(1)), s)
if s.isdigit(): # 数字码:90/100/110...
return (1, int(s), s)
m = re.fullmatch(r"(\d+)\s*[-/]\s*(\d+)\s*(?:M|Y|YRS|YR)?", s) # 童装年龄码
if m:
return (3, (int(m.group(1)) + int(m.group(2))) / 2.0, s)
m = re.search(r"(\d+(?:\.\d+)?)\s*(?:CM)?\s*[X*]", s) # 尺寸规格:30*40/12CM X 12CM
if m:
return (4, float(m.group(1)), s)
return (5, 0, s) # 未知格式:字典序兜底
def _carousel_col(router, idx: int) -> Optional[int]: def _carousel_col(router, idx: int) -> Optional[int]:
"""定位「商品轮播图{idx}」列号:先精确匹配(中文列名),失败则按中/英/日关键词模糊匹配序号。""" """定位「商品轮播图{idx}」列号:先精确匹配(中文列名),失败则按中/英/日关键词模糊匹配序号。"""
try: try:
@@ -109,7 +141,7 @@ def _fill_design_fields(router, spu_code: str, oss_code: str, cn_title: str, en_
for row in router.find_spu_rows(spu_code): for row in router.find_spu_rows(spu_code):
if only_rows is not None and row not in only_rows: if only_rows is not None and row not in only_rows:
continue # 合并模式:只填本产品块的行 continue # 合并模式:只填本产品块的行
lvl = str(router.ws.cell(row, 1).value or "").strip().lower() lvl = str(router.ws.cell(row, router.level_col).value or "").strip().lower()
color = str(router.ws.cell(row, color_col).value or "").strip() if color_col else "" color = str(router.ws.cell(row, color_col).value or "").strip() if color_col else ""
if lvl == "spu": if lvl == "spu":
if spu_col and oss_code: if spu_col and oss_code:
@@ -213,7 +245,7 @@ def _fill_sku_carousel(router, spu_code: str, color: str, color_col: int,
if col is None: if col is None:
continue continue
for row in router.find_spu_rows(spu_code): for row in router.find_spu_rows(spu_code):
if (str(router.ws.cell(row, 1).value or "").strip().lower() == "sku" if (str(router.ws.cell(row, router.level_col).value or "").strip().lower() == "sku"
and str(router.ws.cell(row, color_col).value or "").strip() == color): and str(router.ws.cell(row, color_col).value or "").strip() == color):
router.ws.cell(row, col, str(img)) router.ws.cell(row, col, str(img))
@@ -270,30 +302,44 @@ def _read_spu(db_path, spu_code: str) -> Optional[Dict[str, Any]]:
def _read_meta(router) -> tuple: def _read_meta(router) -> tuple:
"""读模板顶头元信息:经营站点(第2行第1列)、发货仓(第2行第2列)。 """读模板顶头元信息:经营站点、发货仓(按标签名定位,不依赖固定行列)。
返回 (origin_province, warehouses) 返回 (origin_province, warehouses)
- origin_province:经营站点去掉末尾「站」(如「日本站」→「日本」) - origin_province:经营站点去掉末尾「站」(如「日本站」→「日本」)
- warehouses:发货仓按「、」分隔的列表(如「名古屋仓、inkreach——东京」→ 2 个) - warehouses:发货仓按「、」分隔的列表(如「名古屋仓、inkreach——东京」→ 2 个)
""" """
ws = router.ws ws = router.ws
top = max(1, router.group_row - 1) # 元信息区位于分组行之前
def _val(label: str) -> str:
for row in range(1, top + 1):
for col in range(1, min(ws.max_column, 30) + 1):
if str(ws.cell(row, col).value or "").strip() == label:
return str(ws.cell(row + 1, col).value or "").strip()
return ""
site = _val("经营站点")
raw = _val("发货仓")
if not site and not raw:
# 回退:旧版固定位置(第2行第1/2列)
site = str(ws.cell(2, 1).value or "").strip() site = str(ws.cell(2, 1).value or "").strip()
origin_province = site[:-1] if site.endswith("") else site
raw = str(ws.cell(2, 2).value or "").strip() raw = str(ws.cell(2, 2).value or "").strip()
origin_province = site[:-1] if site.endswith("") else site
warehouses = [w.strip() for w in raw.split("") if w.strip()] warehouses = [w.strip() for w in raw.split("") if w.strip()]
return origin_province, warehouses return origin_province, warehouses
def _read_skus(db_path, spu_code: str, sku_code: str) -> List[Dict[str, Any]]: def _read_skus(db_path, spu_code: str, sku_code: str) -> List[Dict[str, Any]]:
"""该款该颜色的全部尺码 SKU。""" """该款该颜色的全部尺码 SKU,按尺码从小到大排序(字母码/数字码/童装码/规格码)"""
conn = _connect(db_path) conn = _connect(db_path)
rows = conn.execute( rows = conn.execute(
"""SELECT s.*, p.code AS spu_code FROM SKU s """SELECT s.*, p.code AS spu_code FROM SKU s
JOIN SPU p ON s.spu_id = p.id JOIN SPU p ON s.spu_id = p.id
WHERE p.code = ? AND s.code = ? WHERE p.code = ? AND s.code = ?""", (spu_code, sku_code)).fetchall()
ORDER BY s.size""", (spu_code, sku_code)).fetchall()
conn.close() conn.close()
return [dict(r) for r in rows] skus = [dict(r) for r in rows]
skus.sort(key=lambda sk: _size_rank(sk.get("size")))
return skus
def export_product( def export_product(
Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

+78
View File
@@ -0,0 +1,78 @@
# 巴西审美与风格-配色规则(prompts/BR/aesthetics.yaml
style_hint: "Vibrant Brazilian energy: tropical rainforest, carnival samba, football passion, beach and surf culture, bold street art. Prefer: Tropical, Carnival, Samba, Football Fan, Amazon, Beach, Street Art, Bossa Nova, Jungle Wildlife, Brazilian Food."
extra_style_rules:
- keywords: [carnival, samba, parade, bloco, mardi gras]
art_style: "vibrant carnival samba illustration"
color_palette: "hot pink, turquoise, gold, lime green, purple"
- keywords: [football, soccer, futebol, fan, stadium, goal]
art_style: "bold football fan badge illustration"
color_palette: "green, yellow, blue, white"
- keywords: [amazon, rainforest, jungle, river, anaconda, piranha]
art_style: "lush tropical jungle illustration"
color_palette: "deep jungle green, leaf green, golden yellow, earth brown"
- keywords: [beach, copacabana, rio, surf, wave, sunset]
art_style: "tropical beach sunset flat illustration"
color_palette: "turquoise, coral, sand, golden orange"
- keywords: [toucan, parrot, macaw, hummingbird, bird]
art_style: "colorful tropical bird illustration"
color_palette: "vivid orange, teal, yellow, black"
- keywords: [jaguar, capybara, sloth, monkey, wildlife, animal]
art_style: "cute tropical wildlife illustration"
color_palette: "warm brown, jungle green, cream, amber"
- keywords: [street art, graffiti, favela, mural, urban]
art_style: "bold brazilian street-art mural style"
color_palette: "electric blue, hot pink, yellow, black"
- keywords: [food, feijoada, brigadeiro, acai, caipirinha, barbecue, churrasco]
art_style: "playful brazilian food illustration"
color_palette: "chili red, corn yellow, avocado green, cream"
- keywords: [samba dancer, carnival mask, confetti, party, festa]
art_style: "festive carnival dancer flat illustration"
color_palette: "fuchsia, turquoise, gold, orange"
- keywords: [bossa nova, forro, music, guitar, dance]
art_style: "retro brazilian music flat illustration"
color_palette: "teal, coral, cream, black"
- keywords: [tropical flower, hibiscus, palm, pineapple, coconut]
art_style: "bold tropical botanical pattern"
color_palette: "hibiscus pink, palm green, pineapple yellow, coral"
- keywords: [capoeira, jiu jitsu, martial arts, fight]
art_style: "dynamic martial arts silhouette graphic"
color_palette: "black, white, brazilian green, gold"
# 巴西常见侵权盲区(按国家隔离,追加到全局黑名单)
extra_blacklist:
# —— 足球俱乐部 / 国家队 ——
- flamengo
- corinthians
- palmeiras
- sao paulo fc
- vasco da gama
- gremio
- internacional
- cruzeiro
- santos fc
- botafogo
- cbf
- brazilian national team
- selecao
# —— 品牌 ——
- havaianas
- natura
- petrobras
- itau
- bradesco
- magazine luiza
# —— 真实人物 ——
- neymar
- ronaldinho
- pele
- ronaldo
- vinicius jr
- anitta
- ivete sangalo
- xuxa
- gisele bundchen
# —— IP / 版权 ——
- turma da monica
- monica and friends
- galinha pintadinha
+10
View File
@@ -0,0 +1,10 @@
# 巴西专属补充指令
- 设计口吻:巴西活力——热带雨林、狂欢节桑巴、足球热情、海滩冲浪、街头艺术;鲜艳高饱和配色(绿/黄/蓝、品红、青绿、金),欢乐庆典氛围。
- 合规重点(巴西特有):
* 足球俱乐部(弗拉门戈、科林蒂安、帕尔梅拉斯、圣保罗等)与巴西国家队(CBF/Seleção)队徽、名称、吉祥物禁止。
* 品牌(Havaianas、Natura、Petrobraslogo 与名称禁止。
* 真实人物:球星(内马尔、小罗、贝利、罗纳尔多、维尼修斯)、歌手(Anitta、Ivete Sangalo)、超模(Gisele Bündchen)肖像权。
* 版权 IPTurma da Mônica(莫妮卡帮)、Galinha Pintadinha 等角色禁止。
- 可做"狂欢节氛围 / 原创桑巴舞者 / 热带雨林野生动物 / 海滩日落 / 街头艺术 / 巴西美食 / 热带花卉"等原创设计。
- 文字规则:葡萄牙语短句可加可不加,与印花适配即可(如 Samba!、Viva Brasil!);任何文字严禁政治/宗教/仇恨/暴力/性/品牌/商标/真实人物姓名等敏感内容。
- Return JSON 输出格式必须严格遵循系统提示词中的 schema,不要输出任何额外文字。
+85
View File
@@ -0,0 +1,85 @@
# 加拿大审美与风格-配色规则(prompts/CA/aesthetics.yaml
style_hint: "Canadian aesthetic: maple leaf and maple syrup, northern lights, Rocky Mountains and lake country, wildlife (moose, beaver, polar bear), hockey and winter sports, cottage life, French-Canadian charm. Prefer: Maple Leaf, Northern Lights, Rocky Mountains, Wildlife, Hockey, Winter, Cottage, Lake Life, French Canada."
extra_style_rules:
- keywords: [maple, maple leaf, maple syrup, autumn, fall]
art_style: "bold maple leaf emblem illustration"
color_palette: "maple red, autumn orange, gold, cream"
- keywords: [northern lights, aurora, night sky, winter night]
art_style: "glowing aurora borealis illustration"
color_palette: "aurora green, teal, purple, deep navy"
- keywords: [rocky mountains, mountain, banff, lake louise, hiking]
art_style: "majestic rocky mountain landscape illustration"
color_palette: "mountain blue, pine green, snow white, slate"
- keywords: [moose, beaver, polar bear, wildlife, animal, loon, whale]
art_style: "cute canadian wildlife illustration"
color_palette: "warm brown, forest green, cream, amber"
- keywords: [hockey, ice hockey, skating, winter sport, rink]
art_style: "dynamic hockey action illustration"
color_palette: "ice blue, red, white, black"
- keywords: [winter, snow, snowflake, snowman, ice, cabin]
art_style: "cozy canadian winter cabin illustration"
color_palette: "snow white, pine green, warm red, blue"
- keywords: [cottage, lake, canoe, kayak, camping, fishing, lake life]
art_style: "serene canadian lake cottage illustration"
color_palette: "lake blue, pine green, wood brown, cream"
- keywords: [french canada, quebec, montreal, old quebec, french]
art_style: "charming french-canadian old town illustration"
color_palette: "stone, terracotta, sky blue, cream"
- keywords: [forest, pine, tree, wilderness, trail, camping]
art_style: "peaceful pine forest illustration"
color_palette: "pine green, moss, amber, sky blue"
- keywords: [food, poutine, butter tart, maple syrup, lobster, salmon]
art_style: "playful canadian food illustration"
color_palette: "gravy brown, cheese yellow, maple gold, red"
- keywords: [city, toronto, vancouver, skyline, cn tower, urban]
art_style: "modern canadian city skyline graphic"
color_palette: "steel blue, glass teal, warm gray, red"
- keywords: [plaid, flannel, lumberjack, mountie, heritage]
art_style: "classic canadian plaid pattern"
color_palette: "plaid red, black, cream, forest green"
# 加拿大常见侵权盲区(按国家隔离,追加到全局黑名单)
extra_blacklist:
# —— 曲棍球联盟 / 球队 ——
- nhl
- toronto maple leafs
- montreal canadiens
- edmonton oilers
- calgary flames
- vancouver canucks
- ottawa senators
- winnipeg jets
- stanley cup
# —— 品牌 ——
- tim hortons
- canada goose
- lululemon
- roots
- arc'teryx
- air canada
- bombardier
- molson
- labatt
- canadian tire
# —— 国旗/国徽 ——
- canadian flag
- maple leaf flag
- canadian coat of arms
# —— 真实人物 ——
- justin trudeau
- trudeau
- drake
- celine dion
- ryan reynolds
- the weeknd
- justin bieber
- wayne gretzky
- sidney crosby
- connor mcdavid
# —— 原住民文化(文化挪用风险)——
- totem pole
- inuit art
- first nations art
- rcmp
- mountie uniform
+11
View File
@@ -0,0 +1,11 @@
# 加拿大专属补充指令
- 设计口吻:加拿大审美——枫叶与枫糖浆、北极光、落基山脉与湖区、野生动物(驼鹿/河狸/北极熊)、曲棍球与冬季运动、湖畔度假屋生活、法语区魅力;配色常含枫叶红、极光绿、松林绿、雪白、湖蓝。
- 合规重点(加拿大特有):
* 曲棍球联盟与球队(NHL、多伦多枫叶、蒙特利尔加拿大人、埃德蒙顿油人、温哥华加人、斯坦利杯等)队徽/名称禁止。
* 品牌(Tim Hortons、Canada Goose、Lululemon、Roots、Arc'teryx、加航、Molson 等)logo 与名称禁止。
* 加拿大国旗/国徽受法律保护,禁止直接复刻。
* 真实人物:特鲁多、Drake、席琳·迪翁、瑞恩·雷诺兹、The Weeknd、贾斯汀·比伯、韦恩·格雷茨基等肖像权。
* **原住民文化(图腾柱、因纽特艺术、原住民艺术)与皇家骑警(RCMP)制服形象存在文化挪用/受保护风险,避免直接复刻**;可做"自然风光/野生动物/枫叶/极光"等原创设计。
- 可做"枫叶 / 北极光 / 落基山 / 野生动物 / 曲棍球氛围 / 冬季木屋 / 湖畔生活 / 法语区街景 / 加拿大美食"等原创设计。
- 文字规则:英语或法语短句可加可不加,与印花适配即可(如 Eh!、Bonjour!、True North);任何文字严禁政治/宗教/仇恨/暴力/性/品牌/商标/真实人物姓名等敏感内容。
- Return JSON 输出格式必须严格遵循系统提示词中的 schema,不要输出任何额外文字。
+87
View File
@@ -0,0 +1,87 @@
# 德国审美与风格-配色规则(prompts/DE/aesthetics.yaml
style_hint: "German aesthetic mix: Bavarian / Alpine folk tradition, Berlin street art, Bauhaus minimalism, industrial heritage, Oktoberfest beer culture and cozy Christmas markets. Prefer: Bavarian, Alpine, Berlin Street Art, Bauhaus, Industrial Minimal, German Typography, Gothic, Medieval, Retro GDR, Nordic."
extra_style_rules:
- keywords: [oktoberfest, beer festival, weisswurst, biergarten, beer]
art_style: "cheerful bavarian beer festival illustration"
color_palette: "bavarian blue, white, golden yellow, red"
- keywords: [bavarian, lederhosen, dirndl, bavaria, munich, bayern]
art_style: "traditional bavarian folk pattern emblem"
color_palette: "bavarian blue, white, alpine green, red"
- keywords: [alpine, alps, mountain, edelweiss, hiking, hut]
art_style: "clean alpine mountain line illustration"
color_palette: "snow white, alpine green, slate blue, warm gray"
- keywords: [berlin, street art, graffiti, east berlin, wall]
art_style: "bold berlin street-art poster graphic"
color_palette: "vivid red, mustard, black, off-white"
- keywords: [bauhaus, minimal, geometric, industrial, architecture]
art_style: "bauhaus geometric minimal poster"
color_palette: "primary red, yellow, blue, black, white"
- keywords: [christmas market, weihnachten, gluhwein, stollen, advent]
art_style: "cozy german christmas market illustration"
color_palette: "pine green, holly red, gold, cream"
- keywords: [gothic, medieval, castle, knight, cathedral]
art_style: "gothic medieval emblem illustration"
color_palette: "stone gray, deep burgundy, gold, black"
- keywords: [forest, black forest, deer, fox, boar, owl]
art_style: "storybook black forest wildlife illustration"
color_palette: "deep forest green, moss, amber, cream"
- keywords: [retro gdr, trabi, east germany, ampelmann, ostalgie]
art_style: "playful retro GDR nostalgia graphic"
color_palette: "traffic-light red, yellow, green, cream"
- keywords: [techno, club, electronic music, rave]
art_style: "minimal techno club graphic"
color_palette: "electric cyan, magenta, black, white"
- keywords: [nordic, viking, runes, fjord, scandinavian]
art_style: "stylized nordic viking emblem"
color_palette: "ice blue, charcoal, rust red, cream"
- keywords: [autobahn, road trip, classic car, vintage car]
art_style: "retro road-trip travel badge"
color_palette: "faded red, cream, slate blue, mustard"
# 德国常见侵权盲区(按国家隔离,追加到全局黑名单)
extra_blacklist:
# —— 纳粹/极右符号(德国法律红线,绝对禁止)——
- swastika
- hakenkreuz
- nazi
- hitler
- heil hitler
- ss symbol
- gestapo
- fuhrer
- holocaust
# —— 足球俱乐部 / 国家队 ——
- fc bayern
- bayern munich
- borussia dortmund
- bvb
- rb leipzig
- schalke
- werder bremen
- hamburger sv
- dfb
- german national team
# —— 品牌 ——
- volkswagen
- vw beetle
- bmw
- mercedes
- audi
- porsche
- adidas
- puma
- siemens
- lidl
- aldi
- deutsche bank
- sap
# —— 真实人物 ——
- angela merkel
- olaf scholz
- frank-walter steinmeier
# —— 乐队/艺人 ——
- rammstein
- kraftwerk
- scorpions
- helene fischer
+10
View File
@@ -0,0 +1,10 @@
# 德国专属补充指令
- 设计口吻:巴伐利亚/阿尔卑斯民俗(皮裤、Dirndl、雪绒花)、柏林街头艺术、包豪斯极简、工业遗产、啤酒节与圣诞市场氛围;配色常含巴伐利亚蓝、白、金、阿尔卑斯绿。
- 合规重点(德国特有):
* **纳粹/极右符号(swastika、hakenkreuz、SS、纳粹口号)是德国法律红线,任何形式(含戏仿/艺术化)一律绝对禁止**。
* 足球俱乐部(拜仁慕尼黑、多特蒙德、莱比锡等)与德国国家队(DFB)队徽/名称禁止。
* 汽车/工业品牌(大众、宝马、奔驰、奥迪、保时捷、阿迪达斯、彪马)logo 与名称禁止。
* 真实人物:政客(默克尔、朔尔茨)、名人肖像权。
- 可做"巴伐利亚民俗 / 阿尔卑斯徒步 / 柏林街头艺术 / 包豪斯几何 / 啤酒节 / 圣诞市场 / 黑森林童话 / 东德复古 / 中世纪城堡 / 北欧维京"等原创设计。
- 文字规则:德语短句可加可不加,与印花适配即可(如 Prost!、Servus);任何文字严禁政治/宗教/仇恨/暴力/性/品牌/商标/真实人物姓名等敏感内容。
- Return JSON 输出格式必须严格遵循系统提示词中的 schema,不要输出任何额外文字。
+84
View File
@@ -0,0 +1,84 @@
# 西班牙审美与风格-配色规则(prompts/ES/aesthetics.yaml
style_hint: "Spanish aesthetic: flamenco passion, Andalusian azulejo tiles, Gaudí modernism, Mediterranean coast, tapas and fiesta culture, Moorish heritage. Prefer: Flamenco, Azulejo, Andalusian, Gaudí, Mediterranean, Spanish Food, Fiesta, Moorish, Costa Brava, Siesta."
extra_style_rules:
- keywords: [flamenco, dancer, sevillanas, castanets, guitar, andalusia]
art_style: "passionate flamenco dancer illustration"
color_palette: "flamenco red, black, gold, cream"
- keywords: [azulejo, tile, ceramic, pattern, andalusian]
art_style: "intricate azulejo tile pattern design"
color_palette: "cobalt blue, white, yellow, green"
- keywords: [gaudi, barcelona, modernism, mosaic, sagrada, architecture]
art_style: "colorful gaudi modernist mosaic style"
color_palette: "vibrant mosaic blue, green, orange, gold"
- keywords: [mediterranean, coast, beach, sea, costa, ibiza, sunset]
art_style: "sunny mediterranean coast illustration"
color_palette: "turquoise, white, sand, coral"
- keywords: [food, tapas, paella, jamon, churros, sangria, olive]
art_style: "playful spanish food illustration"
color_palette: "saffron yellow, chili red, olive green, cream"
- keywords: [fiesta, carnival, festival, celebration, tomato]
art_style: "festive spanish fiesta illustration"
color_palette: "bright red, yellow, orange, purple"
- keywords: [bull, toro, bullring, spain]
art_style: "bold spanish bull emblem illustration"
color_palette: "black, red, gold, cream"
- keywords: [moorish, alhambra, arabesque, granada, palace]
art_style: "elegant moorish arabesque pattern"
color_palette: "terracotta, teal, gold, cream"
- keywords: [siesta, cat, nap, lazy, relax]
art_style: "cozy siesta cat illustration"
color_palette: "warm terracotta, cream, soft blue"
- keywords: [gothic, cathedral, renaissance, medieval, castle]
art_style: "gothic spanish cathedral illustration"
color_palette: "stone gray, deep burgundy, gold"
- keywords: [orange, orange tree, citrus, lemon, garden]
art_style: "fresh spanish citrus illustration"
color_palette: "orange, lemon yellow, leaf green, white"
- keywords: [villa, village, white village, andalusia, pueblo]
art_style: "charming white andalusian village illustration"
color_palette: "white, terracotta, blue, olive green"
# 西班牙常见侵权盲区(按国家隔离,追加到全局黑名单)
extra_blacklist:
# —— 足球俱乐部 / 国家队 ——
- real madrid
- fc barcelona
- barca
- atletico madrid
- sevilla fc
- valencia cf
- athletic bilbao
- real betis
- villarreal
- rfef
- spanish national team
- la liga
# —— 品牌 ——
- zara
- mango
- inditex
- el corte ingles
- santander
- iberia
- seat
- mahou
- estrella damm
# —— 真实人物 ——
- rafael nadal
- fernando alonso
- pedro almodovar
- pablo picasso
- salvador dali
- antonio banderas
- penelope cruz
- rosalia
- enrique iglesias
- shakira
# —— 皇室 ——
- felipe vi
- king of spain
- spanish royal family
# —— 斗牛士(真实人物)——
- morante de la puebla
- manolete
+11
View File
@@ -0,0 +1,11 @@
# 西班牙专属补充指令
- 设计口吻:西班牙审美——弗拉明戈热情、安达卢西亚 azulejo 瓷砖、高迪现代主义、地中海海岸、tapas 与节日文化、摩尔遗产;配色常含弗拉明戈红、钴蓝、藏红花黄、橄榄绿。
- 合规重点(西班牙特有):
* 足球俱乐部(皇家马德里、巴塞罗那、马竞、塞维利亚等)与国家队(RFEF)、西甲联赛(La Liga)队徽/名称禁止。
* 品牌(Zara、Mango、Inditex、El Corte Inglés、桑坦德银行、伊比利亚航空)logo 与名称禁止。
* 真实人物:纳达尔、阿隆索、阿莫多瓦、毕加索、达利、安东尼奥·班德拉斯、佩内洛普·克鲁兹、Rosalía 等肖像权。
* 皇室(费利佩六世)形象禁止。
* 斗牛士真实人物(Manolete 等)肖像权;公牛形象本身可用,但避免具体人物。
- 可做"弗拉明戈氛围 / 原创瓷砖图案 / 高迪风格马赛克 / 地中海海岸 / 西班牙美食 / 节日氛围 / 摩尔纹样 / 白色村庄"等原创设计。
- 文字规则:西班牙语短句可加可不加,与印花适配即可(如 ¡Olé!、¡Viva España!);任何文字严禁政治/宗教/仇恨/暴力/性/品牌/商标/真实人物姓名等敏感内容。
- Return JSON 输出格式必须严格遵循系统提示词中的 schema,不要输出任何额外文字。
+86
View File
@@ -0,0 +1,86 @@
# 意大利审美与风格-配色规则(prompts/IT/aesthetics.yaml
style_hint: "Italian aesthetic: Renaissance art, Roman ruins, Venice canals and masks, Tuscan countryside, Mediterranean food and espresso culture, la dolce vita vintage. Prefer: Renaissance, Roman, Venetian, Tuscan, Italian Food, Espresso, Mediterranean, La Dolce Vita, Italian Vintage."
extra_style_rules:
- keywords: [rome, roman, colosseum, gladiator, empire, ancient]
art_style: "classic roman empire emblem illustration"
color_palette: "travertine stone, terracotta, laurel green, gold"
- keywords: [venice, venetian, gondola, canal, lagoon, mask, carnival]
art_style: "romantic venetian gondola illustration"
color_palette: "canal teal, burgundy, gold, cream"
- keywords: [tuscany, tuscan, hills, cypress, vineyard, countryside]
art_style: "rolling tuscan countryside illustration"
color_palette: "cypress green, golden wheat, terracotta, olive"
- keywords: [renaissance, art, fresco, david, statue, classic]
art_style: "elegant renaissance art style illustration"
color_palette: "fresco earth tones, gold, deep red, cream"
- keywords: [food, pizza, pasta, spaghetti, gelato, tiramisu, espresso]
art_style: "playful italian food illustration"
color_palette: "tomato red, basil green, mozzarella white, espresso brown"
- keywords: [coffee, espresso, caffe, bar, italian coffee]
art_style: "cozy italian espresso culture illustration"
color_palette: "espresso brown, cream, gold, red"
- keywords: [amalfi, coast, lemon, limoncello, riviera, portofino, sea]
art_style: "bright amalfi coast lemon illustration"
color_palette: "lemon yellow, turquoise, white, coral"
- keywords: [la dolce vita, vintage italy, retro, 1950s, classic]
art_style: "retro italian la dolce vita graphic"
color_palette: "faded red, cream, teal, mustard"
- keywords: [venetian mask, carnival of venice, masquerade, ball]
art_style: "ornate venetian carnival mask illustration"
color_palette: "gold, deep purple, black, red"
- keywords: [mosaic, roman mosaic, tile, byzantine]
art_style: "intricate roman mosaic pattern"
color_palette: "gold, teal, terracotta, cream"
- keywords: [sicily, sicilian, island, mediterranean, trulli, puglia]
art_style: "sunny sicilian island illustration"
color_palette: "sea blue, lemon yellow, terracotta, white"
- keywords: [florence, leaning tower, pisa, opera, music, duomo]
art_style: "charming italian city landmark illustration"
color_palette: "stone, terracotta, sky blue, gold"
# 意大利常见侵权盲区(按国家隔离,追加到全局黑名单)
extra_blacklist:
# —— 足球俱乐部 / 国家队 ——
- juventus
- ac milan
- inter milan
- as roma
- lazio
- napoli
- fiorentina
- serie a
- figc
- italian national team
# —— 品牌 ——
- gucci
- prada
- armani
- versace
- dolce gabbana
- ferrari
- lamborghini
- maserati
- ducati
- vespa
- fiat
- barilla
- lavazza
- illy
- nutella
- ferragamo
# —— 真实人物 / 历史人物 ——
- pope francis
- pope
- silvio berlusconi
- sophia loren
- monica bellucci
- michelangelo
- leonardo da vinci
- dante
- giorgio armani
- roberto benigni
# —— IP / 版权 ——
- pinocchio
- super mario
- mario bros
+10
View File
@@ -0,0 +1,10 @@
# 意大利专属补充指令
- 设计口吻:意大利审美——文艺复兴艺术、罗马古迹、威尼斯运河与面具、托斯卡纳乡村、地中海美食与浓缩咖啡文化、la dolce vita 意式复古;配色常含托斯卡纳赭石、威尼斯青绿、番茄红、橄榄绿、金。
- 合规重点(意大利特有):
* 足球俱乐部(尤文图斯、AC 米兰、国际米兰、罗马、拉齐奥、那不勒斯等)与国家队(FIGC)、意甲(Serie A)队徽/名称禁止。
* 品牌(Gucci、Prada、Armani、Versace、法拉利、兰博基尼、玛莎拉蒂、杜卡迪、Vespa、Barilla、Lavazza、Nutella 等)logo 与名称禁止。
* 真实人物/历史人物:教皇、贝卢斯科尼、索菲亚·罗兰、莫妮卡·贝鲁奇、米开朗基罗、达芬奇等肖像权/遗产保护。
* 版权 IP:匹诺曹、超级马里奥等角色禁止。
- 可做"罗马古迹氛围 / 威尼斯运河与原创面具 / 托斯卡纳乡村 / 文艺复兴风格 / 意大利美食 / 浓缩咖啡文化 / 阿马尔菲柠檬海岸 / 意式复古"等原创设计。
- 文字规则:意大利语短句可加可不加,与印花适配即可(如 Ciao!、La Dolce Vita、Mamma Mia!);任何文字严禁政治/宗教/仇恨/暴力/性/品牌/商标/真实人物姓名等敏感内容。
- Return JSON 输出格式必须严格遵循系统提示词中的 schema,不要输出任何额外文字。
+79
View File
@@ -0,0 +1,79 @@
# 波兰审美与风格-配色规则(prompts/PL/aesthetics.yaml
style_hint: "Polish aesthetic: highland (Podhale/Goral) folk tradition, wycinanki paper cutouts and folk embroidery, amber, deep forests and Mazury lakes, Baltic coast, Slavic mythology, medieval castles, retro Polish poster art. Prefer: Highland Folklore, Wycinanki, Folk Embroidery, Amber, Forest, Slavic, Medieval, Retro Poland, Baltic."
extra_style_rules:
- keywords: [highland, podhale, goral, tatra, mountain, folk]
art_style: "traditional highland folk pattern illustration"
color_palette: "rust red, forest green, cream, black"
- keywords: [wycinanki, paper cutout, folk art, cut paper]
art_style: "intricate wycinanki paper-cutout pattern"
color_palette: "red, cream, green, gold"
- keywords: [embroidery, folk embroidery, floral stitch, needlework]
art_style: "delicate folk embroidery floral pattern"
color_palette: "coral red, cornflower blue, cream, green"
- keywords: [amber, jewelry, resin, baltic amber]
art_style: "warm amber jewelry illustration"
color_palette: "honey amber, gold, cream, brown"
- keywords: [forest, bison, wolf, elk, deer, mushroom, wildlife]
art_style: "storybook polish forest wildlife illustration"
color_palette: "deep forest green, moss, amber, cream"
- keywords: [slavic, mythology, folklore, dragon, wawel, legend]
art_style: "stylized slavic mythology illustration"
color_palette: "slate, rust red, gold, forest green"
- keywords: [medieval, castle, knight, armor, old town, krakow]
art_style: "medieval knight castle emblem illustration"
color_palette: "stone gray, deep red, gold, black"
- keywords: [retro poland, communist, vintage poster, retro design]
art_style: "retro polish poster graphic"
color_palette: "faded red, mustard, teal, cream"
- keywords: [baltic, sea, coast, seagull, lighthouse, beach]
art_style: "calm baltic sea coast illustration"
color_palette: "sea blue, sand, white, soft gray"
- keywords: [christmas, wigilia, christmas eve, gingerbread, ornament]
art_style: "cozy polish christmas illustration"
color_palette: "pine green, holly red, gold, cream"
- keywords: [food, pierogi, oscypek, bread, soup, kielbasa]
art_style: "playful polish food illustration"
color_palette: "golden brown, cream, red, green"
- keywords: [stork, white eagle, bird, meadow, wildflower, cornflower]
art_style: "delicate polish meadow bird illustration"
color_palette: "cornflower blue, white, green, yellow"
# 波兰常见侵权盲区(按国家隔离,追加到全局黑名单)
extra_blacklist:
# —— 纳粹/苏联符号(法律红线)——
- swastika
- nazi
- hitler
- ss symbol
- soviet
- hammer and sickle
- cccp
- red army
# —— 国徽/国家象征 ——
- polish eagle emblem
- white eagle emblem
- godzilo
# —— 真实人物 ——
- john paul ii
- jan pawel
- lech walesa
- robert lewandowski
- lewandowski
- frederic chopin
- chopin
- marie curie
- andrzej duda
# —— 品牌 ——
- zubrowka
- tyskie
- zywiec
- belvedere
- lot polish airlines
- pko
# —— 足球俱乐部 ——
- legia warsaw
- lech poznan
- wisla krakow
- pzpn
- polish national team
+11
View File
@@ -0,0 +1,11 @@
# 波兰专属补充指令
- 设计口吻:波兰审美——高地(Podhale/Goral)民俗、wycinanki 剪纸与民间刺绣、琥珀、森林与马祖里湖区、波罗的海海岸、斯拉夫神话、中世纪城堡、复古波兰海报;配色常含锈红、森林绿、奶油白、琥珀金。
- 合规重点(波兰特有):
* **纳粹/苏联符号(swastika、纳粹、锤子镰刀、CCCP)是法律红线,绝对禁止**。
* 波兰国徽(白鹰)受法律保护,禁止直接复刻。
* 真实人物:教皇若望保禄二世(John Paul II)、莱万多夫斯基、肖邦、居里夫人等肖像权/遗产保护。
* 足球俱乐部(华沙莱吉亚、波兹南莱赫、克拉科夫维斯瓦)与国家队(PZPN)队徽/名称禁止。
* 品牌(Żubrówka、Tyskie、Żywiec 等酒类、LOT 航空)logo 与名称禁止。
- 可做"高地民俗 / 剪纸与刺绣 / 琥珀 / 森林野生动物 / 斯拉夫神话 / 中世纪骑士 / 复古波兰海报 / 波罗的海海岸 / 波兰美食"等原创设计。
- 文字规则:波兰语短句可加可不加,与印花适配即可(如 Cześć!、Smacznego!);任何文字严禁政治/宗教/仇恨/暴力/性/品牌/商标/真实人物姓名等敏感内容。
- Return JSON 输出格式必须严格遵循系统提示词中的 schema,不要输出任何额外文字。
+93
View File
@@ -0,0 +1,93 @@
# 沙特阿拉伯审美与风格-配色规则(prompts/SA/aesthetics.yaml
# 保守市场:严格避免宗教符号/人物形象/酒精/猪/国旗国徽/王室;主打自然、几何、文化氛围。
style_hint: "Saudi aesthetic: vast desert dunes, camels and Arabian horses, falconry, decorative Arabic calligraphy and geometric patterns, starry desert nights, Red Sea coral, futuristic city skyline. Conservative and elegant. Prefer: Desert, Camel, Arabian Horse, Falcon, Arabic Calligraphy, Geometric Pattern, Henna, Oasis, Red Sea, Starry Night."
extra_style_rules:
- keywords: [desert, dune, sand, sahara, arid, sandstorm]
art_style: "minimal desert dune line illustration"
color_palette: "warm sand, terracotta, deep amber, cream"
- keywords: [camel, caravan, desert travel, dromedary]
art_style: "elegant camel caravan silhouette illustration"
color_palette: "sand gold, deep brown, dusk purple, cream"
- keywords: [arabian horse, horse, equestrian, stallion]
art_style: "graceful arabian horse line art"
color_palette: "cream, mahogany, gold, black"
- keywords: [falcon, falconry, hawk, bird of prey]
art_style: "majestic falcon emblem illustration"
color_palette: "warm brown, gold, cream, charcoal"
- keywords: [calligraphy, arabic script, lettering, typography]
art_style: "decorative arabic calligraphy art"
color_palette: "gold, deep teal, cream, black"
- keywords: [geometric, pattern, islamic pattern, tessellation, mosaic]
art_style: "intricate geometric pattern design"
color_palette: "teal, gold, navy, cream"
- keywords: [oasis, palm, date palm, date, garden]
art_style: "serene oasis palm illustration"
color_palette: "palm green, sand, turquoise, brown"
- keywords: [starry night, star map, constellation, astronomy, night sky]
art_style: "starry desert night sky illustration"
color_palette: "deep navy, gold, silver, indigo"
- keywords: [red sea, coral, reef, fish, diving, underwater]
art_style: "vibrant red sea coral reef illustration"
color_palette: "coral, turquoise, deep blue, gold"
- keywords: [henna, hand pattern, mehndi, floral pattern]
art_style: "delicate henna floral pattern design"
color_palette: "henna brown, cream, gold"
- keywords: [lantern, arabian nights, genie, magic, fairy tale]
art_style: "whimsical arabian lantern illustration"
color_palette: "gold, deep purple, teal, warm orange"
- keywords: [coffee, arabic coffee, dallah, hospitality]
art_style: "elegant arabic coffee pot illustration"
color_palette: "coffee brown, gold, cream, teal"
- keywords: [skyline, city, futuristic, modern architecture, tower]
art_style: "sleek futuristic city skyline graphic"
color_palette: "steel blue, sand, gold, white"
# 沙特常见侵权盲区(按国家隔离,追加到全局黑名单)
extra_blacklist:
# —— 宗教(保守市场红线,绝对禁止)——
- mecca
- kaaba
- quran
- koran
- allah
- mosque
- prophet
- muhammad
- islamic religious
- hajj
- umrah
- prayer rug
- hijab religious
- burqa
# —— 国旗/国徽/王室 ——
- saudi flag
- saudi emblem
- sword emblem
- royal family
- bin salman
- bin laden
- house of saud
# —— 政治/敏感 ——
- israel
- palestine
- iran
- yemen
- war
- oil embargo
# —— 品牌 ——
- saudia
- almarai
- stc
- sabic
- aramco
# —— 酒精/猪/禁忌 ——
- alcohol
- beer
- wine
- pork
- pig
# —— 人物形象 ——
- celebrity
- singer
- actress
+12
View File
@@ -0,0 +1,12 @@
# 沙特阿拉伯专属补充指令
- 设计口吻:沙特/中东审美——沙漠沙丘、骆驼与阿拉伯马、猎鹰、装饰性阿拉伯书法与几何图案、星空沙漠之夜、红海珊瑚、未来城市天际线;整体**保守、优雅、克制**,避免人物形象(尤其女性)与宗教元素。
- 合规重点(沙特特有,红线):
* **宗教元素绝对禁止**:麦加/天房/古兰经/真主/清真寺/先知/朝觐/礼拜毯/宗教服饰——任何形式(含艺术化)一律禁止。
* 国旗/国徽/王室(沙特国旗、双剑国徽、王室成员)禁止。
* 政治敏感话题(中东冲突、战争)禁止。
* 酒精、猪等伊斯兰禁忌内容禁止。
* 真实人物(名人/歌手/演员)肖像权禁止。
* 品牌(沙特航空、Almarai、STC、SABIC、Aramcologo 与名称禁止。
- 可做"沙漠日落 / 骆驼剪影 / 阿拉伯马 / 猎鹰 / 装饰性书法与几何 / 海娜花纹 / 椰枣绿洲 / 星空 / 红海珊瑚 / 阿拉伯咖啡壶"等原创设计。
- 文字规则:阿拉伯语短句或英文短句可加可不加,与印花适配即可;任何文字严禁宗教/政治/仇恨/暴力/性/品牌/商标/真实人物姓名等敏感内容。
- Return JSON 输出格式必须严格遵循系统提示词中的 schema,不要输出任何额外文字。
-111
View File
@@ -1,111 +0,0 @@
# -*- coding: utf-8 -*-
"""用墨西哥主题简报装配 MX 提示词产物(Google Trends 429 限流期间离线验证模板效果)。
构造 5 个墨西哥风格 safe 简报 → prompt_node 用 MX 模板装配 image_prompt →
输出 output/MX/pure_print_prompts.{json,md}(结构同 regen 脚本)。
"""
import json
import sys
import datetime
from pathlib import Path
BASE = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(BASE))
import yaml
from graph.nodes.prompt_node import prompt_node
MX_BRIEFS = [
{"topic": "dia de los muertos catrina", "design_category": "Style",
"motif": "elegant catrina sugar skull with marigold flower crown",
"art_style": "vibrant sugar-skull folk art illustration",
"color_palette": "marigold orange, magenta, deep purple, black, gold",
"composition": "centered portrait emblem with floral frame", "risk_level": "safe"},
{"topic": "loteria mexicana cards", "design_category": "Niche",
"motif": "retro loteria card with el corazon symbol",
"art_style": "retro loteria card illustration with bold frame",
"color_palette": "cream, crimson, teal, gold",
"composition": "card-style centered layout with banner", "risk_level": "safe"},
{"topic": "aztec calendar sun", "design_category": "Pattern",
"motif": "aztec sun calendar geometric emblem",
"art_style": "aztec geometric pattern emblem",
"color_palette": "jade green, terracotta, obsidian black, gold",
"composition": "concentric circular sun emblem", "risk_level": "safe"},
{"topic": "taco fiesta food", "design_category": "Niche",
"motif": "happy taco with avocado and chili peppers",
"art_style": "playful colorful mexican food icon illustration",
"color_palette": "cactus green, chili red, corn yellow, avocado green",
"composition": "centered food icon with border", "risk_level": "safe"},
{"topic": "lucha libre luchador mask", "design_category": "Style",
"motif": "luchador wrestler mask with stars",
"art_style": "bold retro lucha libre poster graphic",
"color_palette": "bright red, electric blue, gold, black",
"composition": "centered mask emblem with rays", "risk_level": "safe"},
{"topic": "talavera ceramic tile", "design_category": "Pattern",
"motif": "talavera blue ceramic tile floral motif",
"art_style": "talavera ceramic pattern style",
"color_palette": "cobalt blue, white, yellow, green",
"composition": "repeating tile pattern with central medallion", "risk_level": "safe"},
{"topic": "monarch butterfly migration", "design_category": "Style",
"motif": "monarch butterfly among marigold flowers",
"art_style": "delicate monarch butterfly folk pattern",
"color_palette": "burnt orange, black, white, gold",
"composition": "centered butterfly with floral border", "risk_level": "safe"},
{"topic": "charro horse rider", "design_category": "Style",
"motif": "charro cowboy with sombrero on horseback",
"art_style": "bold charro cowboy folk illustration",
"color_palette": "black, silver, red, gold",
"composition": "centered rider emblem with banner", "risk_level": "safe"},
]
config = yaml.safe_load(open(BASE / "config.yaml", encoding="utf-8"))
mx_cfg = yaml.safe_load(open(BASE / "configs" / "countries" / "MX.yaml", encoding="utf-8"))
state = {
"country": "MX", "config": config, "country_config": mx_cfg,
"screened": MX_BRIEFS, "stats": {},
}
out = prompt_node(state)
briefs = out["briefs"]
out_dir = BASE / "output" / "MX"
out_dir.mkdir(parents=True, exist_ok=True)
result = {
"country": "MX", "country_name": "墨西哥",
"template": "pure_print_15x18cm_to_26x32cm_v3",
"template_source": "config.yaml prompt_templates.countries.MX",
"generated_at": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"total": len(briefs), "safe": len(briefs), "review": 0,
"note": "离线演示产物(Google Trends 429 限流期间用墨西哥主题简报装配);正式数据需等限流恢复后跑流水线",
"items": [
{"topic": b["topic"], "category": b.get("design_category"), "verdict": "safe",
"motif": b["motif"], "art_style": b["art_style"],
"color_palette": b["color_palette"], "composition": b["composition"],
"pure_print_prompt": b["image_prompt"]}
for b in briefs
],
}
(out_dir / "pure_print_prompts.json").write_text(
json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
lines = [
"# 墨西哥(MX)纯印花设计提示词产物(15×18cm ~ 26×32cm · v3 国家化模板)\n",
f"- 生成时间:{result['generated_at']}",
"- 模板来源:config.yaml → prompt_templates.countries.MX",
f"- 说明:{result['note']}",
"- 规则:尺寸 **约 15×18cm ~ 26×32cm 自由选择**;英文/西语短标语可加可不加;**任何文字严禁政治/宗教/仇恨/暴力/性/品牌/商标/真实人物(含 Frida Kahlo)/毒枭等敏感内容**\n",
]
for i, it in enumerate(result["items"], 1):
lines.append(f"## {i}. {it['topic']} [{it['category']}] ✅ 可直接用\n")
lines.append(f"- **motif**{it['motif']}")
lines.append(f"- **art_style**{it['art_style']}")
lines.append(f"- **color_palette**{it['color_palette']}")
lines.append(f"- **composition**{it['composition']}\n")
lines.append("```text")
lines.append(it["pure_print_prompt"])
lines.append("```\n")
(out_dir / "pure_print_prompts.md").write_text("\n".join(lines), encoding="utf-8")
print(f"[MX] 产物生成完成:{len(briefs)}")
for b in briefs:
print(f" {b['topic']} | MX-market={'MX-market' in b['image_prompt']} | Spanish={'Spanish slogan' in b['image_prompt']}")
-76
View File
@@ -1,76 +0,0 @@
# -*- coding: utf-8 -*-
"""JP 流程测试:JPTM001 黑色 × 2 个产品(缓存热点模式)。
步骤:
1) 用 mock 种子(6 style + 6 related)生成 JP 主题简报(JP-market 模板装配)→ 写入 output/JP/design_briefs.json 作为缓存
2) run_product_batchtasks=[JPTM001-BL01 × 2]count=2 → 2 个产品各绑一个热点
3) 验证:选色/热点分配/used 去重/JP 标题模板路由/模板导出
"""
import json
import sys
import time
from pathlib import Path
BASE = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(BASE))
import yaml
from graph.templates import assemble_prompts
config = yaml.safe_load(open(BASE / "config.yaml", encoding="utf-8"))
# 种子词 6 个
config["seed_provider"] = "mock"
cfg = config.setdefault("seed_provider_cfg", {})
cfg["max_style_seeds"] = 6
cfg["max_related_seeds"] = 6
# 图像后端 mock、不上传图床
config["compose"]["backend"] = "mock"
config["product"]["backend"] = "mock"
config["oss"]["enabled"] = False
config["seed_shot"]["count"] = 1
jp_topics = [
("kawaii cat cafe", "Style", "original kawaii cat with latte art", "kawaii style, soft rounded shapes", "pink, cream, caramel", "centered mascot"),
("tokyo neon night", "Style", "original neon street lamps silhouette", "retro cyberpunk flat vector", "magenta, cyan, black", "symmetrical emblem"),
("shiba inu summer", "Style", "original shiba inu with watermelon slice", "cute japanese mascot illustration", "orange, red, white", "centered"),
("sakura spring", "Style", "original cherry blossom branch with petals", "soft minimal japanese print", "sakura pink, white, mint", "corner flourish"),
("osaka takoyaki food", "Style", "original takoyaki balls with bonito flakes", "playful food illustration", "golden brown, red, green", "centered badge"),
("mt fuji sunrise", "Style", "original mt fuji with rising sun rays", "ukiyo-e inspired flat design", "indigo, red, cream", "symmetrical"),
]
tpls = config.get("prompt_templates") or {}
briefs = []
for topic, cat, motif, style, palette, comp in jp_topics:
prompts = assemble_prompts(motif, style, palette, comp, tpls, "JP")
briefs.append({
"country": "JP", "topic": topic, "design_category": cat, "risk_level": "safe",
"score": 80 - len(briefs) * 3, "motif": motif, "art_style": style,
"color_palette": palette, "composition": comp,
"image_prompt": prompts["image_prompt"],
"composite_prompt": prompts["composite_prompt"],
"composite_negative": prompts["composite_negative"],
})
out_dir = BASE / "output" / "JP"
out_dir.mkdir(parents=True, exist_ok=True)
(out_dir / "design_briefs.json").write_text(
json.dumps({"generated_at": time.strftime("%Y-%m-%dT%H:%M:%S"), "total": len(briefs),
"design_briefs": briefs}, ensure_ascii=False, indent=2), encoding="utf-8")
print(f"[setup] JP 缓存热点已写入: {len(briefs)} 条(mock 种子 6/6")
p0 = briefs[0]["image_prompt"]
print("[setup] 模板校验: JP-market 风格段 =", "JP-market" in p0, "| 尺寸上限 26x32 =", "26x32" in p0)
from graph.product_batch import run_product_batch
tasks = [{"spu": "JPTM001", "skus": "JPTM001-BL01"}, # 黑色
{"spu": "JPTM001", "skus": "JPTM001-BL01"}] # 数量 2:同一款号生成 2 个产品
out = run_product_batch("JP", config, BASE, BASE, tasks, 2, log_q=None)
print("\n=== 测试结果 ===")
prods = out.get("product") or []
print("产品数:", len(prods))
for r in prods:
print(f" {r.get('spu_code')} | {r.get('sku_code')} | 色={r.get('color')} | topic={r.get('topic')} | "
f"template={bool(r.get('template_path'))} | design={bool(r.get('design_path'))}")
print("errors:", [e.get("message", "")[:80] for e in out.get("errors") or []])
used = json.loads((out_dir / "used_designs.json").read_text(encoding="utf-8")).get("used", []) if (out_dir / "used_designs.json").exists() else []
print("used_designs 记录:", len(used), "条 →", [u.get("topic") for u in used])
-32
View File
@@ -1,32 +0,0 @@
# -*- coding: utf-8 -*-
"""真实 API 全链路验证:JP JPTM001 黑色 × 1oss 真上传)。"""
import json
import sys
from pathlib import Path
BASE = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(BASE))
import yaml
from graph.product_batch import run_product_batch
config = yaml.safe_load(open(BASE / "dist_v2" / "config.yaml", encoding="utf-8"))
config["seed_provider"] = "openai"
config["llm_screen"]["provider"] = "openai"
config["compose"]["backend"] = "openai"
config["product"]["backend"] = "openai"
config["oss"]["enabled"] = True
config["seed_shot"]["count"] = 1
print("使用配置: llm_model =", config["llm_screen"].get("model"), "| img_model =", config["compose"].get("model"))
out = run_product_batch("JP", config, BASE, BASE / "dist_v2",
[{"spu": "JPTM001", "skus": "JPTM001-BL01"}], 1, log_q=None)
print("\n=== 结果 ===")
prods = out.get("product") or []
print("产品数:", len(prods))
for r in prods:
print(f" {r.get('spu_code')} | {r.get('sku_code')} | design={bool(r.get('design_path'))} "
f"| composite={bool(r.get('composite_path'))} | en_title={bool(r.get('en_title'))} "
f"| ja_title={bool(r.get('ja_title'))} | oss_code={r.get('oss_code')}")
print(" URLs:", {k: v[:60] for k, v in r.items() if k.endswith("_url")})
print("errors:", [e.get("message", "")[:100] for e in out.get("errors") or []])
+111 -37
View File
@@ -93,7 +93,13 @@ class TemplateRouter:
raise ValueError(f"工作簿中不存在工作表 {sheet!r},现有: {self.wb.sheetnames}") raise ValueError(f"工作簿中不存在工作表 {sheet!r},现有: {self.wb.sheetnames}")
self.ws = self.wb[sheet] self.ws = self.wb[sheet]
# 完整表头 -> 列号 (如 "基础信息-商品层级" -> 1 # 布局行号(自动探测,失败回退模块级常量,兼容旧版模版
self.group_row = GROUP_ROW
self.header_row = HEADER_ROW
self.data_start = DATA_START
self._detect_layout()
# 完整表头 -> 列号 (如 "基础信息-商品层级" -> 1,含括号全名别名)
self.header_map: dict[str, int] = {} self.header_map: dict[str, int] = {}
# 列名(去分组) -> 列号 (如 "商品层级" -> 1 # 列名(去分组) -> 列号 (如 "商品层级" -> 1
self.column_map: dict[str, int] = {} self.column_map: dict[str, int] = {}
@@ -101,21 +107,82 @@ class TemplateRouter:
self.col_headers: dict[int, str] = {} self.col_headers: dict[int, str] = {}
self._build_headers() self._build_headers()
# 关键列按列名解析(不依赖固定列号,列名缺失时回退模块级常量)
self.level_col = self.column_map.get("商品层级", LEVEL_COL)
self.spu_code_col = self.column_map.get("SPU货号", SPU_CODE_COL)
self._used_rows: set[int] | None = None # 已占用行缓存,见 _refresh() self._used_rows: set[int] | None = None # 已占用行缓存,见 _refresh()
# ------------------------------------------------------------------
# 布局自动探测
# ------------------------------------------------------------------
def _detect_layout(self) -> None:
"""按固定分组名定位布局(不依赖固定行列)。
分组名(如「基础信息(SKU/SPU均必填)」「SPU商品属性」)是模版固定不变的,
以其为锚点:
1. 分组行 = 含「基础信息」的行(去括号说明后精确匹配,兼容含括号全名);
2. 列名行 = 分组行正下方的列名行(校验含「商品层级」+「SPU货号」);
3. 数据起始行 = 列名行之后第一个整行空行(跳过说明行)。
探测失败时保持模块级常量默认值。
"""
max_col = min(self.ws.max_column, 30)
def row_texts(row: int) -> list[str]:
return [str(self.ws.cell(row, c).value or "").strip()
for c in range(1, max_col + 1)]
# 1) 分组行:按固定分组名「基础信息」匹配
group_row = None
for row in range(1, min(self.ws.max_row, 30) + 1):
for v in row_texts(row):
if _GROUP_BRACKET.sub("", v).strip() == "基础信息" or "基础信息" in v:
group_row = row
break
if group_row:
break
# 2) 列名行:固定位于分组行正下方(校验含「商品层级」+「SPU货号」;
# 列名可能变化,校验失败时直接用分组行正下方一行)
header_row = None
if group_row:
for row in range(group_row + 1, min(self.ws.max_row, group_row + 4) + 1):
vals = row_texts(row)
if any("商品层级" in v for v in vals) and any("SPU货号" in v for v in vals):
header_row = row
break
if header_row is None:
header_row = group_row + 1
# 3) 数据起始行:列名行正下方第2行(列名行→说明行→数据起始行)。
# 不用「第一个空行」——已填写的模版首个空行在数据之后,会漏扫已有数据。
if header_row:
data_start = header_row + 2
if group_row:
self.group_row = group_row
if header_row:
self.header_row = header_row
if data_start:
self.data_start = data_start
# ------------------------------------------------------------------ # ------------------------------------------------------------------
# 表头解析 # 表头解析
# ------------------------------------------------------------------ # ------------------------------------------------------------------
def _build_headers(self) -> None: def _build_headers(self) -> None:
for col in range(1, self.ws.max_column + 1): for col in range(1, self.ws.max_column + 1):
raw_group = self.ws.cell(GROUP_ROW, col).value raw_group = self.ws.cell(self.group_row, col).value
raw_name = self.ws.cell(HEADER_ROW, col).value raw_name = self.ws.cell(self.header_row, col).value
group = _GROUP_BRACKET.sub("", str(raw_group)).strip() if raw_group else "" group_full = str(raw_group).strip() if raw_group else ""
group = _GROUP_BRACKET.sub("", group_full).strip()
name = str(raw_name).strip() if raw_name else "" name = str(raw_name).strip() if raw_name else ""
if not name: if not name:
continue continue
header = f"{group}-{name}" if group else name header = f"{group}-{name}" if group else name
self.header_map[header] = col self.header_map[header] = col
if group_full and group_full != group:
# 完整分组名(含括号说明)别名,如「基础信息(SKU/SPU均必填)-商品层级」
self.header_map[f"{group_full}-{name}"] = col
self.column_map[name] = col self.column_map[name] = col
self.col_headers[col] = header self.col_headers[col] = header
@@ -134,19 +201,19 @@ class TemplateRouter:
return m return m
def _refresh_used_rows(self) -> None: def _refresh_used_rows(self) -> None:
"""扫描数据区,收集 A 列(商品层级)非空的行号集合。""" """扫描数据区,收集商品层级列(按列名解析)非空的行号集合。"""
used: set[int] = set() used: set[int] = set()
for row in range(DATA_START, self.ws.max_row + 1): for row in range(self.data_start, self.ws.max_row + 1):
v = self.ws.cell(row, LEVEL_COL).value v = self.ws.cell(row, self.level_col).value
if v is not None and str(v).strip(): if v is not None and str(v).strip():
used.add(row) used.add(row)
self._used_rows = used self._used_rows = used
def first_empty_row(self, start: int = DATA_START) -> int: def first_empty_row(self, start: int | None = None) -> int:
"""返回数据区第一个空行(A 列为空)。""" """返回数据区第一个空行(A 列为空)。"""
if self._used_rows is None: if self._used_rows is None:
self._refresh_used_rows() self._refresh_used_rows()
row = max(start, DATA_START) row = max(start or self.data_start, self.data_start)
while row in self._used_rows: while row in self._used_rows:
row += 1 row += 1
return row return row
@@ -161,8 +228,8 @@ class TemplateRouter:
spu_code = str(spu_code).strip().lower() spu_code = str(spu_code).strip().lower()
match = self._normalize_match(match) match = self._normalize_match(match)
hits = [] hits = []
for row in range(DATA_START, self.ws.max_row + 1): for row in range(self.data_start, self.ws.max_row + 1):
v = self.ws.cell(row, SPU_CODE_COL).value v = self.ws.cell(row, self.spu_code_col).value
if v is None: if v is None:
continue continue
v = str(v).strip().lower() v = str(v).strip().lower()
@@ -171,15 +238,15 @@ class TemplateRouter:
return hits return hits
def find_sku_rows(self, spu_code: str, match: str = "exact") -> list[int]: def find_sku_rows(self, spu_code: str, match: str = "exact") -> list[int]:
"""按 SPU货号(B列+ 层级=skuA列)查找所有 SKU 行号(单 SPU 多色时无 SPU 行,SKU 行即全部)。""" """按 SPU货号(按列名解析+ 层级=sku商品层级列)查找所有 SKU 行号(单 SPU 多色时无 SPU 行,SKU 行即全部)。"""
spu_code = str(spu_code).strip().lower() spu_code = str(spu_code).strip().lower()
match = self._normalize_match(match) match = self._normalize_match(match)
hits = [] hits = []
for row in range(DATA_START, self.ws.max_row + 1): for row in range(self.data_start, self.ws.max_row + 1):
lv = self.ws.cell(row, LEVEL_COL).value lv = self.ws.cell(row, self.level_col).value
if lv is None or str(lv).strip().lower() != "sku": if lv is None or str(lv).strip().lower() != "sku":
continue continue
v = self.ws.cell(row, SPU_CODE_COL).value v = self.ws.cell(row, self.spu_code_col).value
if v is None: if v is None:
continue continue
v = str(v).strip().lower() v = str(v).strip().lower()
@@ -189,7 +256,7 @@ class TemplateRouter:
def find_level_rows(self, level: str, match: str = "exact") -> list[int]: def find_level_rows(self, level: str, match: str = "exact") -> list[int]:
""" """
按 商品层级(A列)查找所有行号。 按 商品层级(按列名解析)查找所有行号。
match="exact"(默认):精准匹配,去首尾空格后完全相等(不区分大小写); match="exact"(默认):精准匹配,去首尾空格后完全相等(不区分大小写);
match="fuzzy" :模糊匹配,层级包含关键字即命中(不区分大小写)。 match="fuzzy" :模糊匹配,层级包含关键字即命中(不区分大小写)。
@@ -197,8 +264,8 @@ class TemplateRouter:
level = str(level).strip().lower() level = str(level).strip().lower()
match = self._normalize_match(match) match = self._normalize_match(match)
hits = [] hits = []
for row in range(DATA_START, self.ws.max_row + 1): for row in range(self.data_start, self.ws.max_row + 1):
v = self.ws.cell(row, LEVEL_COL).value v = self.ws.cell(row, self.level_col).value
if v is None: if v is None:
continue continue
v = str(v).strip().lower() v = str(v).strip().lower()
@@ -278,13 +345,27 @@ class TemplateRouter:
return column_index_from_string(key_s.upper()) return column_index_from_string(key_s.upper())
raise KeyError(f"无法识别的表头: {key!r}(可用完整表头/列名/列号/列字母)") raise KeyError(f"无法识别的表头: {key!r}(可用完整表头/列名/列号/列字母)")
def _value_by_col(self, data: dict, name: str):
"""从 data 中按列名取第一个匹配的值(键可为完整表头/列名/列号/列字母)。"""
col = self.column_map.get(name)
if col is None:
return None
for k, v in data.items():
try:
if self.resolve_col(k) == col:
return v
except KeyError:
continue
return None
def insert(self, data: dict, spu_code: str | None = None, def insert(self, data: dict, spu_code: str | None = None,
level: str | None = None, update: bool = False, level: str | None = None, update: bool = False,
match: str = "exact") -> int: match: str = "exact") -> int:
""" """
插入一行数据到模版表。data 键支持:完整表头(推荐)、列名、列号、列字母。 插入一行数据到模版表。data 键支持:完整表头(推荐)、列名、列号、列字母。
- 若 data 中带「商品层级/基础信息-商品层级」则自动取其值路由; - 若 data 中带「商品层级」(任意键形式,如「基础信息(SKU/SPU均必填)-商品层级」/
「基础信息-商品层级」/「商品层级」)则自动取其值路由;
- 传 spu_code 会把该行路由到对应 SPU 行之后(SKU 关联); - 传 spu_code 会把该行路由到对应 SPU 行之后(SKU 关联);
- update=True 时覆盖已存在的目标行,否则写入新空行; - update=True 时覆盖已存在的目标行,否则写入新空行;
- match 控制货号/层级的匹配模式:exact(精准,默认) / fuzzy(模糊),见 route()。 - match 控制货号/层级的匹配模式:exact(精准,默认) / fuzzy(模糊),见 route()。
@@ -293,25 +374,18 @@ class TemplateRouter:
""" """
match = self._normalize_match(match) match = self._normalize_match(match)
# 1) 解析层级与 spu_code # 1) 解析层级与 spu_code(按列名匹配,不依赖固定键名/列号)
lv = level lv = level if level is not None else self._value_by_col(data, "商品层级")
if lv is None: lv_s = str(lv).strip().lower() if lv is not None else ""
for k in ("基础信息-商品层级", "商品层级", LEVEL_COL):
if k in data:
lv = data[k]
break
# 只有「SKU 层」才需要按 SPU货号 关联路由;SPU/单sku商品 层走新行路由 # 只有「SKU 层」或未声明层级时才按 SPU货号 关联路由;SPU/单sku商品 层走新行路由
use_spu_route = spu_code is not None spu = spu_code
if spu_code is None: use_spu_route = spu is not None
if lv is not None and str(lv).strip().lower() == "sku" and "SPU货号" in data: if spu is None and (lv_s == "sku" or lv is None):
use_spu_route = True # sku 层 -> 插到所属 SPU 行之后 spu = self._value_by_col(data, "SPU货号")
elif lv is None and "SPU货号" in data and self.find_spu_rows(data["SPU货号"], match): if spu is not None:
use_spu_route = True # 无层级但货号已存在 -> 视为该 SPU 的变体行 use_spu_route = True
spu = spu_code if use_spu_route else None if use_spu_route and spu is not None and not self.find_spu_rows(spu, match):
if use_spu_route and spu is None:
spu = data["SPU货号"]
if not self.find_spu_rows(spu, match):
use_spu_route = False # 无 SPU 行(单 SPU 多色,不填 SPU 行)→ 按层级末尾追加 use_spu_route = False # 无 SPU 行(单 SPU 多色,不填 SPU 行)→ 按层级末尾追加
spu = None spu = None
+25 -24
View File
@@ -31,7 +31,7 @@ import yaml
from graph.agent import run_country from graph.agent import run_country
COUNTRIES = ["US", "GB", "JP", "AU", "MX"] COUNTRIES = ["US", "GB", "JP", "AU", "MX", "DE", "BR", "SA", "PL", "ES", "IT", "CA"]
# LLM 只适配 OpenAI 兼容协议:openai(真调用,可在下方配置自定义模型/URL/Key)/ mock(无 key 演示占位) # LLM 只适配 OpenAI 兼容协议:openai(真调用,可在下方配置自定义模型/URL/Key)/ mock(无 key 演示占位)
PROVIDERS = ["openai", "mock"] PROVIDERS = ["openai", "mock"]
@@ -194,7 +194,7 @@ def _apply_provider_mode(config: dict, provider: str) -> None:
f"llm_screen={ls['provider']} compose={cp['backend']} product={pp['backend']}") f"llm_screen={ls['provider']} compose={cp['backend']} product={pp['backend']}")
def fetch_keywords(country, provider, max_style, max_related, log_q, oai=None): def fetch_keywords(country, provider, max_seeds, log_q, oai=None):
"""后台线程:仅跑「采集+去重过滤」链路(seed→fetch→filter), """后台线程:仅跑「采集+去重过滤」链路(seed→fetch→filter),
把过滤后的关键词(数量不定)实时回传 UI 显示。""" 把过滤后的关键词(数量不定)实时回传 UI 显示。"""
from graph.agent import build_country_config from graph.agent import build_country_config
@@ -205,8 +205,7 @@ def fetch_keywords(country, provider, max_style, max_related, log_q, oai=None):
config = load_config() config = load_config()
config["seed_provider"] = provider config["seed_provider"] = provider
cfg = config.setdefault("seed_provider_cfg", {}) cfg = config.setdefault("seed_provider_cfg", {})
cfg["max_style_seeds"] = max_style cfg["max_seeds"] = max_seeds
cfg["max_related_seeds"] = max_related
apply_openai_cfg(config, oai) apply_openai_cfg(config, oai)
_apply_provider_mode(config, provider) # OpenAI 模式开关(采集只用 seed,其余为后续统一) _apply_provider_mode(config, provider) # OpenAI 模式开关(采集只用 seed,其余为后续统一)
@@ -278,7 +277,7 @@ def fetch_keywords(country, provider, max_style, max_related, log_q, oai=None):
log_q.put(("log", f"[UI] 缓存打包失败: {e}\n")) log_q.put(("log", f"[UI] 缓存打包失败: {e}\n"))
def run_pipeline(countries, provider, max_style, max_related, log_q, def run_pipeline(countries, provider, max_seeds, log_q,
spu_code="", sku_code="", spu_count=0, spu_code="", sku_code="", spu_count=0,
spu_tasks=None, oai=None, markup_percent=0.0, code_prefix="DG", spu_tasks=None, oai=None, markup_percent=0.0, code_prefix="DG",
template_path=""): template_path=""):
@@ -297,8 +296,7 @@ def run_pipeline(countries, provider, max_style, max_related, log_q,
config = load_config() config = load_config()
config["seed_provider"] = provider config["seed_provider"] = provider
cfg = config.setdefault("seed_provider_cfg", {}) cfg = config.setdefault("seed_provider_cfg", {})
cfg["max_style_seeds"] = max_style cfg["max_seeds"] = max_seeds
cfg["max_related_seeds"] = max_related
apply_openai_cfg(config, oai) apply_openai_cfg(config, oai)
# OpenAI 模式开关:provider=openai → 全链路真 LLM/真生图;mock → 全 mock 演示 # OpenAI 模式开关:provider=openai → 全链路真 LLM/真生图;mock → 全 mock 演示
_apply_provider_mode(config, provider) _apply_provider_mode(config, provider)
@@ -451,21 +449,19 @@ class App(tk.Tk):
top.pack(fill="x") top.pack(fill="x")
ttk.Label(top, text="国家:").pack(side="left") ttk.Label(top, text="国家:").pack(side="left")
self.country_var = tk.StringVar(value="US") self.country_var = tk.StringVar(value="US")
for c in COUNTRIES: self.country_combo = ttk.Combobox(top, textvariable=self.country_var,
ttk.Radiobutton(top, text=c, value=c, variable=self.country_var, values=COUNTRIES, state="readonly", width=6)
command=self._on_country_selected).pack(side="left", padx=4) self.country_combo.pack(side="left", padx=4)
self.country_combo.bind("<<ComboboxSelected>>", lambda e: self._on_country_selected())
ttk.Label(top, text=" 模式:").pack(side="left", padx=(14, 0)) ttk.Label(top, text=" 模式:").pack(side="left", padx=(14, 0))
self.provider_var = tk.StringVar(value=self._default_provider()) self.provider_var = tk.StringVar(value=self._default_provider())
ttk.Radiobutton(top, text="OpenAI(真 LLM+生图)", value="openai", ttk.Radiobutton(top, text="OpenAI(真 LLM+生图)", value="openai",
variable=self.provider_var).pack(side="left", padx=2) variable=self.provider_var).pack(side="left", padx=2)
ttk.Radiobutton(top, text="Mock 演示", value="mock", ttk.Radiobutton(top, text="Mock 演示", value="mock",
variable=self.provider_var).pack(side="left", padx=2) variable=self.provider_var).pack(side="left", padx=2)
ttk.Label(top, text=" 种子上限:").pack(side="left", padx=(14, 0)) ttk.Label(top, text=" 种子数量:").pack(side="left", padx=(14, 0))
self.style_var = tk.StringVar(value="12") self.seed_var = tk.StringVar(value="24")
ttk.Entry(top, textvariable=self.style_var, width=4).pack(side="left") ttk.Entry(top, textvariable=self.seed_var, width=4).pack(side="left")
ttk.Label(top, text="/").pack(side="left")
self.related_var = tk.StringVar(value="12")
ttk.Entry(top, textvariable=self.related_var, width=4).pack(side="left")
# 右上角:热点状态(缓存时间 / 采集时间) # 右上角:热点状态(缓存时间 / 采集时间)
self.hotspot_time_var = tk.StringVar(value="") self.hotspot_time_var = tk.StringVar(value="")
ttk.Label(top, textvariable=self.hotspot_time_var, anchor="e", ttk.Label(top, textvariable=self.hotspot_time_var, anchor="e",
@@ -763,10 +759,9 @@ class App(tk.Tk):
if self._busy: if self._busy:
return return
try: try:
ms = int(self.style_var.get()) ms = int(self.seed_var.get())
mr = int(self.related_var.get())
except ValueError: except ValueError:
messagebox.showerror("参数错误", "种子上限必须是数字") messagebox.showerror("参数错误", "种子数量必须是数字")
return return
try: try:
int(self.count_var.get()) int(self.count_var.get())
@@ -780,7 +775,7 @@ class App(tk.Tk):
self.run_btn.config(state="disabled") self.run_btn.config(state="disabled")
threading.Thread( threading.Thread(
target=fetch_keywords, target=fetch_keywords,
args=(self.country_var.get(), self.provider_var.get(), ms, mr, self._q, args=(self.country_var.get(), self.provider_var.get(), ms, self._q,
self._oai_cfg()), self._oai_cfg()),
daemon=True, daemon=True,
).start() ).start()
@@ -817,6 +812,13 @@ class App(tk.Tk):
"JP": ("日本站", "日本"), "JP": ("日本站", "日本"),
"AU": ("澳大利亚站", "澳洲站", "澳洲"), "AU": ("澳大利亚站", "澳洲站", "澳洲"),
"MX": ("墨西哥站", "墨西哥"), "MX": ("墨西哥站", "墨西哥"),
"DE": ("德国站", "德国"),
"BR": ("巴西站", "巴西"),
"SA": ("沙特站", "沙特阿拉伯站", "沙特阿拉伯", "沙特"),
"PL": ("波兰站", "波兰"),
"ES": ("西班牙站", "西班牙"),
"IT": ("意大利站", "意大利"),
"CA": ("加拿大站", "加拿大"),
} }
allowed = country_sites.get(str(self.country_var.get()).upper(), ()) allowed = country_sites.get(str(self.country_var.get()).upper(), ())
site_name = "" site_name = ""
@@ -887,12 +889,11 @@ class App(tk.Tk):
return return
countries = [self.country_var.get()] countries = [self.country_var.get()]
try: try:
ms = int(self.style_var.get()) ms = int(self.seed_var.get())
mr = int(self.related_var.get())
spu_count = int(self.count_var.get()) spu_count = int(self.count_var.get())
markup = float(self.markup_var.get()) markup = float(self.markup_var.get())
except ValueError: except ValueError:
messagebox.showerror("参数错误", "种子上限 / 款号数量 / 加价% 必须是数字") messagebox.showerror("参数错误", "种子数量 / 款号数量 / 加价% 必须是数字")
return return
if spu_count < 1: if spu_count < 1:
messagebox.showerror("参数错误", "款号数量必须 ≥ 1(不支持无上限)") messagebox.showerror("参数错误", "款号数量必须 ≥ 1(不支持无上限)")
@@ -935,7 +936,7 @@ class App(tk.Tk):
self.fetch_btn.config(state="disabled") self.fetch_btn.config(state="disabled")
threading.Thread( threading.Thread(
target=run_pipeline, target=run_pipeline,
args=(countries, self.provider_var.get(), ms, mr, self._q, args=(countries, self.provider_var.get(), ms, self._q,
"", "", spu_count, tasks, self._oai_cfg(), markup, "", "", spu_count, tasks, self._oai_cfg(), markup,
self.code_prefix_var.get().strip() or "DG", self.code_prefix_var.get().strip() or "DG",
self.template_path_var.get().strip()), self.template_path_var.get().strip()),
+294
View File
@@ -0,0 +1,294 @@
# POD 趋势感知 Agent · 对接文档
> 面向开发者/维护者的适配与扩展指南。覆盖:项目架构、**如何适配新国家**、核心流程、缓存机制、合规红线、常见问题与打包发布。
> 适用版本:dist_v67 / 源码 `pod_trend_agent/`
---
## 1. 项目概览
**目标**:为 PODPrint on Demand)出海业务自动捕捉海外热点 → 生成可打印的 T 恤印花设计 → 三图合成模特图 → 多语言标题 → 导出商品上传模板。
**技术栈**Python 3.13 · LangGraph7 节点流水线)· tkinter 桌面 UI · requests · Pillow · PyInstaller 打包
**两条运行路径**
| 路径 | 触发条件 | 行为 |
|---|---|---|
| **缓存热点模式**(日常) | `output/<国>/collected_keywords.json` 存在 | 直接用采集缓存分配热点;简报不足时**从采集缓存自动生成简报**(轻量补齐),**绝不触发 Google** |
| **完整流水线**(首次) | 完全无缓存 | `seed → fetch → filter → score → screen → prompt_build → compose → product → seed_shot → template_export → oss_upload` |
---
## 2. 目录结构
```
pod_trend_agent/
├── ui_app.py # 桌面 UI:选品/采集/运行/模板/结果表格
├── cli.py # 命令行入口
├── config.yaml # 全局配置(countries/sources/llm_screen/prompt_templates/compose/oss/product…)
├── configs/countries/<CC>.yaml# ★每国独立配置:种子词/related 种子/采集限额
├── prompts/<CC>/ # ★每国提示词:system_prompt.md + aesthetics.yaml
├── graph/
│ ├── agent.py # LangGraph 流水线编排(START→seed→fetch→…→END
│ ├── nodes/ # 各节点实现(seed/fetch/filter/score/screen/prompt/compose/product/seed_shot/template/oss
│ ├── product_batch.py # 缓存热点批量流程:分配/三级去重/review 兜底/轻量补齐
│ ├── backends/ # 图像后端:openai_image_backend / mock_image_backend
│ ├── llms/ # LLM 后端:openai_compat_backend(多模态标题)/ mock_backend
│ ├── seeds/ # 种子策略:dynamic_strategy(统一池+加权随机)/ static / holidays
│ ├── sources/ # 数据源注册表:google_trendspytrends429 兜底)/ pinterest
│ ├── product.py # 底图/模特查找(IMG_EXTS 全格式)、SKU 逻辑
│ ├── style_rules.py # 风格/配色/构图规则 + sanitize_image_prompt + review 魔改引导
│ ├── paths.py # config_root / project_root / runtime_root 路径解析
│ └── validate.py # 校验 + with_fallback 兜底装饰器
├── templates/ # 商品上传模板 + template_router.py(模板读写)
├── basemap/<款号>/<颜色>/ # 平铺底图(jpg/png…)
├── material_library/<品类>/ # 模特图(webp/jpg/png/avif…)
├── db/ # 商品数据库(sqlite
└── dist_vNN/ # PyInstaller 打包产物(含全部数据)
```
---
## 3. ★适配新国家(核心章节)
以新增 **DE(德国)** 为例,完整步骤:
### 3.1 国家代码入列
`config.yaml`
```yaml
countries:
- US
- GB
- JP
- AU
- MX
- DE # ← 新增
```
### 3.2 每国配置 `configs/countries/DE.yaml`
```yaml
# 德国专属数据源配置
trending:
enabled: true
limit: 40 # Google Trends 抓取上限
style:
enabled: true
seeds: # ★印花风格种子词(重点,越多越好,20~30 个)
- lederhosen
- alpine
- berlin street art
- bauhaus pattern
- autobahn
- ...
related:
enabled: true
seed_keywords:
- ...
exclude_topics: [] # 黑名单热点(已用过/明确不分配的词,可选)
```
**种子词选词红线**(写配置时注意):
- ❌ 会被 `review 兜底 _UNSUITABLE` 剔除的类目:`nails / recipes / lottery / weather / results / prices / jobs / mortgage / election…`(见 `graph/product_batch.py`
- ❌ 品牌/版权/真实人物:`nike / disney / margot robbie / prison break…`
- ❌ 图像策略敏感词:`skull / skeleton / blood / gun / demon…`(生成时会被 `sanitize_image_prompt` 替换,主题会变味)
- ✅ 用各国**本土流行 + 全球趋势**的印花主题(2026 参考:retro vintage / 极简 typography / 自然户外 / 手绘涂鸦 / Y2K / coquette / western / 幽默 quote / 星座塔罗 / 植物线稿)
### 3.3 每国提示词 `prompts/DE/`
- **`system_prompt.md`**screen 阶段 LLM 的角色/输出规则(风险判定、motif/art_style/color_palette/composition 四要素),**必须包含 "Return JSON…" 字样**(阿里云 MaaS 的 `response_format=json_object` 硬性要求)。
- **`aesthetics.yaml`**
```yaml
extra_style_rules: [...] # 该国风格倾向(配色/构图/审美)
extra_blacklist: [...] # 该国合规红线词(德国:纳粹符号等)
```
### 3.4 节假日 `graph/seeds/holidays.py`
`_HOLIDAYS_BY_COUNTRY` 增加国家节日(名称/月/日/规则/窗口),节日种子词自动带权重 3.0 进入统一池:
```python
"DE": [
("Oktoberfest", 9, 21, "third_saturday", 30), # 啤酒节(9 月)
("Weihnachten", 12, 25, "fixed", 25), # 圣诞节
...
]
```
### 3.5 国家模板站点校验 `ui_app.py`
`_check_template_site` 的 `country_sites` 字典加国家→站点关键词:
```python
country_sites = {
...
"DE": ("德国站", "德国"),
}
```
(模板「模版」sheet 第 1 行定位「经营站点」列 → 第 2 行站点名 → 与所选国家不匹配则**导入失败**,提示重新导入)
### 3.6 图像提示词模板 `config.yaml → prompt_templates`
`image_prompt` / `wearable_prompt` / `composite_prompt` 各加国家版本(`{motif}` 等占位符保持不变),注意:
- **提示词中不得出现任何背景描述**"isolated on … background"、"no background scene")——透明背景只由 `background="transparent"` 参数控制(官方要求)
- 不含安全规则段("no politics / no religion / no hate / no violence / no sexual"——这些词本身会触发图像 API 内容政策拦截)
### 3.7 验证清单
```bash
python cli.py -c DE --provider mock # mock 跑通全流程(不花钱)
python -c "from graph.seeds.dynamic_strategy import DynamicStrategy; ..." # 验证种子池
# UI 打开 → 切 DE → 采集 → 运行
```
---
## 4. 核心流程详解
### 4.1 完整流水线(LangGraph 7 节点)
```
START → seed(种子词) → fetch(采集) → filter(过滤) → score(打分) → screen(风险筛选+简报)
→ prompt_build(提示词) → compose(设计稿) → product(合成/标题) → seed_shot(种草图)
→ template_export(模板) → oss_upload(压缩上传) → END
```
每个节点均套 `with_fallback` 兜底(失败不中断整体流程)。
### 4.2 缓存热点模式(日常入口,`ui_app` / `run_product_batch`
```
判断:output/<国>/ 有 collected_keywords.json 或 design_briefs.json → 缓存模式
→ load 简报(简报不足 → _rebuild_briefs_from_cache 从采集缓存生成,不碰 Google)
→ assign_hotspots 分配(三级去重 + review 兜底)
→ product 节点批量处理(并发 ≤5,每 SPU 一线程)
→ 模板导出
```
### 4.3 热点分配与去重(`assign_hotspots`
| 层级 | 逻辑 |
|---|---|
| ① 热点去重 | 本批优先不同 topic(热点1-风格1、热点2-风格1…) |
| ② 风格去重 | 热点用完后自动切:热点1-风格2、热点2-风格2…(同 topic 不同 art_style |
| ③ 兜底 | 剩余未用指纹(低分热点也可);**历史已用 (topic, style) 指纹绝不重复出** |
| review 兜底 | `_UNSUITABLE` 正则剔除不适合类目(美甲/食谱/彩票/天气/比分…),日志提示 |
### 4.4 种子词机制(`dynamic_strategy.py`
- **统一池**:静态 style + 静态 related + 月份主题 + 节日 + LLM 动态 → 全部合并去重(跨类型同词权重累加)
- **权重**:节日 3.0 > 月份主题 2.0 > 静态/动态 1.0(加权随机抽取)
- **每次随机取**(加权不重复);**用完全用**(池 ≤ 需要数时全部使用,不随机限量)
- 每国独立配置(`configs/countries/<CC>.yaml`),种子缓存 `.cache/seeds/`(按 国家+provider+日期,防 Google 429
---
## 5. 缓存文件
| 文件 | 位置 | 作用 |
|---|---|---|
| `collected_keywords.json` | `output/<国>/` | 采集热点池(关键词列表) |
| `design_briefs.json` | `output/<国>/` | 简报池(topic/motif/risk/score/image_prompt…) |
| `used_designs.json` | `output/<国>/` | 已用 (topic, art_style) 指纹(成功生成才写入) |
| `.cache/seeds/` | 项目根 | 种子词日缓存(防 429 重采集) |
| `.cache/llm_screen/` | 项目根 | LLM 筛查缓存 |
> 注意:**失败产品不写 used_designs**(合成/设计失败的,热点下次仍可用)。
> 已用过不要的热点:直接从 `collected_keywords.json` / `design_briefs.json` 物理删除即可(如 8-22 的 18 个 GB 热点处理方式)。
---
## 6. 合规红线(最重要)
1. **review 判定**screen 阶段 LLM 判定疑似商标/版权/真实人物 → `risk_level=review`;openai 模式下生成设计时**自动注入原创化魔改引导**(`REVIEW_REBRAND_HINT`:只做风格参考、禁止复刻 logo/商标/角色、换名换细节)
2. **提示词清洗** `sanitize_image_prompt`(生成设计前必过):
- 删除一切背景描述(透明背景由参数控制)
- 删除内容策略触发段(`any text must be safe: no politics/religion/hate/violence/sexual…`
- 21+ 个敏感词安全替换(skull→smiley mascot、gun→star…)
3. **各国红线**:美国慎政治/宗教;德国慎纳粹符号(`aesthetics.yaml extra_blacklist` 扩展);中东整体保守;真实人物一律不进
4. **review 兜底 `_UNSUITABLE`**:不适合类目自动剔除(分配源头拦截)
---
## 7. 图像生成与合成
### 7.1 设计稿生成(`compose` / `product` 的 `generate`
- **透明背景**`background="transparent"` 参数(compose/product 配置均已设);**提示词不得提背景**
- 并发:compose 并发生成(`compose.design_workers` 默认 5);product 阶段每 SPU 一线程,并发上限 5
- 底图/模特/设计 >2MB → 自动压缩到 <2MB 再上传网关(`_shrink_blob_to_2mb`
### 7.2 三图合成(`product` 的 `print`mark=1
- 上传顺序:**图1 模特图 → 图2 印花设计稿 → 图3 衣服平铺底图**(与提示词角色一一对应)
- 图3 只提取衣服本身底色与面料材质(忽略平铺图背景/桌面/场景)
- 合成失败 → 退避重试 3 次(5/20/40s);仍失败 → 跳过该产品(不生成标题、不写模板)
- 网关处理约 2-6 分钟属正常(重负载 img2img)
---
## 8. 模型与网络配置(`config.yaml`
```yaml
llm_screen: # LLMscreen/种子/标题共用)
model: "qwen3.7-..." # ★标题生成需视觉模型(qwen-vl 系列);纯文本模型会 400
base_url: "https://...maas.aliyuncs.com/compatible-mode/v1"
api_key: "sk-..." # 或环境变量 LLM_API_KEY
compose: # 设计稿图像网关
backend: "openai"
model: "gpt-image-2" # 支持 background=transparent
base_url: "https://api.tofastcode.xyz"
background: "transparent"
product:
backend: "mock" # openai / mock
background: "transparent"
concurrency: 5 # 合成并发上限(默认 min(任务数,5))
```
**代理策略**:模型调用(LLM + 图像)一律直连(`NO_PROXY` + 环境变量级 `no_proxy=*`,用户挂 VPN 也不走代理);**Google 采集(pytrends)走系统代理**(需要 VPN)。
---
## 9. 打包发布(每版流程)
```bash
# 1. 打包(不跑 self-test:会撞 Google 429,浪费 7-10 分钟)
pyinstaller -y PODTrendAgent.spec --distpath dist_vNN --workpath build_cleanNN
# 2. 补齐 dist 数据(必须,否则 exe 缺资源)
cp -r templates db basemap material_library configs prompts .cache dist_vNN/
cp config.yaml dist_vNN/
# 3. 拷贝最近缓存(output/<国>/*.json),避免 exe 首次运行重新采集
# 4. 验证:find_first_model_folder 能查到模特(material_library 拷贝不完整是常见坑)
```
---
## 10. 常见问题(FAQ
| 现象 | 根因 | 解决 |
|---|---|---|
| 有缓存还去采集(Google 429 刷屏) | UI 判断只看 design_briefs,忽略 collected | v60+ 已修:有 collected 即缓存模式,绝不触发 seed/fetch |
| Google 429 / SSL EOF | 限流 | 换 VPN 节点;已采集后运行走缓存不再碰 Google |
| 三图合成全部超时 | 并发过高压垮网关 / 底图过大 | 并发上限 5 + 输入图压缩 <2MB + 退避重试 |
| 生成设计全是商标侵权 | review 简报未魔改 | v57+ 自动注入 REVIEW_REBRAND_HINT |
| 内容政策拦截频繁 | 提示词含敏感词/安全规则段/背景描述 | sanitize_image_prompt 自动清理 |
| 设计稿不透明(RGB 白底) | product 后端未配 background | `product.background: transparent` |
| 标题 400 | 模型不支持图片输入(非视觉模型) | 换 qwen-vl 系列视觉模型 |
| 模特找不到 | material_library 拷贝不全 / avif 不识别 | 全量拷贝;IMG_EXTS 已含 avif/gif/tiff |
| 生成的设计 6 个重复 | compose 只生成 safe 简报的设计 | v48+ 为全部简报(含 review)生成设计 |
---
## 11. 开发环境
```bash
python -m venv .venv
.venv/Scripts/pip install -r requirements.txt # 或 uv syncuv.lock 已锁定)
# 环境变量:LLM_API_KEY / LLM_BASE_URL / OSS_ACCESS_KEY_ID / OSS_ACCESS_KEY_SECRET
```
**对接新国家一句话总结**`configs/countries/<CC>.yaml`(种子词)+ `prompts/<CC>/`(提示词)+ `holidays.py`(节日)+ `config.yaml countries 列表` + UI 国家下拉 + 模板站点映射 → mock 跑通 → 真 LLM 验证。