From 01eadea10b6eaae7da296af7ba876e94d0b36f7f Mon Sep 17 00:00:00 2001 From: Wangnov Date: Wed, 10 Sep 2025 18:04:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20stores=20=E9=83=A8=E5=88=86=E6=8E=A5?= =?UTF-8?q?=E5=85=A5=20i18n=EF=BC=88auth/settings/apistats/dashboard/clien?= =?UTF-8?q?ts=EF=BC=9A=E6=A0=87=E9=A2=98=E3=80=81=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E4=B8=8E=E6=97=A5=E6=9C=9F=E6=8F=90=E7=A4=BA=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E5=8C=96=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/admin-spa/src/stores/apistats.js | 29 +++++++++++++-------- web/admin-spa/src/stores/auth.js | 7 +++--- web/admin-spa/src/stores/clients.js | 5 ++-- web/admin-spa/src/stores/dashboard.js | 36 ++++++++++++++++----------- web/admin-spa/src/stores/settings.js | 11 +++++--- 5 files changed, 53 insertions(+), 35 deletions(-) diff --git a/web/admin-spa/src/stores/apistats.js b/web/admin-spa/src/stores/apistats.js index c07b16c7..582017c0 100644 --- a/web/admin-spa/src/stores/apistats.js +++ b/web/admin-spa/src/stores/apistats.js @@ -1,6 +1,7 @@ import { defineStore } from 'pinia' import { ref, computed } from 'vue' import { apiStatsClient } from '@/config/apiStats' +import i18n from '@/i18n' export const useApiStatsStore = defineStore('apistats', () => { // 状态 @@ -93,7 +94,7 @@ export const useApiStatsStore = defineStore('apistats', () => { } if (!apiKey.value.trim()) { - error.value = '请输入 API Key' + error.value = i18n.global.t('apiStats.enterApiKey') return } @@ -125,14 +126,18 @@ export const useApiStatsStore = defineStore('apistats', () => { // 更新 URL updateURL() } else { - throw new Error(statsResult.message || '查询失败') + throw new Error( + statsResult.message || i18n.global.t('common.errors.requestFailed', { status: 500 }) + ) } } else { - throw new Error(idResult.message || '获取 API Key ID 失败') + throw new Error( + idResult.message || i18n.global.t('common.errors.requestFailed', { status: 500 }) + ) } } catch (err) { console.error('Query stats error:', err) - error.value = err.message || '查询统计数据失败,请检查您的 API Key 是否正确' + error.value = err.message || i18n.global.t('apiStats.errors.queryStatsFailed') statsData.value = null modelStats.value = [] apiId.value = null @@ -209,7 +214,7 @@ export const useApiStatsStore = defineStore('apistats', () => { if (result.success) { modelStats.value = result.data || [] } else { - throw new Error(result.message || '加载模型统计失败') + throw new Error(result.message || i18n.global.t('apiStats.errors.loadModelStatsFailed')) } } catch (err) { console.error('Load model stats error:', err) @@ -266,11 +271,13 @@ export const useApiStatsStore = defineStore('apistats', () => { // 清除错误信息 error.value = '' } else { - throw new Error(result.message || '查询失败') + throw new Error( + result.message || i18n.global.t('common.errors.requestFailed', { status: 500 }) + ) } } catch (err) { console.error('Load stats with apiId error:', err) - error.value = err.message || '查询统计数据失败' + error.value = err.message || i18n.global.t('apiStats.errors.queryStatsFailed') statsData.value = null modelStats.value = [] } finally { @@ -330,7 +337,7 @@ export const useApiStatsStore = defineStore('apistats', () => { async function queryBatchStats() { const keys = parseApiKeys() if (keys.length === 0) { - error.value = '请输入至少一个有效的 API Key' + error.value = i18n.global.t('apiStats.errors.enterAtLeastOneKey') return } @@ -384,11 +391,11 @@ export const useApiStatsStore = defineStore('apistats', () => { // 更新 URL updateBatchURL() } else { - throw new Error(batchResult.message || '批量查询失败') + throw new Error(batchResult.message || i18n.global.t('apiStats.errors.batchQueryFailed')) } } catch (err) { console.error('Batch query error:', err) - error.value = err.message || '批量查询统计数据失败' + error.value = err.message || i18n.global.t('apiStats.errors.batchQueryFailed') aggregatedStats.value = null individualStats.value = [] } finally { @@ -408,7 +415,7 @@ export const useApiStatsStore = defineStore('apistats', () => { if (result.success) { modelStats.value = result.data || [] } else { - throw new Error(result.message || '加载批量模型统计失败') + throw new Error(result.message || i18n.global.t('apiStats.errors.batchModelStatsFailed')) } } catch (err) { console.error('Load batch model stats error:', err) diff --git a/web/admin-spa/src/stores/auth.js b/web/admin-spa/src/stores/auth.js index bbd39c62..465a0f13 100644 --- a/web/admin-spa/src/stores/auth.js +++ b/web/admin-spa/src/stores/auth.js @@ -1,6 +1,7 @@ import { defineStore } from 'pinia' import { ref, computed } from 'vue' import router from '@/router' +import i18n from '@/i18n' import { apiClient } from '@/config/api' export const useAuthStore = defineStore('auth', () => { @@ -39,10 +40,10 @@ export const useAuthStore = defineStore('auth', () => { await router.push('/dashboard') } else { - loginError.value = result.message || '登录失败' + loginError.value = result.message || i18n.global.t('login.loginFailed') } } catch (error) { - loginError.value = error.message || '登录失败,请检查用户名和密码' + loginError.value = error.message || i18n.global.t('login.loginFailedCheck') } finally { loginLoading.value = false } @@ -102,7 +103,7 @@ export const useAuthStore = defineStore('auth', () => { // 设置页面标题 if (result.data.siteName) { - document.title = `${result.data.siteName} - 管理后台` + document.title = `${result.data.siteName} - ${i18n.global.t('header.adminPanel')}` } } } catch (error) { diff --git a/web/admin-spa/src/stores/clients.js b/web/admin-spa/src/stores/clients.js index 7926c69d..10a0476b 100644 --- a/web/admin-spa/src/stores/clients.js +++ b/web/admin-spa/src/stores/clients.js @@ -1,5 +1,6 @@ import { defineStore } from 'pinia' import { apiClient } from '@/config/api' +import i18n from '@/i18n' export const useClientsStore = defineStore('clients', { state: () => ({ @@ -24,13 +25,13 @@ export const useClientsStore = defineStore('clients', { if (response.success) { this.supportedClients = response.data || [] } else { - this.error = response.message || '加载支持的客户端失败' + this.error = response.message || i18n.global.t('common.errors.loadSupportedClientsFailed') console.error('Failed to load supported clients:', this.error) } return this.supportedClients } catch (error) { - this.error = error.message || '加载支持的客户端失败' + this.error = error.message || i18n.global.t('common.errors.loadSupportedClientsFailed') console.error('Error loading supported clients:', error) return [] } finally { diff --git a/web/admin-spa/src/stores/dashboard.js b/web/admin-spa/src/stores/dashboard.js index 20cc40b6..9f3ea2d0 100644 --- a/web/admin-spa/src/stores/dashboard.js +++ b/web/admin-spa/src/stores/dashboard.js @@ -2,6 +2,8 @@ import { defineStore } from 'pinia' import { ref, computed } from 'vue' import { apiClient } from '@/config/api' import { showToast } from '@/utils/toast' +import i18n from '@/i18n' +import i18n from '@/i18n' export const useDashboardStore = defineStore('dashboard', () => { // 状态 @@ -68,9 +70,9 @@ export const useDashboardStore = defineStore('dashboard', () => { customEnd: '', customRange: null, presetOptions: [ - { value: 'today', label: '今日', days: 1 }, - { value: '7days', label: '7天', days: 7 }, - { value: '30days', label: '30天', days: 30 } + { value: 'today', label: i18n.global.t('dashboard.today'), days: 1 }, + { value: '7days', label: i18n.global.t('dashboard.last7Days'), days: 7 }, + { value: '30days', label: i18n.global.t('dashboard.last30Days'), days: 30 } ] }) @@ -89,11 +91,11 @@ export const useDashboardStore = defineStore('dashboard', () => { const minutes = Math.floor((seconds % 3600) / 60) if (days > 0) { - return `${days}天 ${hours}小时` + return i18n.global.t('dashboard.uptimeFormat.daysHours', { days, hours }) } else if (hours > 0) { - return `${hours}小时 ${minutes}分钟` + return i18n.global.t('dashboard.uptimeFormat.hoursMinutes', { hours, minutes }) } else { - return `${minutes}分钟` + return i18n.global.t('dashboard.uptimeFormat.minutes', { minutes }) } }) @@ -636,14 +638,14 @@ export const useDashboardStore = defineStore('dashboard', () => { // 小时粒度:限制 24 小时 const hoursDiff = (end - start) / (1000 * 60 * 60) if (hoursDiff > 24) { - showToast('小时粒度下日期范围不能超过24小时', 'warning') + showToast(i18n.global.t('dashboard.errors.rangeTooLongHour'), 'warning') return } } else { // 天粒度:限制 31 天 const daysDiff = Math.ceil((end - start) / (1000 * 60 * 60 * 24)) + 1 if (daysDiff > 31) { - showToast('日期范围不能超过 31 天', 'warning') + showToast(i18n.global.t('dashboard.errors.rangeTooLongDay'), 'warning') return } } @@ -662,9 +664,13 @@ export const useDashboardStore = defineStore('dashboard', () => { // 根据粒度更新预设选项 if (granularity === 'hour') { dateFilter.value.presetOptions = [ - { value: 'last24h', label: '近24小时', hours: 24 }, - { value: 'yesterday', label: '昨天', hours: 24 }, - { value: 'dayBefore', label: '前天', hours: 24 } + { + value: 'last24h', + label: i18n.global.t('dashboard.usageTrend.periodOptions.last24Hours'), + hours: 24 + }, + { value: 'yesterday', label: i18n.global.t('dashboard.yesterday'), hours: 24 }, + { value: 'dayBefore', label: i18n.global.t('dashboard.dayBefore'), hours: 24 } ] // 检查当前自定义日期范围是否超过24小时 @@ -677,7 +683,7 @@ export const useDashboardStore = defineStore('dashboard', () => { const end = new Date(dateFilter.value.customRange[1]) const hoursDiff = (end - start) / (1000 * 60 * 60) if (hoursDiff > 24) { - showToast('小时粒度下日期范围不能超过24小时,已切换到近24小时', 'warning') + showToast(i18n.global.t('dashboard.errors.rangeTooLongHourSwitched'), 'warning') setDateFilterPreset('last24h') return } @@ -691,9 +697,9 @@ export const useDashboardStore = defineStore('dashboard', () => { } else { // 天粒度 dateFilter.value.presetOptions = [ - { value: 'today', label: '今日', days: 1 }, - { value: '7days', label: '7天', days: 7 }, - { value: '30days', label: '30天', days: 30 } + { value: 'today', label: i18n.global.t('dashboard.today'), days: 1 }, + { value: '7days', label: i18n.global.t('dashboard.last7Days'), days: 7 }, + { value: '30days', label: i18n.global.t('dashboard.last30Days'), days: 30 } ] // 如果当前是小时粒度的预设,切换到天粒度的默认预设 diff --git a/web/admin-spa/src/stores/settings.js b/web/admin-spa/src/stores/settings.js index 986ce327..82279a7a 100644 --- a/web/admin-spa/src/stores/settings.js +++ b/web/admin-spa/src/stores/settings.js @@ -1,6 +1,7 @@ import { defineStore } from 'pinia' import { ref } from 'vue' import { apiClient } from '@/config/api' +import i18n from '@/i18n' export const useSettingsStore = defineStore('settings', () => { // 状态 @@ -77,7 +78,7 @@ export const useSettingsStore = defineStore('settings', () => { const applyOemSettings = () => { // 更新页面标题 if (oemSettings.value.siteName) { - document.title = `${oemSettings.value.siteName} - 管理后台` + document.title = `${oemSettings.value.siteName} - ${i18n.global.t('header.adminPanel')}` } // 更新favicon @@ -94,7 +95,9 @@ export const useSettingsStore = defineStore('settings', () => { // 格式化日期时间 const formatDateTime = (dateString) => { if (!dateString) return '' - return new Date(dateString).toLocaleString('zh-CN', { + const localeMap = { 'zh-cn': 'zh-CN', 'zh-tw': 'zh-TW', en: 'en-US' } + const currentLocale = localeMap[i18n.global.locale.value] || 'en-US' + return new Date(dateString).toLocaleString(currentLocale, { year: 'numeric', month: '2-digit', day: '2-digit', @@ -110,13 +113,13 @@ export const useSettingsStore = defineStore('settings', () => { // 检查文件大小 (350KB) if (file.size > 350 * 1024) { - errors.push('图标文件大小不能超过 350KB') + errors.push(i18n.global.t('settings.validation.iconTooLarge')) } // 检查文件类型 const allowedTypes = ['image/x-icon', 'image/png', 'image/jpeg', 'image/jpg', 'image/svg+xml'] if (!allowedTypes.includes(file.type)) { - errors.push('不支持的文件类型,请选择 .ico, .png, .jpg 或 .svg 文件') + errors.push(i18n.global.t('settings.validation.iconTypeNotSupported')) } return {