Skip to content

Commit 5874c8a

Browse files
feat: i18n
1 parent 29ddee8 commit 5874c8a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+223
-166
lines changed

ui/src/api/user.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,19 @@ const getWecomCallback: (code: string, loading?: Ref<boolean>) => Promise<Result
176176
return get('wecom', { code }, loading)
177177
}
178178

179+
/**
180+
* 设置语言
181+
* data: {
182+
* "language": "string"
183+
* }
184+
*/
185+
const postLanguage: (data: any, loading?: Ref<boolean>) => Promise<Result<User>> = (
186+
data,
187+
loading
188+
) => {
189+
return post('/user/language', data, undefined, loading)
190+
}
191+
179192
export default {
180193
login,
181194
register,
@@ -192,5 +205,6 @@ export default {
192205
getAuthType,
193206
getDingCallback,
194207
getQrType,
195-
getWecomCallback
208+
getWecomCallback,
209+
postLanguage
196210
}

ui/src/layout/components/top-bar/avatar/APIKeyDialog.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
<template>
22
<el-dialog
3-
:title="$t('layout.topbar.avatar.apiKey')"
3+
:title="$t('layout.avatar.apiKey')"
44
v-model="dialogVisible"
55
width="800"
66
:close-on-click-modal="false"
77
:close-on-press-escape="false"
88
>
99
<el-card shadow="never" class="layout-bg mb-16">
1010
<el-text type="info" class="color-secondary">{{
11-
$t('layout.topbar.avatar.apiServiceAddress')
11+
$t('layout.avatar.apiServiceAddress')
1212
}}</el-text>
1313
<p style="margin-top: 10px">
1414
<span class="vertical-middle lighter break-all">

ui/src/layout/components/top-bar/avatar/ResetPassword.vue

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<el-dialog
33
v-model="resetPasswordDialog"
4-
:title="$t('layout.topbar.avatar.resetPassword')"
4+
:title="$t('layout.avatar.resetPassword')"
55
:close-on-click-modal="false"
66
:close-on-press-escape="false"
77
>
@@ -11,13 +11,13 @@
1111
:model="resetPasswordForm"
1212
:rules="rules1"
1313
>
14-
<p class="mb-8 lighter">{{ $t('layout.topbar.avatar.dialog.newPassword') }}</p>
14+
<p class="mb-8 lighter">{{ $t('layout.avatar.dialog.newPassword') }}</p>
1515
<el-form-item prop="password" style="margin-bottom: 8px">
1616
<el-input
1717
type="password"
1818
class="input-item"
1919
v-model="resetPasswordForm.password"
20-
:placeholder="$t('layout.topbar.avatar.dialog.enterPassword')"
20+
:placeholder="$t('layout.avatar.dialog.enterPassword')"
2121
show-password
2222
>
2323
</el-input>
@@ -27,7 +27,7 @@
2727
type="password"
2828
class="input-item"
2929
v-model="resetPasswordForm.re_password"
30-
:placeholder="$t('layout.topbar.avatar.dialog.confirmPassword')"
30+
:placeholder="$t('layout.avatar.dialog.confirmPassword')"
3131
show-password
3232
>
3333
</el-input>
@@ -39,13 +39,13 @@
3939
:model="resetPasswordForm"
4040
:rules="rules2"
4141
>
42-
<p class="mb-8 lighter">{{ $t('layout.topbar.avatar.dialog.useEmail') }}</p>
42+
<p class="mb-8 lighter">{{ $t('layout.avatar.dialog.useEmail') }}</p>
4343
<el-form-item style="margin-bottom: 8px">
4444
<el-input
4545
class="input-item"
4646
:disabled="true"
4747
v-bind:modelValue="user.userInfo?.email"
48-
:placeholder="$t('layout.topbar.avatar.dialog.enterEmail')"
48+
:placeholder="$t('layout.avatar.dialog.enterEmail')"
4949
>
5050
</el-input>
5151
</el-form-item>
@@ -54,7 +54,7 @@
5454
<el-input
5555
class="code-input"
5656
v-model="resetPasswordForm.code"
57-
:placeholder="$t('layout.topbar.avatar.dialog.enterVerificationCode')"
57+
:placeholder="$t('layout.avatar.dialog.enterVerificationCode')"
5858
>
5959
</el-input>
6060
<el-button
@@ -65,8 +65,8 @@
6565
>
6666
{{
6767
isDisabled
68-
? $t('layout.topbar.avatar.dialog.resend', { time })
69-
: $t('layout.topbar.avatar.dialog.getVerificationCode')
68+
? $t('layout.avatar.dialog.resend', { time })
69+
: $t('layout.avatar.dialog.getVerificationCode')
7070
}}
7171
</el-button>
7272
</div>
@@ -115,32 +115,32 @@ const rules1 = ref<FormRules<ResetCurrentUserPasswordRequest>>({
115115
password: [
116116
{
117117
required: true,
118-
message: t('layout.topbar.avatar.dialog.enterPassword'),
118+
message: t('layout.avatar.dialog.enterPassword'),
119119
trigger: 'blur'
120120
},
121121
{
122122
min: 6,
123123
max: 20,
124-
message: t('layout.topbar.avatar.dialog.passwordLength'),
124+
message: t('layout.avatar.dialog.passwordLength'),
125125
trigger: 'blur'
126126
}
127127
],
128128
re_password: [
129129
{
130130
required: true,
131-
message: t('layout.topbar.avatar.dialog.confirmPassword'),
131+
message: t('layout.avatar.dialog.confirmPassword'),
132132
trigger: 'blur'
133133
},
134134
{
135135
min: 6,
136136
max: 20,
137-
message: t('layout.topbar.avatar.dialog.passwordLength'),
137+
message: t('layout.avatar.dialog.passwordLength'),
138138
trigger: 'blur'
139139
},
140140
{
141141
validator: (rule, value, callback) => {
142142
if (resetPasswordForm.value.password != resetPasswordForm.value.re_password) {
143-
callback(new Error(t('layout.topbar.avatar.dialog.passwordMismatch')))
143+
callback(new Error(t('layout.avatar.dialog.passwordMismatch')))
144144
} else {
145145
callback()
146146
}
@@ -154,7 +154,7 @@ const rules2 = ref<FormRules<ResetCurrentUserPasswordRequest>>({
154154
code: [
155155
{
156156
required: true,
157-
message: t('layout.topbar.avatar.dialog.enterVerificationCode'),
157+
message: t('layout.avatar.dialog.enterVerificationCode'),
158158
trigger: 'blur'
159159
}
160160
]
@@ -165,7 +165,7 @@ const rules2 = ref<FormRules<ResetCurrentUserPasswordRequest>>({
165165
const sendEmail = () => {
166166
resetPasswordFormRef1.value?.validate().then(() => {
167167
UserApi.sendEmailToCurrent(loading).then(() => {
168-
MsgSuccess(t('layout.topbar.avatar.dialog.verificationCodeSentSuccess'))
168+
MsgSuccess(t('layout.avatar.dialog.verificationCodeSentSuccess'))
169169
isDisabled.value = true
170170
handleTimeChange()
171171
})

ui/src/layout/components/top-bar/avatar/index.vue

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
<el-dropdown trigger="click" type="primary">
33
<div class="flex-center cursor">
44
<AppAvatar>
5-
<img src="@/assets/user-icon.svg" style="width: 54%" alt=""/>
5+
<img src="@/assets/user-icon.svg" style="width: 54%" alt="" />
66
</AppAvatar>
77
<span class="ml-8">{{ user.userInfo?.username }}</span>
88
<el-icon class="el-icon--right">
9-
<CaretBottom/>
9+
<CaretBottom />
1010
</el-icon>
1111
</div>
1212

@@ -21,45 +21,83 @@
2121
</p>
2222
</div>
2323
<el-dropdown-item class="border-t p-8" @click="openResetPassword">
24-
{{ $t('layout.topbar.avatar.resetPassword') }}
24+
{{ $t('layout.avatar.resetPassword') }}
2525
</el-dropdown-item>
2626
<div v-hasPermission="new ComplexPermission([], ['x-pack'], 'OR')">
2727
<el-dropdown-item class="border-t p-8" @click="openAPIKeyDialog">
28-
{{ $t('layout.topbar.avatar.apiKey') }}
28+
{{ $t('layout.avatar.apiKey') }}
2929
</el-dropdown-item>
3030
</div>
31+
<el-dropdown-item class="border-t" style="padding: 0" @click.stop>
32+
<el-dropdown class="w-full" trigger="hover" placement="left-start">
33+
<div class="flex-between w-full" style="line-height: 22px; padding: 12px 11px">
34+
<span> {{ $t('layout.language') }}</span>
35+
<el-icon><ArrowRight /></el-icon>
36+
</div>
37+
38+
<template #dropdown>
39+
<el-dropdown-menu style="width: 180px">
40+
<el-dropdown-item
41+
v-for="(lang, index) in langList"
42+
:key="index"
43+
:value="lang.value"
44+
@click="changeLang(lang.value)"
45+
class="flex-between"
46+
>
47+
<span :class="lang.value === user.userInfo?.language ? 'primary' : ''">{{
48+
lang.label
49+
}}</span>
50+
51+
<el-icon
52+
:class="lang.value === user.userInfo?.language ? 'primary' : ''"
53+
v-if="lang.value === user.userInfo?.language"
54+
>
55+
<Check />
56+
</el-icon>
57+
</el-dropdown-item>
58+
</el-dropdown-menu>
59+
</template>
60+
</el-dropdown>
61+
</el-dropdown-item>
3162
<el-dropdown-item class="border-t" @click="openAbout">
32-
{{ $t('layout.topbar.avatar.about') }}
63+
{{ $t('layout.avatar.about') }}
3364
</el-dropdown-item>
65+
3466
<el-dropdown-item class="border-t" @click="logout">
35-
{{ $t('layout.topbar.avatar.logout') }}
67+
{{ $t('layout.avatar.logout') }}
3668
</el-dropdown-item>
3769
</el-dropdown-menu>
3870
</template>
3971
</el-dropdown>
4072
<ResetPassword ref="resetPasswordRef"></ResetPassword>
4173
<AboutDialog ref="AboutDialogRef"></AboutDialog>
42-
<APIKeyDialog :user-id="user.userInfo?.id" ref="APIKeyDialogRef"/>
43-
<UserPwdDialog ref="UserPwdDialogRef"/>
74+
<APIKeyDialog :user-id="user.userInfo?.id" ref="APIKeyDialogRef" />
75+
<UserPwdDialog ref="UserPwdDialogRef" />
4476
</template>
4577
<script setup lang="ts">
46-
import {ref, onMounted} from 'vue'
78+
import { ref, onMounted } from 'vue'
4779
import useStore from '@/stores'
48-
import {useRouter} from 'vue-router'
80+
import { useRouter } from 'vue-router'
4981
import ResetPassword from './ResetPassword.vue'
5082
import AboutDialog from './AboutDialog.vue'
5183
import UserPwdDialog from '@/views/user-manage/component/UserPwdDialog.vue'
5284
import APIKeyDialog from './APIKeyDialog.vue'
53-
import {ComplexPermission} from '@/utils/permission/type'
54-
55-
const {user} = useStore()
85+
import { ComplexPermission } from '@/utils/permission/type'
86+
import { langList } from '@/locales/index'
87+
import { useLocale } from '@/locales/useLocale'
88+
const { user } = useStore()
5689
const router = useRouter()
5790
5891
const UserPwdDialogRef = ref()
5992
const AboutDialogRef = ref()
6093
const APIKeyDialogRef = ref()
6194
const resetPasswordRef = ref<InstanceType<typeof ResetPassword>>()
6295
96+
// const { changeLocale } = useLocale()
97+
const changeLang = (lang: string) => {
98+
user.postUserLanguage(lang)
99+
// changeLocale(lang)
100+
}
63101
const openAbout = () => {
64102
AboutDialogRef.value?.open()
65103
}
@@ -74,7 +112,7 @@ const openResetPassword = () => {
74112
75113
const logout = () => {
76114
user.logout().then(() => {
77-
router.push({name: 'login'})
115+
router.push({ name: 'login' })
78116
})
79117
}
80118
@@ -94,6 +132,9 @@ onMounted(() => {
94132
95133
:deep(.el-dropdown-menu__item) {
96134
padding: 12px 11px;
135+
&:hover {
136+
background: var(--app-text-color-light-1);
137+
}
97138
}
98139
}
99140
</style>

ui/src/layout/components/top-bar/index.vue

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
</el-button>
2424
<el-tooltip
2525
effect="dark"
26-
:content="$t('layout.topbar.github')"
26+
:content="$t('layout.github')"
2727
placement="top"
2828
v-if="user.themeInfo?.showProject"
2929
>
@@ -36,7 +36,7 @@
3636
</el-tooltip>
3737
<el-tooltip
3838
effect="dark"
39-
:content="$t('layout.topbar.wiki')"
39+
:content="$t('layout.wiki')"
4040
placement="top"
4141
v-if="user.themeInfo?.showUserManual"
4242
>
@@ -49,7 +49,7 @@
4949
</el-tooltip>
5050
<el-tooltip
5151
effect="dark"
52-
:content="$t('layout.topbar.forum')"
52+
:content="$t('layout.forum')"
5353
placement="top"
5454
v-if="user.themeInfo?.showForum"
5555
>
@@ -60,7 +60,7 @@
6060
@click="toUrl(user.themeInfo?.forumUrl)"
6161
></AppIcon>
6262
</el-tooltip>
63-
<el-dropdown trigger="click" type="primary">
63+
<!-- <el-dropdown trigger="click" type="primary">
6464
<template #dropdown>
6565
<el-dropdown-menu>
6666
<el-dropdown-item
@@ -78,7 +78,7 @@
7878
style="font-size: 20px"
7979
>
8080
</AppIcon>
81-
</el-dropdown>
81+
</el-dropdown> -->
8282
<Avatar></Avatar>
8383
</div>
8484
</div>
@@ -87,17 +87,17 @@
8787
import TopMenu from './top-menu/index.vue'
8888
import Avatar from './avatar/index.vue'
8989
import { useRouter } from 'vue-router'
90-
import { langList } from '@/locales/index'
91-
import { useLocale } from '@/locales/useLocale'
90+
// import { langList } from '@/locales/index'
91+
// import { useLocale } from '@/locales/useLocale'
9292
9393
import useStore from '@/stores'
9494
const { user } = useStore()
9595
const router = useRouter()
9696
97-
const { changeLocale } = useLocale()
98-
const changeLang = (lang: string) => {
99-
changeLocale(lang)
100-
}
97+
// const { changeLocale } = useLocale()
98+
// const changeLang = (lang: string) => {
99+
// changeLocale(lang)
100+
// }
101101
function toUrl(url: string) {
102102
window.open(url, '_blank')
103103
}

ui/src/layout/components/top-bar/top-menu/MenuItem.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
</div> -->
77
<div class="title">
88
{{
9-
$te(`layout.topbar.MenuItem.${String(props.menu.name)}`)
10-
? $t(`layout.topbar.MenuItem.${String(props.menu.name)}`)
9+
$te(`layout.MenuItem.${String(props.menu.name)}`)
10+
? $t(`layout.MenuItem.${String(props.menu.name)}`)
1111
: menu.meta?.title
1212
}}
1313
</div>

ui/src/locales/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ const importMessages = computed(() => {
4040

4141
export const i18n = createI18n({
4242
legacy: false,
43-
locale: useLocalStorage(localeConfigKey, 'zh_CN').value || languages.value[0] || 'zh_CN',
44-
fallbackLocale: 'zh_CN',
43+
locale: useLocalStorage(localeConfigKey, 'zh-CN').value || languages.value[0] || 'zh-CN',
44+
fallbackLocale: 'zh-CN',
4545
messages: importMessages.value,
4646
globalInjection: true,
4747
});
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)