Files
mailgo/internal/web/handlers/i18n.go
T
dsh c881146a40 feat(web): 多语言界面(中/英/日)与用户语言偏好字段
- 新增 internal/i18n 包:以原始中文字符串为 key 的翻译目录(zh 恒等,
  en 兜底,ja 缺译回退 en),t/tf 模板函数与 Accept-Language 解析
  (按 q 值排序,兜底英语)
- User 模型新增 language 字段(auto|en|zh|ja,默认 auto),
  AutoMigrate 自动加列;UserStore 新增 UpdateLanguage
- 语言解析:登录用户按偏好(auto 时取浏览器 Accept-Language),
  登录/封禁页按浏览器语言;所有 c.HTML 渲染注入 Lang 模板数据
- 全部页面模板(用户页 + 管理后台 12 页)接入翻译:导航、文件夹、
  邮件列表/阅读/写信、设置、登录、封禁页、表单、表格、JS 确认框等;
  html lang 属性随语言切换;日期函数(shortDate/time12/time12m)
  与 folderLabel 改为语言感知(上午/下午 vs AM/PM vs 午前/午後)
- 设置页新增「界面语言」选择(自动/English/中文/日本語),
  /settings 表单支持单独提交语言偏好;管理后台用户表单可预设语言
- 封禁原因等入库中文文案在展示时经 t 翻译(未知 key 原样回退)
- 测试:i18n 单测(解析/回退/译文)、render 测试补 Lang 数据、
  时间格式化测试适配新签名;全量 go test 通过
2026-08-20 00:21:10 -04:00

40 lines
1.0 KiB
Go

package handlers
import (
"mail_go/internal/i18n"
"github.com/gin-gonic/gin"
)
// langOf 返回当前请求的界面语言:优先取中间件解析好的 context 值
// (登录用户偏好 / 浏览器语言),未设置时按浏览器 Accept-Language 兜底。
func langOf(c *gin.Context) string {
if v, ok := c.Get("lang"); ok {
if s, ok := v.(string); ok && i18n.Supported(s) {
return s
}
}
return i18n.FromAcceptLanguage(c.GetHeader("Accept-Language"))
}
// withLang 把当前请求的界面语言注入模板数据(key "lang"),
// 所有 c.HTML 渲染入口都应经过它,保证模板可调用 {{t .Lang "..."}}。
func withLang(c *gin.Context, data gin.H) gin.H {
if data == nil {
data = gin.H{}
}
data["Lang"] = langOf(c)
return data
}
// normLang 把表单提交的语言偏好规整为合法值(auto | en | zh | ja),
// 非法值回退 auto(跟随浏览器)。
func normLang(v string) string {
switch v {
case i18n.LangAuto, i18n.LangEn, i18n.LangZh, i18n.LangJa:
return v
default:
return i18n.LangAuto
}
}