diff --git a/packages/web/src/App.vue b/packages/web/src/App.vue index a9f3c2c5..2a27df1c 100644 --- a/packages/web/src/App.vue +++ b/packages/web/src/App.vue @@ -1,8 +1,41 @@ - + + + + + + + + + 中文 + + + English + + + + + + \ No newline at end of file diff --git a/packages/web/src/components/CreateMCP/index.vue b/packages/web/src/components/CreateMCP/index.vue index d8b5926b..3a7312e0 100644 --- a/packages/web/src/components/CreateMCP/index.vue +++ b/packages/web/src/components/CreateMCP/index.vue @@ -6,13 +6,13 @@ variant="default" class="ml-auto my-4" > - 添加MCP + {{ $t("button.add",{msg:"MCP"}) }} - 添加MCP + {{ $t("button.add", { msg: "MCP" }) }} 添加MCP完成操作 @@ -29,7 +29,7 @@ @@ -50,7 +50,9 @@ - + @@ -77,7 +79,7 @@ @@ -97,7 +99,7 @@ @@ -129,8 +131,8 @@ - @@ -179,7 +181,7 @@ @@ -196,7 +198,7 @@ - 开启 + {{ $t('state.open') }} - 添加MCP + {{ $t("button.add", { msg: "MCP" }) }} diff --git a/packages/web/src/components/CreateModel/index.vue b/packages/web/src/components/CreateModel/index.vue index 933cb749..3f159539 100644 --- a/packages/web/src/components/CreateModel/index.vue +++ b/packages/web/src/components/CreateModel/index.vue @@ -3,13 +3,13 @@ - 添加Model + {{ $t("button.add",{msg:"Model"}) }} - 添加Model + {{ $t("button.add", { msg: "Model" }) }} 使用不用厂商的大模型 @@ -26,7 +26,7 @@ @@ -46,8 +46,8 @@ @@ -67,7 +67,7 @@ @@ -88,7 +88,7 @@ - + @@ -120,7 +120,7 @@ @@ -141,7 +141,7 @@ - + @@ -168,7 +168,7 @@ - 添加Model + {{ $t("button.add", { msg: "Model" }) }} diff --git a/packages/web/src/components/MainContainer/index.vue b/packages/web/src/components/MainContainer/index.vue index c915149d..f4192cce 100644 --- a/packages/web/src/components/MainContainer/index.vue +++ b/packages/web/src/components/MainContainer/index.vue @@ -12,10 +12,10 @@ - + {{ breadcrumbItem.breadcrumb }} @@ -23,7 +23,7 @@ - + {{ breadcrumbItem.breadcrumb }} @@ -52,17 +52,24 @@ import { BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, - Separator + Separator, + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, } from '@memoh/ui' -import {useRoute} from 'vue-router' +import { useRoute } from 'vue-router' import { computed } from 'vue' +import SvgIcon from '@jamescoyle/vue-icon' +import { mdiTranslate } from '@mdi/js' + const route = useRoute() -const curBreadcrumb = computed(() => { +const curBreadcrumb = computed(() => { return route.matched.map(routeItem => ({ path: routeItem.path, breadcrumb: routeItem.meta['breadcrumb'] - })) + })) }) \ No newline at end of file diff --git a/packages/web/src/components/Sidebar/index.vue b/packages/web/src/components/Sidebar/index.vue index 885a17fe..19bd559d 100644 --- a/packages/web/src/components/Sidebar/index.vue +++ b/packages/web/src/components/Sidebar/index.vue @@ -56,7 +56,7 @@ class="flex-[0.7] mb-10" @click="exit" > - 退出登录 + {{ $t("login.exit") }} @@ -81,45 +81,50 @@ import { Collapsible, Button } from '@memoh/ui' -import { reactive } from 'vue' +import { computed } from 'vue' import SvgIcon from '@jamescoyle/vue-icon' import { mdiRobot, mdiChatOutline, mdiCogBox, mdiListBox, mdiHome, mdiBookArrowDown } from '@mdi/js' import { useRouter } from 'vue-router' -import {useUserStore} from '@/store/User.ts' +import { useUserStore } from '@/store/User.ts' +import i18n from '@/i18n' +const router=useRouter() -const router = useRouter() +const { t } = i18n.global -const sidebarInfo = reactive([{ - title: '创建对话', - name: 'chat', - icon: mdiChatOutline -}, { - title: '主页', - name: 'home', - icon: mdiHome -}, -{ - title: '模型配置', - name: 'models', - icon: mdiRobot -}, { - title: '设置', - name: 'settings', - icon: mdiCogBox -}, { - title: 'MCP', - name: 'mcp', - icon: mdiListBox -}, { - title: '平台', - name: 'platform', - icon: mdiBookArrowDown - }]) +const sidebarInfo = computed(() => [ + { + title: t('slidebar.chat'), + name: 'chat', + icon: mdiChatOutline + }, + { + title: t('slidebar.home'), + name: 'home', + icon: mdiHome + }, + { + title: t('slidebar.model_setting'), + name: 'models', + icon: mdiRobot + }, { + title: t('slidebar.setting'), + name: 'settings', + icon: mdiCogBox + }, { + title: 'MCP', + name: 'mcp', + icon: mdiListBox + }, { + title: t('slidebar.platform'), + name: 'platform', + icon: mdiBookArrowDown + } +]) - const {exitLogin}=useUserStore() +const { exitLogin } = useUserStore() const exit = () => { exitLogin() - router.replace({name:'Login'}) + router.replace({ name: 'Login' }) } \ No newline at end of file diff --git a/packages/web/src/i18n.ts b/packages/web/src/i18n.ts index 65955b03..54e6b9ab 100644 --- a/packages/web/src/i18n.ts +++ b/packages/web/src/i18n.ts @@ -1,7 +1,29 @@ import { createI18n } from 'vue-i18n' +import en from '@/i18n/locales/en.json' +import zh from '@/i18n/locales/zh.json' +import { computed } from 'vue' -const i18n = createI18n({ - locale: 'en', +type enMessageSchema = typeof en +type zhMessageSchema = typeof zh; + + +const i18n = createI18n<[enMessageSchema, zhMessageSchema], 'en' | 'zh'>({ + locale: 'zh', + legacy: false, + fallbackLocale: 'en', + messages: { + en, + zh + } }) -export default i18n \ No newline at end of file + +export default i18n + +const t = i18n.global.t + +export const i18nRef = (arg:string) => { + return computed(() => { + return t(arg) + }) +} diff --git a/packages/web/src/i18n/locales/en.json b/packages/web/src/i18n/locales/en.json index e69de29b..66243e47 100644 --- a/packages/web/src/i18n/locales/en.json +++ b/packages/web/src/i18n/locales/en.json @@ -0,0 +1,39 @@ +{ + "login": { + "username": "Username", + "password": "Password", + "login": "Login", + "register": "Register", + "forget": "Forgot your password?", + "exit": "Sign Out" + }, + "prompt": { + "enter": "Please enter {msg}", + "select": "Please select {msg}" + }, + "slidebar": { + "setting": "Settings", + "platform": "Platform", + "chat": "Create Chat", + "model_setting": "Model Settings", + "home": "Home" + }, + "desc": { + "question": "your question" + }, + "chat": { + "send": "Send", + "chat": "Chat" + }, + "breadcrumb": { + "main": "Main" + }, + "button": { + "edit": "Edit", + "delete": "Delete", + "add": "Add {msg}" + }, + "state":{ + "open":"Open" + } +} diff --git a/packages/web/src/i18n/locales/zh.json b/packages/web/src/i18n/locales/zh.json new file mode 100644 index 00000000..2acf0ffc --- /dev/null +++ b/packages/web/src/i18n/locales/zh.json @@ -0,0 +1,39 @@ +{ + "login": { + "username": "用户名", + "password": "密码", + "login": "登录", + "register": "注册", + "forget": "忘记密码?", + "exit": "退出登录" + }, + "desc": { + "question": "您的问题" + }, + "prompt": { + "enter": "请输入{msg}", + "select": "请选择{msg}" + }, + "slidebar": { + "setting": "设置", + "platform": "平台", + "chat": "创建对话", + "model_setting": "模型配置", + "home": "主页" + }, + "chat": { + "send": "发送", + "chat": "对话" + }, + "breadcrumb": { + "main": "主菜单" + }, + "button": { + "edit": "编辑", + "delete": "删除", + "add": "添加{msg}" + }, + "state": { + "open": "Open" + } +} diff --git a/packages/web/src/main.ts b/packages/web/src/main.ts index 8c83933d..819c6ba1 100644 --- a/packages/web/src/main.ts +++ b/packages/web/src/main.ts @@ -13,4 +13,4 @@ createApp(App) .use(PiniaColada) .use(router) .use(i18n) - .mount('#app') + .mount('#app') \ No newline at end of file diff --git a/packages/web/src/pages/chat/index.vue b/packages/web/src/pages/chat/index.vue index fb072993..e3f17b80 100644 --- a/packages/web/src/pages/chat/index.vue +++ b/packages/web/src/pages/chat/index.vue @@ -23,7 +23,7 @@ - 发送 + {{ $t('chat.send') }} - Username + {{ $t("login.username") }} @@ -45,12 +45,12 @@ > - Password + {{ $t('login.password') }} @@ -65,7 +65,7 @@ href="#" class="ml-auto inline-block text-sm underline mt-2" > - Forgot your password? + {{ $t('login.forget') }} @@ -75,13 +75,13 @@ type="submit" @click="login" > - 登录 + {{ $t("login.login") }} - 注册 + {{ $t("login.register") }} @@ -153,8 +153,6 @@ const login = form.handleSubmit(async (values) => { } finally { loading.value=false } - - }) diff --git a/packages/web/src/pages/mcp/index.vue b/packages/web/src/pages/mcp/index.vue index e71b5b05..10e8bdd0 100644 --- a/packages/web/src/pages/mcp/index.vue +++ b/packages/web/src/pages/mcp/index.vue @@ -19,7 +19,8 @@ import { Badge, Button } from '@memoh/ui' -import { type MCPListItem as MCPType } from '@memoh/shared' +import { type MCPListItem as MCPType } from '@memoh/shared' +import { i18nRef } from '@/i18n' const open = ref(false) @@ -94,7 +95,7 @@ const columns:ColumnDef[] = [ } open.value=true } - }, ()=>'编辑'), + }, ()=>i18nRef('button.edit').value), h(Button, { variant: 'destructive', async onClick() { @@ -104,7 +105,7 @@ const columns:ColumnDef[] = [ return } } - },()=>'删除') + },()=>i18nRef('button.delete').value) ]) } ] diff --git a/packages/web/src/pages/models/index.vue b/packages/web/src/pages/models/index.vue index 9ebb6397..7848ff17 100644 --- a/packages/web/src/pages/models/index.vue +++ b/packages/web/src/pages/models/index.vue @@ -5,19 +5,19 @@ import CreateModel from '@/components/CreateModel/index.vue' import { useQuery, useMutation, useQueryCache } from '@pinia/colada' import { Button, - Pagination, - PaginationContent, - PaginationEllipsis, - PaginationItem, - PaginationNext, - PaginationPrevious, + // Pagination, + // PaginationContent, + // PaginationEllipsis, + // PaginationItem, + // PaginationNext, + // PaginationPrevious, Checkbox } from '@memoh/ui' import DataTable from '@/components/DataTable/index.vue' import request from '@/utils/request' import { type ColumnDef } from '@tanstack/vue-table' import {type ModelTable as ModelType} from '@memoh/shared' - +import { i18nRef } from '@/i18n' const openDialogModel = ref(false) const editModelInfo = ref(null) @@ -131,11 +131,11 @@ const columns: ComputedRef[]> = computed(() => [ editModelInfo.value = row.original openDialogModel.value = true } - }, () => '编辑'), h(Button, { + }, () => i18nRef('button.edit').value), h(Button, { variant: 'destructive', onClick() { deleteModel(row.original.id) } - }, () => '删除')]) + }, () => i18nRef('button.delete').value)]) } ]) diff --git a/packages/web/src/pages/settings/index.vue b/packages/web/src/pages/settings/index.vue index 4fcbe0fb..1385a5ca 100644 --- a/packages/web/src/pages/settings/index.vue +++ b/packages/web/src/pages/settings/index.vue @@ -23,7 +23,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -88,7 +88,7 @@ - + @@ -119,7 +119,9 @@ - + @@ -149,7 +151,7 @@ diff --git a/packages/web/src/router.ts b/packages/web/src/router.ts index b9d66da5..a1cd5ac0 100644 --- a/packages/web/src/router.ts +++ b/packages/web/src/router.ts @@ -1,4 +1,7 @@ +import { computed } from 'vue' import { createRouter, createWebHistory } from 'vue-router' +import i18n from './i18n' +import { i18nRef } from './i18n' const routes = [ { @@ -15,14 +18,14 @@ const routes = [ path: '/main', redirect: '/main/chat', meta: { - breadcrumb: '主菜单' + breadcrumb: i18nRef('breadcrumb.main') }, children: [{ name: 'chat', path: 'chat', component: () => import('@/pages/chat/index.vue'), meta: { - breadcrumb: '对话' + breadcrumb: i18nRef('chat.chat') } }, { name: 'home', @@ -36,14 +39,14 @@ const routes = [ path: 'models', component: () => import('@/pages/models/index.vue'), meta: { - breadcrumb: '模型管理' + breadcrumb: i18nRef('slidebar.model_setting') } }, { name: 'settings', path: 'settings', component: () => import('@/pages/settings/index.vue'), meta: { - breadcrumb: '设置' + breadcrumb: i18nRef('slidebar.setting') } }, { name: 'mcp', @@ -57,7 +60,7 @@ const routes = [ path: 'platform', component: () => import('@/pages/platform/index.vue'), meta: { - breadcrumb: '平台' + breadcrumb: i18nRef('slidebar.platform') } }] } diff --git a/packages/web/tsconfig.app.json b/packages/web/tsconfig.app.json index e11aafd0..3c0202a5 100644 --- a/packages/web/tsconfig.app.json +++ b/packages/web/tsconfig.app.json @@ -12,7 +12,7 @@ "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true, "typeRoots": ["./node_modules/@types", "./type.d.ts"], - "baseUrl": ".", + "rootDir": ".", "paths": { "@/*": ["./src/*"] }