feat: login view add language setting
This commit is contained in:
parent
37d65b4125
commit
4da513a1ca
@ -6,6 +6,33 @@
|
|||||||
<div class="login-image" :style="{ backgroundImage: `url(${loginImage})` }"></div>
|
<div class="login-image" :style="{ backgroundImage: `url(${loginImage})` }"></div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="24" :md="14" :lg="14" :xl="14" class="right-container flex-center">
|
<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>
|
<slot></slot>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@ -16,10 +43,20 @@
|
|||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { getThemeImg } from '@/utils/theme'
|
import { getThemeImg } from '@/utils/theme'
|
||||||
import useStore from '@/stores'
|
import useStore from '@/stores'
|
||||||
import { request } from '@/request'
|
import { useLocalStorage } from '@vueuse/core'
|
||||||
|
import { langList, localeConfigKey, getBrowserLang } from '@/locales/index'
|
||||||
defineOptions({ name: 'LoginLayout' })
|
defineOptions({ name: 'LoginLayout' })
|
||||||
const { user } = useStore()
|
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(() => {
|
const fileURL = computed(() => {
|
||||||
if (user.themeInfo?.loginImage) {
|
if (user.themeInfo?.loginImage) {
|
||||||
if (typeof user.themeInfo?.loginImage === 'string') {
|
if (typeof user.themeInfo?.loginImage === 'string') {
|
||||||
@ -52,5 +89,13 @@ const loginImage = computed(() => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
.right-container {
|
||||||
|
position: relative;
|
||||||
|
.lang {
|
||||||
|
position: absolute;
|
||||||
|
right: 20px;
|
||||||
|
top: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -9,13 +9,13 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { MdEditor, config } from 'md-editor-v3'
|
import { MdEditor, config } from 'md-editor-v3'
|
||||||
|
import { getBrowserLang } from '@/locales/index'
|
||||||
import './assets/markdown-iconfont.js'
|
import './assets/markdown-iconfont.js'
|
||||||
// 引入公共库中的语言配置
|
// 引入公共库中的语言配置
|
||||||
import ZH_TW from '@vavt/cm-extension/dist/locale/zh-TW'
|
import ZH_TW from '@vavt/cm-extension/dist/locale/zh-TW'
|
||||||
|
|
||||||
defineOptions({ name: 'MdEditor' })
|
defineOptions({ name: 'MdEditor' })
|
||||||
const language = computed(() => localStorage.getItem('MaxKB-locale') || '')
|
const language = computed(() => localStorage.getItem('MaxKB-locale') || getBrowserLang() || '')
|
||||||
config({
|
config({
|
||||||
editorConfig: {
|
editorConfig: {
|
||||||
languageUserDefined: {
|
languageUserDefined: {
|
||||||
|
|||||||
@ -1,66 +1,82 @@
|
|||||||
import { useLocalStorage, usePreferredLanguages } from '@vueuse/core';
|
import { useLocalStorage, usePreferredLanguages } from '@vueuse/core'
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue'
|
||||||
import { createI18n } from 'vue-i18n';
|
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 generateLangModuleMap = () => {
|
||||||
const fullPaths = Object.keys(langModules);
|
const fullPaths = Object.keys(langModules)
|
||||||
fullPaths.forEach((fullPath) => {
|
fullPaths.forEach((fullPath) => {
|
||||||
const k = fullPath.replace('./lang', '');
|
const k = fullPath.replace('./lang', '')
|
||||||
const startIndex = 1;
|
const startIndex = 1
|
||||||
const lastIndex = k.lastIndexOf('/');
|
const lastIndex = k.lastIndexOf('/')
|
||||||
const code = k.substring(startIndex, lastIndex);
|
const code = k.substring(startIndex, lastIndex)
|
||||||
langCode.push(code);
|
langCode.push(code)
|
||||||
langModuleMap.set(code, langModules[fullPath]);
|
langModuleMap.set(code, langModules[fullPath])
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
// 导出 Message
|
// 导出 Message
|
||||||
const importMessages = computed(() => {
|
const importMessages = computed(() => {
|
||||||
generateLangModuleMap();
|
generateLangModuleMap()
|
||||||
|
|
||||||
const message: Recordable = {};
|
const message: Recordable = {}
|
||||||
langModuleMap.forEach((value: any, key) => {
|
langModuleMap.forEach((value: any, key) => {
|
||||||
message[key] = value.default;
|
message[key] = value.default
|
||||||
});
|
})
|
||||||
return message;
|
return message
|
||||||
});
|
})
|
||||||
|
|
||||||
export const i18n = createI18n({
|
export const i18n = createI18n({
|
||||||
legacy: false,
|
legacy: false,
|
||||||
locale: useLocalStorage(localeConfigKey, 'zh-CN').value || languages.value[0] || 'zh-CN',
|
locale: useLocalStorage(localeConfigKey, getBrowserLang()).value || getBrowserLang(),
|
||||||
fallbackLocale: 'zh-CN',
|
fallbackLocale: getBrowserLang(),
|
||||||
messages: importMessages.value,
|
messages: importMessages.value,
|
||||||
globalInjection: true,
|
globalInjection: true
|
||||||
});
|
})
|
||||||
|
|
||||||
export const langList = computed(() => {
|
export const langList = computed(() => {
|
||||||
if (langModuleMap.size === 0) generateLangModuleMap();
|
if (langModuleMap.size === 0) generateLangModuleMap()
|
||||||
|
|
||||||
const list:any=[]
|
const list: any = []
|
||||||
langModuleMap.forEach((value: any, key) => {
|
langModuleMap.forEach((value: any, key) => {
|
||||||
list.push({
|
list.push({
|
||||||
label: value.default.lang,
|
label: value.default.lang,
|
||||||
value: key,
|
value: key
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
return list;
|
return list
|
||||||
});
|
})
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
export const { t } = i18n.global;
|
export const { t } = i18n.global
|
||||||
|
|
||||||
export default i18n;
|
export default i18n
|
||||||
|
|||||||
@ -58,7 +58,7 @@ const locale_map: any = {
|
|||||||
'en-US': enUs
|
'en-US': enUs
|
||||||
}
|
}
|
||||||
app.use(ElementPlus, {
|
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)
|
app.use(router)
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import ThemeApi from '@/api/theme'
|
|||||||
import { useElementPlusTheme } from 'use-element-plus-theme'
|
import { useElementPlusTheme } from 'use-element-plus-theme'
|
||||||
import { defaultPlatformSetting } from '@/utils/theme'
|
import { defaultPlatformSetting } from '@/utils/theme'
|
||||||
import { useLocalStorage } from '@vueuse/core'
|
import { useLocalStorage } from '@vueuse/core'
|
||||||
import { localeConfigKey } from '@/locales/index'
|
import { localeConfigKey, getBrowserLang } from '@/locales/index'
|
||||||
export interface userStateTypes {
|
export interface userStateTypes {
|
||||||
userType: number // 1 系统操作者 2 对话用户
|
userType: number // 1 系统操作者 2 对话用户
|
||||||
userInfo: User | null
|
userInfo: User | null
|
||||||
@ -33,7 +33,7 @@ const useUserStore = defineStore({
|
|||||||
actions: {
|
actions: {
|
||||||
getLanguage() {
|
getLanguage() {
|
||||||
return this.userType === 1
|
return this.userType === 1
|
||||||
? localStorage.getItem('MaxKB-locale')
|
? localStorage.getItem('MaxKB-locale') || getBrowserLang()
|
||||||
: sessionStorage.getItem('language')
|
: sessionStorage.getItem('language')
|
||||||
},
|
},
|
||||||
showXpack() {
|
showXpack() {
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import {
|
|||||||
import { ref, nextTick, defineProps } from 'vue'
|
import { ref, nextTick, defineProps } from 'vue'
|
||||||
import { MsgError } from '@/utils/message'
|
import { MsgError } from '@/utils/message'
|
||||||
import useStore from '@/stores'
|
import useStore from '@/stores'
|
||||||
|
import { getBrowserLang } from '@/locales/index'
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const wwLogin = ref({})
|
const wwLogin = ref({})
|
||||||
@ -36,7 +36,7 @@ const init = async () => {
|
|||||||
corpId: props.config.corp_id,
|
corpId: props.config.corp_id,
|
||||||
agentId: props.config.agent_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
|
const redirectUri = window.location.origin
|
||||||
try {
|
try {
|
||||||
wwLogin.value = ww.createWWLoginPanel({
|
wwLogin.value = ww.createWWLoginPanel({
|
||||||
|
|||||||
@ -109,7 +109,7 @@ import useStore from '@/stores'
|
|||||||
import authApi from '@/api/auth-setting'
|
import authApi from '@/api/auth-setting'
|
||||||
import { MsgConfirm, MsgSuccess } from '@/utils/message'
|
import { MsgConfirm, MsgSuccess } from '@/utils/message'
|
||||||
|
|
||||||
import { t } from '@/locales'
|
import { t, getBrowserLang } from '@/locales'
|
||||||
import QrCodeTab from '@/views/login/components/QrCodeTab.vue'
|
import QrCodeTab from '@/views/login/components/QrCodeTab.vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
const { locale } = useI18n({ useScope: 'global' })
|
const { locale } = useI18n({ useScope: 'global' })
|
||||||
@ -217,7 +217,7 @@ const login = () => {
|
|||||||
user
|
user
|
||||||
.login(loginMode.value, loginForm.value.username, loginForm.value.password)
|
.login(loginMode.value, loginForm.value.username, loginForm.value.password)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
locale.value = localStorage.getItem('MaxKB-locale') || 'zh-CN'
|
locale.value = localStorage.getItem('MaxKB-locale') || getBrowserLang() || 'zh-CN'
|
||||||
router.push({ name: 'home' })
|
router.push({ name: 'home' })
|
||||||
})
|
})
|
||||||
.finally(() => (loading.value = false))
|
.finally(() => (loading.value = false))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user