文章目录
参考资料
https://doc.vben.pro/guide/in-depth/locale.html
Accept-Language
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Reference/Headers/Accept-Language
提示词
bash
当前使用loadMessages加载了应用的本地语言包.
请你修改这个函数,优先加载网络语言包,当网络语言包不可用时,再换为加载本地语言包。
网络语言包位置为:http://127.0.0.1:5500/langs/**/*.json
请复用modules来确定网络语言包文件名。
typescript
loadNetworkMessages返回的数据中,缺少以文件名作为包开头,导致数据不对。
生成的代码
typescript
/** 网络语言包基础地址(通过 Vite proxy 代理,避免跨域) */
const NETWORK_LANGS_BASE_URL = '/langs';
/**
* 从网络加载语言包,复用 modules 确定文件名
* @param lang
*/
async function loadNetworkMessages(
lang: SupportedLanguagesType,
): Promise<Record<string, any>> {
// 从 modules 中提取当前语言对应的文件相对路径(langs/zh-CN/page.json)
const filePaths = Object.keys(modules)
.filter((key) => key.startsWith(`./langs/${lang}/`))
.map((key) => key.replace('./langs/', ''));
if (filePaths.length === 0) {
throw new Error(`No network language files found for ${lang}`);
}
const responses = await Promise.all(
filePaths.map(async (path) => {
const url = `${NETWORK_LANGS_BASE_URL}/${path}`;
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch ${url}: HTTP ${response.status}`);
}
// 提取文件名(不含扩展名)作为键名,与 loadLocalesMapFromDir 行为一致
const fileName = path.replace(/^.*\/(.+)\.json$/, '$1');
return { fileName, data: await response.json() };
}),
);
// 合并所有 JSON 文件为一个对象,以文件名作为包名
const messages: Record<string, any> = {};
for (const { fileName, data } of responses) {
messages[fileName] = data;
}
return messages;
}
/**
* 加载应用特有的语言包
* 优先从网络加载(http://127.0.0.1:5500/langs/),
* 网络不可用时回退到本地语言包
* @param lang
*/
async function loadMessages(lang: SupportedLanguagesType) {
const [appLocaleMessages] = await Promise.all([
(async () => {
try {
const messages = await loadNetworkMessages(lang);
//console.warn(`Successfully loaded network language files for ${lang}`);
return { default: messages };
} catch {
// 网络加载失败,回退到本地语言包
//console.warn(`网络加载失败,回退到本地语言包`);
return localesMap[lang]?.();
}
})(),
loadThirdPartyMessage(lang),
]);
return appLocaleMessages?.default;
}