190 lines
5.9 KiB
TypeScript
190 lines
5.9 KiB
TypeScript
import type { App } from 'vue'
|
|
import { createI18n } from 'vue-i18n'
|
|
import type { I18n, Composer } from 'vue-i18n'
|
|
import { useConfig } from '/@/stores/config'
|
|
import { isEmpty } from 'lodash-es'
|
|
|
|
/*
|
|
* 默认只引入 element-plus 的中英文语言包
|
|
* 其他语言包请自行在此 import,并添加到 assignLocale 内
|
|
* 动态 import 只支持相对路径,所以无法按需 import element-plus 的语言包
|
|
* 但i18n的 messages 内是按需载入的
|
|
*/
|
|
import elementZhcnLocale from 'element-plus/es/locale/lang/zh-cn'
|
|
import elementEnLocale from 'element-plus/es/locale/lang/en'
|
|
|
|
export let i18n: {
|
|
global: Composer
|
|
}
|
|
|
|
// 准备要合并的语言包
|
|
const assignLocale: anyObj = {
|
|
'zh-cn': [elementZhcnLocale],
|
|
en: [elementEnLocale],
|
|
}
|
|
|
|
export async function loadLang(app: App) {
|
|
const config = useConfig()
|
|
const locale = config.lang.defaultLang
|
|
|
|
// 加载框架全局语言包
|
|
// const lang = await import(`./globs-${locale}.ts`)
|
|
const message = {
|
|
Id: 'ID',
|
|
State: '状态',
|
|
Home: '首页',
|
|
Complete: '完成',
|
|
Edit: '编辑',
|
|
Add: '添加',
|
|
Info: '查看详情',
|
|
Delete: '删除',
|
|
Refresh: '刷新',
|
|
Operate: '操作',
|
|
Confirm: '确认',
|
|
Cancel: '取消',
|
|
Save: '保存',
|
|
Upload: '上传',
|
|
Retry: '重试',
|
|
Reminder: '温馨提示',
|
|
Disable: '禁用',
|
|
Enable: '启用',
|
|
Shrink: '收缩',
|
|
Open: '展开',
|
|
Search: '搜索',
|
|
Reset: '重置',
|
|
To: '至',
|
|
None: '无',
|
|
Unknown: '未知',
|
|
Weigh: '权重',
|
|
'Drag sort': '拖动以排序',
|
|
'Save and edit next item': '保存并编辑下一项',
|
|
'Quick search placeholder': '通过{fields}模糊搜索',
|
|
'Please select field': '请选择{field}',
|
|
'Please input field': '请输入{field}',
|
|
'Please enter the correct field': '请输入正确的{field}',
|
|
'Update time': '修改时间',
|
|
'Create time': '创建时间',
|
|
'Fuzzy query': '模糊查询',
|
|
'Click select': '点击选择',
|
|
'Edit selected row': '编辑选中行',
|
|
'Delete selected row': '删除选中行',
|
|
'Are you sure to delete the selected record?': '确定删除选中记录?',
|
|
'All submenus': '所有子菜单',
|
|
'Shrink all': '收缩所有',
|
|
'Expand all': '展开所有',
|
|
'Expand generic search': '展开通用搜索',
|
|
'Link address': '链接地址',
|
|
'No route found to jump~': '没有找到可以跳转的路由~',
|
|
}
|
|
// 按需加载语言包文件的句柄
|
|
if (locale == 'zh-cn') {
|
|
window.loadLangHandle = {
|
|
...import.meta.glob('./backend/zh-cn/**/*.ts'),
|
|
...import.meta.glob('./backend/zh-cn.ts'),
|
|
}
|
|
} else {
|
|
window.loadLangHandle = {
|
|
...import.meta.glob('./backend/en/**/*.ts'),
|
|
...import.meta.glob('./backend/en.ts'),
|
|
}
|
|
}
|
|
|
|
/*
|
|
* 加载页面语言包 import.meta.glob 的路径不能使用变量 import() 在 Vite 中目录名不能使用变量(编译后,文件名可以)
|
|
*/
|
|
if (locale == 'zh-cn') {
|
|
assignLocale[locale].push(getLangFileMessage(import.meta.glob('./common/zh-cn/**/*.ts', { eager: true }), locale))
|
|
} else if (locale == 'en') {
|
|
assignLocale[locale].push(getLangFileMessage(import.meta.glob('./common/en/**/*.ts', { eager: true }), locale))
|
|
}
|
|
|
|
const messages = {
|
|
[locale]: {
|
|
...message,
|
|
},
|
|
}
|
|
|
|
// 合并语言包(含element-puls、页面语言包)
|
|
Object.assign(messages[locale], ...assignLocale[locale])
|
|
|
|
i18n = createI18n({
|
|
locale: locale,
|
|
legacy: false, // 组合式api
|
|
globalInjection: true, // 挂载$t,$d等到全局
|
|
fallbackLocale: config.lang.fallbackLang,
|
|
messages,
|
|
})
|
|
|
|
app.use(i18n as I18n)
|
|
return i18n
|
|
}
|
|
|
|
function getLangFileMessage(mList: any, locale: string) {
|
|
let msg: anyObj = {}
|
|
locale = '/' + locale
|
|
for (const path in mList) {
|
|
if (mList[path].default) {
|
|
// 获取文件名
|
|
const pathName = path.slice(path.lastIndexOf(locale) + (locale.length + 1), path.lastIndexOf('.'))
|
|
if (pathName.indexOf('/') > 0) {
|
|
msg = handleMsglist(msg, mList[path].default, pathName)
|
|
} else {
|
|
msg[pathName] = mList[path].default
|
|
}
|
|
}
|
|
}
|
|
return msg
|
|
}
|
|
|
|
export function mergeMessage(message: anyObj, pathName = '') {
|
|
if (isEmpty(message)) return
|
|
if (!pathName) {
|
|
return i18n.global.mergeLocaleMessage(i18n.global.locale.value, message)
|
|
}
|
|
let msg: anyObj = {}
|
|
if (pathName.indexOf('/') > 0) {
|
|
msg = handleMsglist(msg, message, pathName)
|
|
} else {
|
|
msg[pathName] = message
|
|
}
|
|
i18n.global.mergeLocaleMessage(i18n.global.locale.value, msg)
|
|
}
|
|
|
|
export function handleMsglist(msg: anyObj, mList: anyObj, pathName: string) {
|
|
const pathNameTmp = pathName.split('/')
|
|
let obj: anyObj = {}
|
|
for (let i = pathNameTmp.length - 1; i >= 0; i--) {
|
|
if (i == pathNameTmp.length - 1) {
|
|
obj = {
|
|
[pathNameTmp[i]]: mList,
|
|
}
|
|
} else {
|
|
obj = {
|
|
[pathNameTmp[i]]: obj,
|
|
}
|
|
}
|
|
}
|
|
return mergeMsg(msg, obj)
|
|
}
|
|
|
|
export function mergeMsg(msg: anyObj, obj: anyObj) {
|
|
for (const key in obj) {
|
|
if (typeof msg[key] == 'undefined') {
|
|
msg[key] = obj[key]
|
|
} else if (typeof msg[key] == 'object') {
|
|
msg[key] = mergeMsg(msg[key], obj[key])
|
|
}
|
|
}
|
|
return msg
|
|
}
|
|
|
|
export function editDefaultLang(lang: string): void {
|
|
const config = useConfig()
|
|
config.setLang(lang)
|
|
|
|
/*
|
|
* 语言包是按需加载的,比如默认语言为中文,则只在app实例内加载了中文语言包,所以切换语言需要进行 reload
|
|
*/
|
|
location.reload()
|
|
}
|