diff --git a/dashboard/src/i18n/composables.ts b/dashboard/src/i18n/composables.ts index c2df9fc91..3d569ef3e 100644 --- a/dashboard/src/i18n/composables.ts +++ b/dashboard/src/i18n/composables.ts @@ -1,44 +1,43 @@ -import { ref, computed, watchEffect } from 'vue'; -import { I18nLoader } from './loader'; +import { ref, computed } from 'vue'; +import { translations as staticTranslations } from './translations'; import type { Locale } from './types'; // 全局状态 const currentLocale = ref('zh-CN'); -const loader = new I18nLoader(); const translations = ref>({}); -// 加载器实例 -let loaderInstance: I18nLoader | null = null; - /** * 初始化i18n系统 */ export async function initI18n(locale: Locale = 'zh-CN') { - loaderInstance = new I18nLoader(); currentLocale.value = locale; - // 加载初始翻译 - await loadTranslations(locale); + // 加载静态翻译数据 + loadTranslations(locale); } /** - * 加载翻译数据 + * 加载翻译数据(现在从静态导入获取) */ -async function loadTranslations(locale: Locale) { - if (!loaderInstance) { - throw new Error('I18n not initialized. Call initI18n() first.'); - } - +function loadTranslations(locale: Locale) { try { - const data = await loaderInstance.loadLocale(locale); - translations.value = data; + const data = staticTranslations[locale]; + if (data) { + translations.value = data; + } else { + console.warn(`Translations not found for locale: ${locale}`); + // 回退到中文 + if (locale !== 'zh-CN') { + console.log('Falling back to zh-CN'); + translations.value = staticTranslations['zh-CN']; + } + } } catch (error) { console.error(`Failed to load translations for ${locale}:`, error); // 回退到中文 if (locale !== 'zh-CN') { console.log('Falling back to zh-CN'); - const fallbackData = await loaderInstance.loadLocale('zh-CN'); - translations.value = fallbackData; + translations.value = staticTranslations['zh-CN']; } } } @@ -84,7 +83,7 @@ export function useI18n() { const setLocale = async (newLocale: Locale) => { if (newLocale !== currentLocale.value) { currentLocale.value = newLocale; - await loadTranslations(newLocale); + loadTranslations(newLocale); // 保存到localStorage localStorage.setItem('astrbot-locale', newLocale); diff --git a/dashboard/src/i18n/loader.ts b/dashboard/src/i18n/loader.ts index 73191f10b..743603129 100644 --- a/dashboard/src/i18n/loader.ts +++ b/dashboard/src/i18n/loader.ts @@ -85,15 +85,10 @@ export class I18nLoader { } try { - // 使用fetch方式加载JSON文件 - const modulePath = `/src/i18n/locales/${locale}/${moduleInfo.path}`; - const response = await fetch(modulePath); - - if (!response.ok) { - throw new Error(`HTTP ${response.status}: ${response.statusText}`); - } - - const data = await response.json(); + // 使用动态import加载JSON文件,兼容构建和开发环境 + const modulePath = `../locales/${locale}/${moduleInfo.path}`; + const module = await import(/* @vite-ignore */ modulePath); + const data = module.default || module; // 缓存结果 this.cache.set(cacheKey, data); @@ -105,7 +100,30 @@ export class I18nLoader { return data; } catch (error) { console.error(`加载模块 ${moduleName} 失败:`, error); - return {}; + + // 回退方案:尝试使用fetch(开发环境) + try { + const modulePath = `/src/i18n/locales/${locale}/${moduleInfo.path}`; + const response = await fetch(modulePath); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const data = await response.json(); + + // 缓存结果 + this.cache.set(cacheKey, data); + + // 更新模块信息 + moduleInfo.loaded = true; + moduleInfo.data = data; + + return data; + } catch (fetchError) { + console.error(`回退fetch加载也失败:`, fetchError); + return {}; + } } } diff --git a/dashboard/src/i18n/translations.ts b/dashboard/src/i18n/translations.ts new file mode 100644 index 000000000..59d4b0568 --- /dev/null +++ b/dashboard/src/i18n/translations.ts @@ -0,0 +1,132 @@ +// 静态导入所有翻译文件 +// 这种方式确保构建时所有翻译都会被正确打包 + +// 中文翻译 +import zhCNCommon from './locales/zh-CN/core/common.json'; +import zhCNActions from './locales/zh-CN/core/actions.json'; +import zhCNStatus from './locales/zh-CN/core/status.json'; +import zhCNNavigation from './locales/zh-CN/core/navigation.json'; +import zhCNHeader from './locales/zh-CN/core/header.json'; + +import zhCNChat from './locales/zh-CN/features/chat.json'; +import zhCNExtension from './locales/zh-CN/features/extension.json'; +import zhCNConversation from './locales/zh-CN/features/conversation.json'; +import zhCNToolUse from './locales/zh-CN/features/tool-use.json'; +import zhCNProvider from './locales/zh-CN/features/provider.json'; +import zhCNPlatform from './locales/zh-CN/features/platform.json'; +import zhCNConfig from './locales/zh-CN/features/config.json'; +import zhCNConsole from './locales/zh-CN/features/console.json'; +import zhCNAbout from './locales/zh-CN/features/about.json'; +import zhCNSettings from './locales/zh-CN/features/settings.json'; +import zhCNAuth from './locales/zh-CN/features/auth.json'; +import zhCNChart from './locales/zh-CN/features/chart.json'; +import zhCNDashboard from './locales/zh-CN/features/dashboard.json'; +import zhCNAlkaidIndex from './locales/zh-CN/features/alkaid/index.json'; +import zhCNAlkaidKnowledgeBase from './locales/zh-CN/features/alkaid/knowledge-base.json'; +import zhCNAlkaidMemory from './locales/zh-CN/features/alkaid/memory.json'; + +import zhCNErrors from './locales/zh-CN/messages/errors.json'; +import zhCNSuccess from './locales/zh-CN/messages/success.json'; +import zhCNValidation from './locales/zh-CN/messages/validation.json'; + +// 英文翻译 +import enUSCommon from './locales/en-US/core/common.json'; +import enUSActions from './locales/en-US/core/actions.json'; +import enUSStatus from './locales/en-US/core/status.json'; +import enUSNavigation from './locales/en-US/core/navigation.json'; +import enUSHeader from './locales/en-US/core/header.json'; + +import enUSChat from './locales/en-US/features/chat.json'; +import enUSExtension from './locales/en-US/features/extension.json'; +import enUSConversation from './locales/en-US/features/conversation.json'; +import enUSToolUse from './locales/en-US/features/tool-use.json'; +import enUSProvider from './locales/en-US/features/provider.json'; +import enUSPlatform from './locales/en-US/features/platform.json'; +import enUSConfig from './locales/en-US/features/config.json'; +import enUSConsole from './locales/en-US/features/console.json'; +import enUSAbout from './locales/en-US/features/about.json'; +import enUSSettings from './locales/en-US/features/settings.json'; +import enUSAuth from './locales/en-US/features/auth.json'; +import enUSChart from './locales/en-US/features/chart.json'; +import enUSDashboard from './locales/en-US/features/dashboard.json'; +import enUSAlkaidIndex from './locales/en-US/features/alkaid/index.json'; +import enUSAlkaidKnowledgeBase from './locales/en-US/features/alkaid/knowledge-base.json'; +import enUSAlkaidMemory from './locales/en-US/features/alkaid/memory.json'; + +import enUSErrors from './locales/en-US/messages/errors.json'; +import enUSSuccess from './locales/en-US/messages/success.json'; +import enUSValidation from './locales/en-US/messages/validation.json'; + +// 组装翻译对象 +export const translations = { + 'zh-CN': { + core: { + common: zhCNCommon, + actions: zhCNActions, + status: zhCNStatus, + navigation: zhCNNavigation, + header: zhCNHeader + }, + features: { + chat: zhCNChat, + extension: zhCNExtension, + conversation: zhCNConversation, + tooluse: zhCNToolUse, + provider: zhCNProvider, + platform: zhCNPlatform, + config: zhCNConfig, + console: zhCNConsole, + about: zhCNAbout, + settings: zhCNSettings, + auth: zhCNAuth, + chart: zhCNChart, + dashboard: zhCNDashboard, + alkaid: { + index: zhCNAlkaidIndex, + 'knowledge-base': zhCNAlkaidKnowledgeBase, + memory: zhCNAlkaidMemory + } + }, + messages: { + errors: zhCNErrors, + success: zhCNSuccess, + validation: zhCNValidation + } + }, + 'en-US': { + core: { + common: enUSCommon, + actions: enUSActions, + status: enUSStatus, + navigation: enUSNavigation, + header: enUSHeader + }, + features: { + chat: enUSChat, + extension: enUSExtension, + conversation: enUSConversation, + tooluse: enUSToolUse, + provider: enUSProvider, + platform: enUSPlatform, + config: enUSConfig, + console: enUSConsole, + about: enUSAbout, + settings: enUSSettings, + auth: enUSAuth, + chart: enUSChart, + dashboard: enUSDashboard, + alkaid: { + index: enUSAlkaidIndex, + 'knowledge-base': enUSAlkaidKnowledgeBase, + memory: enUSAlkaidMemory + } + }, + messages: { + errors: enUSErrors, + success: enUSSuccess, + validation: enUSValidation + } + } +}; + +export type TranslationData = typeof translations; \ No newline at end of file