refactor: remove LocaleSwitcher component and update locale handling
- Removed LocaleSwitcher from NavUser, SiteHeader, and WorkbenchHeader components. - Updated tests to reflect the removal of LocaleSwitcher. - Changed default locale from "en-US" to "zh-CN" in i18n configuration. - Refactored locale resolution logic to read configured locale without relying on browser language detection. - Updated AgentDesk SDK to support language configuration from public API. - Cleaned up unused auth options fetching in the auth API.
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Language string `yaml:"language"`
|
||||
Server ServerConfig `yaml:"server"`
|
||||
DB DBConfig `yaml:"db"`
|
||||
Logger LoggerConfig `yaml:"logger"`
|
||||
@@ -21,6 +22,17 @@ type Config struct {
|
||||
CustomerSession CustomerSessionConfig `yaml:"customerSession"`
|
||||
}
|
||||
|
||||
func (c Config) LanguageOrDefault() string {
|
||||
switch strings.ToLower(strings.TrimSpace(c.Language)) {
|
||||
case "zh", "zh-cn", "zh_cn", "zh-hans":
|
||||
return "zh-CN"
|
||||
case "en", "en-us", "en_us":
|
||||
return "en-US"
|
||||
default:
|
||||
return "zh-CN"
|
||||
}
|
||||
}
|
||||
|
||||
type WxWorkNotifyConfig struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
ToUsers []int64 `yaml:"toUsers"`
|
||||
|
||||
@@ -19,7 +19,8 @@ type LoginResponse struct {
|
||||
Roles []string `json:"roles"`
|
||||
}
|
||||
|
||||
type AuthOptionsResponse struct {
|
||||
WxWorkEnabled bool `json:"wxworkEnabled"`
|
||||
OIDCEnabled bool `json:"oidcEnabled"`
|
||||
type PublicConfigResponse struct {
|
||||
Language string `json:"language"`
|
||||
WxWorkEnabled bool `json:"wxworkEnabled"`
|
||||
OIDCEnabled bool `json:"oidcEnabled"`
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ func (e *I18nError) Error() string {
|
||||
if e == nil {
|
||||
return ""
|
||||
}
|
||||
return e.Message(i18nx.LocaleZhCN)
|
||||
return e.Message(i18nx.DefaultLocale)
|
||||
}
|
||||
|
||||
func (e *I18nError) Unwrap() error {
|
||||
|
||||
@@ -20,7 +20,7 @@ func (e *Error) Error() string {
|
||||
if e == nil {
|
||||
return ""
|
||||
}
|
||||
return e.Message(LocaleZhCN)
|
||||
return e.Message(DefaultLocale)
|
||||
}
|
||||
|
||||
func (e *Error) Message(locale string) string {
|
||||
|
||||
@@ -9,27 +9,24 @@ import (
|
||||
)
|
||||
|
||||
func TestNormalizeLocale(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
in string
|
||||
want string
|
||||
}{
|
||||
{name: "default for blank", in: "", want: LocaleEnUS},
|
||||
{name: "default for blank", in: "", want: LocaleZhCN},
|
||||
{name: "exact chinese", in: "zh-CN", want: LocaleZhCN},
|
||||
{name: "underscore chinese", in: "zh_CN", want: LocaleZhCN},
|
||||
{name: "short chinese", in: "zh", want: LocaleZhCN},
|
||||
{name: "exact english", in: "en-US", want: LocaleEnUS},
|
||||
{name: "underscore english", in: "en_US", want: LocaleEnUS},
|
||||
{name: "short english", in: "en", want: LocaleEnUS},
|
||||
{name: "unsupported falls back", in: "fr-FR", want: LocaleEnUS},
|
||||
{name: "unsupported falls back", in: "fr-FR", want: LocaleZhCN},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
if got := NormalizeLocale(tt.in); got != tt.want {
|
||||
t.Fatalf("NormalizeLocale(%q) = %q, want %q", tt.in, got, tt.want)
|
||||
}
|
||||
@@ -37,36 +34,33 @@ func TestNormalizeLocale(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveLocaleFromHeaders(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
func TestResolveLocaleUsesDefaultLocale(t *testing.T) {
|
||||
SetDefaultLocale(LocaleZhCN)
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/dashboard/user/list", nil)
|
||||
req.Header.Set("Accept-Language", "fr-FR, en-US;q=0.9, zh-CN;q=0.8")
|
||||
|
||||
if got := ResolveRequestLocale(req); got != LocaleEnUS {
|
||||
t.Fatalf("ResolveRequestLocale() = %q, want %q", got, LocaleEnUS)
|
||||
if got := ResolveRequestLocale(req); got != LocaleZhCN {
|
||||
t.Fatalf("ResolveRequestLocale() = %q, want %q", got, LocaleZhCN)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveLocalePrefersXLocale(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
func TestResolveLocaleIgnoresRequestLocaleHeaders(t *testing.T) {
|
||||
SetDefaultLocale(LocaleZhCN)
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/dashboard/user/list", nil)
|
||||
req.Header.Set("X-Locale", "en-US")
|
||||
req.Header.Set("Accept-Language", "zh-CN")
|
||||
|
||||
if got := ResolveRequestLocale(req); got != LocaleEnUS {
|
||||
t.Fatalf("ResolveRequestLocale() = %q, want %q", got, LocaleEnUS)
|
||||
if got := ResolveRequestLocale(req); got != LocaleZhCN {
|
||||
t.Fatalf("ResolveRequestLocale() = %q, want %q", got, LocaleZhCN)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTranslateFallsBackToEnglish(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
func TestTranslateUsesConfiguredDefaultForUnsupportedLocale(t *testing.T) {
|
||||
SetDefaultLocale(LocaleZhCN)
|
||||
if got := TLocale(LocaleEnUS, "error.auth.expired"); got != "Your session has expired. Please sign in again." {
|
||||
t.Fatalf("english translation = %q", got)
|
||||
}
|
||||
if got := TLocale("fr-FR", "error.auth.expired"); got != "Your session has expired. Please sign in again." {
|
||||
if got := TLocale("fr-FR", "error.auth.expired"); got != "未登录或登录已过期" {
|
||||
t.Fatalf("fallback translation = %q", got)
|
||||
}
|
||||
}
|
||||
@@ -143,6 +137,7 @@ func TestGetfFallsBackToKey(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMiddlewareStoresLocale(t *testing.T) {
|
||||
SetDefaultLocale(LocaleZhCN)
|
||||
gin.SetMode(gin.TestMode)
|
||||
router := gin.New()
|
||||
router.Use(Middleware())
|
||||
@@ -159,7 +154,7 @@ func TestMiddlewareStoresLocale(t *testing.T) {
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want %d", recorder.Code, http.StatusOK)
|
||||
}
|
||||
if got := recorder.Body.String(); got != LocaleEnUS {
|
||||
t.Fatalf("middleware locale = %q, want %q", got, LocaleEnUS)
|
||||
if got := recorder.Body.String(); got != LocaleZhCN {
|
||||
t.Fatalf("middleware locale = %q, want %q", got, LocaleZhCN)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,11 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
const (
|
||||
LocaleZhCN = "zh-CN"
|
||||
LocaleEnUS = "en-US"
|
||||
DefaultLocale = LocaleEnUS
|
||||
LocaleZhCN = "zh-CN"
|
||||
LocaleEnUS = "en-US"
|
||||
)
|
||||
|
||||
var supportedLocales = map[string]string{
|
||||
@@ -24,6 +22,12 @@ var supportedLocales = map[string]string{
|
||||
"en_us": LocaleEnUS,
|
||||
}
|
||||
|
||||
var DefaultLocale = LocaleZhCN
|
||||
|
||||
func SetDefaultLocale(locale string) {
|
||||
DefaultLocale = NormalizeLocale(locale)
|
||||
}
|
||||
|
||||
func NormalizeLocale(value string) string {
|
||||
key := strings.ToLower(strings.TrimSpace(value))
|
||||
if key == "" {
|
||||
@@ -35,19 +39,7 @@ func NormalizeLocale(value string) string {
|
||||
return DefaultLocale
|
||||
}
|
||||
|
||||
func ResolveRequestLocale(req *http.Request) string {
|
||||
if req == nil {
|
||||
return DefaultLocale
|
||||
}
|
||||
if locale := normalizeSupportedLocale(req.Header.Get("X-Locale")); locale != "" {
|
||||
return locale
|
||||
}
|
||||
if locale := resolveAcceptLanguage(req.Header.Get("Accept-Language")); locale != "" {
|
||||
return locale
|
||||
}
|
||||
if locale := normalizeSupportedLocale(req.URL.Query().Get("locale")); locale != "" {
|
||||
return locale
|
||||
}
|
||||
func ResolveRequestLocale(_ *http.Request) string {
|
||||
return DefaultLocale
|
||||
}
|
||||
|
||||
@@ -57,31 +49,3 @@ func Middleware() gin.HandlerFunc {
|
||||
ctx.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeSupportedLocale(value string) string {
|
||||
key := strings.ToLower(strings.TrimSpace(value))
|
||||
if key == "" {
|
||||
return ""
|
||||
}
|
||||
if locale, ok := supportedLocales[key]; ok {
|
||||
return locale
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func resolveAcceptLanguage(value string) string {
|
||||
tags, _, err := language.ParseAcceptLanguage(value)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
for _, tag := range tags {
|
||||
if locale := normalizeSupportedLocale(tag.String()); locale != "" {
|
||||
return locale
|
||||
}
|
||||
base, _ := tag.Base()
|
||||
if locale := normalizeSupportedLocale(base.String()); locale != "" {
|
||||
return locale
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user