mirror of
https://gitee.com/bootx/dax-pay-ui
synced 2026-08-11 23:25:33 +08:00
fix(i18n): 语言切换后保持菜单标题语种正确
loadMessages 并入对应 menu-titles;inject 不再把简体挂到短码 zh,避免 zh-TW/zh-HK 回退成简体。
This commit is contained in:
@@ -8,21 +8,30 @@ import zhCnMenuTitles from '../../locales/menu-titles/zh-CN.json';
|
||||
import enUsMenuTitles from '../../locales/menu-titles/en-US.json';
|
||||
import zhHkMenuTitles from '../../locales/menu-titles/zh-HK.json';
|
||||
import zhTwMenuTitles from '../../locales/menu-titles/zh-TW.json';
|
||||
import jaJpMenuTitles from '../../locales/menu-titles/ja-JP.json';
|
||||
import koKrMenuTitles from '../../locales/menu-titles/ko-KR.json';
|
||||
|
||||
/**
|
||||
* 注入菜单标题国际化文案
|
||||
* 数据源为静态语言包文件(menu-titles/*.json),不依赖 DB title_cn/title_en 列
|
||||
* DB 仅存 i18n_key,文案真相源在语言包
|
||||
*
|
||||
* 写入完整 locale(zh-CN/en-US/zh-TW/zh-HK)与短码(zh/en),避免 fallback 差异导致侧栏标题未命中
|
||||
* 仅写入完整 locale(zh-CN/en-US/zh-TW/zh-HK/ja-JP/ko-KR)。
|
||||
* 禁止把简体挂到短码 `zh`:vue-i18n 对 zh-TW/zh-HK 会回退 zh,会导致繁体界面菜单标题变简体。
|
||||
* en/ja/ko 短码可保留(与完整 locale 文案同语种,回退无害)。
|
||||
* 语言切换时由 locales/loadMessages 再次并入对应 menu-titles,与本函数双保险。
|
||||
*/
|
||||
export function injectMenuI18n() {
|
||||
i18n.global.mergeLocaleMessage('zh-CN', zhCnMenuTitles);
|
||||
i18n.global.mergeLocaleMessage('zh', zhCnMenuTitles);
|
||||
// 不注入短码 zh,避免 zh-TW/zh-HK 回退到简体
|
||||
i18n.global.mergeLocaleMessage('en-US', enUsMenuTitles);
|
||||
i18n.global.mergeLocaleMessage('en', enUsMenuTitles);
|
||||
i18n.global.mergeLocaleMessage('zh-TW', zhTwMenuTitles);
|
||||
i18n.global.mergeLocaleMessage('zh-HK', zhHkMenuTitles);
|
||||
i18n.global.mergeLocaleMessage('ja-JP', jaJpMenuTitles);
|
||||
i18n.global.mergeLocaleMessage('ja', jaJpMenuTitles);
|
||||
i18n.global.mergeLocaleMessage('ko-KR', koKrMenuTitles);
|
||||
i18n.global.mergeLocaleMessage('ko', koKrMenuTitles);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,26 +11,67 @@ import { $t, setupI18n as coreSetup, loadLocalesMapFromDir } from '@vben/locales
|
||||
import { preferences } from '@vben/preferences';
|
||||
|
||||
import antdEnLocale from 'antdv-next/dist/locale/en_US';
|
||||
import antdJaLocale from 'antdv-next/dist/locale/ja_JP';
|
||||
import antdKoLocale from 'antdv-next/dist/locale/ko_KR';
|
||||
import antdHkLocale from 'antdv-next/dist/locale/zh_HK';
|
||||
import antdTwLocale from 'antdv-next/dist/locale/zh_TW';
|
||||
import antdDefaultLocale from 'antdv-next/dist/locale/zh_CN';
|
||||
import dayjs from 'dayjs';
|
||||
import { VxeUI } from 'vxe-table';
|
||||
|
||||
// 菜单标题包:在 loadMessages 内并入,避免与 menu.api 循环依赖;与 injectMenuI18n 同源
|
||||
import enUsMenuTitles from './menu-titles/en-US.json';
|
||||
import jaJpMenuTitles from './menu-titles/ja-JP.json';
|
||||
import koKrMenuTitles from './menu-titles/ko-KR.json';
|
||||
import zhCnMenuTitles from './menu-titles/zh-CN.json';
|
||||
import zhHkMenuTitles from './menu-titles/zh-HK.json';
|
||||
import zhTwMenuTitles from './menu-titles/zh-TW.json';
|
||||
|
||||
const antdLocale = ref<Locale>(antdDefaultLocale);
|
||||
|
||||
const modules = import.meta.glob('./langs/**/*.json');
|
||||
|
||||
const localesMap = loadLocalesMapFromDir(/\.\/langs\/([^/]+)\/(.*)\.json$/, modules);
|
||||
|
||||
/** 按完整 locale 取菜单标题(flat key),不注入短码 zh,防止繁体回退简体 */
|
||||
function getMenuTitlesFor(lang: SupportedLanguagesType): Record<string, string> {
|
||||
switch (lang) {
|
||||
case 'en-US': {
|
||||
return enUsMenuTitles as Record<string, string>;
|
||||
}
|
||||
case 'zh-TW': {
|
||||
return zhTwMenuTitles as Record<string, string>;
|
||||
}
|
||||
case 'zh-HK': {
|
||||
return zhHkMenuTitles as Record<string, string>;
|
||||
}
|
||||
case 'ja-JP': {
|
||||
return jaJpMenuTitles as Record<string, string>;
|
||||
}
|
||||
case 'ko-KR': {
|
||||
return koKrMenuTitles as Record<string, string>;
|
||||
}
|
||||
case 'zh-CN':
|
||||
default: {
|
||||
return zhCnMenuTitles as Record<string, string>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载应用特有的语言包
|
||||
* 这里也可以改造为从服务端获取翻译数据
|
||||
* 每次语言切换都会走这里:业务 langs + menu-titles 一并 merge,
|
||||
* 避免 setLocaleMessage 冲掉登录时 inject 的菜单标题后回退到错误语种
|
||||
* @param lang
|
||||
*/
|
||||
async function loadMessages(lang: SupportedLanguagesType) {
|
||||
const [appLocaleMessages] = await Promise.all([localesMap[lang]?.(), loadThirdPartyMessage(lang)]);
|
||||
return appLocaleMessages?.default;
|
||||
const base = (appLocaleMessages?.default ?? {}) as Record<string, unknown>;
|
||||
// 菜单标题真相源:menu-titles/{lang}.json,与 injectMenuI18n 同源
|
||||
return {
|
||||
...base,
|
||||
...getMenuTitlesFor(lang),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,6 +105,14 @@ async function loadDayjsLocale(lang: SupportedLanguagesType) {
|
||||
locale = await import('dayjs/locale/zh-hk');
|
||||
break;
|
||||
}
|
||||
case 'ja-JP': {
|
||||
locale = await import('dayjs/locale/ja');
|
||||
break;
|
||||
}
|
||||
case 'ko-KR': {
|
||||
locale = await import('dayjs/locale/ko');
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
locale = await import('dayjs/locale/zh-cn');
|
||||
}
|
||||
@@ -97,6 +146,14 @@ async function loadAntdLocale(lang: SupportedLanguagesType) {
|
||||
antdLocale.value = antdHkLocale;
|
||||
break;
|
||||
}
|
||||
case 'ja-JP': {
|
||||
antdLocale.value = antdJaLocale;
|
||||
break;
|
||||
}
|
||||
case 'ko-KR': {
|
||||
antdLocale.value = antdKoLocale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +179,14 @@ async function loadVxeLocale(lang: SupportedLanguagesType) {
|
||||
VxeUI.setLanguage('zh-HK');
|
||||
break;
|
||||
}
|
||||
case 'ja-JP': {
|
||||
VxeUI.setLanguage('ja-JP');
|
||||
break;
|
||||
}
|
||||
case 'ko-KR': {
|
||||
VxeUI.setLanguage('ko-KR');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { $t, i18n } from '#/locales';
|
||||
import enUsPerm from '../locales/langs/en-US/perm.json';
|
||||
import jaJpPerm from '../locales/langs/ja-JP/perm.json';
|
||||
import koKrPerm from '../locales/langs/ko-KR/perm.json';
|
||||
import zhCnPerm from '../locales/langs/zh-CN/perm.json';
|
||||
import zhHkPerm from '../locales/langs/zh-HK/perm.json';
|
||||
import zhTwPerm from '../locales/langs/zh-TW/perm.json';
|
||||
@@ -17,7 +19,8 @@ function toFlatPermMessages(bag: Record<string, string>): Record<string, string>
|
||||
|
||||
/**
|
||||
* 注入权限码国际化文案(flat key)
|
||||
* 写入 zh-CN/en-US/zh-TW/zh-HK 与短码 zh/en
|
||||
* 写入完整 locale zh-CN/en-US/zh-TW/zh-HK/ja-JP/ko-KR,以及短码 en/ja/ko
|
||||
* 禁止把简体挂到短码 `zh`:vue-i18n 对 zh-TW/zh-HK 会回退 zh,繁体界面会串成简体
|
||||
* 可重复调用:语言切换会 setLocaleMessage 覆盖整包,需在翻译前再次 merge
|
||||
*/
|
||||
export function injectPermI18n() {
|
||||
@@ -25,12 +28,18 @@ export function injectPermI18n() {
|
||||
const en = toFlatPermMessages(enUsPerm as Record<string, string>);
|
||||
const tw = toFlatPermMessages(zhTwPerm as Record<string, string>);
|
||||
const hk = toFlatPermMessages(zhHkPerm as Record<string, string>);
|
||||
const ja = toFlatPermMessages(jaJpPerm as Record<string, string>);
|
||||
const ko = toFlatPermMessages(koKrPerm as Record<string, string>);
|
||||
i18n.global.mergeLocaleMessage('zh-CN', zh);
|
||||
i18n.global.mergeLocaleMessage('zh', zh);
|
||||
// 不注入短码 zh,避免 zh-TW/zh-HK 回退到简体
|
||||
i18n.global.mergeLocaleMessage('en-US', en);
|
||||
i18n.global.mergeLocaleMessage('en', en);
|
||||
i18n.global.mergeLocaleMessage('zh-TW', tw);
|
||||
i18n.global.mergeLocaleMessage('zh-HK', hk);
|
||||
i18n.global.mergeLocaleMessage('ja-JP', ja);
|
||||
i18n.global.mergeLocaleMessage('ja', ja);
|
||||
i18n.global.mergeLocaleMessage('ko-KR', ko);
|
||||
i18n.global.mergeLocaleMessage('ko', ko);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user