Initial commit

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
lofyer
2026-07-13 15:38:41 +08:00
co-authored by factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
commit 71db82393a
180 changed files with 170640 additions and 0 deletions
+127
View File
@@ -0,0 +1,127 @@
"""
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"]