From a79ec3f1d80dd2eca2567225c74335d57ea347ff Mon Sep 17 00:00:00 2001 From: Baobhan Sith <80159437+Heavrnl@users.noreply.github.com> Date: Sat, 26 Apr 2025 10:12:07 +0800 Subject: [PATCH] update --- packages/backend/src/i18n.ts | 2 +- .../locales/{en => en-US}/notifications.json | 0 .../locales/{jp => ja-JP}/notifications.json | 0 .../locales/{zh => zh-CN}/notifications.json | 0 packages/frontend/src/i18n.ts | 30 ++++++++++++----- .../src/locales/{en.json => en-US.json} | 0 .../src/locales/{jp.json => ja-JP.json} | 0 .../src/locales/{zh.json => zh-CN.json} | 16 +++++++++- .../frontend/src/stores/settings.store.ts | 32 +++++++++++++------ packages/frontend/src/views/SettingsView.vue | 6 ++-- 10 files changed, 64 insertions(+), 22 deletions(-) rename packages/backend/src/locales/{en => en-US}/notifications.json (100%) rename packages/backend/src/locales/{jp => ja-JP}/notifications.json (100%) rename packages/backend/src/locales/{zh => zh-CN}/notifications.json (100%) rename packages/frontend/src/locales/{en.json => en-US.json} (100%) rename packages/frontend/src/locales/{jp.json => ja-JP.json} (100%) rename packages/frontend/src/locales/{zh.json => zh-CN.json} (98%) diff --git a/packages/backend/src/i18n.ts b/packages/backend/src/i18n.ts index cbf30ea..89cb2f4 100644 --- a/packages/backend/src/i18n.ts +++ b/packages/backend/src/i18n.ts @@ -21,7 +21,7 @@ try { } // 确保默认语言在支持列表中,如果目录扫描失败则添加 -export const defaultLng = 'en'; +export const defaultLng = 'en-US'; // 更新为 en-US if (!dynamicSupportedLngs.includes(defaultLng)) { dynamicSupportedLngs.push(defaultLng); console.warn(`[i18next] Default language '${defaultLng}' not found in detected directories, adding it to supported list.`); diff --git a/packages/backend/src/locales/en/notifications.json b/packages/backend/src/locales/en-US/notifications.json similarity index 100% rename from packages/backend/src/locales/en/notifications.json rename to packages/backend/src/locales/en-US/notifications.json diff --git a/packages/backend/src/locales/jp/notifications.json b/packages/backend/src/locales/ja-JP/notifications.json similarity index 100% rename from packages/backend/src/locales/jp/notifications.json rename to packages/backend/src/locales/ja-JP/notifications.json diff --git a/packages/backend/src/locales/zh/notifications.json b/packages/backend/src/locales/zh-CN/notifications.json similarity index 100% rename from packages/backend/src/locales/zh/notifications.json rename to packages/backend/src/locales/zh-CN/notifications.json diff --git a/packages/frontend/src/i18n.ts b/packages/frontend/src/i18n.ts index 3d715e5..5a851bd 100644 --- a/packages/frontend/src/i18n.ts +++ b/packages/frontend/src/i18n.ts @@ -27,23 +27,37 @@ if (availableLocales.length === 0) { // 如果没有加载到文件,则使用空对象作为 fallback,避免运行时错误 type MessageSchema = typeof messages[availableLocales[0]] | {}; -// 定义默认语言 (优先使用 'en',如果不存在则使用第一个找到的语言) -export const defaultLng = availableLocales.includes('en') ? 'en' : availableLocales[0] || 'en'; // 添加 'en' 作为最终 fallback +// 定义默认语言 (优先使用 'en-US',如果不存在则使用第一个找到的语言) +export const defaultLng = availableLocales.includes('en-US') ? 'en-US' : availableLocales[0] || 'en-US'; // 更新为 en-US const localStorageKey = 'user-locale'; // 尝试从 localStorage 获取语言,否则回退 const getInitialLocale = (): string => { const storedLocale = localStorage.getItem(localStorageKey); - // 检查存储的 locale 是否在当前可用的语言列表中 + // 1. 检查 localStorage 中存储的完整 locale 是否可用 if (storedLocale && availableLocales.includes(storedLocale)) { + console.log(`[i18n] Using locale from localStorage: ${storedLocale}`); return storedLocale; } - // 回退逻辑:检查浏览器语言是否可用 - const navigatorLang = navigator.language?.split('-')[0]; - if (navigatorLang && availableLocales.includes(navigatorLang)) { - return navigatorLang; + + // 2. 回退逻辑:检查浏览器提供的完整区域代码 (e.g., 'zh-CN') 是否可用 + const navigatorLocale = navigator.language; // 获取完整代码,如 'zh-CN' + if (navigatorLocale && availableLocales.includes(navigatorLocale)) { + console.log(`[i18n] Using locale from navigator.language: ${navigatorLocale}`); + return navigatorLocale; } - // 最后回退到默认语言 + + // 3. (可选,但更健壮) 检查浏览器语言的主语言部分 (e.g., 'zh') 是否可用 + // 这在只有 'zh-CN' 但浏览器是 'zh-TW' 时可能有用,如果想回退到 'en' 而不是 'zh-CN' + // 或者如果我们未来添加了通用的 'zh' 文件 + const navigatorLangPart = navigatorLocale?.split('-')[0]; + if (navigatorLangPart && availableLocales.includes(navigatorLangPart)) { + console.log(`[i18n] Using locale based on navigator language part: ${navigatorLangPart}`); + return navigatorLangPart; + } + + // 4. 最后回退到默认语言 + console.log(`[i18n] Falling back to default locale: ${defaultLng}`); return defaultLng; }; diff --git a/packages/frontend/src/locales/en.json b/packages/frontend/src/locales/en-US.json similarity index 100% rename from packages/frontend/src/locales/en.json rename to packages/frontend/src/locales/en-US.json diff --git a/packages/frontend/src/locales/jp.json b/packages/frontend/src/locales/ja-JP.json similarity index 100% rename from packages/frontend/src/locales/jp.json rename to packages/frontend/src/locales/ja-JP.json diff --git a/packages/frontend/src/locales/zh.json b/packages/frontend/src/locales/zh-CN.json similarity index 98% rename from packages/frontend/src/locales/zh.json rename to packages/frontend/src/locales/zh-CN.json index 02801e1..26f7c88 100644 --- a/packages/frontend/src/locales/zh.json +++ b/packages/frontend/src/locales/zh-CN.json @@ -628,8 +628,22 @@ "error": { "saveFailed": "保存 CAPTCHA 设置失败。" } + }, + "commandInputSync": { + "title": "命令输入同步", + "selectLabel": "同步目标:", + "targetNone": "无", + "targetQuickCommands": "快捷指令", + "targetCommandHistory": "命令历史", + "description": "将命令输入栏的内容实时同步到所选面板的搜索框。", + "success": { + "saved": "同步目标已保存。" + }, + "error": { + "saveFailed": "保存同步目标失败。" + } } - }, +}, "common": { "loading": "加载中...", "cancel": "取消", diff --git a/packages/frontend/src/stores/settings.store.ts b/packages/frontend/src/stores/settings.store.ts index a155889..183d08f 100644 --- a/packages/frontend/src/stores/settings.store.ts +++ b/packages/frontend/src/stores/settings.store.ts @@ -210,17 +210,23 @@ export const useSettingsStore = defineStore('settings', () => { // --- 语言设置 --- const langFromSettings = settings.value.language; console.log(`[SettingsStore] Language from fetched settings: ${langFromSettings}`); // <-- 添加日志 - // 检查从设置加载的语言是否在可用语言列表中 + // 检查从设置加载的语言 (完整区域代码) 是否在可用语言列表中 if (langFromSettings && availableLocales.includes(langFromSettings)) { determinedLang = langFromSettings; } else { - // 如果设置中的语言无效或缺失,尝试浏览器语言 - const navigatorLang = navigator.language?.split('-')[0]; - if (navigatorLang && availableLocales.includes(navigatorLang)) { - determinedLang = navigatorLang; + // 如果设置中的语言无效或缺失,尝试浏览器提供的完整区域代码 + const navigatorLocale = navigator.language; + if (navigatorLocale && availableLocales.includes(navigatorLocale)) { + determinedLang = navigatorLocale; } else { - // 最后回退到 i18n 配置的默认语言 - determinedLang = defaultLng; + // (可选) 尝试浏览器语言的主语言部分 + const navigatorLangPart = navigatorLocale?.split('-')[0]; + if (navigatorLangPart && availableLocales.includes(navigatorLangPart)) { + determinedLang = navigatorLangPart; + } else { + // 最后回退到 i18n 配置的默认语言 + determinedLang = defaultLng; + } } console.warn(`[SettingsStore] Invalid or missing language setting ('${langFromSettings}') received from backend. Falling back to '${determinedLang}'.`); // Optionally save the fallback language back @@ -242,8 +248,15 @@ export const useSettingsStore = defineStore('settings', () => { error.value = err.response?.data?.message || err.message || 'Failed to load settings'; // 出错时(例如未登录),根据浏览器语言设置回退语言 const navigatorLang = navigator.language?.split('-')[0]; - // 错误时也检查浏览器语言是否可用 - const fallbackLang = (navigatorLang && availableLocales.includes(navigatorLang)) ? navigatorLang : defaultLng; + // 错误时也尝试浏览器完整区域代码,然后主语言部分,最后默认 + const navigatorLocale = navigator.language; + const navigatorLangPart = navigatorLocale?.split('-')[0]; + let fallbackLang = defaultLng; // Start with default + if (navigatorLocale && availableLocales.includes(navigatorLocale)) { + fallbackLang = navigatorLocale; + } else if (navigatorLangPart && availableLocales.includes(navigatorLangPart)) { + fallbackLang = navigatorLangPart; + } console.log(`[SettingsStore] Error loading settings. Falling back to language: ${fallbackLang}. Calling setLocale...`); // <-- 添加日志 setLocale(fallbackLang); } finally { @@ -466,6 +479,7 @@ export const useSettingsStore = defineStore('settings', () => { // 移除外观相关 actions: saveCustomThemes, resetCustomThemes, toggleStyleCustomizer // --- Getters --- + // Use defaultLng (which is now 'en-US' or the first available) from i18n.ts as the final fallback const language = computed(() => settings.value.language || defaultLng); // Getter for the popup editor setting, returning boolean diff --git a/packages/frontend/src/views/SettingsView.vue b/packages/frontend/src/views/SettingsView.vue index 972d6e0..b4c7bff 100644 --- a/packages/frontend/src/views/SettingsView.vue +++ b/packages/frontend/src/views/SettingsView.vue @@ -542,9 +542,9 @@ const ipWhitelistInput = ref(''); const selectedLanguage = ref(storeLanguage.value); // 改为 string 类型以支持动态语言 // 可选:创建一个语言名称映射 const languageNames: Record = { - en: 'English', - zh: '中文', - jp: '日本語', // 添加日语或其他语言 + 'en-US': 'English', // 更新为 en-US + 'zh-CN': '中文', + 'ja-JP': '日本語', // 更新为 ja-JP (如果您的文件名是 ja-JP.json) // Add more languages here as needed }; const blacklistSettingsForm = reactive({ // Renamed to avoid conflict with store state name