From 436fcb405b65ff9cd13777247afd019dc36e5631 Mon Sep 17 00:00:00 2001 From: fengsilin Date: Fri, 17 Apr 2026 11:45:02 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=90=8E=E5=8F=B0=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E8=AF=AD=E8=A8=80=E5=8A=9F=E8=83=BD=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 --- ...6-04-17-default-language-setting-design.md | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-17-default-language-setting-design.md diff --git a/docs/superpowers/specs/2026-04-17-default-language-setting-design.md b/docs/superpowers/specs/2026-04-17-default-language-setting-design.md new file mode 100644 index 0000000..df1fcd5 --- /dev/null +++ b/docs/superpowers/specs/2026-04-17-default-language-setting-design.md @@ -0,0 +1,114 @@ +--- +created: 2026-04-17 +status: approved +scope: backend + frontend +files: 6 +--- + +# 后台设置默认语言 + +> 管理员可在系统设置中配置全局默认语言,影响未登录用户和未设置语言偏好的已登录用户。 + +## 需求 + +- 管理员在**系统设置**页面配置一个「默认语言」 +- **未登录用户**:强制使用管理员设定的默认语言,忽略浏览器语言检测 +- **已登录但未设置语言偏好的用户**:使用管理员设定的默认语言 +- **已登录且已设置语言偏好的用户**:使用个人设置的语言(不受默认语言影响) +- 支持的语言:zh-CN、zh-TW、en、fr、ja、ru、vi +- 可选"自动(跟随浏览器)"选项,等于未设定,保持现有行为 + +## 语言优先级 + +``` +1. 用户个人设置语言(已登录 + 已设置语言偏好) +2. 管理员设定的默认语言(强制使用,忽略浏览器语言) +3. zh-CN(fallbackLng) +``` + +## 后端改动 + +### 1. `common/constants.go` + +新增变量: + +```go +var DefaultLanguage = "" // 空字符串=未设定,保持现有浏览器检测行为 +``` + +### 2. `model/option.go` + +在 `updateOptionMap` 的 switch 中新增 case: + +```go +case "DefaultLanguage": + common.DefaultLanguage = value +``` + +### 3. `controller/misc.go` — `GetStatus()` + +在 status 响应 JSON 中新增字段: + +```go +"default_language": common.DefaultLanguage, +``` + +## 前端改动 + +### 4. `web/src/components/settings/SystemSetting.jsx` + +- `inputs` state 新增 `DefaultLanguage: ''` +- 在系统设置表单中添加一个 `Select` 下拉框 +- 选项:7 种语言 + 空字符串选项("自动 / 跟随浏览器") +- 与其他系统设置一起通过 `/api/option/` 保存 + +### 5. `web/src/components/layout/PageLayout.jsx` + +在 `loadStatus` 回调中,获取 `data.default_language` 后: + +```javascript +if (data.default_language && data.default_language !== '') { + const savedLang = localStorage.getItem('i18nextLng'); + // 仅在没有用户个人设置语言时应用默认语言 + // 注意:UserContext 会在用户加载后覆盖此设置 + if (!localStorage.getItem('user')) { + i18n.changeLanguage(data.default_language); + } +} +``` + +同时保留现有的 `localStorage.getItem('i18nextLng')` 逻辑作为 fallback。 + +### 6. `web/src/context/User/index.jsx` + +调整语言同步逻辑: + +```javascript +// 当前:仅在有 settings.language 时切换 +// 新增:无 settings.language 时,回退到 status 中的 default_language +if (settings.language) { + i18n.changeLanguage(settings.language); +} else if (statusDefaultLanguage) { + i18n.changeLanguage(statusDefaultLanguage); +} +``` + +需要从 StatusContext 获取 `default_language` 值。 + +## 涉及文件 + +| 文件 | 改动类型 | 改动量 | +|------|---------|-------| +| `common/constants.go` | 新增变量 | +1 行 | +| `model/option.go` | 新增 switch case | +2 行 | +| `controller/misc.go` | 新增 status 字段 | +1 行 | +| `web/src/components/settings/SystemSetting.jsx` | inputs + 表单 UI | ~30 行 | +| `web/src/components/layout/PageLayout.jsx` | loadStatus 后应用默认语言 | ~5 行 | +| `web/src/context/User/index.jsx` | 无偏好时回退到默认语言 | ~5 行 | + +## 不涉及 + +- 不修改 i18n.js 的初始化配置 +- 不修改 LanguageSelector 组件 +- 不添加新的 API 端点 +- 不修改数据库 schema(使用现有 options 表)