""" 专业玉雕设计提示词构建器(数据库版) 从数据库 prompt_templates + prompt_mappings 读取配置,支持后台热更新 """ import logging from typing import Optional, Dict, List from ..database import SessionLocal from ..models.prompt_template import PromptTemplate, PromptMapping logger = logging.getLogger(__name__) # ============================================================ # 品类视角配置(保留硬编码,因为与业务流程强关联) # ============================================================ CATEGORY_VIEWS: Dict[str, List[str]] = { "牌子": ["效果图", "正面图", "背面图"], "珠子": ["效果图", "正面图"], "手把件": ["效果图", "正面图", "侧面图", "背面图"], "雕刻件": ["效果图", "正面图", "侧面图", "背面图"], "摆件": ["效果图", "正面图", "侧面图", "背面图"], "手镯": ["效果图", "正面图", "侧面图"], "耳钉": ["效果图", "正面图"], "耳饰": ["效果图", "正面图"], "手链": ["效果图", "正面图"], "项链": ["效果图", "正面图"], "戒指": ["效果图", "正面图", "侧面图"], "表带": ["效果图", "正面图"], "随形": ["效果图", "正面图", "侧面图", "背面图"], } def _load_mappings(mapping_type: str) -> Dict[str, str]: """从数据库加载指定类型的映射字典""" try: db = SessionLocal() try: rows = db.query(PromptMapping).filter( PromptMapping.mapping_type == mapping_type ).order_by(PromptMapping.sort_order).all() return {r.cn_key: r.en_value for r in rows} finally: db.close() except Exception as e: logger.warning(f"加载映射 {mapping_type} 失败: {e}") return {} def _load_template(template_key: str, default: str = "") -> str: """从数据库加载模板""" try: db = SessionLocal() try: tpl = db.query(PromptTemplate).filter( PromptTemplate.template_key == template_key ).first() if tpl: return tpl.template_value finally: db.close() except Exception as e: logger.warning(f"加载模板 {template_key} 失败: {e}") return default def get_views_for_category(category_name: str) -> List[str]: """获取品类对应的视角列表""" return CATEGORY_VIEWS.get(category_name, ["效果图", "正面图"]) def build_prompt( category_name: str, view_name: str, sub_type_name: Optional[str] = None, color_name: Optional[str] = None, user_prompt: Optional[str] = None, carving_technique: Optional[str] = None, design_style: Optional[str] = None, motif: Optional[str] = None, size_spec: Optional[str] = None, surface_finish: Optional[str] = None, usage_scene: Optional[str] = None, ) -> str: """ 构建专业英文生图提示词(从数据库读取映射和模板) 业务逻辑:用户参数 → 中英映射 → 填入模板 → 最终prompt """ # 从数据库加载所有映射 category_map = _load_mappings("category") color_map = _load_mappings("color") view_map = _load_mappings("view") carving_map = _load_mappings("carving") style_map = _load_mappings("style") motif_map = _load_mappings("motif") finish_map = _load_mappings("finish") scene_map = _load_mappings("scene") sub_type_map = _load_mappings("sub_type") # 加载模板 quality_suffix = _load_template("quality_suffix", "professional jewelry product photography, studio lighting setup, pure white background, ultra-detailed, sharp focus, 8K resolution, photorealistic rendering, high-end commercial quality") default_color = _load_template("default_color", "natural Hetian nephrite jade with warm luster") # 构建各部分 parts = [] # 1. 品类主体 subject = category_map.get(category_name, f"Chinese Hetian nephrite jade {category_name}") parts.append(subject) # 2. 子类型 if sub_type_name: sub_detail = sub_type_map.get(sub_type_name, sub_type_name) parts.append(sub_detail) # 3. 颜色 if color_name: color_desc = color_map.get(color_name, f"{color_name} colored nephrite jade") parts.append(color_desc) else: parts.append(default_color) # 4. 题材纹样 if motif: motif_desc = motif_map.get(motif, f"{motif} themed design") parts.append(f"featuring {motif_desc}") # 5. 雕刻工艺 if carving_technique: tech_desc = carving_map.get(carving_technique, carving_technique) parts.append(tech_desc) # 6. 设计风格 if design_style: style_desc = style_map.get(design_style, design_style) parts.append(style_desc) # 7. 表面处理 if surface_finish: finish_desc = finish_map.get(surface_finish, surface_finish) parts.append(finish_desc) # 8. 用途场景 if usage_scene: scene_desc = scene_map.get(usage_scene, usage_scene) parts.append(scene_desc) # 9. 尺寸 if size_spec: parts.append(f"size approximately {size_spec}") # 10. 用户描述 if user_prompt: parts.append(f"design concept: {user_prompt}") # 11. 视角 view_desc = view_map.get(view_name, "three-quarter view") parts.append(view_desc) # 12. 质量后缀 parts.append(quality_suffix) return ", ".join(parts)