diff --git a/web/admin-spa/src/i18n/index.js b/web/admin-spa/src/i18n/index.js new file mode 100644 index 00000000..4bd2028f --- /dev/null +++ b/web/admin-spa/src/i18n/index.js @@ -0,0 +1,68 @@ +import { createI18n } from 'vue-i18n' +import zhCn from './locales/zh-cn.js' +import zhTw from './locales/zh-tw.js' +import en from './locales/en.js' + +// 获取浏览器语言设置 +function getBrowserLocale() { + const navigatorLocale = navigator.languages ? navigator.languages[0] : navigator.language + + if (!navigatorLocale) { + return 'zh-cn' + } + + const trimmedLocale = navigatorLocale.trim().split(';')[0].toLowerCase() + + if (trimmedLocale.includes('zh')) { + if ( + trimmedLocale.includes('tw') || + trimmedLocale.includes('hk') || + trimmedLocale.includes('mo') + ) { + return 'zh-tw' + } + return 'zh-cn' + } + + if (trimmedLocale.includes('en')) { + return 'en' + } + + return 'zh-cn' // 默认简体中文 +} + +// 获取保存的语言设置或浏览器语言 +const savedLocale = localStorage.getItem('app-locale') +const defaultLocale = savedLocale || getBrowserLocale() + +export const SUPPORTED_LOCALES = { + 'zh-cn': { + name: '简体中文', + flag: '简', + shortName: '简' + }, + 'zh-tw': { + name: '繁體中文', + flag: '繁', + shortName: '繁' + }, + en: { + name: 'English', + flag: 'EN', + shortName: 'EN' + } +} + +export const i18n = createI18n({ + legacy: false, // 使用 Composition API 模式 + locale: defaultLocale, + fallbackLocale: 'zh-cn', + messages: { + 'zh-cn': zhCn, + 'zh-tw': zhTw, + en: en + }, + globalInjection: true // 全局注入 $t 函数 +}) + +export default i18n diff --git a/web/admin-spa/src/i18n/locales/en.js b/web/admin-spa/src/i18n/locales/en.js new file mode 100644 index 00000000..671af8ec --- /dev/null +++ b/web/admin-spa/src/i18n/locales/en.js @@ -0,0 +1,38 @@ +export default { + common: { + save: 'Save', + cancel: 'Cancel', + confirm: 'Confirm', + loading: 'Loading...', + edit: 'Edit', + delete: 'Delete', + create: 'Create', + update: 'Update', + search: 'Search', + reset: 'Reset' + }, + language: { + zh: '简体中文', + 'zh-tw': '繁體中文', + en: 'English', + current: 'Current Language', + switch: 'Switch Language' + }, + header: { + adminPanel: 'Admin Panel', + userMenu: 'User Menu', + logout: 'Logout', + settings: 'Settings' + }, + apiStats: { + title: 'API Key Usage Statistics', + tutorialTitle: 'Tutorial', + userLogin: 'User Login', + adminPanel: 'Admin Panel', + statsQuery: 'Statistics Query', + tutorial: 'Tutorial', + timeRange: 'Statistics Time Range', + today: 'Today', + thisMonth: 'This Month' + } +} diff --git a/web/admin-spa/src/i18n/locales/zh-cn.js b/web/admin-spa/src/i18n/locales/zh-cn.js new file mode 100644 index 00000000..38b3d997 --- /dev/null +++ b/web/admin-spa/src/i18n/locales/zh-cn.js @@ -0,0 +1,38 @@ +export default { + common: { + save: '保存', + cancel: '取消', + confirm: '确认', + loading: '加载中...', + edit: '编辑', + delete: '删除', + create: '创建', + update: '更新', + search: '搜索', + reset: '重置' + }, + language: { + zh: '简体中文', + 'zh-tw': '繁體中文', + en: 'English', + current: '当前语言', + switch: '切换语言' + }, + header: { + adminPanel: '管理后台', + userMenu: '用户菜单', + logout: '退出登录', + settings: '系统设置' + }, + apiStats: { + title: 'API Key 使用统计', + tutorialTitle: '使用教程', + userLogin: '用户登录', + adminPanel: '管理后台', + statsQuery: '统计查询', + tutorial: '使用教程', + timeRange: '统计时间范围', + today: '今日', + thisMonth: '本月' + } +} diff --git a/web/admin-spa/src/i18n/locales/zh-tw.js b/web/admin-spa/src/i18n/locales/zh-tw.js new file mode 100644 index 00000000..4290241d --- /dev/null +++ b/web/admin-spa/src/i18n/locales/zh-tw.js @@ -0,0 +1,38 @@ +export default { + common: { + save: '保存', + cancel: '取消', + confirm: '確認', + loading: '載入中...', + edit: '編輯', + delete: '刪除', + create: '建立', + update: '更新', + search: '搜尋', + reset: '重置' + }, + language: { + zh: '簡體中文', + 'zh-tw': '繁體中文', + en: 'English', + current: '當前語言', + switch: '切換語言' + }, + header: { + adminPanel: '管理後台', + userMenu: '用戶選單', + logout: '退出登錄', + settings: '系統設置' + }, + apiStats: { + title: 'API Key 使用統計', + tutorialTitle: '使用教學', + userLogin: '用戶登錄', + adminPanel: '管理後台', + statsQuery: '統計查詢', + tutorial: '使用教學', + timeRange: '統計時間範圍', + today: '今日', + thisMonth: '本月' + } +} diff --git a/web/admin-spa/src/stores/locale.js b/web/admin-spa/src/stores/locale.js new file mode 100644 index 00000000..7b6ad24d --- /dev/null +++ b/web/admin-spa/src/stores/locale.js @@ -0,0 +1,42 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' +import { i18n, SUPPORTED_LOCALES } from '@/i18n' + +export const useLocaleStore = defineStore('locale', () => { + const currentLocale = ref(i18n.global.locale.value) + + // 切换语言 + const setLocale = (locale) => { + if (!SUPPORTED_LOCALES[locale]) { + console.warn(`Unsupported locale: ${locale}`) + return + } + + currentLocale.value = locale + i18n.global.locale.value = locale + localStorage.setItem('app-locale', locale) + + // 更新HTML lang属性 + document.documentElement.setAttribute('lang', locale) + } + + // 获取当前语言信息 + const getCurrentLocaleInfo = () => { + return SUPPORTED_LOCALES[currentLocale.value] || SUPPORTED_LOCALES['zh-cn'] + } + + // 获取所有支持的语言 + const getSupportedLocales = () => { + return Object.entries(SUPPORTED_LOCALES).map(([key, value]) => ({ + code: key, + ...value + })) + } + + return { + currentLocale, + setLocale, + getCurrentLocaleInfo, + getSupportedLocales + } +})