Files
report-admin/i18n/__init__.py
T
lofyerandfactory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> 71db82393a Initial commit
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-07-13 15:38:41 +08:00

128 lines
4.4 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.
"""
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"]