baodan/api/insurance/poster/format_registry.py

90 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""海报输出格式注册表。
逻辑尺寸用于 HTML 排版,输出尺寸用于最终 PNG背景素材尺寸用于图片模型。
三者不得通过同一个宽高字符串互相推断。
"""
from copy import deepcopy
class PosterFormatError(ValueError):
"""海报格式不受支持。"""
_FORMATS = (
{
"id": "single_2_3",
"label": "竖版单图 2:3",
"outputMode": "single",
"layout": {"width": 512, "height": 768},
"output": {"width": 1024, "height": 1536},
"exportSize": "1024x1536",
"backgroundAssetSize": "1024x1536",
},
{
"id": "single_9_16",
"label": "竖屏单图 9:16",
"outputMode": "single",
"layout": {"width": 540, "height": 960},
"output": {"width": 1080, "height": 1920},
"exportSize": "1080x1920",
"backgroundAssetSize": "1024x1536",
},
{
"id": "long_1242_auto",
"label": "完整方案长图",
"outputMode": "long",
"layout": {"width": 414, "height": None},
"output": {"width": 1242, "height": None},
"exportSize": "1242xauto",
"backgroundAssetSize": "1024x1536",
},
)
_FORMAT_BY_ID = {item["id"]: item for item in _FORMATS}
_DEFAULT_BY_MODE = {
"single": "single_2_3",
"long": "long_1242_auto",
}
_LEGACY_FORMATS = {
("single", "1024x1792"): "single_2_3",
("single", "1024x1536"): "single_2_3",
("single", "1080x1920"): "single_9_16",
("long", "1080x2160"): "long_1242_auto",
("long", "1080x3240"): "long_1242_auto",
("long", "1080x4320"): "long_1242_auto",
("long", "1242xauto"): "long_1242_auto",
}
def list_poster_formats() -> list[dict]:
"""返回可供前端选择的安全格式副本。"""
return deepcopy(list(_FORMATS))
def resolve_poster_format(
format_id: str | None = None,
legacy_size: str | None = None,
output_mode: str = "single",
) -> dict:
"""解析并校验海报格式,未知值必须明确失败。"""
mode = str(output_mode or "single")
if mode not in _DEFAULT_BY_MODE:
raise PosterFormatError(f"不支持的输出模式: {output_mode}")
if format_id:
spec = _FORMAT_BY_ID.get(str(format_id))
if not spec:
raise PosterFormatError(f"不支持的海报格式: {format_id}")
elif legacy_size:
resolved_id = _LEGACY_FORMATS.get((mode, str(legacy_size)))
if not resolved_id:
raise PosterFormatError(f"不支持的海报尺寸: {legacy_size}")
spec = _FORMAT_BY_ID[resolved_id]
else:
spec = _FORMAT_BY_ID[_DEFAULT_BY_MODE[mode]]
if spec["outputMode"] != mode:
mode_label = "长图" if mode == "long" else "单图"
raise PosterFormatError(f"格式 {spec['id']} 不支持{mode_label}模式")
return deepcopy(spec)