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() }