diff --git a/dashboard/package.json b/dashboard/package.json index cd621b0b7..7a5dd44a5 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -31,6 +31,7 @@ "vee-validate": "4.11.3", "vite-plugin-vuetify": "1.0.2", "vue": "3.3.4", + "vue-i18n": "^11.1.5", "vue-router": "4.2.4", "vue3-apexcharts": "1.4.4", "vue3-print-nb": "0.1.4", @@ -41,11 +42,11 @@ "@mdi/font": "7.2.96", "@rushstack/eslint-patch": "1.3.3", "@types/chance": "1.1.3", - "@types/node": "20.5.7", + "@types/node": "^20.5.7", "@vitejs/plugin-vue": "4.3.3", "@vue/eslint-config-prettier": "8.0.0", "@vue/eslint-config-typescript": "11.0.3", - "@vue/tsconfig": "0.4.0", + "@vue/tsconfig": "^0.4.0", "eslint": "8.48.0", "eslint-plugin-vue": "9.17.0", "prettier": "3.0.2", diff --git a/dashboard/src/components/ConfirmDialog.vue b/dashboard/src/components/ConfirmDialog.vue index 60380764b..9b77a6b6b 100644 --- a/dashboard/src/components/ConfirmDialog.vue +++ b/dashboard/src/components/ConfirmDialog.vue @@ -5,8 +5,8 @@ {{ message }} - 取消 - 确定 + {{ t('core.common.dialog.cancelButton') }} + {{ t('core.common.dialog.confirmButton') }} @@ -14,6 +14,9 @@ + + \ No newline at end of file diff --git a/dashboard/src/components/shared/ListConfigItem.vue b/dashboard/src/components/shared/ListConfigItem.vue index 075df2793..76d446ed4 100644 --- a/dashboard/src/components/shared/ListConfigItem.vue +++ b/dashboard/src/components/shared/ListConfigItem.vue @@ -37,11 +37,11 @@
- mdi-plus - 添加 + {{ t('core.common.list.addButton') }}
@@ -49,8 +49,14 @@ diff --git a/dashboard/src/components/shared/ReadmeDialog.vue b/dashboard/src/components/shared/ReadmeDialog.vue index 3d7ce7869..739b9a4dd 100644 --- a/dashboard/src/components/shared/ReadmeDialog.vue +++ b/dashboard/src/components/shared/ReadmeDialog.vue @@ -1,9 +1,10 @@ \ No newline at end of file diff --git a/dashboard/src/layouts/full/vertical-sidebar/sidebarItem.ts b/dashboard/src/layouts/full/vertical-sidebar/sidebarItem.ts index 8495ece41..8c1436d5f 100644 --- a/dashboard/src/layouts/full/vertical-sidebar/sidebarItem.ts +++ b/dashboard/src/layouts/full/vertical-sidebar/sidebarItem.ts @@ -14,59 +14,62 @@ export interface menu { subCaption?: string; } +// 注意:这个文件现在包含i18n键值而不是直接的文本 +// 在组件中使用时需要通过t()函数进行翻译 +// 所有键名都使用 core.navigation.* 格式 const sidebarItem: menu[] = [ { - title: '统计', + title: 'core.navigation.dashboard', icon: 'mdi-view-dashboard', to: '/dashboard/default' }, { - title: '消息平台', + title: 'core.navigation.platforms', icon: 'mdi-message-processing', to: '/platforms', }, { - title: '服务提供商', + title: 'core.navigation.providers', icon: 'mdi-creation', to: '/providers', }, { - title: 'MCP', + title: 'core.navigation.toolUse', icon: 'mdi-function-variant', to: '/tool-use' }, { - title: '配置文件', + title: 'core.navigation.config', icon: 'mdi-cog', to: '/config', }, { - title: '插件', + title: 'core.navigation.extension', icon: 'mdi-puzzle', to: '/extension' }, { - title: '聊天', + title: 'core.navigation.chat', icon: 'mdi-chat', to: '/chat' }, { - title: '对话数据', + title: 'core.navigation.conversation', icon: 'mdi-database', to: '/conversation' }, { - title: '控制台', + title: 'core.navigation.console', icon: 'mdi-console', to: '/console' }, { - title: 'Alkaid', + title: 'core.navigation.alkaid', icon: 'mdi-test-tube', to: '/alkaid' }, { - title: '关于', + title: 'core.navigation.about', icon: 'mdi-information', to: '/about' }, diff --git a/dashboard/src/main.ts b/dashboard/src/main.ts index cbfcc2e95..7d522fe6d 100644 --- a/dashboard/src/main.ts +++ b/dashboard/src/main.ts @@ -4,6 +4,7 @@ import App from './App.vue'; import { router } from './router'; import vuetify from './plugins/vuetify'; import confirmPlugin from './plugins/confirmPlugin'; +import { setupI18n } from './i18n/composables'; import '@/scss/style.scss'; import VueApexCharts from 'vue3-apexcharts'; @@ -11,14 +12,31 @@ import print from 'vue3-print-nb'; import { loader } from '@guolao/vue-monaco-editor' import axios from 'axios'; -const app = createApp(App); -app.use(router); -app.use(createPinia()); -app.use(print); -app.use(VueApexCharts); -app.use(vuetify); -app.use(confirmPlugin); -app.mount('#app'); +// 初始化新的i18n系统,等待完成后再挂载应用 +setupI18n().then(() => { + console.log('🌍 新i18n系统初始化完成'); + + const app = createApp(App); + app.use(router); + app.use(createPinia()); + app.use(print); + app.use(VueApexCharts); + app.use(vuetify); + app.use(confirmPlugin); + app.mount('#app'); +}).catch(error => { + console.error('❌ 新i18n系统初始化失败:', error); + + // 即使i18n初始化失败,也要挂载应用(使用回退机制) + const app = createApp(App); + app.use(router); + app.use(createPinia()); + app.use(print); + app.use(VueApexCharts); + app.use(vuetify); + app.use(confirmPlugin); + app.mount('#app'); +}); axios.interceptors.request.use((config) => { diff --git a/dashboard/src/router/index.ts b/dashboard/src/router/index.ts index 738fdda1d..18b5737e4 100644 --- a/dashboard/src/router/index.ts +++ b/dashboard/src/router/index.ts @@ -1,11 +1,11 @@ -import { createRouter, createWebHistory } from 'vue-router'; +import { createRouter, createWebHashHistory } from 'vue-router'; import MainRoutes from './MainRoutes'; import AuthRoutes from './AuthRoutes'; import ChatBoxRoutes from './ChatBoxRoutes'; import { useAuthStore } from '@/stores/auth'; export const router = createRouter({ - history: createWebHistory(import.meta.env.BASE_URL), + history: createWebHashHistory(import.meta.env.BASE_URL), routes: [ MainRoutes, AuthRoutes, @@ -26,7 +26,7 @@ router.beforeEach(async (to, from, next) => { const authRequired = !publicPages.includes(to.path); const auth: AuthStore = useAuthStore(); - // 如果用户已登录且试图访问登录页面,则重定向到首页或之前尝试访问的页面 + // 如果用户已登录且试图访问登录页面,则重定向到首页 if (to.path === '/auth/login' && auth.has_token()) { return next(auth.returnUrl || '/'); } diff --git a/dashboard/src/scss/components/_VScrollbar.scss b/dashboard/src/scss/components/_VScrollbar.scss new file mode 100644 index 000000000..900a8448e --- /dev/null +++ b/dashboard/src/scss/components/_VScrollbar.scss @@ -0,0 +1,141 @@ +/* 自定义滚动条样式 - 紫色主题 */ + +/* 全局滚动条样式 */ +::-webkit-scrollbar { + width: 10px; + height: 10px; +} + +::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.05); + border-radius: 5px; +} + +::-webkit-scrollbar-thumb { + background: rgba(160, 60, 254, 0.75); + border-radius: 5px; + transition: all 0.3s ease; + border: 1px solid rgba(255, 255, 255, 0.2); +} + +::-webkit-scrollbar-thumb:hover { + background: rgba(147, 51, 234, 0.85); + transform: scale(1.05); + box-shadow: 0 2px 8px rgba(147, 51, 234, 0.3); +} + +::-webkit-scrollbar-thumb:active { + background: rgba(147, 51, 234, 0.95); +} + +::-webkit-scrollbar-corner { + background: transparent; +} + +/* 深色主题滚动条样式 */ +.v-theme--PurpleThemeDark { + ::-webkit-scrollbar-track { + background: rgba(255, 255, 255, 0.05); + } + + ::-webkit-scrollbar-thumb { + background: rgba(192, 132, 252, 0.75); + border: 1px solid rgba(0, 0, 0, 0.2); + } + + ::-webkit-scrollbar-thumb:hover { + background: rgba(192, 132, 252, 0.85); + box-shadow: 0 2px 8px rgba(192, 132, 252, 0.4); + } + + ::-webkit-scrollbar-thumb:active { + background: rgba(192, 132, 252, 0.95); + } +} + +/* 细滚动条变体 */ +.thin-scrollbar { + ::-webkit-scrollbar { + width: 8px; + height: 8px; + } + + ::-webkit-scrollbar-thumb { + background: rgba(147, 51, 234, 0.75); + border: none; + } +} + +.v-theme--PurpleThemeDark .thin-scrollbar { + ::-webkit-scrollbar-thumb { + background: rgba(192, 132, 252, 0.75); + } +} + +/* 聊天区域滚动条 */ +.chat-scrollbar { + ::-webkit-scrollbar { + width: 8px; + } + + ::-webkit-scrollbar-track { + background: rgba(147, 51, 234, 0.08); + border-radius: 4px; + } + + ::-webkit-scrollbar-thumb { + background: rgba(147, 51, 234, 0.75); + border-radius: 4px; + border: 1px solid rgba(255, 255, 255, 0.1); + } + + ::-webkit-scrollbar-thumb:hover { + background: rgba(147, 51, 234, 0.85); + } +} + +.v-theme--PurpleThemeDark .chat-scrollbar { + ::-webkit-scrollbar-track { + background: rgba(192, 132, 252, 0.08); + } + + ::-webkit-scrollbar-thumb { + background: rgba(192, 132, 252, 0.75); + border: 1px solid rgba(0, 0, 0, 0.1); + } + + ::-webkit-scrollbar-thumb:hover { + background: rgba(192, 132, 252, 0.85); + } +} + +/* 隐藏滚动条变体 */ +.hidden-scrollbar { + ::-webkit-scrollbar { + width: 0px; + height: 0px; + } + + scrollbar-width: none; + -ms-overflow-style: none; +} + +/* Firefox 兼容性 */ +* { + scrollbar-width: thin; + scrollbar-color: rgba(147, 51, 234, 0.75) rgba(0, 0, 0, 0.05); +} + +.v-theme--PurpleThemeDark * { + scrollbar-color: rgba(192, 132, 252, 0.75) rgba(255, 255, 255, 0.05); +} + +/* 平滑滚动 */ +html { + scroll-behavior: smooth; +} + +/* 移动端触摸滚动优化 */ +* { + -webkit-overflow-scrolling: touch; +} \ No newline at end of file diff --git a/dashboard/src/scss/style.scss b/dashboard/src/scss/style.scss index 60a8b11ff..8371f2b68 100644 --- a/dashboard/src/scss/style.scss +++ b/dashboard/src/scss/style.scss @@ -12,5 +12,6 @@ @import './components/VShadow'; @import './components/VTextField'; @import './components/VTabs'; +@import './components/VScrollbar'; @import './pages/dashboards'; diff --git a/dashboard/src/stores/common.js b/dashboard/src/stores/common.js index d186e2db5..8983eef4a 100644 --- a/dashboard/src/stores/common.js +++ b/dashboard/src/stores/common.js @@ -155,7 +155,6 @@ export const useCommonStore = defineStore({ return data; }) .catch((err) => { - this.toast("获取插件市场数据失败: " + err, "error"); return Promise.reject(err); }); }, diff --git a/dashboard/src/views/AboutPage.vue b/dashboard/src/views/AboutPage.vue index 0cfd3efd8..453bfbba5 100644 --- a/dashboard/src/views/AboutPage.vue +++ b/dashboard/src/views/AboutPage.vue @@ -10,16 +10,16 @@ AstrBot Logo
-

AstrBot

-

A project out of interests and loves ❤️

+

{{ tm('hero.title') }}

+

{{ tm('hero.subtitle') }}

- Star 这个项目! 🌟 + {{ tm('hero.starButton') }} - 提交 Issue + {{ tm('hero.issueButton') }}
@@ -31,12 +31,12 @@ -

贡献者

+

{{ tm('contributors.title') }}

- 本项目由众多开源社区成员共同维护。感谢每一位贡献者的付出! + {{ tm('contributors.description') }}

- 查看 AstrBot 贡献者 + {{ tm('contributors.viewLink') }}

@@ -60,11 +60,11 @@ -

全球部署

+

{{ tm('stats.title') }}

-

AstrBot 采用 AGPL v3 协议开源

+

{{ tm('stats.license') }}

@@ -89,9 +89,14 @@ - - LLM 服务 + {{ tm('conversation.llmService') }} - 语音转文本 + {{ tm('conversation.speechToText') }} @@ -119,7 +99,7 @@ const props = defineProps({ mdi-delete - 删除此对话 + {{ tm('actions.deleteChat') }} @@ -131,19 +111,25 @@ const props = defineProps({
-

{{ getCurrentConversation.title || '新对话' }}

+

{{ getCurrentConversation.title || tm('conversation.newConversation') }}

{{ formatDate(getCurrentConversation.updated_at) }}
- + + + + + - + - +