refactor(settings): 统一语言设置,合并 interface_language 和 ai_language

- 后端 Schema 将 interface_language 和 ai_language 合并为 language
- 前端设置界面只保留一个语言选项
- AI 回复语言统一使用 language 设置
- 更新协议文档
- 新增数据库迁移脚本
This commit is contained in:
ZL-Q
2026-04-28 17:19:47 +08:00
parent 940c67e642
commit b9617ae152
20 changed files with 740 additions and 176 deletions
@@ -15,8 +15,7 @@ class TestParseProfileSettings:
raw = {
"version": 1,
"preferences": {
"interface_language": "en-US",
"ai_language": "en-US",
"language": "en-US",
"timezone": "America/New_York",
"country": "US",
},
@@ -31,8 +30,7 @@ class TestParseProfileSettings:
assert isinstance(result, ProfileSettingsV1)
assert result.version == 1
assert isinstance(result.preferences, PreferenceSettings)
assert result.preferences.interface_language == "en-US"
assert result.preferences.ai_language == "en-US"
assert result.preferences.language == "en-US"
assert result.preferences.timezone == "America/New_York"
assert result.preferences.country == "US"
assert isinstance(result.notification, NotificationSettings)
@@ -45,8 +43,7 @@ class TestParseProfileSettings:
assert isinstance(result, ProfileSettingsV1)
assert result.version == 1
assert isinstance(result.preferences, PreferenceSettings)
assert result.preferences.interface_language == "zh-CN"
assert result.preferences.ai_language == "zh-CN"
assert result.preferences.language == "zh-CN"
assert result.preferences.timezone == "Asia/Shanghai"
assert result.preferences.country == "US"
assert isinstance(result.notification, NotificationSettings)
@@ -56,13 +53,12 @@ class TestParseProfileSettings:
def test_parse_profile_settings_with_partial_preferences(self) -> None:
raw = {
"preferences": {
"interface_language": "en-US",
"language": "en-US",
},
}
result = parse_profile_settings(raw)
assert result.preferences.interface_language == "en-US"
assert result.preferences.ai_language == "zh-CN"
assert result.preferences.language == "en-US"
assert result.preferences.timezone == "Asia/Shanghai"
assert result.preferences.country == "US"
@@ -93,7 +89,7 @@ class TestParseProfileSettings:
def test_parse_profile_settings_invalid_language_uses_default(self) -> None:
raw = {
"preferences": {
"interface_language": "invalid-language",
"language": "invalid-language",
},
}
with pytest.raises(ValueError, match="language must be a valid BCP-47 tag"):
@@ -120,8 +116,7 @@ class TestParseProfileSettings:
def test_profile_settings_v1_model_dump(self) -> None:
settings = ProfileSettingsV1(
preferences=PreferenceSettings(
interface_language="en-US",
ai_language="en-US",
language="en-US",
timezone="UTC",
country="US",
),
@@ -132,6 +127,6 @@ class TestParseProfileSettings:
)
dumped = settings.model_dump(mode="json")
assert dumped["preferences"]["interface_language"] == "en-US"
assert dumped["preferences"]["language"] == "en-US"
assert dumped["notification"]["allow_notifications"] is True
assert dumped["notification"]["allow_vibration"] is False