"""构建海报预览、Prompt 与导出共同使用的 renderDocument v2。""" from copy import deepcopy from insurance.poster.content_builder import build_poster_content DEFAULT_SECTIONS = ( "hero", "summary", "benefits", "features", "cta", "disclaimer", ) def build_render_document( *, format_spec: dict, template: dict | None, copy_content: dict, case_facts: dict, product_rules: dict, plan_type: str, compliance_revision: str, custom_height: int | None = None, sections: list[dict] | None = None, brand: dict | None = None, ) -> dict: """按固定优先级组装唯一渲染文档。""" template = template or {} facts = deepcopy(case_facts or product_rules.get("facts") or {}) rules = deepcopy(product_rules or {}) if not rules.get("features") and facts.get("key_benefits"): rules["features"] = [ {"title": item, "summary": ""} if isinstance(item, str) else item for item in facts["key_benefits"] ] content = build_poster_content( parsed_data=facts, product_rules=rules, output_mode=format_spec["outputMode"], plan_type=plan_type or "other", ) theme = _build_theme(template.get("colorScheme") or {}) normalized_sections = _normalize_sections(sections, format_spec["outputMode"], content) requested_output = deepcopy(format_spec["output"]) export_size = format_spec["exportSize"] if custom_height is not None: requested_output["height"] = custom_height export_size = f"{requested_output['width']}x{custom_height}" return { "schemaVersion": 2, "revision": 1, "formatId": format_spec["id"], "outputMode": format_spec["outputMode"], "layoutKey": template.get("layoutKey") or ( "long_complete" if format_spec["outputMode"] == "long" else "single_hero_data" ), "templateId": template.get("id"), "layout": deepcopy(format_spec["layout"]), "requestedOutput": requested_output, "exportSize": export_size, "copy": deepcopy(copy_content or {}), "facts": facts, "summary": content["summary"], "features": content["features"], "benefits": content["benefit_table"], "theme": theme, "style": theme, "sections": normalized_sections, "background": {}, "brand": deepcopy(brand or {}), "fieldProfile": content["field_profile"], "warnings": content["warnings"], "complianceRevision": compliance_revision or "", } def _build_theme(color_scheme: dict) -> dict: return { "primary": color_scheme.get("primary") or "#173f35", "accent": color_scheme.get("accent") or "#c99a4b", "surface": color_scheme.get("surface") or "#f7f4ed", "text": color_scheme.get("text") or "#17231f", "muted": color_scheme.get("muted") or "#64716d", } def _normalize_sections(sections: list[dict] | None, output_mode: str, content: dict) -> list[dict]: current = { item.get("id"): item.get("visible", True) for item in (sections or []) if isinstance(item, dict) and item.get("id") in DEFAULT_SECTIONS } result = [] for section_id in DEFAULT_SECTIONS: visible = current.get(section_id, True) if section_id == "benefits": visible = visible and output_mode == "long" and len(content["benefit_table"]) >= 3 elif section_id == "features": visible = visible and bool(content["features"]) elif section_id == "summary": visible = visible and any(content["summary"].values()) result.append({"id": section_id, "visible": visible}) return result