ljw 1 year ago
parent
commit
8be855ff3e

+ 4 - 2
src/layout/components/menu/item.vue

@@ -7,7 +7,7 @@
7
       <el-icon v-if="route.meta?.icon">
7
       <el-icon v-if="route.meta?.icon">
8
         <component :is="`el-icon-${route.meta.icon}`"></component>
8
         <component :is="`el-icon-${route.meta.icon}`"></component>
9
       </el-icon>
9
       </el-icon>
10
-      <span>{{route.meta?.title||route.name}}</span>
10
+      <span>{{ T(route.meta?.title) || T(route.name) }}</span>
11
     </template>
11
     </template>
12
     <menu-item v-for="(_route,_index) in route.children"
12
     <menu-item v-for="(_route,_index) in route.children"
13
                :route="_route"
13
                :route="_route"
@@ -18,12 +18,13 @@
18
     <el-icon v-if="parseRoute(route).meta?.icon">
18
     <el-icon v-if="parseRoute(route).meta?.icon">
19
       <component :is="`el-icon-${parseRoute(route).meta.icon}`"></component>
19
       <component :is="`el-icon-${parseRoute(route).meta.icon}`"></component>
20
     </el-icon>
20
     </el-icon>
21
-    <span>{{parseRoute(route).meta?.title||parseRoute(route).name}}</span>
21
+    <span>{{ T(parseRoute(route).meta?.title) || T(parseRoute(route).name) }}</span>
22
   </el-menu-item>
22
   </el-menu-item>
23
 </template>
23
 </template>
24
 
24
 
25
 <script>
25
 <script>
26
   import { defineComponent } from 'vue'
26
   import { defineComponent } from 'vue'
27
+  import { T } from '@/utils/i18n'
27
 
28
 
28
   export default defineComponent({
29
   export default defineComponent({
29
     name: 'MenuItem',
30
     name: 'MenuItem',
@@ -43,6 +44,7 @@
43
       }
44
       }
44
       return {
45
       return {
45
         parseRoute,
46
         parseRoute,
47
+        T,
46
       }
48
       }
47
     },
49
     },
48
   })
50
   })

+ 12 - 2
src/layout/components/setting/index.vue

@@ -1,5 +1,8 @@
1
 <template>
1
 <template>
2
   <div class="setting">
2
   <div class="setting">
3
+    <div>
4
+      <el-button size="small" @click="changeLang" style="width: 100px">{{ T('ChangeLang') }}</el-button>
5
+    </div>
3
     <el-dropdown class="menu-item">
6
     <el-dropdown class="menu-item">
4
       <div class="title">
7
       <div class="title">
5
         <!--        <el-image class="avatar" :src="user.avatar"></el-image>-->
8
         <!--        <el-image class="avatar" :src="user.avatar"></el-image>-->
@@ -7,12 +10,13 @@
7
         <el-icon>
10
         <el-icon>
8
           <el-icon-arrow-down/>
11
           <el-icon-arrow-down/>
9
         </el-icon>
12
         </el-icon>
13
+
10
       </div>
14
       </div>
11
 
15
 
12
       <template #dropdown>
16
       <template #dropdown>
13
         <el-dropdown-menu>
17
         <el-dropdown-menu>
14
-          <el-dropdown-item @click="showChangePwd">修改密码</el-dropdown-item>
15
-          <el-dropdown-item @click="logout">退出登录</el-dropdown-item>
18
+          <el-dropdown-item @click="showChangePwd">{{T('ChangePassword')}}</el-dropdown-item>
19
+          <el-dropdown-item @click="logout">{{ T('Logout')}}</el-dropdown-item>
16
         </el-dropdown-menu>
20
         </el-dropdown-menu>
17
       </template>
21
       </template>
18
     </el-dropdown>
22
     </el-dropdown>
@@ -22,11 +26,14 @@
22
 
26
 
23
 <script setup>
27
 <script setup>
24
   import { useUserStore } from '@/store/user'
28
   import { useUserStore } from '@/store/user'
29
+  import { useAppStore } from '@/store/app'
25
   import changePwdDialog from '@/components/changePwdDialog.vue'
30
   import changePwdDialog from '@/components/changePwdDialog.vue'
26
   import { ref } from 'vue'
31
   import { ref } from 'vue'
32
+  import { T } from '@/utils/i18n'
27
 
33
 
28
   const userStore = useUserStore()
34
   const userStore = useUserStore()
29
   const user = userStore
35
   const user = userStore
36
+  const appStore = useAppStore()
30
 
37
 
31
   const logout = () => {
38
   const logout = () => {
32
     userStore.logout()
39
     userStore.logout()
@@ -37,6 +44,9 @@
37
   const showChangePwd = () => {
44
   const showChangePwd = () => {
38
     changePwdVisible.value = true
45
     changePwdVisible.value = true
39
   }
46
   }
47
+  const changeLang = () => {
48
+    appStore.changeLang()
49
+  }
40
 </script>
50
 </script>
41
 
51
 
42
 <style lang="scss" scoped>
52
 <style lang="scss" scoped>

+ 9 - 6
src/layout/components/tags/index.vue

@@ -7,7 +7,7 @@
7
           @click="toTag(t)"
7
           @click="toTag(t)"
8
           :type="t.active?'primary':'info'"
8
           :type="t.active?'primary':'info'"
9
           :effect="t.active?'dark':'plain'">
9
           :effect="t.active?'dark':'plain'">
10
-    {{t.title}}
10
+    {{ T(t.title) }}
11
   </el-tag>
11
   </el-tag>
12
 </template>
12
 </template>
13
 
13
 
@@ -15,6 +15,7 @@
15
   import { defineComponent, ref, onMounted, watch } from 'vue'
15
   import { defineComponent, ref, onMounted, watch } from 'vue'
16
   import { useTagsStore } from '@/store/tags'
16
   import { useTagsStore } from '@/store/tags'
17
   import { useRoute, useRouter } from 'vue-router'
17
   import { useRoute, useRouter } from 'vue-router'
18
+  import { T } from '@/utils/i18n'
18
 
19
 
19
   export default defineComponent({
20
   export default defineComponent({
20
     name: 'Index',
21
     name: 'Index',
@@ -64,6 +65,7 @@
64
         close,
65
         close,
65
         toLastTag,
66
         toLastTag,
66
         toTag,
67
         toTag,
68
+        T,
67
       }
69
       }
68
     },
70
     },
69
   })
71
   })
@@ -71,10 +73,11 @@
71
 
73
 
72
 <style lang="scss" scoped>
74
 <style lang="scss" scoped>
73
 
75
 
74
-  .tag {
75
-    border-radius: 0;
76
-    cursor: pointer;
77
-    &.active {
78
-    }
76
+.tag {
77
+  border-radius: 0;
78
+  cursor: pointer;
79
+
80
+  &.active {
79
   }
81
   }
82
+}
80
 </style>
83
 </style>

+ 49 - 61
src/layout/index.vue

@@ -1,85 +1,73 @@
1
 <template>
1
 <template>
2
-  <el-container>
3
-    <el-aside :width="leftWidth" class="app-left">
4
-      <g-aside></g-aside>
5
-    </el-aside>
6
-    <el-container class="app-container ">
7
-      <el-header class="app-header">
8
-        <g-header></g-header>
9
-      </el-header>
10
-      <div class="header-tags">
11
-        <tags></tags>
12
-      </div>
2
+  <el-config-provider :locale="appStore.setting.locale">
3
+    <el-container>
4
+      <el-aside :width="leftWidth" class="app-left">
5
+        <g-aside></g-aside>
6
+      </el-aside>
7
+      <el-container class="app-container ">
8
+        <el-header class="app-header">
9
+          <g-header></g-header>
10
+        </el-header>
11
+        <div class="header-tags">
12
+          <tags></tags>
13
+        </div>
13
 
14
 
14
-      <el-main class="app-main">
15
-        <router-view v-slot="{ Component }">
16
-          <transition mode="out-in" name="el-fade-in-linear">
17
-            <keep-alive :include="[...cachedTags]">
18
-              <component :is="Component"/>
19
-            </keep-alive>
20
-          </transition>
21
-        </router-view>
22
-      </el-main>
15
+        <el-main class="app-main">
16
+          <router-view v-slot="{ Component }">
17
+            <transition mode="out-in" name="el-fade-in-linear">
18
+              <keep-alive :include="[...cachedTags]">
19
+                <component :is="Component"/>
20
+              </keep-alive>
21
+            </transition>
22
+          </router-view>
23
+        </el-main>
24
+      </el-container>
23
     </el-container>
25
     </el-container>
24
-  </el-container>
26
+  </el-config-provider>
25
 </template>
27
 </template>
26
 
28
 
27
-<script>
29
+<script setup>
28
   import { useUserStore } from '@/store/user'
30
   import { useUserStore } from '@/store/user'
29
-  import { useRouteStore } from '@/store/router'
30
   import { useAppStore } from '@/store/app'
31
   import { useAppStore } from '@/store/app'
31
   import { useTagsStore } from '@/store/tags'
32
   import { useTagsStore } from '@/store/tags'
32
-  import LayerHeader from '@/layout/components/header.vue'
33
-  import { defineComponent, ref, onMounted, watch, reactive, computed, toRef } from 'vue'
33
+  import { ref, computed } from 'vue'
34
   import Tags from '@/layout/components/tags/index.vue'
34
   import Tags from '@/layout/components/tags/index.vue'
35
   import GAside from '@/layout/components/aside.vue'
35
   import GAside from '@/layout/components/aside.vue'
36
   import GHeader from '@/layout/components/header.vue'
36
   import GHeader from '@/layout/components/header.vue'
37
 
37
 
38
-  export default defineComponent({
39
-    name: 'Layout',
40
-    components: { LayerHeader, Tags, GAside, GHeader },
41
-    setup (props) {
42
-      const userStore = useUserStore()
43
-      const appStore = useAppStore()
44
-      const tagStore = useTagsStore()
38
+  const appStore = useAppStore()
39
+  const tagStore = useTagsStore()
45
 
40
 
46
-      const leftWidth = computed(() => appStore.setting.sideIsCollapse ? '64px' : '210px')
41
+  const leftWidth = computed(() => appStore.setting.sideIsCollapse ? '64px' : '210px')
47
 
42
 
48
-      const cachedTags = ref([])
43
+  const cachedTags = ref([])
49
 
44
 
50
-      cachedTags.value = tagStore.cached
51
-
52
-      return {
53
-        cachedTags,
54
-        leftWidth,
55
-      }
56
-    },
57
-  })
45
+  cachedTags.value = tagStore.cached
58
 </script>
46
 </script>
59
 
47
 
60
 <style lang="scss" scoped>
48
 <style lang="scss" scoped>
61
-  .app-header {
62
-    background-color: #3f454b;
63
-    color: var(--basicWhite);
64
-    display: flex;
65
-    height: 50px;
66
-  }
49
+.app-header {
50
+  background-color: #3f454b;
51
+  color: var(--basicWhite);
52
+  display: flex;
53
+  height: 50px;
54
+}
67
 
55
 
68
-  .header-tags {
69
-    height: auto;
70
-    border-bottom: 1px solid #eee;
71
-    display: flex;
72
-    padding: 0;
73
-  }
56
+.header-tags {
57
+  height: auto;
58
+  border-bottom: 1px solid #eee;
59
+  display: flex;
60
+  padding: 0;
61
+}
74
 
62
 
75
-  .app-left {
76
-    height: 100%;
77
-    transition: width 0.5s;
78
-  }
63
+.app-left {
64
+  height: 100%;
65
+  transition: width 0.5s;
66
+}
79
 
67
 
80
-  .app-container {
81
-    min-height: 100vh;
82
-  }
68
+.app-container {
69
+  min-height: 100vh;
70
+}
83
 </style>
71
 </style>
84
 
72
 
85
 
73
 

+ 15 - 15
src/router/index.js

@@ -4,7 +4,7 @@ const constantRoutes = [
4
   {
4
   {
5
     path: '/login',
5
     path: '/login',
6
     name: 'Login',
6
     name: 'Login',
7
-    meta: { title: '登录' },
7
+    meta: { title: 'Login' },
8
     component: () => import('@/views/login/login.vue'),
8
     component: () => import('@/views/login/login.vue'),
9
   },
9
   },
10
 
10
 
@@ -45,25 +45,25 @@ export const asyncRoutes = [
45
     path: '/my',
45
     path: '/my',
46
     name: 'My',
46
     name: 'My',
47
     redirect: '/my/info',
47
     redirect: '/my/info',
48
-    meta: { title: '我的', icon: 'UserFilled' },
48
+    meta: { title: 'My', icon: 'UserFilled' },
49
     component: () => import('@/layout/index.vue'),
49
     component: () => import('@/layout/index.vue'),
50
     children: [
50
     children: [
51
       {
51
       {
52
         path: '/',
52
         path: '/',
53
         name: 'MyInfo',
53
         name: 'MyInfo',
54
-        meta: { title: '个人信息', icon: 'User' /*keepAlive: true*/ },
54
+        meta: { title: 'Info', icon: 'User' /*keepAlive: true*/ },
55
         component: () => import('@/views/my/info.vue'),
55
         component: () => import('@/views/my/info.vue'),
56
       },
56
       },
57
       {
57
       {
58
         path: 'address_book',
58
         path: 'address_book',
59
         name: 'MyAddressBookList',
59
         name: 'MyAddressBookList',
60
-        meta: { title: '地址簿管理', icon: 'Notebook' /*keepAlive: true*/ },
60
+        meta: { title: 'AddressBooks', icon: 'Notebook' /*keepAlive: true*/ },
61
         component: () => import('@/views/my/address_book/index.vue'),
61
         component: () => import('@/views/my/address_book/index.vue'),
62
       },
62
       },
63
       {
63
       {
64
         path: 'tag',
64
         path: 'tag',
65
         name: 'MyTagList',
65
         name: 'MyTagList',
66
-        meta: { title: '标签管理', icon: 'CollectionTag' /*keepAlive: true*/ },
66
+        meta: { title: 'Tags', icon: 'CollectionTag' /*keepAlive: true*/ },
67
         component: () => import('@/views/my/tag/index.vue'),
67
         component: () => import('@/views/my/tag/index.vue'),
68
       },
68
       },
69
     ],
69
     ],
@@ -72,62 +72,62 @@ export const asyncRoutes = [
72
     path: '/user',
72
     path: '/user',
73
     name: 'User',
73
     name: 'User',
74
     redirect: '/user/index',
74
     redirect: '/user/index',
75
-    meta: { title: '系统', icon: 'Setting' },
75
+    meta: { title: 'System', icon: 'Setting' },
76
     component: () => import('@/layout/index.vue'),
76
     component: () => import('@/layout/index.vue'),
77
     children: [
77
     children: [
78
       {
78
       {
79
         path: 'peer',
79
         path: 'peer',
80
         name: 'Peer',
80
         name: 'Peer',
81
-        meta: { title: '设备管理', icon: 'Monitor' /*keepAlive: true*/ },
81
+        meta: { title: 'PeerManage', icon: 'Monitor' /*keepAlive: true*/ },
82
         component: () => import('@/views/peer/index.vue'),
82
         component: () => import('@/views/peer/index.vue'),
83
       },
83
       },
84
       {
84
       {
85
         path: 'group',
85
         path: 'group',
86
         name: 'UserGroup',
86
         name: 'UserGroup',
87
-        meta: { title: '群组管理', icon: 'ChatRound' /*keepAlive: true*/ },
87
+        meta: { title: 'GroupManage', icon: 'ChatRound' /*keepAlive: true*/ },
88
         component: () => import('@/views/group/index.vue'),
88
         component: () => import('@/views/group/index.vue'),
89
       },
89
       },
90
       {
90
       {
91
         path: 'index',
91
         path: 'index',
92
         name: 'UserList',
92
         name: 'UserList',
93
-        meta: { title: '用户列表', icon: 'User' /*keepAlive: true*/ },
93
+        meta: { title: 'UserManage', icon: 'User' /*keepAlive: true*/ },
94
         component: () => import('@/views/user/index.vue'),
94
         component: () => import('@/views/user/index.vue'),
95
       },
95
       },
96
       {
96
       {
97
         path: 'add',
97
         path: 'add',
98
         name: 'UserAdd',
98
         name: 'UserAdd',
99
-        meta: { title: '用户添加', hide: true },
99
+        meta: { title: 'UserAdd', hide: true },
100
         component: () => import('@/views/user/edit.vue'),
100
         component: () => import('@/views/user/edit.vue'),
101
       },
101
       },
102
       {
102
       {
103
         path: 'edit/:id',
103
         path: 'edit/:id',
104
         name: 'UserEdit',
104
         name: 'UserEdit',
105
-        meta: { title: '用户编辑', hide: true },
105
+        meta: { title: 'UserEdit', hide: true },
106
         component: () => import('@/views/user/edit.vue'),
106
         component: () => import('@/views/user/edit.vue'),
107
       },
107
       },
108
 
108
 
109
       {
109
       {
110
         path: 'addressBook',
110
         path: 'addressBook',
111
         name: 'UserAddressBook',
111
         name: 'UserAddressBook',
112
-        meta: { title: '地址簿管理', icon: 'Notebook' /*keepAlive: true*/ },
112
+        meta: { title: 'AddressBookManage', icon: 'Notebook' /*keepAlive: true*/ },
113
         component: () => import('@/views/address_book/index.vue'),
113
         component: () => import('@/views/address_book/index.vue'),
114
       },
114
       },
115
       {
115
       {
116
         path: 'tag',
116
         path: 'tag',
117
         name: 'UserTag',
117
         name: 'UserTag',
118
-        meta: { title: '标签管理', icon: 'CollectionTag' /*keepAlive: true*/ },
118
+        meta: { title: 'TagsManage', icon: 'CollectionTag' /*keepAlive: true*/ },
119
         component: () => import('@/views/tag/index.vue'),
119
         component: () => import('@/views/tag/index.vue'),
120
       },
120
       },
121
       {
121
       {
122
         path: '/oauth',
122
         path: '/oauth',
123
         name: 'Oauth',
123
         name: 'Oauth',
124
-        meta: { title: 'Oauth管理', icon: 'Link' /*keepAlive: true*/ },
124
+        meta: { title: 'OauthManage', icon: 'Link' /*keepAlive: true*/ },
125
         component: () => import('@/views/oauth/index.vue'),
125
         component: () => import('@/views/oauth/index.vue'),
126
       },
126
       },
127
       {
127
       {
128
         path: '/loginLog',
128
         path: '/loginLog',
129
         name: 'LoginLog',
129
         name: 'LoginLog',
130
-        meta: { title: '登录日志', icon: 'List' /*keepAlive: true*/ },
130
+        meta: { title: 'LoginLog', icon: 'List' /*keepAlive: true*/ },
131
         component: () => import('@/views/login/log.vue'),
131
         component: () => import('@/views/login/log.vue'),
132
       },
132
       },
133
     ],
133
     ],

+ 13 - 1
src/store/app.js

@@ -1,13 +1,17 @@
1
 import { defineStore, acceptHMRUpdate } from 'pinia'
1
 import { defineStore, acceptHMRUpdate } from 'pinia'
2
 import logo from '@/assets/logo.png'
2
 import logo from '@/assets/logo.png'
3
+import zhCn from 'element-plus/es/locale/lang/zh-cn'
4
+import en from 'element-plus/es/locale/lang/en'
3
 
5
 
4
 export const useAppStore = defineStore({
6
 export const useAppStore = defineStore({
5
   id: 'App',
7
   id: 'App',
6
   state: () => ({
8
   state: () => ({
7
     setting: {
9
     setting: {
8
-      title: 'Gwen-Admin',
10
+      title: 'Rustdesk-Api-Admin',
9
       sideIsCollapse: false,
11
       sideIsCollapse: false,
10
       logo,
12
       logo,
13
+      lang: localStorage.getItem('lang') || 'zh-CN',
14
+      locale: zhCn,
11
     },
15
     },
12
   }),
16
   }),
13
 
17
 
@@ -15,6 +19,14 @@ export const useAppStore = defineStore({
15
     sideCollapse () {
19
     sideCollapse () {
16
       this.setting.sideIsCollapse = !this.setting.sideIsCollapse
20
       this.setting.sideIsCollapse = !this.setting.sideIsCollapse
17
     },
21
     },
22
+    setLang (lang) {
23
+      this.setting.lang = lang
24
+      this.setting.locale = lang === 'zh-CN' ? zhCn : en
25
+      localStorage.setItem('lang', lang)
26
+    },
27
+    changeLang () {
28
+      this.setLang(this.setting.lang === 'zh-CN' ? 'en' : 'zh-CN')
29
+    },
18
   },
30
   },
19
 })
31
 })
20
 
32
 

+ 9 - 9
src/store/tags.js

@@ -8,15 +8,15 @@ export const useTagsStore = defineStore({
8
   }),
8
   }),
9
   actions: {
9
   actions: {
10
     initTags () {
10
     initTags () {
11
-      this.tags.push(
12
-        {
13
-          name: 'Home',
14
-          path: '/Home',
15
-          title: '首页',
16
-          active: false,
17
-          closeable: false,
18
-          keepAlive: false,
19
-        })
11
+      // this.tags.push(
12
+      //   {
13
+      //     name: 'Home',
14
+      //     path: '/Home',
15
+      //     title: '首页',
16
+      //     active: false,
17
+      //     closeable: false,
18
+      //     keepAlive: false,
19
+      //   })
20
     },
20
     },
21
     addTag (route) {
21
     addTag (route) {
22
       const tags = this.tags
22
       const tags = this.tags

+ 21 - 0
src/utils/i18n.js

@@ -0,0 +1,21 @@
1
+import en from '@/utils/i18n/en.json'
2
+import zhCN from '@/utils/i18n/zh_CN.json'
3
+import { useAppStore } from '@/store/app'
4
+import { pinia } from '@/store'
5
+
6
+export function T (key, params, num = 0) {
7
+  const appStore = useAppStore(pinia)
8
+  const lang = appStore.setting.lang
9
+  const trans = lang === 'zh-CN' ? zhCN : en
10
+  const tran = trans[key]
11
+  if (!tran) {
12
+    return key
13
+  }
14
+  const msg = num > 0 ? (tran.Other ? tran.Other : tran.One) : tran.One
15
+  //msg 是这样 {name} is name
16
+  //params 是这样 {name: 'zhangsan'}
17
+  //替换
18
+  return msg.replace(/{(\w+)}/g, function (match, key) {
19
+    return params[key] || match
20
+  })
21
+}

+ 236 - 0
src/utils/i18n/en.json

@@ -0,0 +1,236 @@
1
+{
2
+  "Login": {
3
+    "One": "Login"
4
+  },
5
+  "Logout": {
6
+    "One": "Logout"
7
+  },
8
+  "Register": {
9
+    "One": "Register"
10
+  },
11
+  "Confirm": {
12
+    "One": "Confirm"
13
+  },
14
+  "Username": {
15
+    "One": "Username"
16
+  },
17
+  "Password": {
18
+    "One": "Password"
19
+  },
20
+  "LoginSuccess": {
21
+    "One": "Login Success"
22
+  },
23
+  "ForgotPassword": {
24
+    "One": "Forgot Password"
25
+  },
26
+  "ResetPassword": {
27
+    "One": "Reset Password"
28
+  },
29
+  "ChangePassword": {
30
+    "One": "Change Password"
31
+  },
32
+  "Userinfo": {
33
+    "One": "User Info"
34
+  },
35
+  "ParamRequired": {
36
+    "One": "{param} is required"
37
+  },
38
+  "HasBind": {
39
+    "One": "Has bind"
40
+  },
41
+  "NoBind": {
42
+    "One": "No bind"
43
+  },
44
+  "UnBind": {
45
+    "One": "UnBind"
46
+  },
47
+  "ToBind": {
48
+    "One": "To Bind"
49
+  },
50
+  "Confirm?": {
51
+    "One": "{param} Confirm?"
52
+  },
53
+  "Cancel": {
54
+    "One": "Cancel"
55
+  },
56
+  "Platform": {
57
+    "One": "Platform"
58
+  },
59
+  "Status": {
60
+    "One": "Status"
61
+  },
62
+  "Actions": {
63
+    "One": "Actions"
64
+  },
65
+  "Filter": {
66
+    "One": "Filter"
67
+  },
68
+  "Add": {
69
+    "One": "Add"
70
+  },
71
+  "Hostname": {
72
+    "One": "Hostname"
73
+  },
74
+  "Alias": {
75
+    "One": "Alias"
76
+  },
77
+  "Hash": {
78
+    "One": "Hash"
79
+  },
80
+  "Tags": {
81
+    "One": "Tags"
82
+  },
83
+  "Edit": {
84
+    "One": "Edit"
85
+  },
86
+  "Delete": {
87
+    "One": "Delete"
88
+  },
89
+  "Create": {
90
+    "One": "Create"
91
+  },
92
+  "Update": {
93
+    "One": "Update"
94
+  },
95
+  "LoginName": {
96
+    "One": "Login Name"
97
+  },
98
+  "Submit": {
99
+    "One": "Submit"
100
+  },
101
+  "OperationSuccess": {
102
+    "One": "Operation Success"
103
+  },
104
+  "Owner": {
105
+    "One": "Owner"
106
+  },
107
+  "Name": {
108
+    "One": "Name"
109
+  },
110
+  "Color": {
111
+    "One": "Color"
112
+  },
113
+  "CreatedAt": {
114
+    "One": "Created At"
115
+  },
116
+  "UpdatedAt": {
117
+    "One": "Updated At"
118
+  },
119
+  "Memory": {
120
+    "One": "Memory"
121
+  },
122
+  "Os": {
123
+    "One": "Os"
124
+  },
125
+  "Uuid": {
126
+    "One": "Uuid"
127
+  },
128
+  "Version": {
129
+    "One": "Version"
130
+  },
131
+  "Type": {
132
+    "One": "Type"
133
+  },
134
+  "Group": {
135
+    "One": "Group"
136
+  },
137
+  "CommonGroup": {
138
+    "One": "Common Group"
139
+  },
140
+  "CommonGroupNote": {
141
+    "One": "Only admins can see group members and their devices"
142
+  },
143
+  "SharedGroup": {
144
+    "One": "Shared Group"
145
+  },
146
+  "SharedGroupNote": {
147
+    "One": "All users can see group members and their devices"
148
+  },
149
+  "Nickname": {
150
+    "One": "Nickname"
151
+  },
152
+  "UserTags": {
153
+    "One": "User Tags"
154
+  },
155
+  "UserAddressBook": {
156
+    "One": "User Address Book"
157
+  },
158
+  "IsAdmin": {
159
+    "One": "Is Admin"
160
+  },
161
+  "PleaseInputNewPassword": {
162
+    "One": "Please input new password"
163
+  },
164
+  "AutoRegister": {
165
+    "One": "Auto Register"
166
+  },
167
+  "AutoRegisterNote": {
168
+    "One": "If Enable,An account will be automatically registered when a user logs in with OAuth without binding an existing account"
169
+  },
170
+  "ThirdName": {
171
+    "One": "Third Name"
172
+  },
173
+  "Close": {
174
+    "One": "Close"
175
+  },
176
+  "OauthBinding": {
177
+    "One": "You are authorizing the binding"
178
+  },
179
+  "OauthLogining": {
180
+    "One": "You are authorizing the login"
181
+  },
182
+  "OauthCloseNote": {
183
+    "One": "If it is not authorized by you, please close the page directly"
184
+  },
185
+  "OperationSuccessAndCloseAfter3Seconds": {
186
+    "One": "Operation Success,Close after 3 seconds"
187
+  },
188
+  "ConfirmOauth": {
189
+    "One": "Confirm Oauth"
190
+  },
191
+  "Device": {
192
+    "One": "Device"
193
+  },
194
+  "ChangeLang": {
195
+    "One": "切换中文"
196
+  },
197
+  "My": {
198
+    "One": "My"
199
+  },
200
+  "Info": {
201
+    "One": "Info"
202
+  },
203
+  "AddressBooks": {
204
+    "One": "Address Books"
205
+  },
206
+  "System": {
207
+    "One": "System"
208
+  },
209
+  "PeerManage": {
210
+    "One": "Peers"
211
+  },
212
+  "AddressBookManage": {
213
+    "One": "Address Books"
214
+  },
215
+  "GroupManage": {
216
+    "One": "Groups"
217
+  },
218
+  "UserManage": {
219
+    "One": "Users"
220
+  },
221
+  "UserAdd": {
222
+    "One": "User Add"
223
+  },
224
+  "UserEdit": {
225
+    "One": "User Edit"
226
+  },
227
+  "TagsManage": {
228
+    "One": "Tags"
229
+  },
230
+  "OauthManage": {
231
+    "One": "Oauth"
232
+  },
233
+  "LoginLog": {
234
+    "One": "Login Log"
235
+  }
236
+}

+ 236 - 0
src/utils/i18n/zh_CN.json

@@ -0,0 +1,236 @@
1
+{
2
+  "Login": {
3
+    "One": "登录"
4
+  },
5
+  "Logout": {
6
+    "One": "退出登录"
7
+  },
8
+  "Register": {
9
+    "One": "注册"
10
+  },
11
+  "Confirm": {
12
+    "One": "确认"
13
+  },
14
+  "Username": {
15
+    "One": "用户名"
16
+  },
17
+  "Password": {
18
+    "One": "密码"
19
+  },
20
+  "LoginSuccess": {
21
+    "One": "登录成功"
22
+  },
23
+  "ForgotPassword": {
24
+    "One": "忘记密码"
25
+  },
26
+  "ResetPassword": {
27
+    "One": "重置密码"
28
+  },
29
+  "ChangePassword": {
30
+    "One": "修改密码"
31
+  },
32
+  "Userinfo": {
33
+    "One": "用户信息"
34
+  },
35
+  "ParamRequired": {
36
+    "One": "{param} 是必须的"
37
+  },
38
+  "HasBind": {
39
+    "One": "已绑定"
40
+  },
41
+  "NoBind": {
42
+    "One": "未绑定"
43
+  },
44
+  "UnBind": {
45
+    "One": "解绑"
46
+  },
47
+  "ToBind": {
48
+    "One": "绑定"
49
+  },
50
+  "Confirm?": {
51
+    "One": "确定{param}?"
52
+  },
53
+  "Cancel": {
54
+    "One": "取消"
55
+  },
56
+  "Platform": {
57
+    "One": "平台"
58
+  },
59
+  "Status": {
60
+    "One": "状态"
61
+  },
62
+  "Actions": {
63
+    "One": "操作"
64
+  },
65
+  "Filter": {
66
+    "One": "筛选"
67
+  },
68
+  "Add": {
69
+    "One": "添加"
70
+  },
71
+  "Hostname": {
72
+    "One": "主机名"
73
+  },
74
+  "Alias": {
75
+    "One": "别名"
76
+  },
77
+  "Hash": {
78
+    "One": "哈希"
79
+  },
80
+  "Tags": {
81
+    "One": "标签"
82
+  },
83
+  "Edit": {
84
+    "One": "编辑"
85
+  },
86
+  "Delete": {
87
+    "One": "删除"
88
+  },
89
+  "Create": {
90
+    "One": "创建"
91
+  },
92
+  "Update": {
93
+    "One": "更新"
94
+  },
95
+  "LoginName": {
96
+    "One": "登录名"
97
+  },
98
+  "Submit": {
99
+    "One": "提交"
100
+  },
101
+  "OperationSuccess": {
102
+    "One": "操作成功"
103
+  },
104
+  "Owner": {
105
+    "One": "所有者"
106
+  },
107
+  "Name": {
108
+    "One": "名称"
109
+  },
110
+  "Color": {
111
+    "One": "颜色"
112
+  },
113
+  "CreatedAt": {
114
+    "One": "创建时间"
115
+  },
116
+  "UpdatedAt": {
117
+    "One": "更新时间"
118
+  },
119
+  "Memory": {
120
+    "One": "内存"
121
+  },
122
+  "Os": {
123
+    "One": "操作系统"
124
+  },
125
+  "Uuid": {
126
+    "One": "UUID"
127
+  },
128
+  "Version": {
129
+    "One": "版本"
130
+  },
131
+  "Type": {
132
+    "One": "类型"
133
+  },
134
+  "Group": {
135
+    "One": "组"
136
+  },
137
+  "CommonGroup": {
138
+    "One": "普通组"
139
+  },
140
+  "CommonGroupNote": {
141
+    "One": "只有管理员才能查看群组成员及其设备"
142
+  },
143
+  "SharedGroup": {
144
+    "One": "共享组"
145
+  },
146
+  "SharedGroupNote": {
147
+    "One": "所有用户都可以查看群组成员及其设备"
148
+  },
149
+  "Nickname": {
150
+    "One": "昵称"
151
+  },
152
+  "UserTags": {
153
+    "One": "用户标签"
154
+  },
155
+  "UserAddressBook": {
156
+    "One": "用户地址簿"
157
+  },
158
+  "IsAdmin": {
159
+    "One": "是否管理员"
160
+  },
161
+  "PleaseInputNewPassword": {
162
+    "One": "请输入新密码"
163
+  },
164
+  "AutoRegister": {
165
+    "One": "自动注册"
166
+  },
167
+  "AutoRegisterNote": {
168
+    "One": "如果启用,则当用户使用 OAuth 登录时,将自动注册一个帐户,而无需绑定现有帐户"
169
+  },
170
+  "ThirdName": {
171
+    "One": "第三方名称"
172
+  },
173
+  "Close": {
174
+    "One": "关闭"
175
+  },
176
+  "OauthBinding": {
177
+    "One": "您正在授权绑定"
178
+  },
179
+  "OauthLogining": {
180
+    "One": "您正在授权登录"
181
+  },
182
+  "OauthCloseNote": {
183
+    "One": "如不是您发起的授权,请直接关闭页面"
184
+  },
185
+  "OperationSuccessAndCloseAfter3Seconds": {
186
+    "One": "操作成功,3秒后将自动关闭页面"
187
+  },
188
+  "ConfirmOauth": {
189
+    "One": "确认授权"
190
+  },
191
+  "Device": {
192
+    "One": "设备"
193
+  },
194
+  "ChangeLang": {
195
+    "One": "ToEnglish"
196
+  },
197
+  "My": {
198
+    "One": "我的"
199
+  },
200
+  "Info": {
201
+    "One": "信息"
202
+  },
203
+  "AddressBooks": {
204
+    "One": "地址簿"
205
+  },
206
+  "System": {
207
+    "One": "系统"
208
+  },
209
+  "PeerManage": {
210
+    "One": "设备管理"
211
+  },
212
+  "AddressBookManage": {
213
+    "One": "地址簿管理"
214
+  },
215
+  "GroupManage": {
216
+    "One": "群组管理"
217
+  },
218
+  "UserManage": {
219
+    "One": "用户管理"
220
+  },
221
+  "UserAdd": {
222
+    "One": "用户添加"
223
+  },
224
+  "UserEdit": {
225
+    "One": "用户编辑"
226
+  },
227
+  "TagsManage": {
228
+    "One": "标签管理"
229
+  },
230
+  "OauthManage": {
231
+    "One": "Oauth管理"
232
+  },
233
+  "LoginLog": {
234
+    "One": "登录日志"
235
+  }
236
+}

+ 13 - 4
src/utils/request.js

@@ -3,6 +3,7 @@ import { ElMessage } from 'element-plus'
3
 import { getToken, removeToken } from '@/utils/auth'
3
 import { getToken, removeToken } from '@/utils/auth'
4
 import { useUserStore } from '@/store/user'
4
 import { useUserStore } from '@/store/user'
5
 import { pinia } from '@/store'
5
 import { pinia } from '@/store'
6
+import { useAppStore } from '@/store/app'
6
 
7
 
7
 // create an axios instance
8
 // create an axios instance
8
 const service = axios.create({
9
 const service = axios.create({
@@ -14,15 +15,23 @@ const service = axios.create({
14
 // request interceptor
15
 // request interceptor
15
 service.interceptors.request.use(
16
 service.interceptors.request.use(
16
   config => {
17
   config => {
18
+    if (!config.headers) {
19
+      config.headers = {}
20
+    }
17
     const userStore = useUserStore(pinia)
21
     const userStore = useUserStore(pinia)
18
 
22
 
19
     const token = userStore.token || getToken()
23
     const token = userStore.token || getToken()
20
     if (token) {
24
     if (token) {
21
-      if (!config.headers) {
22
-        config.headers = {}
23
-      }
24
       config.headers['api-token'] = token
25
       config.headers['api-token'] = token
25
     }
26
     }
27
+
28
+    const app = useAppStore()
29
+    const lang = app.setting.lang
30
+    if (lang) {
31
+      console.log('lang', lang)
32
+      config.headers['Accept-Language'] = lang
33
+    }
34
+
26
     return config
35
     return config
27
   },
36
   },
28
   error => {
37
   error => {
@@ -66,7 +75,7 @@ service.interceptors.response.use(
66
   error => {
75
   error => {
67
     if (error.code === 'ECONNABORTED'
76
     if (error.code === 'ECONNABORTED'
68
       && error.message.indexOf('timeout') > -1) {
77
       && error.message.indexOf('timeout') > -1) {
69
-      error.message = '请求超时!'
78
+      error.message = 'Connection Time Out!'
70
     }
79
     }
71
     ElMessage({
80
     ElMessage({
72
       message: error.message,
81
       message: error.message,

+ 7 - 6
src/views/address_book/index.js

@@ -1,7 +1,8 @@
1
-import { onActivated, onMounted, reactive, ref, watch } from 'vue'
1
+import { reactive, ref } from 'vue'
2
 import { create, list, remove, update } from '@/api/address_book'
2
 import { create, list, remove, update } from '@/api/address_book'
3
 import { ElMessage, ElMessageBox } from 'element-plus'
3
 import { ElMessage, ElMessageBox } from 'element-plus'
4
 import { useRoute } from 'vue-router'
4
 import { useRoute } from 'vue-router'
5
+import { T } from '@/utils/i18n'
5
 
6
 
6
 export function useRepositories () {
7
 export function useRepositories () {
7
   const route = useRoute()
8
   const route = useRoute()
@@ -35,9 +36,9 @@ export function useRepositories () {
35
   }
36
   }
36
 
37
 
37
   const del = async (row) => {
38
   const del = async (row) => {
38
-    const cf = await ElMessageBox.confirm('确定删除么?', {
39
-      confirmButtonText: '确定',
40
-      cancelButtonText: '取消',
39
+    const cf = await ElMessageBox.confirm(T('Confirm?', { param: T('Delete') }), {
40
+      confirmButtonText: T('Confirm'),
41
+      cancelButtonText: T('Cancel'),
41
       type: 'warning',
42
       type: 'warning',
42
     }).catch(_ => false)
43
     }).catch(_ => false)
43
     if (!cf) {
44
     if (!cf) {
@@ -46,7 +47,7 @@ export function useRepositories () {
46
 
47
 
47
     const res = await remove({ row_id: row.row_id }).catch(_ => false)
48
     const res = await remove({ row_id: row.row_id }).catch(_ => false)
48
     if (res) {
49
     if (res) {
49
-      ElMessage.success('操作成功')
50
+      ElMessage.success(T('OperationSuccess'))
50
       getList()
51
       getList()
51
     }
52
     }
52
   }
53
   }
@@ -110,7 +111,7 @@ export function useRepositories () {
110
     const api = formData.row_id ? update : create
111
     const api = formData.row_id ? update : create
111
     const res = await api(formData).catch(_ => false)
112
     const res = await api(formData).catch(_ => false)
112
     if (res) {
113
     if (res) {
113
-      ElMessage.success('操作成功')
114
+      ElMessage.success(T('OperationSuccess'))
114
       formVisible.value = false
115
       formVisible.value = false
115
       getList()
116
       getList()
116
     }
117
     }

+ 27 - 29
src/views/address_book/index.vue

@@ -1,8 +1,8 @@
1
 <template>
1
 <template>
2
   <div>
2
   <div>
3
     <el-card class="list-query" shadow="hover">
3
     <el-card class="list-query" shadow="hover">
4
-      <el-form inline label-width="60px">
5
-        <el-form-item label="用户">
4
+      <el-form inline label-width="80px">
5
+        <el-form-item :label="T('Owner')">
6
           <el-select v-model="listQuery.user_id" clearable>
6
           <el-select v-model="listQuery.user_id" clearable>
7
             <el-option
7
             <el-option
8
                 v-for="item in allUsers"
8
                 v-for="item in allUsers"
@@ -13,8 +13,8 @@
13
           </el-select>
13
           </el-select>
14
         </el-form-item>
14
         </el-form-item>
15
         <el-form-item>
15
         <el-form-item>
16
-          <el-button type="primary" @click="handlerQuery">筛选</el-button>
17
-          <el-button type="danger" @click="toAdd">添加</el-button>
16
+          <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
17
+          <el-button type="danger" @click="toAdd">{{ T('Add') }}</el-button>
18
         </el-form-item>
18
         </el-form-item>
19
       </el-form>
19
       </el-form>
20
     </el-card>
20
     </el-card>
@@ -22,24 +22,24 @@
22
       <!--      <el-tag type="danger" style="margin-bottom: 10px">不建议在此操作地址簿,可能会造成数据不同步</el-tag>-->
22
       <!--      <el-tag type="danger" style="margin-bottom: 10px">不建议在此操作地址簿,可能会造成数据不同步</el-tag>-->
23
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
23
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
24
         <el-table-column prop="id" label="id" align="center"/>
24
         <el-table-column prop="id" label="id" align="center"/>
25
-        <el-table-column label="所属用户" align="center">
25
+        <el-table-column :label="T('Owner')" align="center">
26
           <template #default="{row}">
26
           <template #default="{row}">
27
             <span v-if="row.user_id"> <el-tag>{{ allUsers?.find(u => u.id === row.user_id)?.username }}</el-tag> </span>
27
             <span v-if="row.user_id"> <el-tag>{{ allUsers?.find(u => u.id === row.user_id)?.username }}</el-tag> </span>
28
           </template>
28
           </template>
29
         </el-table-column>
29
         </el-table-column>
30
-        <el-table-column prop="username" label="用户名" align="center"/>
31
-        <el-table-column prop="hostname" label="主机名" align="center"/>
32
-        <el-table-column prop="alias" label="别名" align="center"/>
33
-        <el-table-column prop="platform" label="平台" align="center"/>
34
-        <el-table-column prop="hash" label="hash" align="center"/>
35
-        <el-table-column prop="tags" label="标签" align="center"/>
30
+        <el-table-column prop="username" :label="T('Username')" align="center"/>
31
+        <el-table-column prop="hostname" :label="T('Hostname')" align="center"/>
32
+        <el-table-column prop="alias" :label="T('Alias')" align="center"/>
33
+        <el-table-column prop="platform" :label="T('Platform')" align="center"/>
34
+        <el-table-column prop="hash" :label="T('Hash')" align="center"/>
35
+        <el-table-column prop="tags" :label="T('Tags')" align="center"/>
36
         <!--        <el-table-column prop="created_at" label="创建时间" align="center"/>-->
36
         <!--        <el-table-column prop="created_at" label="创建时间" align="center"/>-->
37
         <!--        <el-table-column prop="updated_at" label="更新时间" align="center"/>-->
37
         <!--        <el-table-column prop="updated_at" label="更新时间" align="center"/>-->
38
         <el-table-column label="操作" align="center" width="400">
38
         <el-table-column label="操作" align="center" width="400">
39
           <template #default="{row}">
39
           <template #default="{row}">
40
             <el-button type="success" @click="toWebClientLink(row)">Web-Client</el-button>
40
             <el-button type="success" @click="toWebClientLink(row)">Web-Client</el-button>
41
-            <el-button @click="toEdit(row)">编辑</el-button>
42
-            <el-button type="danger" @click="del(row)">删除</el-button>
41
+            <el-button @click="toEdit(row)">{{ T('Edit') }}</el-button>
42
+            <el-button type="danger" @click="del(row)">{{ T('Delete') }}</el-button>
43
           </template>
43
           </template>
44
         </el-table-column>
44
         </el-table-column>
45
       </el-table>
45
       </el-table>
@@ -53,9 +53,9 @@
53
                      :total="listRes.total">
53
                      :total="listRes.total">
54
       </el-pagination>
54
       </el-pagination>
55
     </el-card>
55
     </el-card>
56
-    <el-dialog v-model="formVisible" width="800" :title="!formData.row_id?'创建':'修改'">
56
+    <el-dialog v-model="formVisible" width="800" :title="!formData.row_id?T('Create') :T('Update') ">
57
       <el-form class="dialog-form" ref="form" :model="formData" label-width="120px">
57
       <el-form class="dialog-form" ref="form" :model="formData" label-width="120px">
58
-        <el-form-item label="用户" prop="user_id" required>
58
+        <el-form-item :label="T('Owner')" prop="user_id" required>
59
           <el-select v-model="formData.user_id" @change="changeUser">
59
           <el-select v-model="formData.user_id" @change="changeUser">
60
             <el-option
60
             <el-option
61
                 v-for="item in allUsers"
61
                 v-for="item in allUsers"
@@ -68,25 +68,25 @@
68
         <el-form-item label="id" prop="id" required>
68
         <el-form-item label="id" prop="id" required>
69
           <el-input v-model="formData.id"></el-input>
69
           <el-input v-model="formData.id"></el-input>
70
         </el-form-item>
70
         </el-form-item>
71
-        <el-form-item label="用户名" prop="username">
71
+        <el-form-item :label="T('Username')" prop="username">
72
           <el-input v-model="formData.username"></el-input>
72
           <el-input v-model="formData.username"></el-input>
73
         </el-form-item>
73
         </el-form-item>
74
-        <el-form-item label="别名" prop="alias">
74
+        <el-form-item :label="T('Alias')" prop="alias">
75
           <el-input v-model="formData.alias"></el-input>
75
           <el-input v-model="formData.alias"></el-input>
76
         </el-form-item>
76
         </el-form-item>
77
-        <el-form-item label="hash" prop="hash">
77
+        <el-form-item :label="T('Hash')" prop="hash">
78
           <el-input v-model="formData.hash"></el-input>
78
           <el-input v-model="formData.hash"></el-input>
79
         </el-form-item>
79
         </el-form-item>
80
-        <el-form-item label="主机名" prop="hostname">
80
+        <el-form-item :label="T('Hostname')" prop="hostname">
81
           <el-input v-model="formData.hostname"></el-input>
81
           <el-input v-model="formData.hostname"></el-input>
82
         </el-form-item>
82
         </el-form-item>
83
-        <el-form-item label="登录名" prop="login_name">
84
-          <el-input v-model="formData.login_name"></el-input>
83
+        <el-form-item :label="T('LoginName')" prop="loginName">
84
+          <el-input v-model="formData.loginName"></el-input>
85
         </el-form-item>
85
         </el-form-item>
86
-        <el-form-item label="密码" prop="password">
86
+        <el-form-item :label="T('Password')" prop="password">
87
           <el-input v-model="formData.password"></el-input>
87
           <el-input v-model="formData.password"></el-input>
88
         </el-form-item>
88
         </el-form-item>
89
-        <el-form-item label="平台" prop="platform">
89
+        <el-form-item :label="T('Platform')" prop="platform">
90
           <el-select v-model="formData.platform">
90
           <el-select v-model="formData.platform">
91
             <el-option
91
             <el-option
92
                 v-for="item in platformList"
92
                 v-for="item in platformList"
@@ -97,7 +97,7 @@
97
           </el-select>
97
           </el-select>
98
         </el-form-item>
98
         </el-form-item>
99
 
99
 
100
-        <el-form-item label="标签" prop="tags">
100
+        <el-form-item :label="T('Tags')" prop="tags">
101
           <el-select v-model="formData.tags" multiple>
101
           <el-select v-model="formData.tags" multiple>
102
             <el-option
102
             <el-option
103
                 v-for="item in tagList"
103
                 v-for="item in tagList"
@@ -125,8 +125,8 @@
125
 
125
 
126
 
126
 
127
         <el-form-item>
127
         <el-form-item>
128
-          <el-button @click="formVisible = false">取消</el-button>
129
-          <el-button @click="submit" type="primary">提交</el-button>
128
+          <el-button @click="formVisible = false">{{ T('Cancel') }}</el-button>
129
+          <el-button @click="submit" type="primary">{{ T('Submit') }}</el-button>
130
         </el-form-item>
130
         </el-form-item>
131
       </el-form>
131
       </el-form>
132
     </el-dialog>
132
     </el-dialog>
@@ -135,13 +135,11 @@
135
 
135
 
136
 <script setup>
136
 <script setup>
137
   import { onActivated, onMounted, reactive, ref, watch } from 'vue'
137
   import { onActivated, onMounted, reactive, ref, watch } from 'vue'
138
-  import { create, list, remove, update } from '@/api/address_book'
139
   import { list as fetchTagList } from '@/api/tag'
138
   import { list as fetchTagList } from '@/api/tag'
140
-  import { ElMessage, ElMessageBox } from 'element-plus'
141
   import { loadAllUsers } from '@/global'
139
   import { loadAllUsers } from '@/global'
142
-  import { useRoute } from 'vue-router'
143
   import { useRepositories } from '@/views/address_book/index'
140
   import { useRepositories } from '@/views/address_book/index'
144
   import { toWebClientLink } from '@/utils/webclient'
141
   import { toWebClientLink } from '@/utils/webclient'
142
+  import { T } from '@/utils/i18n'
145
 
143
 
146
   const { allUsers, getAllUsers } = loadAllUsers()
144
   const { allUsers, getAllUsers } = loadAllUsers()
147
   getAllUsers()
145
   getAllUsers()

+ 22 - 21
src/views/group/index.vue

@@ -1,26 +1,26 @@
1
 <template>
1
 <template>
2
   <div>
2
   <div>
3
     <el-card class="list-query" shadow="hover">
3
     <el-card class="list-query" shadow="hover">
4
-      <el-form inline label-width="60px">
4
+      <el-form inline label-width="80px">
5
         <!--        <el-form-item label="名称">
5
         <!--        <el-form-item label="名称">
6
                   <el-input v-model="listQuery.name"></el-input>
6
                   <el-input v-model="listQuery.name"></el-input>
7
                 </el-form-item>-->
7
                 </el-form-item>-->
8
         <el-form-item>
8
         <el-form-item>
9
-          <el-button type="primary" @click="handlerQuery">筛选</el-button>
10
-          <el-button type="danger" @click="toAdd">添加</el-button>
9
+          <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
10
+          <el-button type="danger" @click="toAdd">{{ T('Add') }}</el-button>
11
         </el-form-item>
11
         </el-form-item>
12
       </el-form>
12
       </el-form>
13
     </el-card>
13
     </el-card>
14
     <el-card class="list-body" shadow="hover">
14
     <el-card class="list-body" shadow="hover">
15
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
15
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
16
         <el-table-column prop="id" label="id" align="center"></el-table-column>
16
         <el-table-column prop="id" label="id" align="center"></el-table-column>
17
-        <el-table-column prop="name" label="名称" align="center"/>
18
-        <el-table-column prop="created_at" label="创建时间" align="center"/>
19
-        <el-table-column prop="updated_at" label="更新时间" align="center"/>
20
-        <el-table-column label="操作" align="center">
17
+        <el-table-column prop="name" :label="T('Name')" align="center"/>
18
+        <el-table-column prop="created_at" :label="T('CreatedAt')" align="center"/>
19
+        <el-table-column prop="updated_at" :label="T('UpdatedAt')" align="center"/>
20
+        <el-table-column :label="T('Actions')" align="center">
21
           <template #default="{row}">
21
           <template #default="{row}">
22
-            <el-button @click="toEdit(row)">编辑</el-button>
23
-            <el-button type="danger" @click="del(row)">删除</el-button>
22
+            <el-button @click="toEdit(row)">{{ T('Edit') }}</el-button>
23
+            <el-button type="danger" @click="del(row)">{{ T('Delete') }}</el-button>
24
           </template>
24
           </template>
25
         </el-table-column>
25
         </el-table-column>
26
       </el-table>
26
       </el-table>
@@ -34,12 +34,12 @@
34
                      :total="listRes.total">
34
                      :total="listRes.total">
35
       </el-pagination>
35
       </el-pagination>
36
     </el-card>
36
     </el-card>
37
-    <el-dialog v-model="formVisible" :title="!formData.id?'创建':'修改'" width="800">
37
+    <el-dialog v-model="formVisible" :title="!formData.id?T('Create'):T('Update')" width="800">
38
       <el-form class="dialog-form" ref="form" :model="formData" label-width="120px">
38
       <el-form class="dialog-form" ref="form" :model="formData" label-width="120px">
39
-        <el-form-item label="名称" prop="name" required>
39
+        <el-form-item :label="T('Name')" prop="name" required>
40
           <el-input v-model="formData.name"></el-input>
40
           <el-input v-model="formData.name"></el-input>
41
         </el-form-item>
41
         </el-form-item>
42
-        <el-form-item label="类型" prop="type" required>
42
+        <el-form-item :label="T('Type')" prop="type" required>
43
           <el-radio-group v-model="formData.type">
43
           <el-radio-group v-model="formData.type">
44
             <el-radio v-for="item in groupTypes" :key="item.value" :label="item.value" style="display: block">
44
             <el-radio v-for="item in groupTypes" :key="item.value" :label="item.value" style="display: block">
45
               {{ item.label }}
45
               {{ item.label }}
@@ -48,8 +48,8 @@
48
           </el-radio-group>
48
           </el-radio-group>
49
         </el-form-item>
49
         </el-form-item>
50
         <el-form-item>
50
         <el-form-item>
51
-          <el-button @click="formVisible = false">取消</el-button>
52
-          <el-button @click="submit" type="primary">提交</el-button>
51
+          <el-button @click="formVisible = false">{{ T('Cancel') }}</el-button>
52
+          <el-button @click="submit" type="primary">{{ T('Submit') }}</el-button>
53
         </el-form-item>
53
         </el-form-item>
54
       </el-form>
54
       </el-form>
55
     </el-dialog>
55
     </el-dialog>
@@ -60,6 +60,7 @@
60
   import { onMounted, reactive, watch, ref, onActivated } from 'vue'
60
   import { onMounted, reactive, watch, ref, onActivated } from 'vue'
61
   import { list, create, update, detail, remove } from '@/api/group'
61
   import { list, create, update, detail, remove } from '@/api/group'
62
   import { ElMessage, ElMessageBox } from 'element-plus'
62
   import { ElMessage, ElMessageBox } from 'element-plus'
63
+  import { T } from '@/utils/i18n'
63
 
64
 
64
   const listRes = reactive({
65
   const listRes = reactive({
65
     list: [], total: 0, loading: false,
66
     list: [], total: 0, loading: false,
@@ -87,9 +88,9 @@
87
   }
88
   }
88
 
89
 
89
   const del = async (row) => {
90
   const del = async (row) => {
90
-    const cf = await ElMessageBox.confirm('确定删除么?', {
91
-      confirmButtonText: '确定',
92
-      cancelButtonText: '取消',
91
+    const cf = await ElMessageBox.confirm(T('Confirm?', { param: T('Delete') }), {
92
+      confirmButtonText: T('Confirm'),
93
+      cancelButtonText: T('Cancel'),
93
       type: 'warning',
94
       type: 'warning',
94
     }).catch(_ => false)
95
     }).catch(_ => false)
95
     if (!cf) {
96
     if (!cf) {
@@ -98,7 +99,7 @@
98
 
99
 
99
     const res = await remove({ id: row.id }).catch(_ => false)
100
     const res = await remove({ id: row.id }).catch(_ => false)
100
     if (res) {
101
     if (res) {
101
-      ElMessage.success('操作成功')
102
+      ElMessage.success(T('OperationSuccess'))
102
       getList()
103
       getList()
103
     }
104
     }
104
   }
105
   }
@@ -110,8 +111,8 @@
110
   watch(() => listQuery.page_size, handlerQuery)
111
   watch(() => listQuery.page_size, handlerQuery)
111
 
112
 
112
   const groupTypes = [
113
   const groupTypes = [
113
-    { label: '普通组', value: 1, note: '只有管理员能看到小组成员和成员的设备' },
114
-    { label: '共享组', value: 2, note: '所有用户都能看到小组成员和成员的设备' },
114
+    { label: T('CommonGroup'), value: 1, note: T('CommonGroupNote') },
115
+    { label: T('SharedGroup'), value: 2, note: T('SharedGroupNote') },
115
   ]
116
   ]
116
   const formVisible = ref(false)
117
   const formVisible = ref(false)
117
   const formData = reactive({
118
   const formData = reactive({
@@ -136,7 +137,7 @@
136
     const api = formData.id ? update : create
137
     const api = formData.id ? update : create
137
     const res = await api(formData).catch(_ => false)
138
     const res = await api(formData).catch(_ => false)
138
     if (res) {
139
     if (res) {
139
-      ElMessage.success('操作成功')
140
+      ElMessage.success(T('OperationSuccess'))
140
       formVisible.value = false
141
       formVisible.value = false
141
       getList()
142
       getList()
142
     }
143
     }

+ 1 - 1
src/views/login/log.vue

@@ -1,7 +1,7 @@
1
 <template>
1
 <template>
2
   <div>
2
   <div>
3
     <el-card class="list-query" shadow="hover">
3
     <el-card class="list-query" shadow="hover">
4
-      <el-form inline label-width="60px">
4
+      <el-form inline label-width="80px">
5
         <el-form-item label="用户">
5
         <el-form-item label="用户">
6
           <el-select v-model="listQuery.user_id" clearable>
6
           <el-select v-model="listQuery.user_id" clearable>
7
             <el-option
7
             <el-option

+ 32 - 40
src/views/login/login.vue

@@ -1,65 +1,57 @@
1
 <template>
1
 <template>
2
   <div class="login">
2
   <div class="login">
3
     <el-card class="login-card">
3
     <el-card class="login-card">
4
-      <h1>登录</h1>
5
-      <el-form label-width="60px">
6
-        <el-form-item label="用户名">
4
+      <h1>{{ T('Login') }}</h1>
5
+      <el-form label-width="100px">
6
+        <el-form-item :label=" T('Username') ">
7
           <el-input v-model="form.username"></el-input>
7
           <el-input v-model="form.username"></el-input>
8
         </el-form-item>
8
         </el-form-item>
9
-        <el-form-item label="密码">
9
+        <el-form-item :label=" T('Password') ">
10
           <el-input v-model="form.password" type="password" @keyup.enter.native="login" show-password></el-input>
10
           <el-input v-model="form.password" type="password" @keyup.enter.native="login" show-password></el-input>
11
         </el-form-item>
11
         </el-form-item>
12
         <el-form-item>
12
         <el-form-item>
13
-          <el-button @click="login" type="primary">登录</el-button>
13
+          <el-button @click="login" type="primary">{{ T('Login') }}</el-button>
14
         </el-form-item>
14
         </el-form-item>
15
       </el-form>
15
       </el-form>
16
     </el-card>
16
     </el-card>
17
   </div>
17
   </div>
18
 </template>
18
 </template>
19
 
19
 
20
-<script>
20
+<script setup>
21
   import { defineComponent, reactive } from 'vue'
21
   import { defineComponent, reactive } from 'vue'
22
   import { useUserStore } from '@/store/user'
22
   import { useUserStore } from '@/store/user'
23
   import { ElMessage } from 'element-plus'
23
   import { ElMessage } from 'element-plus'
24
   import { useRoute, useRouter } from 'vue-router'
24
   import { useRoute, useRouter } from 'vue-router'
25
+  import { T } from '@/utils/i18n'
25
 
26
 
26
-  export default defineComponent({
27
-    setup (props) {
28
-      const userStore = useUserStore()
29
-      const route = useRoute()
30
-      const router = useRouter()
27
+  const userStore = useUserStore()
28
+  const route = useRoute()
29
+  const router = useRouter()
31
 
30
 
32
-      let platform = window.navigator.platform
33
-      if (navigator.platform.indexOf('Mac') === 0) {
34
-        platform = 'mac'
35
-      } else if (navigator.platform.indexOf('Win') === 0) {
36
-        platform = 'windows'
37
-      } else if (navigator.platform.indexOf('Linux armv') === 0) {
38
-        platform = 'android'
39
-      } else if (navigator.platform.indexOf('Linux') === 0) {
40
-        platform = 'linux'
41
-      }
31
+  let platform = window.navigator.platform
32
+  if (navigator.platform.indexOf('Mac') === 0) {
33
+    platform = 'mac'
34
+  } else if (navigator.platform.indexOf('Win') === 0) {
35
+    platform = 'windows'
36
+  } else if (navigator.platform.indexOf('Linux armv') === 0) {
37
+    platform = 'android'
38
+  } else if (navigator.platform.indexOf('Linux') === 0) {
39
+    platform = 'linux'
40
+  }
42
 
41
 
43
-      const form = reactive({
44
-        username: '',
45
-        password: '',
46
-        platform: platform,
47
-      })
48
-      const redirect = route.query?.redirect
49
-      const login = async () => {
50
-        const res = await userStore.login(form)
51
-        if (res) {
52
-          ElMessage.success('登录成功')
53
-          router.push({ path: redirect || '/', replace: true })
54
-        }
55
-      }
56
-      return {
57
-        redirect,
58
-        form,
59
-        login,
60
-      }
61
-    },
42
+  const form = reactive({
43
+    username: '',
44
+    password: '',
45
+    platform: platform,
62
   })
46
   })
47
+  const redirect = route.query?.redirect
48
+  const login = async () => {
49
+    const res = await userStore.login(form)
50
+    if (res) {
51
+      ElMessage.success(T('LoginSuccess'))
52
+      router.push({ path: redirect || '/', replace: true })
53
+    }
54
+  }
63
 </script>
55
 </script>
64
 
56
 
65
 <style scoped lang="scss">
57
 <style scoped lang="scss">

+ 25 - 50
src/views/my/address_book/index.vue

@@ -1,10 +1,10 @@
1
 <template>
1
 <template>
2
   <div>
2
   <div>
3
     <el-card class="list-query" shadow="hover">
3
     <el-card class="list-query" shadow="hover">
4
-      <el-form inline label-width="60px">
4
+      <el-form inline label-width="80px">
5
         <el-form-item>
5
         <el-form-item>
6
-          <el-button type="primary" @click="handlerQuery">筛选</el-button>
7
-          <el-button type="danger" @click="toAdd">添加</el-button>
6
+          <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
7
+          <el-button type="danger" @click="toAdd">{{ T('Add') }}</el-button>
8
         </el-form-item>
8
         </el-form-item>
9
       </el-form>
9
       </el-form>
10
     </el-card>
10
     </el-card>
@@ -12,19 +12,19 @@
12
       <!--      <el-tag type="danger" style="margin-bottom: 10px">不建议在此操作地址簿,可能会造成数据不同步</el-tag>-->
12
       <!--      <el-tag type="danger" style="margin-bottom: 10px">不建议在此操作地址簿,可能会造成数据不同步</el-tag>-->
13
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
13
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
14
         <el-table-column prop="id" label="id" align="center"/>
14
         <el-table-column prop="id" label="id" align="center"/>
15
-        <el-table-column prop="username" label="用户名" align="center"/>
16
-        <el-table-column prop="hostname" label="主机名" align="center"/>
17
-        <el-table-column prop="alias" label="别名" align="center"/>
18
-        <el-table-column prop="platform" label="平台" align="center"/>
19
-        <el-table-column prop="hash" label="hash" align="center"/>
20
-        <el-table-column prop="tags" label="标签" align="center"/>
15
+        <el-table-column prop="username" :label="T('Username')" align="center"/>
16
+        <el-table-column prop="hostname" :label="T('Hostname')" align="center"/>
17
+        <el-table-column prop="alias" :label="T('Alias')" align="center"/>
18
+        <el-table-column prop="platform" :label="T('Platform')" align="center"/>
19
+        <el-table-column prop="hash" :label="T('Hash')" align="center"/>
20
+        <el-table-column prop="tags" :label="T('Tags')" align="center"/>
21
         <!--        <el-table-column prop="created_at" label="创建时间" align="center"/>-->
21
         <!--        <el-table-column prop="created_at" label="创建时间" align="center"/>-->
22
         <!--        <el-table-column prop="updated_at" label="更新时间" align="center"/>-->
22
         <!--        <el-table-column prop="updated_at" label="更新时间" align="center"/>-->
23
-        <el-table-column label="操作" align="center" width="400">
23
+        <el-table-column :label="T('Actions')" align="center" width="400">
24
           <template #default="{row}">
24
           <template #default="{row}">
25
             <el-button type="success" @click="toWebClientLink(row)">Web-Client</el-button>
25
             <el-button type="success" @click="toWebClientLink(row)">Web-Client</el-button>
26
-            <el-button @click="toEdit(row)">编辑</el-button>
27
-            <el-button type="danger" @click="del(row)">删除</el-button>
26
+            <el-button @click="toEdit(row)">{{ T('Edit') }}</el-button>
27
+            <el-button type="danger" @click="del(row)">{{ T('Delete') }}</el-button>
28
           </template>
28
           </template>
29
         </el-table-column>
29
         </el-table-column>
30
       </el-table>
30
       </el-table>
@@ -38,30 +38,30 @@
38
                      :total="listRes.total">
38
                      :total="listRes.total">
39
       </el-pagination>
39
       </el-pagination>
40
     </el-card>
40
     </el-card>
41
-    <el-dialog v-model="formVisible" width="800" :title="!formData.row_id?'创建':'修改'">
41
+    <el-dialog v-model="formVisible" width="800" :title="!formData.row_id?T('Create') :T('Update') ">
42
       <el-form class="dialog-form" ref="form" :model="formData" label-width="120px">
42
       <el-form class="dialog-form" ref="form" :model="formData" label-width="120px">
43
         <el-form-item label="id" prop="id" required>
43
         <el-form-item label="id" prop="id" required>
44
           <el-input v-model="formData.id"></el-input>
44
           <el-input v-model="formData.id"></el-input>
45
         </el-form-item>
45
         </el-form-item>
46
-        <el-form-item label="用户名" prop="username">
46
+        <el-form-item :label="T('Username')" prop="username">
47
           <el-input v-model="formData.username"></el-input>
47
           <el-input v-model="formData.username"></el-input>
48
         </el-form-item>
48
         </el-form-item>
49
-        <el-form-item label="别名" prop="alias">
49
+        <el-form-item :label="T('Alias')" prop="alias">
50
           <el-input v-model="formData.alias"></el-input>
50
           <el-input v-model="formData.alias"></el-input>
51
         </el-form-item>
51
         </el-form-item>
52
-        <el-form-item label="hash" prop="hash">
52
+        <el-form-item :label="T('Hash')" prop="hash">
53
           <el-input v-model="formData.hash"></el-input>
53
           <el-input v-model="formData.hash"></el-input>
54
         </el-form-item>
54
         </el-form-item>
55
-        <el-form-item label="主机名" prop="hostname">
55
+        <el-form-item :label="T('Hostname')" prop="hostname">
56
           <el-input v-model="formData.hostname"></el-input>
56
           <el-input v-model="formData.hostname"></el-input>
57
         </el-form-item>
57
         </el-form-item>
58
-        <el-form-item label="登录名" prop="login_name">
59
-          <el-input v-model="formData.login_name"></el-input>
58
+        <el-form-item :label="T('LoginName')" prop="loginName">
59
+          <el-input v-model="formData.loginName"></el-input>
60
         </el-form-item>
60
         </el-form-item>
61
-        <el-form-item label="密码" prop="password">
61
+        <el-form-item :label="T('Password')" prop="password">
62
           <el-input v-model="formData.password"></el-input>
62
           <el-input v-model="formData.password"></el-input>
63
         </el-form-item>
63
         </el-form-item>
64
-        <el-form-item label="平台" prop="platform">
64
+        <el-form-item :label="T('Platform')" prop="platform">
65
           <el-select v-model="formData.platform">
65
           <el-select v-model="formData.platform">
66
             <el-option
66
             <el-option
67
                 v-for="item in platformList"
67
                 v-for="item in platformList"
@@ -72,7 +72,7 @@
72
           </el-select>
72
           </el-select>
73
         </el-form-item>
73
         </el-form-item>
74
 
74
 
75
-        <el-form-item label="标签" prop="tags">
75
+        <el-form-item :label="T('Tags')" prop="tags">
76
           <el-select v-model="formData.tags" multiple>
76
           <el-select v-model="formData.tags" multiple>
77
             <el-option
77
             <el-option
78
                 v-for="item in tagList"
78
                 v-for="item in tagList"
@@ -100,8 +100,8 @@
100
 
100
 
101
 
101
 
102
         <el-form-item>
102
         <el-form-item>
103
-          <el-button @click="formVisible = false">取消</el-button>
104
-          <el-button @click="submit" type="primary">提交</el-button>
103
+          <el-button @click="formVisible = false">{{ T('Cancel') }}</el-button>
104
+          <el-button @click="submit" type="primary">{{ T('Submit') }}</el-button>
105
         </el-form-item>
105
         </el-form-item>
106
       </el-form>
106
       </el-form>
107
     </el-dialog>
107
     </el-dialog>
@@ -110,10 +110,10 @@
110
 
110
 
111
 <script setup>
111
 <script setup>
112
   import { onActivated, onMounted, reactive, ref, watch } from 'vue'
112
   import { onActivated, onMounted, reactive, ref, watch } from 'vue'
113
-  import { create, list, remove, update } from '@/api/address_book'
114
   import { list as fetchTagList } from '@/api/tag'
113
   import { list as fetchTagList } from '@/api/tag'
115
   import { useRepositories } from '@/views/address_book'
114
   import { useRepositories } from '@/views/address_book'
116
   import { toWebClientLink } from '@/utils/webclient'
115
   import { toWebClientLink } from '@/utils/webclient'
116
+  import { T } from '@/utils/i18n'
117
 
117
 
118
   const tagList = ref([])
118
   const tagList = ref([])
119
   const fetchTagListData = async () => {
119
   const fetchTagListData = async () => {
@@ -136,8 +136,6 @@
136
     toEdit,
136
     toEdit,
137
     toAdd,
137
     toAdd,
138
     submit,
138
     submit,
139
-    activeChange,
140
-    currentColor,
141
   } = useRepositories()
139
   } = useRepositories()
142
 
140
 
143
   listQuery.is_my = 1
141
   listQuery.is_my = 1
@@ -149,29 +147,6 @@
149
 
147
 
150
   watch(() => listQuery.page_size, handlerQuery)
148
   watch(() => listQuery.page_size, handlerQuery)
151
 
149
 
152
-  /*watch(() => listRes.list, () => {
153
-        const peers = {}
154
-        listRes.list.map(item => {
155
-          peers[item.id] = {
156
-            'view-style': 'shrink',
157
-            tm: new Date().getTime(),
158
-            info: {
159
-              'id': item.id,
160
-              'username': item.username,
161
-              'hostname': item.hostname,
162
-              'alias': item.alias,
163
-              'platform': item.platform,
164
-              'hash': item.hash,
165
-              'tags': item.tags,
166
-            },
167
-          }
168
-        })
169
-        localStorage.setItem('peers', JSON.stringify(peers))
170
-      },
171
-      {
172
-        immediate: true,
173
-      })*/
174
-
175
 </script>
150
 </script>
176
 
151
 
177
 <style scoped lang="scss">
152
 <style scoped lang="scss">

+ 15 - 14
src/views/my/info.vue

@@ -1,26 +1,26 @@
1
 <template>
1
 <template>
2
   <div>
2
   <div>
3
-    <el-card title="个人信息">
3
+    <el-card :title="T('Userinfo')">
4
       <el-form class="info-form" ref="form" label-width="120px" label-suffix=":">
4
       <el-form class="info-form" ref="form" label-width="120px" label-suffix=":">
5
-        <el-form-item label="用户名">
5
+        <el-form-item :label="T('Username')">
6
           <div>{{ userStore.username }}</div>
6
           <div>{{ userStore.username }}</div>
7
         </el-form-item>
7
         </el-form-item>
8
-        <el-form-item label="密码" prop="password">
9
-          <el-button type="danger" @click="showChangePwd">修改密码</el-button>
8
+        <el-form-item :label="T('Password')" prop="password">
9
+          <el-button type="danger" @click="showChangePwd">{{ T('ChangePassword') }}</el-button>
10
         </el-form-item>
10
         </el-form-item>
11
         <el-form-item label="OIDC">
11
         <el-form-item label="OIDC">
12
           <el-table :data="oidcData" border fit>
12
           <el-table :data="oidcData" border fit>
13
-            <el-table-column label="平台" prop="third_type" align="center"></el-table-column>
14
-            <el-table-column label="状态" prop="status" align="center">
13
+            <el-table-column :label="T('Platform')" prop="third_type" align="center"></el-table-column>
14
+            <el-table-column :label="T('Status')" prop="status" align="center">
15
               <template #default="{ row }">
15
               <template #default="{ row }">
16
-                <el-tag v-if="row.status === 1" type="success">已绑定</el-tag>
17
-                <el-tag v-else type="danger">未绑定</el-tag>
16
+                <el-tag v-if="row.status === 1" type="success">{{ T('HasBind') }}</el-tag>
17
+                <el-tag v-else type="danger">{{ T('NoBind') }}</el-tag>
18
               </template>
18
               </template>
19
             </el-table-column>
19
             </el-table-column>
20
-            <el-table-column label="操作" align="center" width="200">
20
+            <el-table-column :label="T('Actions')" align="center" width="200">
21
               <template #default="{ row }">
21
               <template #default="{ row }">
22
-                <el-button v-if="row.status === 1" type="danger" size="small" @click="toUnBind(row)">解除绑定</el-button>
23
-                <el-button v-else type="success" size="small" @click="toBind(row)">去绑定</el-button>
22
+                <el-button v-if="row.status === 1" type="danger" size="small" @click="toUnBind(row)">{{ T('UnBind') }}</el-button>
23
+                <el-button v-else type="success" size="small" @click="toBind(row)">{{ T('ToBind') }}</el-button>
24
               </template>
24
               </template>
25
             </el-table-column>
25
             </el-table-column>
26
           </el-table>
26
           </el-table>
@@ -38,6 +38,7 @@
38
   import { bind, unbind } from '@/api/oauth'
38
   import { bind, unbind } from '@/api/oauth'
39
   import { myOauth } from '@/api/user'
39
   import { myOauth } from '@/api/user'
40
   import { ElMessageBox } from 'element-plus'
40
   import { ElMessageBox } from 'element-plus'
41
+  import { T } from '@/utils/i18n'
41
 
42
 
42
   const userStore = useUserStore()
43
   const userStore = useUserStore()
43
   const changePwdVisible = ref(false)
44
   const changePwdVisible = ref(false)
@@ -61,9 +62,9 @@
61
     }
62
     }
62
   }
63
   }
63
   const toUnBind = async (row) => {
64
   const toUnBind = async (row) => {
64
-    const cf = await ElMessageBox.confirm('确定解除绑定么?', {
65
-      confirmButtonText: '确定',
66
-      cancelButtonText: '取消',
65
+    const cf = await ElMessageBox.confirm(T('Confirm?', { param: T('UnBind') }), {
66
+      confirmButtonText: T('Confirm'),
67
+      cancelButtonText: T('Cancel'),
67
       type: 'warning',
68
       type: 'warning',
68
     }).catch(_ => false)
69
     }).catch(_ => false)
69
     if (!cf) {
70
     if (!cf) {

+ 15 - 14
src/views/my/tag/index.vue

@@ -1,18 +1,18 @@
1
 <template>
1
 <template>
2
   <div>
2
   <div>
3
     <el-card class="list-query" shadow="hover">
3
     <el-card class="list-query" shadow="hover">
4
-      <el-form inline label-width="60px">
4
+      <el-form inline label-width="80px">
5
         <el-form-item>
5
         <el-form-item>
6
-          <el-button type="primary" @click="handlerQuery">筛选</el-button>
7
-          <el-button type="danger" @click="toAdd">添加</el-button>
6
+          <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
7
+          <el-button type="danger" @click="toAdd">{{ T('Add') }}</el-button>
8
         </el-form-item>
8
         </el-form-item>
9
       </el-form>
9
       </el-form>
10
     </el-card>
10
     </el-card>
11
     <el-card class="list-body" shadow="hover">
11
     <el-card class="list-body" shadow="hover">
12
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
12
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
13
         <el-table-column prop="id" label="id" align="center"/>
13
         <el-table-column prop="id" label="id" align="center"/>
14
-        <el-table-column prop="name" label="名称" align="center"/>
15
-        <el-table-column prop="color" label="颜色" align="center">
14
+        <el-table-column prop="name" :label="T('Name')" align="center"/>
15
+        <el-table-column prop="color" :label="T('Color')" align="center">
16
           <template #default="{row}">
16
           <template #default="{row}">
17
             <div class="colors">
17
             <div class="colors">
18
               <div style="background-color: #efeff2" class="colorbox">
18
               <div style="background-color: #efeff2" class="colorbox">
@@ -26,12 +26,12 @@
26
             </div>
26
             </div>
27
           </template>
27
           </template>
28
         </el-table-column>
28
         </el-table-column>
29
-        <el-table-column prop="created_at" label="创建时间" align="center"/>
30
-        <el-table-column prop="updated_at" label="更新时间" align="center"/>
29
+        <el-table-column prop="created_at" :label="T('CreatedAt')" align="center"/>
30
+        <el-table-column prop="updated_at" :label="T('UpdatedAt')" align="center"/>
31
         <el-table-column label="操作" align="center">
31
         <el-table-column label="操作" align="center">
32
           <template #default="{row}">
32
           <template #default="{row}">
33
-            <el-button @click="toEdit(row)">编辑</el-button>
34
-            <el-button type="danger" @click="del(row)">删除</el-button>
33
+            <el-button @click="toEdit(row)">{{ T('Edit') }}</el-button>
34
+            <el-button type="danger" @click="del(row)">{{ T('Delete') }}</el-button>
35
           </template>
35
           </template>
36
         </el-table-column>
36
         </el-table-column>
37
       </el-table>
37
       </el-table>
@@ -45,12 +45,12 @@
45
                      :total="listRes.total">
45
                      :total="listRes.total">
46
       </el-pagination>
46
       </el-pagination>
47
     </el-card>
47
     </el-card>
48
-    <el-dialog v-model="formVisible" :title="!formData.id?'创建':'修改'" width="800">
48
+    <el-dialog v-model="formVisible" :title="!formData.id?T('Create'):T('Update')" width="800">
49
       <el-form class="dialog-form" ref="form" :model="formData" label-width="120px">
49
       <el-form class="dialog-form" ref="form" :model="formData" label-width="120px">
50
-        <el-form-item label="名称" prop="name" required>
50
+        <el-form-item :label="T('Name')" prop="name" required>
51
           <el-input v-model="formData.name"></el-input>
51
           <el-input v-model="formData.name"></el-input>
52
         </el-form-item>
52
         </el-form-item>
53
-        <el-form-item label="颜色" prop="color" required>
53
+        <el-form-item :label="T('Color')" prop="color" required>
54
           <el-color-picker v-model="formData.color" show-alpha @active-change="activeChange"></el-color-picker>
54
           <el-color-picker v-model="formData.color" show-alpha @active-change="activeChange"></el-color-picker>
55
           <br>
55
           <br>
56
           <div class="colors">
56
           <div class="colors">
@@ -65,8 +65,8 @@
65
           </div>
65
           </div>
66
         </el-form-item>
66
         </el-form-item>
67
         <el-form-item>
67
         <el-form-item>
68
-          <el-button @click="formVisible = false">取消</el-button>
69
-          <el-button @click="submit" type="primary">提交</el-button>
68
+          <el-button @click="formVisible = false">{{ T('Cancel') }}</el-button>
69
+          <el-button @click="submit" type="primary">{{ T('Submit') }}</el-button>
70
         </el-form-item>
70
         </el-form-item>
71
       </el-form>
71
       </el-form>
72
     </el-dialog>
72
     </el-dialog>
@@ -76,6 +76,7 @@
76
 <script setup>
76
 <script setup>
77
   import { onMounted, watch, onActivated } from 'vue'
77
   import { onMounted, watch, onActivated } from 'vue'
78
   import { useRepositories } from '@/views/tag'
78
   import { useRepositories } from '@/views/tag'
79
+  import { T } from '@/utils/i18n'
79
 
80
 
80
   const {
81
   const {
81
     listRes,
82
     listRes,

+ 8 - 7
src/views/oauth/bind.vue

@@ -1,22 +1,22 @@
1
 <template>
1
 <template>
2
   <div class="oauth">
2
   <div class="oauth">
3
     <el-card class="card">
3
     <el-card class="card">
4
-      <h2>您正在授权绑定</h2>
4
+      <h2>{{ T('OauthBinding') }}</h2>
5
       <el-form class="info" label-width="100px">
5
       <el-form class="info" label-width="100px">
6
-        <el-form-item label="平台">
6
+        <el-form-item :label="T('Op')">
7
           <div class="impt">{{ oauthInfo.op }}</div>
7
           <div class="impt">{{ oauthInfo.op }}</div>
8
         </el-form-item>
8
         </el-form-item>
9
-        <el-form-item label="用户名">
9
+        <el-form-item :label="T('ThirdName')">
10
           <div class="impt">{{ oauthInfo.third_name }}</div>
10
           <div class="impt">{{ oauthInfo.third_name }}</div>
11
         </el-form-item>
11
         </el-form-item>
12
         <el-form-item label-width="0">
12
         <el-form-item label-width="0">
13
-          <el-button style="width: 100%" v-if="!resStatus" type="success" size="large" @click="toConfirm">绑定</el-button>
13
+          <el-button style="width: 100%" v-if="!resStatus" type="success" size="large" @click="toConfirm">{{ T('Bind') }}</el-button>
14
         </el-form-item>
14
         </el-form-item>
15
         <el-form-item label-width="0">
15
         <el-form-item label-width="0">
16
-          <el-button style="width: 100%" size="large" @click="out">关闭页面</el-button>
16
+          <el-button style="width: 100%" size="large" @click="out">{{ T('Close') }}</el-button>
17
         </el-form-item>
17
         </el-form-item>
18
       </el-form>
18
       </el-form>
19
-      如果不是您操作的授权,请直接关闭页面
19
+      {{ T('OauthCloseNote') }}
20
     </el-card>
20
     </el-card>
21
   </div>
21
   </div>
22
 </template>
22
 </template>
@@ -26,6 +26,7 @@
26
   import { info, confirm, bindConfirm } from '@/api/oauth'
26
   import { info, confirm, bindConfirm } from '@/api/oauth'
27
   import { useRoute, useRouter } from 'vue-router'
27
   import { useRoute, useRouter } from 'vue-router'
28
   import { ElMessage } from 'element-plus'
28
   import { ElMessage } from 'element-plus'
29
+  import { T } from '@/utils/i18n'
29
 
30
 
30
   const oauthInfo = ref({})
31
   const oauthInfo = ref({})
31
   const route = useRoute()
32
   const route = useRoute()
@@ -48,7 +49,7 @@
48
     const res = await bindConfirm({ code }).catch(_ => false)
49
     const res = await bindConfirm({ code }).catch(_ => false)
49
     if (res) {
50
     if (res) {
50
       resStatus.value = 1
51
       resStatus.value = 1
51
-      ElMessage.success('操作成功,3秒后将自动关闭本页面')
52
+      ElMessage.success(T('OperationSuccessAndCloseAfter3Seconds'))
52
       setTimeout(_ => {
53
       setTimeout(_ => {
53
         out()
54
         out()
54
       }, 3000)
55
       }, 3000)

+ 27 - 26
src/views/oauth/index.vue

@@ -1,24 +1,24 @@
1
 <template>
1
 <template>
2
   <div>
2
   <div>
3
     <el-card class="list-query" shadow="hover">
3
     <el-card class="list-query" shadow="hover">
4
-      <el-form inline label-width="60px">
4
+      <el-form inline label-width="80px">
5
         <el-form-item>
5
         <el-form-item>
6
-          <el-button type="primary" @click="handlerQuery">筛选</el-button>
7
-          <el-button type="danger" @click="toAdd">添加</el-button>
6
+          <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
7
+          <el-button type="danger" @click="toAdd">{{ T('Add') }}</el-button>
8
         </el-form-item>
8
         </el-form-item>
9
       </el-form>
9
       </el-form>
10
     </el-card>
10
     </el-card>
11
     <el-card class="list-body" shadow="hover">
11
     <el-card class="list-body" shadow="hover">
12
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
12
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
13
         <el-table-column prop="id" label="id" align="center"/>
13
         <el-table-column prop="id" label="id" align="center"/>
14
-        <el-table-column prop="op" label="名称" align="center"/>
15
-        <el-table-column prop="auto_register" label="自动注册" align="center"/>
16
-        <el-table-column prop="created_at" label="创建时间" align="center"/>
17
-        <el-table-column prop="updated_at" label="更新时间" align="center"/>
18
-        <el-table-column label="操作" align="center">
14
+        <el-table-column prop="op" :label="T('Op')" align="center"/>
15
+        <el-table-column prop="auto_register" :label="T('AutoRegister')" align="center"/>
16
+        <el-table-column prop="created_at" :label="T('CreatedAt')" align="center"/>
17
+        <el-table-column prop="updated_at" :label="T('UpdatedAt')" align="center"/>
18
+        <el-table-column :label="T('Actions')" align="center">
19
           <template #default="{row}">
19
           <template #default="{row}">
20
-            <el-button @click="toEdit(row)">编辑</el-button>
21
-            <el-button type="danger" @click="del(row)">删除</el-button>
20
+            <el-button @click="toEdit(row)">{{ T('Edit') }}</el-button>
21
+            <el-button type="danger" @click="del(row)">{{ T('Delete') }}</el-button>
22
           </template>
22
           </template>
23
         </el-table-column>
23
         </el-table-column>
24
       </el-table>
24
       </el-table>
@@ -32,7 +32,7 @@
32
                      :total="listRes.total">
32
                      :total="listRes.total">
33
       </el-pagination>
33
       </el-pagination>
34
     </el-card>
34
     </el-card>
35
-    <el-dialog v-model="formVisible" :title="!formData.id?'创建':'修改'" width="800">
35
+    <el-dialog v-model="formVisible" :title="!formData.id?T('Create') :T('Update')" width="800">
36
       <el-form class="dialog-form" ref="form" :model="formData" :rules="rules" label-width="120px">
36
       <el-form class="dialog-form" ref="form" :model="formData" :rules="rules" label-width="120px">
37
         <el-form-item label="ClientId" prop="client_id">
37
         <el-form-item label="ClientId" prop="client_id">
38
           <el-input v-model="formData.client_id"></el-input>
38
           <el-input v-model="formData.client_id"></el-input>
@@ -43,23 +43,23 @@
43
         <el-form-item label="RedirectUrl" prop="redirect_url">
43
         <el-form-item label="RedirectUrl" prop="redirect_url">
44
           <el-input v-model="formData.redirect_url"></el-input>
44
           <el-input v-model="formData.redirect_url"></el-input>
45
         </el-form-item>
45
         </el-form-item>
46
-        <el-form-item label="类型" prop="op" >
46
+        <el-form-item label="op" prop="op">
47
           <el-radio-group v-model="formData.op" :disabled="!!formData.id">
47
           <el-radio-group v-model="formData.op" :disabled="!!formData.id">
48
-            <el-radio v-for="item in ops" :key="item.value" :label="item.value" style="display: block">
48
+            <el-radio v-for="item in ops" :key="item.value" :value="item.value" style="display: block">
49
               {{ item.label }}
49
               {{ item.label }}
50
             </el-radio>
50
             </el-radio>
51
           </el-radio-group>
51
           </el-radio-group>
52
         </el-form-item>
52
         </el-form-item>
53
-        <el-form-item label="自动注册" prop="open_auto_register">
53
+        <el-form-item :label="T('AutoRegister')" prop="auto_register">
54
           <el-switch v-model="formData.auto_register"
54
           <el-switch v-model="formData.auto_register"
55
                      :active-value="true"
55
                      :active-value="true"
56
                      :inactive-value="false"
56
                      :inactive-value="false"
57
           ></el-switch>
57
           ></el-switch>
58
-          <div style="display: block;margin-left: 10px">如果开启,当用户使用oauth登录而没绑定时,会自动注册一个账号</div>
58
+          <div style="display: block;margin-left: 10px">{{ T('AutoRegisterNote') }}</div>
59
         </el-form-item>
59
         </el-form-item>
60
         <el-form-item>
60
         <el-form-item>
61
-          <el-button @click="formVisible = false">取消</el-button>
62
-          <el-button @click="submit" type="primary">提交</el-button>
61
+          <el-button @click="formVisible = false">{{ T('Cancel') }}</el-button>
62
+          <el-button @click="submit" type="primary">{{ T('Submit') }}</el-button>
63
         </el-form-item>
63
         </el-form-item>
64
       </el-form>
64
       </el-form>
65
     </el-dialog>
65
     </el-dialog>
@@ -70,6 +70,7 @@
70
   import { onMounted, reactive, watch, ref, onActivated } from 'vue'
70
   import { onMounted, reactive, watch, ref, onActivated } from 'vue'
71
   import { list, create, update, detail, remove } from '@/api/oauth'
71
   import { list, create, update, detail, remove } from '@/api/oauth'
72
   import { ElMessage, ElMessageBox } from 'element-plus'
72
   import { ElMessage, ElMessageBox } from 'element-plus'
73
+  import { T } from '@/utils/i18n'
73
 
74
 
74
   const listRes = reactive({
75
   const listRes = reactive({
75
     list: [], total: 0, loading: false,
76
     list: [], total: 0, loading: false,
@@ -100,9 +101,9 @@
100
   }
101
   }
101
 
102
 
102
   const del = async (row) => {
103
   const del = async (row) => {
103
-    const cf = await ElMessageBox.confirm('确定删除么?', {
104
-      confirmButtonText: '确定',
105
-      cancelButtonText: '取消',
104
+    const cf = await ElMessageBox.confirm(T('Confirm?', { param: T('Delete') }), {
105
+      confirmButtonText: T('Confirm'),
106
+      cancelButtonText: T('Cancel'),
106
       type: 'warning',
107
       type: 'warning',
107
     }).catch(_ => false)
108
     }).catch(_ => false)
108
     if (!cf) {
109
     if (!cf) {
@@ -111,7 +112,7 @@
111
 
112
 
112
     const res = await remove({ id: row.id }).catch(_ => false)
113
     const res = await remove({ id: row.id }).catch(_ => false)
113
     if (res) {
114
     if (res) {
114
-      ElMessage.success('操作成功')
115
+      ElMessage.success(T('OperationSuccess'))
115
       getList()
116
       getList()
116
     }
117
     }
117
   }
118
   }
@@ -132,10 +133,10 @@
132
     auto_register: false,
133
     auto_register: false,
133
   })
134
   })
134
   const rules = {
135
   const rules = {
135
-    client_id: [{ required: true, message: '请输入ClientId', trigger: 'blur' }],
136
-    client_secret: [{ required: true, message: '请输入ClientSecret', trigger: 'blur' }],
137
-    redirect_url: [{ required: true, message: '请输入RedirectUrl', trigger: 'blur' }],
138
-    op: [{ required: true, message: '请选择类型', trigger: 'blur' }],
136
+    client_id: [{ required: true, message: T('ParamRequired', { param: 'client_id' }), trigger: 'blur' }],
137
+    client_secret: [{ required: true, message: T('ParamRequired', { param: 'client_secret' }), trigger: 'blur' }],
138
+    redirect_url: [{ required: true, message: T('ParamRequired', { param: 'redirect_url' }), trigger: 'blur' }],
139
+    op: [{ required: true, message: T('ParamRequired', { param: 'op' }), trigger: 'blur' }],
139
   }
140
   }
140
   const toEdit = (row) => {
141
   const toEdit = (row) => {
141
     formVisible.value = true
142
     formVisible.value = true
@@ -165,7 +166,7 @@
165
     const api = formData.id ? update : create
166
     const api = formData.id ? update : create
166
     const res = await api(formData).catch(_ => false)
167
     const res = await api(formData).catch(_ => false)
167
     if (res) {
168
     if (res) {
168
-      ElMessage.success('操作成功')
169
+      ElMessage.success(T('OperationSuccess'))
169
       formVisible.value = false
170
       formVisible.value = false
170
       getList()
171
       getList()
171
     }
172
     }

+ 6 - 6
src/views/oauth/login.vue

@@ -1,22 +1,22 @@
1
 <template>
1
 <template>
2
   <div class="oauth">
2
   <div class="oauth">
3
     <el-card class="card">
3
     <el-card class="card">
4
-      <h2>您正在授权登录</h2>
4
+      <h2>{{ T('OauthLogining') }}</h2>
5
       <el-form class="info" label-width="100px">
5
       <el-form class="info" label-width="100px">
6
-        <el-form-item label="设备">
6
+        <el-form-item :label="T('Device')">
7
           <div class="impt">{{ oauthInfo.device_name }}</div>
7
           <div class="impt">{{ oauthInfo.device_name }}</div>
8
         </el-form-item>
8
         </el-form-item>
9
         <el-form-item label="ID">
9
         <el-form-item label="ID">
10
           <div class="impt">{{ oauthInfo.id }}</div>
10
           <div class="impt">{{ oauthInfo.id }}</div>
11
         </el-form-item>
11
         </el-form-item>
12
         <el-form-item label-width="0">
12
         <el-form-item label-width="0">
13
-          <el-button style="width: 100%" v-if="!resStatus" type="success" size="large" @click="toConfirm">授权登录</el-button>
13
+          <el-button style="width: 100%" v-if="!resStatus" type="success" size="large" @click="toConfirm">{{ T('ConfirmOauth') }}</el-button>
14
         </el-form-item>
14
         </el-form-item>
15
         <el-form-item label-width="0">
15
         <el-form-item label-width="0">
16
-          <el-button style="width: 100%" size="large" @click="out">关闭页面</el-button>
16
+          <el-button style="width: 100%" size="large" @click="out">{{ T('Close') }}</el-button>
17
         </el-form-item>
17
         </el-form-item>
18
       </el-form>
18
       </el-form>
19
-      如果不是您操作的授权,请直接关闭页面
19
+      {{ T('OauthCloseNote') }}
20
     </el-card>
20
     </el-card>
21
   </div>
21
   </div>
22
 </template>
22
 </template>
@@ -48,7 +48,7 @@
48
     const res = await confirm({ code }).catch(_ => false)
48
     const res = await confirm({ code }).catch(_ => false)
49
     if (res) {
49
     if (res) {
50
       resStatus.value = 1
50
       resStatus.value = 1
51
-      ElMessage.success('操作成功,3秒后将自动关闭本页面')
51
+      ElMessage.success(T('OperationSuccessAndCloseAfter3Seconds'))
52
       setTimeout(_ => {
52
       setTimeout(_ => {
53
         out()
53
         out()
54
       }, 3000)
54
       }, 3000)

+ 29 - 30
src/views/peer/index.vue

@@ -1,10 +1,10 @@
1
 <template>
1
 <template>
2
   <div>
2
   <div>
3
     <el-card class="list-query" shadow="hover">
3
     <el-card class="list-query" shadow="hover">
4
-      <el-form inline label-width="60px">
4
+      <el-form inline label-width="80px">
5
         <el-form-item>
5
         <el-form-item>
6
-          <el-button type="primary" @click="handlerQuery">筛选</el-button>
7
-          <el-button type="danger" @click="toAdd">添加</el-button>
6
+          <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
7
+          <el-button type="danger" @click="toAdd">{{ T('Add') }}</el-button>
8
         </el-form-item>
8
         </el-form-item>
9
       </el-form>
9
       </el-form>
10
     </el-card>
10
     </el-card>
@@ -12,19 +12,19 @@
12
       <el-table :data="listRes.list" v-loading="listRes.loading" border size="small">
12
       <el-table :data="listRes.list" v-loading="listRes.loading" border size="small">
13
         <el-table-column prop="id" label="id" align="center"/>
13
         <el-table-column prop="id" label="id" align="center"/>
14
         <el-table-column prop="cpu" label="cpu" align="center"/>
14
         <el-table-column prop="cpu" label="cpu" align="center"/>
15
-        <el-table-column prop="hostname" label="主机名" align="center"/>
16
-        <el-table-column prop="memory" label="内存" align="center"/>
17
-        <el-table-column prop="os" label="系统" align="center"/>
18
-        <el-table-column prop="username" label="username" align="center"/>
19
-        <el-table-column prop="uuid" label="uuid" align="center"/>
20
-        <el-table-column prop="version" label="版本号" align="center"/>
21
-        <el-table-column prop="created_at" label="创建时间" align="center"/>
22
-        <el-table-column prop="updated_at" label="更新时间" align="center"/>
23
-        <el-table-column label="操作" align="center" width="400">
15
+        <el-table-column prop="hostname" :label="T('Hostname')" align="center"/>
16
+        <el-table-column prop="memory" :label="T('Memory')" align="center"/>
17
+        <el-table-column prop="os" :label="T('Os')" align="center"/>
18
+        <el-table-column prop="username" :label="T('Username')" align="center"/>
19
+        <el-table-column prop="uuid" :label="T('Uuid')" align="center"/>
20
+        <el-table-column prop="version" :label="T('Version')" align="center"/>
21
+        <el-table-column prop="created_at" :label="T('CreatedAt')" align="center"/>
22
+        <el-table-column prop="updated_at" :label="T('UpdatedAt')" align="center"/>
23
+        <el-table-column :label="T('Actions')" align="center" width="400">
24
           <template #default="{row}">
24
           <template #default="{row}">
25
             <el-button type="success" @click="toWebClientLink(row)">Web-Client</el-button>
25
             <el-button type="success" @click="toWebClientLink(row)">Web-Client</el-button>
26
-            <el-button @click="toEdit(row)">编辑</el-button>
27
-            <el-button type="danger" @click="del(row)">删除</el-button>
26
+            <el-button @click="toEdit(row)">{{ T('Edit') }}</el-button>
27
+            <el-button type="danger" @click="del(row)">{{ T('Delete') }}</el-button>
28
           </template>
28
           </template>
29
         </el-table-column>
29
         </el-table-column>
30
       </el-table>
30
       </el-table>
@@ -38,36 +38,36 @@
38
                      :total="listRes.total">
38
                      :total="listRes.total">
39
       </el-pagination>
39
       </el-pagination>
40
     </el-card>
40
     </el-card>
41
-    <el-dialog v-model="formVisible" :title="!formData.row_id?'创建':'修改'" width="800">
41
+    <el-dialog v-model="formVisible" :title="!formData.row_id?T('Create'):T('Update')" width="800">
42
       <el-form class="dialog-form" ref="form" :model="formData" label-width="120px">
42
       <el-form class="dialog-form" ref="form" :model="formData" label-width="120px">
43
         <el-form-item label="id" prop="id" required>
43
         <el-form-item label="id" prop="id" required>
44
           <el-input v-model="formData.id"></el-input>
44
           <el-input v-model="formData.id"></el-input>
45
         </el-form-item>
45
         </el-form-item>
46
-        <el-form-item label="用户名" prop="username">
46
+        <el-form-item :label="T('Username')" prop="username">
47
           <el-input v-model="formData.username"></el-input>
47
           <el-input v-model="formData.username"></el-input>
48
         </el-form-item>
48
         </el-form-item>
49
-        <el-form-item label="主机名" prop="hostname">
49
+        <el-form-item :label="T('Hostname')" prop="hostname">
50
           <el-input v-model="formData.hostname"></el-input>
50
           <el-input v-model="formData.hostname"></el-input>
51
         </el-form-item>
51
         </el-form-item>
52
         <el-form-item label="cpu" prop="cpu">
52
         <el-form-item label="cpu" prop="cpu">
53
           <el-input v-model="formData.cpu"></el-input>
53
           <el-input v-model="formData.cpu"></el-input>
54
         </el-form-item>
54
         </el-form-item>
55
-        <el-form-item label="内存" prop="memory">
55
+        <el-form-item :label="T('Memory')" prop="memory">
56
           <el-input v-model="formData.memory"></el-input>
56
           <el-input v-model="formData.memory"></el-input>
57
         </el-form-item>
57
         </el-form-item>
58
-        <el-form-item label="系统" prop="os">
58
+        <el-form-item :label="T('Os')" prop="os">
59
           <el-input v-model="formData.os"></el-input>
59
           <el-input v-model="formData.os"></el-input>
60
         </el-form-item>
60
         </el-form-item>
61
-        <el-form-item label="uuid" prop="uuid">
61
+        <el-form-item :label="T('Uuid')" prop="uuid">
62
           <el-input v-model="formData.uuid"></el-input>
62
           <el-input v-model="formData.uuid"></el-input>
63
         </el-form-item>
63
         </el-form-item>
64
-        <el-form-item label="版本" prop="version">
64
+        <el-form-item :label="T('Version')" prop="version">
65
           <el-input v-model="formData.version"></el-input>
65
           <el-input v-model="formData.version"></el-input>
66
         </el-form-item>
66
         </el-form-item>
67
 
67
 
68
         <el-form-item>
68
         <el-form-item>
69
-          <el-button @click="formVisible = false">取消</el-button>
70
-          <el-button @click="submit" type="primary">提交</el-button>
69
+          <el-button @click="formVisible = false">{{ T('Cancel') }}</el-button>
70
+          <el-button @click="submit" type="primary">{{ T('Submit') }}</el-button>
71
         </el-form-item>
71
         </el-form-item>
72
       </el-form>
72
       </el-form>
73
     </el-dialog>
73
     </el-dialog>
@@ -77,10 +77,9 @@
77
 <script setup>
77
 <script setup>
78
   import { onActivated, onMounted, reactive, ref, watch } from 'vue'
78
   import { onActivated, onMounted, reactive, ref, watch } from 'vue'
79
   import { create, list, remove, update } from '@/api/peer'
79
   import { create, list, remove, update } from '@/api/peer'
80
-  import { list as fetchTagList } from '@/api/tag'
81
   import { ElMessage, ElMessageBox } from 'element-plus'
80
   import { ElMessage, ElMessageBox } from 'element-plus'
82
-  import { loadAllUsers } from '@/global'
83
   import { toWebClientLink } from '@/utils/webclient'
81
   import { toWebClientLink } from '@/utils/webclient'
82
+  import { T } from '@/utils/i18n'
84
 
83
 
85
   const listRes = reactive({
84
   const listRes = reactive({
86
     list: [], total: 0, loading: false,
85
     list: [], total: 0, loading: false,
@@ -108,9 +107,9 @@
108
   }
107
   }
109
 
108
 
110
   const del = async (row) => {
109
   const del = async (row) => {
111
-    const cf = await ElMessageBox.confirm('确定删除么?', {
112
-      confirmButtonText: '确定',
113
-      cancelButtonText: '取消',
110
+    const cf = await ElMessageBox.confirm(T('Confirm?', { param: T('Delete') }), {
111
+      confirmButtonText: T('Confirm'),
112
+      cancelButtonText: T('Cancel'),
114
       type: 'warning',
113
       type: 'warning',
115
     }).catch(_ => false)
114
     }).catch(_ => false)
116
     if (!cf) {
115
     if (!cf) {
@@ -119,7 +118,7 @@
119
 
118
 
120
     const res = await remove({ row_id: row.row_id }).catch(_ => false)
119
     const res = await remove({ row_id: row.row_id }).catch(_ => false)
121
     if (res) {
120
     if (res) {
122
-      ElMessage.success('操作成功')
121
+      ElMessage.success(T('OperationSuccess'))
123
       getList()
122
       getList()
124
     }
123
     }
125
   }
124
   }
@@ -173,7 +172,7 @@
173
     const api = formData.row_id ? update : create
172
     const api = formData.row_id ? update : create
174
     const res = await api(formData).catch(_ => false)
173
     const res = await api(formData).catch(_ => false)
175
     if (res) {
174
     if (res) {
176
-      ElMessage.success('操作成功')
175
+      ElMessage.success(T('OperationSuccess'))
177
       formVisible.value = false
176
       formVisible.value = false
178
       getList()
177
       getList()
179
     }
178
     }

+ 6 - 5
src/views/tag/index.js

@@ -2,6 +2,7 @@ import { onActivated, onMounted, reactive, ref, watch } from 'vue'
2
 import { create, list, remove, update } from '@/api/tag'
2
 import { create, list, remove, update } from '@/api/tag'
3
 import { ElMessage, ElMessageBox } from 'element-plus'
3
 import { ElMessage, ElMessageBox } from 'element-plus'
4
 import { useRoute } from 'vue-router'
4
 import { useRoute } from 'vue-router'
5
+import { T } from '@/utils/i18n'
5
 
6
 
6
 export function useRepositories () {
7
 export function useRepositories () {
7
   //获取query
8
   //获取query
@@ -74,9 +75,9 @@ export function useRepositories () {
74
   }
75
   }
75
 
76
 
76
   const del = async (row) => {
77
   const del = async (row) => {
77
-    const cf = await ElMessageBox.confirm('确定删除么?', {
78
-      confirmButtonText: '确定',
79
-      cancelButtonText: '取消',
78
+    const cf = await ElMessageBox.confirm(T('Confirm?', { param: T('Delete') }), {
79
+      confirmButtonText: T('Confirm'),
80
+      cancelButtonText: T('Cancel'),
80
       type: 'warning',
81
       type: 'warning',
81
     }).catch(_ => false)
82
     }).catch(_ => false)
82
     if (!cf) {
83
     if (!cf) {
@@ -85,7 +86,7 @@ export function useRepositories () {
85
 
86
 
86
     const res = await remove({ id: row.id }).catch(_ => false)
87
     const res = await remove({ id: row.id }).catch(_ => false)
87
     if (res) {
88
     if (res) {
88
-      ElMessage.success('操作成功')
89
+      ElMessage.success(T('OperationSuccess'))
89
       getList()
90
       getList()
90
     }
91
     }
91
   }
92
   }
@@ -133,7 +134,7 @@ export function useRepositories () {
133
     console.log(data)
134
     console.log(data)
134
     const res = await api(data).catch(_ => false)
135
     const res = await api(data).catch(_ => false)
135
     if (res) {
136
     if (res) {
136
-      ElMessage.success('操作成功')
137
+      ElMessage.success(T('OperationSuccess'))
137
       formVisible.value = false
138
       formVisible.value = false
138
       getList()
139
       getList()
139
     }
140
     }

+ 19 - 23
src/views/tag/index.vue

@@ -1,8 +1,8 @@
1
 <template>
1
 <template>
2
   <div>
2
   <div>
3
     <el-card class="list-query" shadow="hover">
3
     <el-card class="list-query" shadow="hover">
4
-      <el-form inline label-width="60px">
5
-        <el-form-item label="用户">
4
+      <el-form inline label-width="80px">
5
+        <el-form-item :label="T('Owner')">
6
           <el-select v-model="listQuery.user_id" clearable>
6
           <el-select v-model="listQuery.user_id" clearable>
7
             <el-option
7
             <el-option
8
                 v-for="item in allUsers"
8
                 v-for="item in allUsers"
@@ -13,21 +13,21 @@
13
           </el-select>
13
           </el-select>
14
         </el-form-item>
14
         </el-form-item>
15
         <el-form-item>
15
         <el-form-item>
16
-          <el-button type="primary" @click="handlerQuery">筛选</el-button>
17
-          <el-button type="danger" @click="toAdd">添加</el-button>
16
+          <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
17
+          <el-button type="danger" @click="toAdd">{{ T('Add') }}</el-button>
18
         </el-form-item>
18
         </el-form-item>
19
       </el-form>
19
       </el-form>
20
     </el-card>
20
     </el-card>
21
     <el-card class="list-body" shadow="hover">
21
     <el-card class="list-body" shadow="hover">
22
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
22
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
23
         <el-table-column prop="id" label="id" align="center"/>
23
         <el-table-column prop="id" label="id" align="center"/>
24
-        <el-table-column label="所属用户" align="center">
24
+        <el-table-column :label="T('Owner')" align="center">
25
           <template #default="{row}">
25
           <template #default="{row}">
26
             <span v-if="row.user_id"> <el-tag>{{ allUsers?.find(u => u.id === row.user_id)?.username }}</el-tag> </span>
26
             <span v-if="row.user_id"> <el-tag>{{ allUsers?.find(u => u.id === row.user_id)?.username }}</el-tag> </span>
27
           </template>
27
           </template>
28
         </el-table-column>
28
         </el-table-column>
29
-        <el-table-column prop="name" label="名称" align="center"/>
30
-        <el-table-column prop="color" label="颜色" align="center">
29
+        <el-table-column prop="name" :label="T('Name')" align="center"/>
30
+        <el-table-column prop="color" :label="T('Color')" align="center">
31
           <template #default="{row}">
31
           <template #default="{row}">
32
             <div class="colors">
32
             <div class="colors">
33
               <div style="background-color: #efeff2" class="colorbox">
33
               <div style="background-color: #efeff2" class="colorbox">
@@ -41,12 +41,12 @@
41
             </div>
41
             </div>
42
           </template>
42
           </template>
43
         </el-table-column>
43
         </el-table-column>
44
-        <el-table-column prop="created_at" label="创建时间" align="center"/>
45
-        <el-table-column prop="updated_at" label="更新时间" align="center"/>
44
+        <el-table-column prop="created_at" :label="T('CreatedAt')" align="center"/>
45
+        <el-table-column prop="updated_at" :label="T('UpdatedAt')" align="center"/>
46
         <el-table-column label="操作" align="center">
46
         <el-table-column label="操作" align="center">
47
           <template #default="{row}">
47
           <template #default="{row}">
48
-            <el-button @click="toEdit(row)">编辑</el-button>
49
-            <el-button type="danger" @click="del(row)">删除</el-button>
48
+            <el-button @click="toEdit(row)">{{ T('Edit') }}</el-button>
49
+            <el-button type="danger" @click="del(row)">{{ T('Delete') }}</el-button>
50
           </template>
50
           </template>
51
         </el-table-column>
51
         </el-table-column>
52
       </el-table>
52
       </el-table>
@@ -60,12 +60,12 @@
60
                      :total="listRes.total">
60
                      :total="listRes.total">
61
       </el-pagination>
61
       </el-pagination>
62
     </el-card>
62
     </el-card>
63
-    <el-dialog v-model="formVisible" :title="!formData.id?'创建':'修改'" width="800">
63
+    <el-dialog v-model="formVisible" :title="!formData.id?T('Create'):T('Update')" width="800">
64
       <el-form class="dialog-form" ref="form" :model="formData" label-width="120px">
64
       <el-form class="dialog-form" ref="form" :model="formData" label-width="120px">
65
-        <el-form-item label="名称" prop="name" required>
65
+        <el-form-item :label="T('Name')" prop="name" required>
66
           <el-input v-model="formData.name"></el-input>
66
           <el-input v-model="formData.name"></el-input>
67
         </el-form-item>
67
         </el-form-item>
68
-        <el-form-item label="颜色" prop="color" required>
68
+        <el-form-item :label="T('Color')" prop="color" required>
69
           <el-color-picker v-model="formData.color" show-alpha @active-change="activeChange"></el-color-picker>
69
           <el-color-picker v-model="formData.color" show-alpha @active-change="activeChange"></el-color-picker>
70
           <br>
70
           <br>
71
           <div class="colors">
71
           <div class="colors">
@@ -79,7 +79,7 @@
79
             </div>
79
             </div>
80
           </div>
80
           </div>
81
         </el-form-item>
81
         </el-form-item>
82
-        <el-form-item label="用户" prop="user_id" required>
82
+        <el-form-item :label="T('Owner')" prop="user_id" required>
83
           <el-select v-model="formData.user_id">
83
           <el-select v-model="formData.user_id">
84
             <el-option
84
             <el-option
85
                 v-for="item in allUsers"
85
                 v-for="item in allUsers"
@@ -90,8 +90,8 @@
90
           </el-select>
90
           </el-select>
91
         </el-form-item>
91
         </el-form-item>
92
         <el-form-item>
92
         <el-form-item>
93
-          <el-button @click="formVisible = false">取消</el-button>
94
-          <el-button @click="submit" type="primary">提交</el-button>
93
+          <el-button @click="formVisible = false">{{ T('Cancel') }}</el-button>
94
+          <el-button @click="submit" type="primary">{{ T('Submit') }}</el-button>
95
         </el-form-item>
95
         </el-form-item>
96
       </el-form>
96
       </el-form>
97
     </el-dialog>
97
     </el-dialog>
@@ -100,13 +100,9 @@
100
 
100
 
101
 <script setup>
101
 <script setup>
102
   import { onMounted, reactive, watch, ref, onActivated } from 'vue'
102
   import { onMounted, reactive, watch, ref, onActivated } from 'vue'
103
-  import { list, create, update, detail, remove } from '@/api/tag'
104
-  import { ElMessage, ElMessageBox } from 'element-plus'
105
   import { loadAllUsers } from '@/global'
103
   import { loadAllUsers } from '@/global'
106
-  import { useRoute } from 'vue-router'
107
   import { useRepositories } from '@/views/tag/index'
104
   import { useRepositories } from '@/views/tag/index'
108
-
109
-
105
+  import { T } from '@/utils/i18n'
110
 
106
 
111
   const { allUsers, getAllUsers } = loadAllUsers()
107
   const { allUsers, getAllUsers } = loadAllUsers()
112
   getAllUsers()
108
   getAllUsers()
@@ -123,7 +119,7 @@
123
     submit,
119
     submit,
124
     activeChange,
120
     activeChange,
125
     currentColor,
121
     currentColor,
126
-  } = useRepositories(0)
122
+  } = useRepositories()
127
 
123
 
128
   onMounted(getList)
124
   onMounted(getList)
129
   onActivated(getList)
125
   onActivated(getList)

+ 6 - 4
src/views/user/composables/edit.js

@@ -3,6 +3,7 @@ import { create, detail, update, remove } from '@/api/user'
3
 import { ElMessage, ElMessageBox } from 'element-plus'
3
 import { ElMessage, ElMessageBox } from 'element-plus'
4
 import { useRouter } from 'vue-router'
4
 import { useRouter } from 'vue-router'
5
 import { list as groups } from '@/api/group'
5
 import { list as groups } from '@/api/group'
6
+import { T } from '@/utils/i18n'
6
 
7
 
7
 export function useGetDetail (id) {
8
 export function useGetDetail (id) {
8
   let item = ref({})  //保留原始值
9
   let item = ref({})  //保留原始值
@@ -28,7 +29,7 @@ export function useGetDetail (id) {
28
     form,
29
     form,
29
     item,
30
     item,
30
     getDetail,
31
     getDetail,
31
-    groupsList
32
+    groupsList,
32
   }
33
   }
33
 }
34
 }
34
 
35
 
@@ -36,9 +37,10 @@ export function useSubmit (form, id) {
36
   const root = ref(null)
37
   const root = ref(null)
37
   const router = useRouter()
38
   const router = useRouter()
38
   const rules = reactive({
39
   const rules = reactive({
39
-    username: [{ required: true, message: '用户名是必须的' }],
40
+    username: [{ required: true, message: T('ParamRequired', { param: T('Username') }) }],
41
+    group_id: [{ required: true, message: T('ParamRequired', { param: T('Group') }) }],
40
     // nickname: [{ required: true, message: '昵称是必须的' }],
42
     // nickname: [{ required: true, message: '昵称是必须的' }],
41
-    status: [{ required: true, message: '请选择状态' }],
43
+    status: [{ required: true, message: T('ParamRequired', { param: T('Status') }) }],
42
   })
44
   })
43
 
45
 
44
   const validate = async () => {
46
   const validate = async () => {
@@ -65,7 +67,7 @@ export function useSubmit (form, id) {
65
 
67
 
66
     const res = await submitFunc()
68
     const res = await submitFunc()
67
     if (res) {
69
     if (res) {
68
-      ElMessage.success('操作成功')
70
+      ElMessage.success(T('OperationSuccess'))
69
       router.back()
71
       router.back()
70
     }
72
     }
71
   }
73
   }

+ 12 - 11
src/views/user/composables/index.js

@@ -3,6 +3,7 @@ import { list, remove, changePwd } from '@/api/user'
3
 import { list as groups } from '@/api/group'
3
 import { list as groups } from '@/api/group'
4
 import { useRouter } from 'vue-router'
4
 import { useRouter } from 'vue-router'
5
 import { ElMessageBox, ElMessage } from 'element-plus'
5
 import { ElMessageBox, ElMessage } from 'element-plus'
6
+import { T } from '@/utils/i18n'
6
 
7
 
7
 export function useRepositories () {
8
 export function useRepositories () {
8
 
9
 
@@ -74,15 +75,15 @@ export function useToEditOrAdd () {
74
     toAdd,
75
     toAdd,
75
     toEdit,
76
     toEdit,
76
     toTag,
77
     toTag,
77
-    toAddressBook
78
+    toAddressBook,
78
   }
79
   }
79
 }
80
 }
80
 
81
 
81
 export function useDel () {
82
 export function useDel () {
82
   const del = async (id) => {
83
   const del = async (id) => {
83
-    const cf = await ElMessageBox.confirm('确定删除么?', {
84
-      confirmButtonText: '确定',
85
-      cancelButtonText: '取消',
84
+    const cf = await ElMessageBox.confirm(T('Confirm?', { param: T('Delete') }), {
85
+      confirmButtonText: T('Confirm'),
86
+      cancelButtonText: T('Cancel'),
86
       type: 'warning',
87
       type: 'warning',
87
     }).catch(_ => false)
88
     }).catch(_ => false)
88
     if (!cf) {
89
     if (!cf) {
@@ -99,16 +100,16 @@ export function useDel () {
99
 
100
 
100
 export function useChangePwd () {
101
 export function useChangePwd () {
101
   const changePass = async (admin) => {
102
   const changePass = async (admin) => {
102
-    const input = await ElMessageBox.prompt('请输入新密码', '重置密码', {
103
-      confirmButtonText: '确定',
104
-      cancelButtonText: '取消',
103
+    const input = await ElMessageBox.prompt(T('PleaseInputNewPassword'), T('ResetPassword'), {
104
+      confirmButtonText: T('Confirm'),
105
+      cancelButtonText: T('Cancel'),
105
     }).catch(_ => false)
106
     }).catch(_ => false)
106
     if (!input) {
107
     if (!input) {
107
       return
108
       return
108
     }
109
     }
109
-    const confirm = await ElMessageBox.confirm('确定重置密码么?', {
110
-      confirmButtonText: '确定',
111
-      cancelButtonText: '取消',
110
+    const confirm = await ElMessageBox.confirm(T('Confirm?', { param: T('ResetPassword') }), {
111
+      confirmButtonText: T('Confirm'),
112
+      cancelButtonText: T('Cancel'),
112
     }).catch(_ => false)
113
     }).catch(_ => false)
113
     if (!confirm) {
114
     if (!confirm) {
114
       return
115
       return
@@ -117,7 +118,7 @@ export function useChangePwd () {
117
     if (!res) {
118
     if (!res) {
118
       return
119
       return
119
     }
120
     }
120
-    ElMessage.success('修改成功')
121
+    ElMessage.success(T('OperationSuccess'))
121
   }
122
   }
122
 
123
 
123
   return { changePass }
124
   return { changePass }

+ 13 - 33
src/views/user/edit.vue

@@ -1,14 +1,14 @@
1
 <template>
1
 <template>
2
   <div class="form-card">
2
   <div class="form-card">
3
     <el-form ref="root" label-width="120px" :model="form" :rules="rules">
3
     <el-form ref="root" label-width="120px" :model="form" :rules="rules">
4
-      <el-form-item label="用户名" prop="username">
4
+      <el-form-item :label="T('Username')" prop="username">
5
         <el-input v-model="form.username"></el-input>
5
         <el-input v-model="form.username"></el-input>
6
       </el-form-item>
6
       </el-form-item>
7
-      <el-form-item label="昵称" prop="nickname">
7
+      <el-form-item :label="T('Nickname')" prop="nickname">
8
         <el-input v-model="form.nickname"></el-input>
8
         <el-input v-model="form.nickname"></el-input>
9
       </el-form-item>
9
       </el-form-item>
10
-      <el-form-item label="小组" prop="group_id">
11
-        <el-select v-model="form.group_id" placeholder="请选择小组">
10
+      <el-form-item :label="T('Group')" prop="group_id">
11
+        <el-select v-model="form.group_id">
12
           <el-option
12
           <el-option
13
               v-for="item in groupsList"
13
               v-for="item in groupsList"
14
               :key="item.id"
14
               :key="item.id"
@@ -17,57 +17,37 @@
17
           ></el-option>
17
           ></el-option>
18
         </el-select>
18
         </el-select>
19
       </el-form-item>
19
       </el-form-item>
20
-      <el-form-item label="是否是管理员" prop="is_admin">
20
+      <el-form-item :label="T('IsAdmin')" prop="is_admin">
21
         <el-switch v-model="form.is_admin"
21
         <el-switch v-model="form.is_admin"
22
                    :active-value="true"
22
                    :active-value="true"
23
                    :inactive-value="false"
23
                    :inactive-value="false"
24
         ></el-switch>
24
         ></el-switch>
25
       </el-form-item>
25
       </el-form-item>
26
-      <el-form-item label="状态" prop="status">
26
+      <el-form-item :label="T('Status')" prop="status">
27
         <el-switch v-model="form.status"
27
         <el-switch v-model="form.status"
28
                    :active-value="ENABLE_STATUS"
28
                    :active-value="ENABLE_STATUS"
29
                    :inactive-value="DISABLE_STATUS"
29
                    :inactive-value="DISABLE_STATUS"
30
         ></el-switch>
30
         ></el-switch>
31
       </el-form-item>
31
       </el-form-item>
32
       <el-form-item>
32
       <el-form-item>
33
-        <el-button @click="cancel">取消</el-button>
34
-        <el-button @click="submit" type="primary">提交</el-button>
33
+        <el-button @click="cancel">{{ T('Cancel') }}</el-button>
34
+        <el-button @click="submit" type="primary">{{ T('Submit') }}</el-button>
35
       </el-form-item>
35
       </el-form-item>
36
     </el-form>
36
     </el-form>
37
   </div>
37
   </div>
38
 </template>
38
 </template>
39
 
39
 
40
-<script>
41
-  import { defineComponent, toRef } from 'vue'
40
+<script setup>
42
   import { useRoute } from 'vue-router'
41
   import { useRoute } from 'vue-router'
43
   import { useGetDetail, useSubmit } from '@/views/user/composables/edit'
42
   import { useGetDetail, useSubmit } from '@/views/user/composables/edit'
44
   import { ENABLE_STATUS, DISABLE_STATUS } from '@/utils/common_options'
43
   import { ENABLE_STATUS, DISABLE_STATUS } from '@/utils/common_options'
44
+  import { T } from '@/utils/i18n'
45
 
45
 
46
-  export default defineComponent({
47
-    name: 'UserEdit',
48
-    props: {},
49
-    setup (props, context) {
46
+  const route = useRoute()
47
+  const { form, item, getDetail, groupsList } = useGetDetail(route.params.id)
50
 
48
 
51
-      const route = useRoute()
52
-      const { form, item, getDetail, groupsList } = useGetDetail(route.params.id)
49
+  const { root, rules, validate, submit, cancel } = useSubmit(form, route.params.id)
53
 
50
 
54
-      const { root, rules, validate, submit, cancel } = useSubmit(form, route.params.id)
55
-
56
-      return {
57
-        form,
58
-        item,
59
-        getDetail,
60
-
61
-        rules,
62
-        validate,
63
-        root,
64
-        submit,
65
-        cancel,
66
-        groupsList,
67
-        ENABLE_STATUS, DISABLE_STATUS,
68
-      }
69
-    },
70
-  })
71
 </script>
51
 </script>
72
 
52
 
73
 <style lang="scss" scoped>
53
 <style lang="scss" scoped>

+ 17 - 17
src/views/user/index.vue

@@ -1,36 +1,36 @@
1
 <template>
1
 <template>
2
   <div>
2
   <div>
3
     <el-card class="list-query" shadow="hover">
3
     <el-card class="list-query" shadow="hover">
4
-      <el-form inline label-width="60px">
5
-        <el-form-item label="用户名">
4
+      <el-form inline label-width="80px">
5
+        <el-form-item :label="T('Username')">
6
           <el-input v-model="listQuery.username"></el-input>
6
           <el-input v-model="listQuery.username"></el-input>
7
         </el-form-item>
7
         </el-form-item>
8
         <el-form-item>
8
         <el-form-item>
9
-          <el-button type="primary" @click="handlerQuery">筛选</el-button>
10
-          <el-button type="danger" @click="toAdd">添加</el-button>
9
+          <el-button type="primary" @click="handlerQuery">{{ T('Filter') }}</el-button>
10
+          <el-button type="danger" @click="toAdd">{{ T('Add') }}</el-button>
11
         </el-form-item>
11
         </el-form-item>
12
       </el-form>
12
       </el-form>
13
     </el-card>
13
     </el-card>
14
     <el-card class="list-body" shadow="hover">
14
     <el-card class="list-body" shadow="hover">
15
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
15
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
16
         <el-table-column prop="id" label="id" align="center"></el-table-column>
16
         <el-table-column prop="id" label="id" align="center"></el-table-column>
17
-        <el-table-column prop="username" label="用户名" align="center"/>
18
-        <el-table-column prop="nickname" label="昵称" align="center"/>
19
-        <el-table-column label="所在小组" align="center">
17
+        <el-table-column prop="username" :label="T('Username')" align="center"/>
18
+        <el-table-column prop="nickname" :label="T('Nickname')" align="center"/>
19
+        <el-table-column :label="T('Group')" align="center">
20
           <template #default="{row}">
20
           <template #default="{row}">
21
             <span v-if="row.group_id"> <el-tag>{{ listRes.groups?.find(g => g.id === row.group_id)?.name }} </el-tag> </span>
21
             <span v-if="row.group_id"> <el-tag>{{ listRes.groups?.find(g => g.id === row.group_id)?.name }} </el-tag> </span>
22
-            <span v-else> 未分组 </span>
22
+            <span v-else> - </span>
23
           </template>
23
           </template>
24
         </el-table-column>
24
         </el-table-column>
25
-        <el-table-column prop="created_at" label="创建时间" align="center"/>
26
-        <el-table-column prop="updated_at" label="更新时间" align="center"/>
27
-        <el-table-column label="操作" align="center" width="550">
25
+        <el-table-column prop="created_at" :label="T('CreatedAt')" align="center"/>
26
+        <el-table-column prop="updated_at" :label="T('UpdatedAt')" align="center"/>
27
+        <el-table-column :label="T('Actions')" align="center" width="650">
28
           <template #default="{row}">
28
           <template #default="{row}">
29
-            <el-button @click="toTag(row)">他的标签</el-button>
30
-            <el-button @click="toAddressBook(row)">他的地址簿</el-button>
31
-            <el-button @click="toEdit(row)">编辑</el-button>
32
-            <el-button type="warning" @click="changePass(row)">重置密码</el-button>
33
-            <el-button type="danger" @click="remove(row)">删除</el-button>
29
+            <el-button @click="toTag(row)">{{ T('UserTags') }}</el-button>
30
+            <el-button @click="toAddressBook(row)">{{ T('UserAddressBook') }}</el-button>
31
+            <el-button @click="toEdit(row)">{{ T('Edit') }}</el-button>
32
+            <el-button type="warning" @click="changePass(row)">{{ T('ResetPassword') }}</el-button>
33
+            <el-button type="danger" @click="remove(row)">{{ T('Delete') }}</el-button>
34
           </template>
34
           </template>
35
         </el-table-column>
35
         </el-table-column>
36
       </el-table>
36
       </el-table>
@@ -49,7 +49,7 @@
49
 
49
 
50
 <script setup>
50
 <script setup>
51
   import { useRepositories, useDel, useToEditOrAdd, useChangePwd } from '@/views/user/composables'
51
   import { useRepositories, useDel, useToEditOrAdd, useChangePwd } from '@/views/user/composables'
52
-
52
+  import { T } from '@/utils/i18n'
53
   //列表
53
   //列表
54
   const {
54
   const {
55
     listRes,
55
     listRes,