diff --git a/src/App.vue b/src/App.vue
index 057bf18..0d585fa 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -7,7 +7,7 @@
diff --git a/src/locales/index.ts b/src/locales/index.ts
index 71c4aa3..4cb7cda 100644
--- a/src/locales/index.ts
+++ b/src/locales/index.ts
@@ -1,29 +1,12 @@
-import { createI18n } from 'vue-i18n'
-import el_zh_cn from 'element-plus/dist/locale/zh-cn'
-import el_en from 'element-plus/dist/locale/en'
-
+import {createI18n} from 'vue-i18n'
import config from "@/config"
-import tools from '@/utils/tools'
-import zh_cn from '@/locales/lang/zh-cn'
-import en from '@/locales/lang/en'
-
-const messages = {
- 'zh-cn': {
- ...el_zh_cn,
- ...zh_cn
- },
- 'en': {
- ...el_en,
- ...en
- }
-}
const i18n = createI18n({
- legacy: false,
- fallbackLocale: 'zh-cn',
- locale: tools.data.get("APP_LANG") || config.LANG,
- globalInjection: true,
- messages,
+ legacy: false,
+ fallbackLocale: config.LANG,
+ locale: config.LANG,
+ globalInjection: true,
+ messages: {}
})
export default i18n;
diff --git a/src/locales/lang/ja.ts b/src/locales/lang/ja.ts
new file mode 100644
index 0000000..b1c6ea4
--- /dev/null
+++ b/src/locales/lang/ja.ts
@@ -0,0 +1 @@
+export default {}
diff --git a/src/locales/lang/ms.ts b/src/locales/lang/ms.ts
new file mode 100644
index 0000000..b1c6ea4
--- /dev/null
+++ b/src/locales/lang/ms.ts
@@ -0,0 +1 @@
+export default {}
diff --git a/src/locales/lang/vi.ts b/src/locales/lang/vi.ts
new file mode 100644
index 0000000..b1c6ea4
--- /dev/null
+++ b/src/locales/lang/vi.ts
@@ -0,0 +1 @@
+export default {}
diff --git a/src/locales/languages.ts b/src/locales/languages.ts
new file mode 100644
index 0000000..4eaca0a
--- /dev/null
+++ b/src/locales/languages.ts
@@ -0,0 +1,22 @@
+import el_zh_cn from "element-plus/dist/locale/zh-cn";
+import el_en from "element-plus/dist/locale/en";
+import el_vi from "element-plus/dist/locale/vi";
+import el_ms from "element-plus/dist/locale/ms";
+import el_ja from "element-plus/dist/locale/ja";
+
+import lang_zh_cn from "@/locales/lang/zh-cn";
+import lang_en from "@/locales/lang/en";
+import lang_ja from "@/locales/lang/ja";
+import lang_vi from "@/locales/lang/vi";
+import lang_ms from "@/locales/lang/ms";
+
+export const LANGUAGE_MAP: Record<
+ string,
+ { el: any; local: any }
+> = {
+ "zh-cn": {el: el_zh_cn, local: lang_zh_cn},
+ en: {el: el_en, local: lang_en},
+ ja: {el: el_ja, local: lang_ja},
+ vi: {el: el_vi, local: lang_vi},
+ ms: {el: el_ms, local: lang_ms},
+};
diff --git a/src/locales/setup.ts b/src/locales/setup.ts
new file mode 100644
index 0000000..2ff7f27
--- /dev/null
+++ b/src/locales/setup.ts
@@ -0,0 +1,22 @@
+import i18n from "@/locales/index";
+import config from "@/config";
+import tools from "@/utils/tools";
+import api from "@/api";
+import {LANGUAGE_MAP} from "@/locales/languages";
+
+export async function setupI18n(locale: string = null) {
+ locale = locale || tools.data.get("APP_LANG") || config.LANG;
+ const langConfig = LANGUAGE_MAP[locale];
+ // 先从缓存中取
+ var messages = tools.data.get("LOCALE:" + locale)
+ if (!messages) {
+ const res = await api.system.translation.load({locale});
+ messages = tools.deepMerge(langConfig.el, langConfig.local, res['data'] || {})
+ tools.data.set("LOCALE:" + locale, messages, 86400)
+ }
+ // 设置语言包内容
+ i18n.global.setLocaleMessage(locale, messages);
+ // 切换语言
+ i18n.global.locale.value = locale;
+ return i18n;
+}
diff --git a/src/main.ts b/src/main.ts
index 74d9a91..0f41a26 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,21 +1,29 @@
-import { createApp } from 'vue'
+import {createApp} from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import 'element-plus/theme-chalk/display.css'
import i18n from './locales'
+import {setupI18n} from "@/locales/setup"
import App from './App.vue'
-
import pinia from './store'
import router from './router'
import pi from './pi'
-const app = createApp(App);
+async function bootstrap() {
+ await setupI18n();
+ const app = createApp(App);
+
+ app.use(pinia);
+ app.use(router);
+ app.use(ElementPlus);
+ app.use(i18n);
+ app.use(pi);
+
+ //挂载app
+ app.mount('#app');
+}
+
+bootstrap()
+
-app.use(pinia);
-app.use(router);
-app.use(ElementPlus);
-app.use(i18n);
-app.use(pi);
-//挂载app
-app.mount('#app');
diff --git a/src/utils/request.ts b/src/utils/request.ts
index 0ac447d..ffcf7b0 100644
--- a/src/utils/request.ts
+++ b/src/utils/request.ts
@@ -19,6 +19,9 @@ axios.interceptors.request.use((config) => {
config.params = config.params || {};
config.params['_'] = new Date().getTime();
}
+ // 多语言
+ const lang = tools.data.get("APP_LANG") || 'zh-cn'
+ config.headers['Accept-Language'] = lang
return config;
})
//响应拦截
diff --git a/src/utils/tools.ts b/src/utils/tools.ts
index dc99e3a..fd051f9 100644
--- a/src/utils/tools.ts
+++ b/src/utils/tools.ts
@@ -214,6 +214,28 @@ const tools = {
}
}
}
+ },
+ // 深度合并数据
+ deepMerge: (...objects: any[]) => {
+ const result: any = {}
+ for (const obj of objects) {
+ tools.mergeObject(result, obj)
+ }
+ return result
+ },
+ mergeObject: (target: any, source: any) => {
+ if (!source || typeof source !== 'object') return
+ for (const key in source) {
+ const value = source[key]
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
+ if (!target[key] || typeof target[key] !== 'object') {
+ target[key] = {}
+ }
+ tools.mergeObject(target[key], value)
+ } else {
+ target[key] = value
+ }
+ }
}
}
export default tools
diff --git a/src/views/system/login/index.vue b/src/views/system/login/index.vue
index 2e632e2..bc020c3 100644
--- a/src/views/system/login/index.vue
+++ b/src/views/system/login/index.vue
@@ -71,6 +71,7 @@