feat: 原文中文对照(逐句)— 高亮句同色同序号对位

- /api/translate 增加逐句模式(sentences): 前端拆句(en 为原文精确文本)→ 模型逐句翻译,
  数量/顺序校验复用 _count_check(不一致自动重试);响应 en 原样回填保证对位可靠
- 左栏原文区新增「原文中文对照 →」: 逐句中文展示,命中批注 evidence 的句子
  与原文同色(note-rhetoric/repeat/growth/structure)+ 同序号(sup),
  点击对照行可联动高亮原文句与批注卡片
- 对照缓存按段保存并持久化(原文变化/换文书自动失效清空)
- 测试: 新增逐句模式 2 个 hermetic 测试(33 passed)
- 浏览器实测 18/18 通过(含逐句渲染/高亮对位/点击联动/刷新持久化)
This commit is contained in:
LuminousRuoxi
2026-09-10 14:39:39 +08:00
parent 85a2eb720a
commit 6e0db821a8
5 changed files with 156 additions and 8 deletions
+19
View File
@@ -530,6 +530,25 @@ def test_api_translate_coerces_list_translation():
assert r.json()["translation"] == "第一句。第二句。"
def test_api_translate_sentences_shape():
"""原文中文对照(逐句):en 原样回填、zh 按序对位 —— 前端据此做高亮对位。"""
payload = {"sentences": [{"zh": "第一句译文。"}, {"zh": "第二句译文。"}]}
r = api_client(payload).post(
"/api/translate", json={"sentences": ["One.", "Two."], "paragraph_id": "p1"}
)
assert r.status_code == 200
data = r.json()
assert [s["en"] for s in data["sentences"]] == ["One.", "Two."]
assert data["sentences"][1]["zh"] == "第二句译文。"
def test_api_translate_sentences_blank_422():
r = api_client({"sentences": [{"zh": "x"}]}).post(
"/api/translate", json={"sentences": [" ", ""]}
)
assert r.status_code == 422
def test_api_translate_empty_translation_502():
r = api_client({"translation": " "}).post("/api/translate", json={"text": "Hello."})
assert r.status_code == 502