Skip to content

Commit

Permalink
feat: login view add language setting
Browse files Browse the repository at this point in the history
  • Loading branch information
wangdan-fit2cloud committed Feb 5, 2025
1 parent 37d65b4 commit 4da513a
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 53 deletions.
47 changes: 46 additions & 1 deletion ui/src/components/login-layout/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,33 @@
<div class="login-image" :style="{ backgroundImage: `url(${loginImage})` }"></div>
</el-col>
<el-col :xs="24" :sm="24" :md="14" :lg="14" :xl="14" class="right-container flex-center">
<el-dropdown trigger="click" type="primary" class="lang">
<template #dropdown>
<el-dropdown-menu style="width: 180px">
<el-dropdown-item
v-for="(lang, index) in langList"
:key="index"
:value="lang.value"
@click="changeLang(lang.value)"
class="flex-between"
>
<span :class="lang.value === user.getLanguage() ? 'primary' : ''">{{
lang.label
}}</span>

<el-icon
:class="lang.value === user.getLanguage() ? 'primary' : ''"
v-if="lang.value === user.getLanguage()"
>
<Check />
</el-icon>
</el-dropdown-item>
</el-dropdown-menu>
</template>
<el-button>
{{ currentLanguage }}<el-icon class="el-icon--right"><arrow-down /></el-icon>
</el-button>
</el-dropdown>
<slot></slot>
</el-col>
</el-row>
Expand All @@ -16,10 +43,20 @@
import { computed } from 'vue'
import { getThemeImg } from '@/utils/theme'
import useStore from '@/stores'
import { request } from '@/request'
import { useLocalStorage } from '@vueuse/core'
import { langList, localeConfigKey, getBrowserLang } from '@/locales/index'
defineOptions({ name: 'LoginLayout' })
const { user } = useStore()
const changeLang = (lang: string) => {
useLocalStorage(localeConfigKey, getBrowserLang()).value = lang
window.location.reload()
}
const currentLanguage = computed(() => {
return langList.value?.filter((v: any) => v.value === user.getLanguage())[0].label
})
const fileURL = computed(() => {
if (user.themeInfo?.loginImage) {
if (typeof user.themeInfo?.loginImage === 'string') {
Expand Down Expand Up @@ -52,5 +89,13 @@ const loginImage = computed(() => {
width: 100%;
height: 100%;
}
.right-container {
position: relative;
.lang {
position: absolute;
right: 20px;
top: 20px;
}
}
}
</style>
4 changes: 2 additions & 2 deletions ui/src/components/markdown/MdEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
<script setup lang="ts">
import { computed } from 'vue'
import { MdEditor, config } from 'md-editor-v3'
import { getBrowserLang } from '@/locales/index'
import './assets/markdown-iconfont.js'
// 引入公共库中的语言配置
import ZH_TW from '@vavt/cm-extension/dist/locale/zh-TW'
defineOptions({ name: 'MdEditor' })
const language = computed(() => localStorage.getItem('MaxKB-locale') || '')
const language = computed(() => localStorage.getItem('MaxKB-locale') || getBrowserLang() || '')
config({
editorConfig: {
languageUserDefined: {
Expand Down
102 changes: 59 additions & 43 deletions ui/src/locales/index.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,82 @@
import { useLocalStorage, usePreferredLanguages } from '@vueuse/core';
import { computed } from 'vue';
import { createI18n } from 'vue-i18n';
import { useLocalStorage, usePreferredLanguages } from '@vueuse/core'
import { computed } from 'vue'
import { createI18n } from 'vue-i18n'

// 导入语言文件
const langModules = import.meta.glob('./lang/*/index.ts', { eager: true }) as Record<string, () => Promise<{ default: Object }>>;
const langModules = import.meta.glob('./lang/*/index.ts', { eager: true }) as Record<
string,
() => Promise<{ default: Object }>
>

const langModuleMap = new Map<string, Object>();
const langModuleMap = new Map<string, Object>()

export const langCode: Array<string> = [];
export const langCode: Array<string> = []

export const localeConfigKey = 'MaxKB-locale';
export const localeConfigKey = 'MaxKB-locale'

// 获取浏览器默认语言环境
const languages = usePreferredLanguages();
const languages = usePreferredLanguages()

export function getBrowserLang() {
const browserLang = navigator.language ? navigator.language : languages.value[0]
let defaultBrowserLang = ''
if (browserLang === 'zh-HK' || browserLang === 'zh-TW') {
defaultBrowserLang = 'zh-Hant'
} else if (browserLang === 'zh-CN') {
defaultBrowserLang = 'zh-CN'
} else {
defaultBrowserLang = 'en-US'
}
return defaultBrowserLang
}

// 生成语言模块列表
const generateLangModuleMap = () => {
const fullPaths = Object.keys(langModules);
fullPaths.forEach((fullPath) => {
const k = fullPath.replace('./lang', '');
const startIndex = 1;
const lastIndex = k.lastIndexOf('/');
const code = k.substring(startIndex, lastIndex);
langCode.push(code);
langModuleMap.set(code, langModules[fullPath]);
});
};
const fullPaths = Object.keys(langModules)
fullPaths.forEach((fullPath) => {
const k = fullPath.replace('./lang', '')
const startIndex = 1
const lastIndex = k.lastIndexOf('/')
const code = k.substring(startIndex, lastIndex)
langCode.push(code)
langModuleMap.set(code, langModules[fullPath])
})
}

// 导出 Message
const importMessages = computed(() => {
generateLangModuleMap();
generateLangModuleMap()

const message: Recordable = {};
langModuleMap.forEach((value: any, key) => {
message[key] = value.default;
});
return message;
});
const message: Recordable = {}
langModuleMap.forEach((value: any, key) => {
message[key] = value.default
})
return message
})

export const i18n = createI18n({
legacy: false,
locale: useLocalStorage(localeConfigKey, 'zh-CN').value || languages.value[0] || 'zh-CN',
fallbackLocale: 'zh-CN',
messages: importMessages.value,
globalInjection: true,
});
legacy: false,
locale: useLocalStorage(localeConfigKey, getBrowserLang()).value || getBrowserLang(),
fallbackLocale: getBrowserLang(),
messages: importMessages.value,
globalInjection: true
})

export const langList = computed(() => {
if (langModuleMap.size === 0) generateLangModuleMap();
if (langModuleMap.size === 0) generateLangModuleMap()

const list:any=[]
langModuleMap.forEach((value: any, key) => {
list.push({
label: value.default.lang,
value: key,
});
});
const list: any = []
langModuleMap.forEach((value: any, key) => {
list.push({
label: value.default.lang,
value: key
})
})

return list;
});
return list
})

// @ts-ignore
export const { t } = i18n.global;
export const { t } = i18n.global

export default i18n;
export default i18n
2 changes: 1 addition & 1 deletion ui/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const locale_map: any = {
'en-US': enUs
}
app.use(ElementPlus, {
locale: locale_map[localStorage.getItem('MaxKB-locale') || 'zh-CN']
locale: locale_map[localStorage.getItem('MaxKB-locale') || navigator.language || 'zh-CN']
})

app.use(router)
Expand Down
4 changes: 2 additions & 2 deletions ui/src/stores/modules/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import ThemeApi from '@/api/theme'
import { useElementPlusTheme } from 'use-element-plus-theme'
import { defaultPlatformSetting } from '@/utils/theme'
import { useLocalStorage } from '@vueuse/core'
import { localeConfigKey } from '@/locales/index'
import { localeConfigKey, getBrowserLang } from '@/locales/index'
export interface userStateTypes {
userType: number // 1 系统操作者 2 对话用户
userInfo: User | null
Expand All @@ -33,7 +33,7 @@ const useUserStore = defineStore({
actions: {
getLanguage() {
return this.userType === 1
? localStorage.getItem('MaxKB-locale')
? localStorage.getItem('MaxKB-locale') || getBrowserLang()
: sessionStorage.getItem('language')
},
showXpack() {
Expand Down
4 changes: 2 additions & 2 deletions ui/src/views/login/components/wecomQrCode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import { ref, nextTick, defineProps } from 'vue'
import { MsgError } from '@/utils/message'
import useStore from '@/stores'
import { getBrowserLang } from '@/locales/index'
const router = useRouter()
const wwLogin = ref({})
Expand All @@ -36,7 +36,7 @@ const init = async () => {
corpId: props.config.corp_id,
agentId: props.config.agent_id
}
const lang = localStorage.getItem('MaxKB-locale') || 'zh-CN'
const lang = localStorage.getItem('MaxKB-locale') || getBrowserLang() || 'zh-CN'
const redirectUri = window.location.origin
try {
wwLogin.value = ww.createWWLoginPanel({
Expand Down
4 changes: 2 additions & 2 deletions ui/src/views/login/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ import useStore from '@/stores'
import authApi from '@/api/auth-setting'
import { MsgConfirm, MsgSuccess } from '@/utils/message'
import { t } from '@/locales'
import { t, getBrowserLang } from '@/locales'
import QrCodeTab from '@/views/login/components/QrCodeTab.vue'
import { useI18n } from 'vue-i18n'
const { locale } = useI18n({ useScope: 'global' })
Expand Down Expand Up @@ -217,7 +217,7 @@ const login = () => {
user
.login(loginMode.value, loginForm.value.username, loginForm.value.password)
.then(() => {
locale.value = localStorage.getItem('MaxKB-locale') || 'zh-CN'
locale.value = localStorage.getItem('MaxKB-locale') || getBrowserLang() || 'zh-CN'
router.push({ name: 'home' })
})
.finally(() => (loading.value = false))
Expand Down

0 comments on commit 4da513a

Please sign in to comment.