index.ts 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import {createI18n} from 'vue-i18n';
  2. import pinia from '/@/stores/index';
  3. import {storeToRefs} from 'pinia';
  4. import {useThemeConfig} from '/@/stores/themeConfig';
  5. import {info} from '/@/api/admin/i18n';
  6. // 定义语言国际化内容
  7. /**
  8. * 说明:
  9. * 须在 pages 下新建文件夹(建议 `要国际化界面目录` 与 `i18n 目录` 相同,方便查找),
  10. * 注意国际化定义的字段,不要与原有的定义字段相同。
  11. * 1、/src/i18n/lang 下的 ts 为框架的国际化内容
  12. * 2、/src/i18n/pages 下的 ts 为各界面的国际化内容
  13. */
  14. // element plus 自带国际化
  15. import enLocale from 'element-plus/es/locale/lang/en';
  16. import zhcnLocale from 'element-plus/es/locale/lang/zh-cn';
  17. // 定义变量内容
  18. const messages = {};
  19. const element = {en: enLocale, 'zh-cn': zhcnLocale};
  20. const itemize = {en: [] as any[], 'zh-cn': [] as any[]};
  21. const modules: Record<string, any> = import.meta.glob('./**/*.ts', {eager: true});
  22. const pages: Record<string, any> = import.meta.glob('./../../**/**/**/i18n/*.ts', {eager: true});
  23. // 对自动引入的 modules 进行分类 en、zh-cn、zh-tw
  24. for (const path in modules) {
  25. const key = path.match(/(\S+)\/(\S+).ts/);
  26. if (itemize[key![2]]) itemize[key![2]].push(modules[path].default);
  27. else itemize[key![2]] = modules[path];
  28. }
  29. for (const path in pages) {
  30. const key = path.match(/(\S+)\/(\S+).ts/);
  31. if (itemize[key![2]]) itemize[key![2]].push(pages[path].default);
  32. else itemize[key![2]] = pages[path];
  33. }
  34. // 合并数组对象(非标准数组对象,数组中对象的每项 key、value 都不同)
  35. function mergeArrObj<T>(list: T, key: string) {
  36. let obj = {};
  37. list[key].forEach((i: EmptyObjectType) => {
  38. obj = Object.assign({}, obj, i);
  39. });
  40. return obj;
  41. }
  42. for (const key in itemize) {
  43. messages[key] = {
  44. name: key,
  45. el: element[key].el,
  46. ...mergeArrObj(itemize, key),
  47. };
  48. }
  49. // 读取 pinia 默认语言
  50. const stores = useThemeConfig(pinia);
  51. const {themeConfig} = storeToRefs(stores);
  52. // 导出语言国际化
  53. export const i18n = createI18n({
  54. legacy: false,
  55. silentTranslationWarn: true,
  56. missingWarn: false,
  57. silentFallbackWarn: true,
  58. fallbackWarn: false,
  59. locale: themeConfig.value.globalI18n,
  60. fallbackLocale: zhcnLocale.name,
  61. messages,
  62. });
  63. await fetchI18n()
  64. // 远程获取i18n
  65. async function fetchI18n() {
  66. const infoI18n = await info();
  67. const messageLocal = {};
  68. const itemizeLocal = {en: [] as any[], 'zh-cn': [] as any[]};
  69. itemizeLocal['zh-cn'].push(...infoI18n.data.data['zh-cn']);
  70. itemizeLocal.en.push(...infoI18n.data.data.en);
  71. for (const key in itemizeLocal) {
  72. messageLocal[key] = {
  73. name: key,
  74. ...mergeArrObj(itemizeLocal, key),
  75. };
  76. }
  77. i18n.global.mergeLocaleMessage('zh-cn', messageLocal['zh-cn']);
  78. i18n.global.mergeLocaleMessage('en', messageLocal['en']);
  79. i18n.global.locale.value = themeConfig.value.globalI18n;
  80. }