""" i18n 包:报告中英文国际化支持 设计原则: 1. 数据层 key 保持中文(不破坏 PCA / 缓存兼容性) 2. 仅在显示层(模板/LLM prompt)通过 t() 翻译 3. 找不到 key 时 fallback 到中文原值,保证渐进式迁移不会爆 Jinja """ from typing import Dict, Any from . import zh_CN, en_US _BUNDLES = { "zh": zh_CN.STRINGS, "en": en_US.STRINGS, } DEFAULT_LANG = "zh" class Translator: """ 可点号访问的翻译器,供 Jinja 模板使用: Jinja 模板用法: {{ t.score }} → "得分" / "Score" {{ t.dim('课程领导力') }} → "课程领导力" / "Curriculum Leadership" {{ t.sub('国家标准遵循') }} → "国家标准遵循" / "National Standards Compliance" {{ t.level_desc('国家标准遵循', 4) }} → 水平 4 的描述 {{ t.part('part3') }} → "第三部分 课程领导力表现" / "Part III. Curriculum Leadership" """ def __init__(self, lang: str = DEFAULT_LANG): self.lang = lang if lang in _BUNDLES else DEFAULT_LANG self._bundle: Dict[str, Any] = _BUNDLES[self.lang] self._fallback: Dict[str, Any] = _BUNDLES[DEFAULT_LANG] # ---- 字符串字段(UI label) ---- def __getattr__(self, key: str) -> str: # 首先在 UI 字典中找,找不到回退到中文 ui = self._bundle.get("UI", {}) if key in ui: return ui[key] ui_zh = self._fallback.get("UI", {}) return ui_zh.get(key, key) def get(self, key: str, default: str = "") -> str: ui = self._bundle.get("UI", {}) if key in ui: return ui[key] ui_zh = self._fallback.get("UI", {}) return ui_zh.get(key, default or key) # ---- 维度名翻译 ---- def dim(self, name_zh: str) -> str: """7 大二级维度名翻译""" d = self._bundle.get("DIMENSIONS", {}) return d.get(name_zh, name_zh) def sub(self, name_zh: str) -> str: """20 个三级维度名翻译""" d = self._bundle.get("SUB_DIMENSIONS", {}) return d.get(name_zh, name_zh) def part(self, part_id: str) -> str: """部分标题:part0/part1/part3..part9/part10""" d = self._bundle.get("PARTS", {}) return d.get(part_id, part_id) def part_number(self, part_id: str) -> str: """部分编号:第三部分 / Part III.""" d = self._bundle.get("PART_NUMBERS", {}) return d.get(part_id, part_id) def level_desc(self, sub_dim_zh: str, level: int) -> str: """子维度水平描述(4 档)""" d = self._bundle.get("LEVEL_DESCRIPTIONS", {}) sub = d.get(sub_dim_zh, {}) if not sub: sub = self._fallback.get("LEVEL_DESCRIPTIONS", {}).get(sub_dim_zh, {}) return sub.get(level, sub.get(str(level), "")) def dim_def(self, name_zh: str) -> str: """7 大维度的概念定义(用于 LLM prompt + 模板说明)""" d = self._bundle.get("DIMENSION_DEFINITIONS", {}) return d.get(name_zh, "") def sub_def(self, name_zh: str) -> str: """20 个三级维度的概念定义""" d = self._bundle.get("SUB_DIMENSION_DEFINITIONS", {}) return d.get(name_zh, "") def cluster_label(self, kind: str) -> str: """聚类标签:good / weak / mid""" d = self._bundle.get("CLUSTERS", {}) return d.get(kind, kind) def school_type(self, type_zh: str) -> str: """学校类型翻译(市实验性示范性高中等)""" d = self._bundle.get("SCHOOL_TYPES", {}) return d.get(type_zh, type_zh) def district(self, name_zh: str) -> str: """区域名翻译(长宁区等)""" d = self._bundle.get("DISTRICTS", {}) return d.get(name_zh, name_zh) def date(self, dt) -> str: """日期格式化(按语言)""" from datetime import datetime if isinstance(dt, str): return dt if self.lang == "en": return dt.strftime("%B %d, %Y") return dt.strftime("%Y年%m月%d日") def get_translator(lang: str = DEFAULT_LANG) -> Translator: """获取翻译器实例""" return Translator(lang) def get_bundle(lang: str = DEFAULT_LANG) -> Dict[str, Any]: """获取语言原始字典(供低层代码使用)""" return _BUNDLES.get(lang, _BUNDLES[DEFAULT_LANG]) __all__ = ["Translator", "get_translator", "get_bundle", "DEFAULT_LANG"]