refactor: 完成多语言国际化全量替换与补充
1. 新增大量中英文语言包文件,覆盖自定义组件、页面、工具类的文案 2. 替换硬编码文本为多语言调用,统一全局文案管理 3. 优化语言包结构,拆分公共模块与业务模块 4. 修复部分语言加载与国际化适配问题
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
export const langConfig = {
|
||||
// 语言列表 — 与后端 Lang.php::overrides() 白名单对齐
|
||||
// 增删需要后端同步改 LangOverrideModel::normalizeAppType 旁的 $allow_lang
|
||||
langList: ['zh-cn', 'en-us', 'zh-tw', 'ja-jp', 'ko-kr', 'th-th', 'vi-vn', 'id-id', 'es-es', 'fr-fr', 'de-de', 'ru-ru', 'ar-sa', 'pt-pt', 'it-it', 'tr-tr'],
|
||||
langList: ['zh-cn', 'en-us'],
|
||||
// 默认语言
|
||||
defaultLang: 'zh-cn',
|
||||
// 语言包加载方式:'lazy'(按需加载)或 'preload'(预加载)
|
||||
|
||||
@@ -11,7 +11,13 @@ try {
|
||||
uniacid: site.uniacid,
|
||||
}
|
||||
} else {
|
||||
console.warn('小程序发行环境下,必须配置site.js文件, 不然将使用默认配置,影响小程序定制分发!');
|
||||
// 惰性加载 Lang 避免循环依赖(lang.js 引用了 config.js)
|
||||
try {
|
||||
const Lang = require('@/common/js/lang.js').default;
|
||||
console.warn(Lang.lang('common.config.siteJsNotConfigured'));
|
||||
} catch (e) {
|
||||
console.warn('小程序发行环境下,必须配置site.js文件,不然将使用默认配置,影响小程序定制分发!');
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
// #endif
|
||||
|
||||
@@ -100,7 +100,7 @@ export class CustomerService {
|
||||
|
||||
if (!config || !config.type) {
|
||||
result.isValid = false;
|
||||
result.errors.push('客服类型未配置');
|
||||
result.errors.push(this.vm.$lang('customerService.serviceTypeNotConfigured'));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,10 @@ export default {
|
||||
isEnEnv() {
|
||||
return this.$langConfig.getCurrentLocale() === 'en-us';
|
||||
},
|
||||
// 是否是非中文环境(用于多语言商品名/字段切换)
|
||||
isNotZhEnv() {
|
||||
return this.$langConfig.getCurrentLocale() !== 'zh-cn';
|
||||
},
|
||||
// 动态判断:当前页面是否是 TabBar 根页面(tab 根页不应显示返回按钮)
|
||||
isTabRootPage() {
|
||||
const tabBarList = this.$store.state.tabBarList;
|
||||
|
||||
@@ -261,7 +261,7 @@ export class NavigationHelper {
|
||||
}
|
||||
|
||||
// 显示用户友好的错误信息
|
||||
this.showError(Lang.lang('navigation.serviceUnavailable'))
|
||||
this.showError(Lang.lang('common.navigation.serviceUnavailable'))
|
||||
}
|
||||
|
||||
// 显示错误提示
|
||||
|
||||
@@ -149,28 +149,28 @@ export const Platform = {
|
||||
// #ifdef H5
|
||||
if (platform === 'h5') {
|
||||
cachedAppTypeName = this.isWeiXin()
|
||||
? _t('platform.wechatOfficialAccount', '微信公众号')
|
||||
: _t('platform.h5', 'H5');
|
||||
? _t('common.platform.wechatOfficialAccount', '微信公众号')
|
||||
: _t('common.platform.h5', 'H5');
|
||||
return cachedAppTypeName;
|
||||
}
|
||||
// #endif
|
||||
|
||||
const platformNameMap = {
|
||||
weapp: _t('platform.wechatMiniProgram', '微信小程序'),
|
||||
alipay: _t('platform.alipayMiniProgram', '支付宝小程序'),
|
||||
baidu: _t('platform.baiduMiniProgram', '百度小程序'),
|
||||
toutiao: _t('platform.toutiaoMiniProgram', '头条小程序'),
|
||||
qq: _t('platform.qqMiniProgram', 'QQ小程序'),
|
||||
kuaishou: _t('platform.kuaishouMiniProgram', '快手小程序'),
|
||||
jd: _t('platform.jdMiniProgram', '京东小程序'),
|
||||
'360': _t('platform.miniProgram360', '360小程序'),
|
||||
xhs: _t('platform.xhsMiniProgram', '小红书小程序'),
|
||||
harmony: _t('platform.harmonyService', '鸿蒙元服务'),
|
||||
app: _t('platform.app', 'APP'),
|
||||
pc: _t('platform.pc', 'PC端'),
|
||||
weapp: _t('common.platform.wechatMiniProgram', '微信小程序'),
|
||||
alipay: _t('common.platform.alipayMiniProgram', '支付宝小程序'),
|
||||
baidu: _t('common.platform.baiduMiniProgram', '百度小程序'),
|
||||
toutiao: _t('common.platform.toutiaoMiniProgram', '头条小程序'),
|
||||
qq: _t('common.platform.qqMiniProgram', 'QQ小程序'),
|
||||
kuaishou: _t('common.platform.kuaishouMiniProgram', '快手小程序'),
|
||||
jd: _t('common.platform.jdMiniProgram', '京东小程序'),
|
||||
'360': _t('common.platform.miniProgram360', '360小程序'),
|
||||
xhs: _t('common.platform.xhsMiniProgram', '小红书小程序'),
|
||||
harmony: _t('common.platform.harmonyService', '鸿蒙元服务'),
|
||||
app: _t('common.platform.app', 'APP'),
|
||||
pc: _t('common.platform.pc', 'PC端'),
|
||||
};
|
||||
|
||||
cachedAppTypeName = platformNameMap[platform] || _t('platform.unknown', '未知平台');
|
||||
cachedAppTypeName = platformNameMap[platform] || _t('common.platform.unknown', '未知平台');
|
||||
return cachedAppTypeName;
|
||||
},
|
||||
|
||||
|
||||
@@ -433,21 +433,46 @@ export default {
|
||||
* @param {string} mode 模式 navigateTo、redirectTo、reLaunch、tabbar, 默认navigateTo
|
||||
*/
|
||||
redirectTo(to, param = {}, mode = 'navigateTo') {
|
||||
let url = to;
|
||||
// 1. 拆分 path 与已有 query,避免后面 indexOf('?') 误判
|
||||
const queryIdx = to.indexOf('?');
|
||||
let path = queryIdx === -1 ? to : to.substring(0, queryIdx);
|
||||
const existingParams = {};
|
||||
|
||||
if (queryIdx !== -1) {
|
||||
to.substring(queryIdx + 1).split('&').forEach(kv => {
|
||||
if (!kv) return;
|
||||
// 用 indexOf('=') 取首个等号,兼容 value 里带 '=' 的场景
|
||||
const eqIdx = kv.indexOf('=');
|
||||
const k = eqIdx === -1 ? kv : kv.substring(0, eqIdx);
|
||||
const v = eqIdx === -1 ? '' : kv.substring(eqIdx + 1);
|
||||
if (k) existingParams[k] = v;
|
||||
});
|
||||
}
|
||||
|
||||
// 2. 合并 param:同 key 时新值覆盖旧值,杜绝 ?name=A&name=B 这种重复
|
||||
const merged = Object.assign({}, existingParams, param || {});
|
||||
|
||||
// 3. 统一编码。decode -> encode 双向 roundtrip 兼具两种语义:
|
||||
// - 调用方传原始值(/pages_tool/index/diy?name=XXX) -> encode 后 %2F%3F...
|
||||
// - 调用方已传编码值(%2F%3F...) -> decode 还原 -> encode 还原回去,不会被二次编码
|
||||
// - 任何不能 decode 的非法序列(如裸 %) 走 catch 路径,直接 encode
|
||||
const safeEncode = (v) => {
|
||||
const s = v == null ? '' : String(v);
|
||||
try {
|
||||
return encodeURIComponent(decodeURIComponent(s));
|
||||
} catch (e) {
|
||||
return encodeURIComponent(s);
|
||||
}
|
||||
};
|
||||
const queryStr = Object.keys(merged)
|
||||
.map(k => safeEncode(k) + '=' + safeEncode(merged[k]))
|
||||
.join('&');
|
||||
|
||||
let url = path + (queryStr ? '?' + queryStr : '');
|
||||
|
||||
// 替换url中的前缀
|
||||
url = adaptSubpackageUrl(url);
|
||||
|
||||
if (param != undefined) {
|
||||
Object.keys(param).forEach(function (key) {
|
||||
if (url.indexOf('?') != -1) {
|
||||
url += "&" + key + "=" + param[key];
|
||||
} else {
|
||||
url += "?" + key + "=" + param[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 针对tabBar.list中的路径,直接切换tabBar
|
||||
for (let i = 0; i < systemTabBarList.length; i++) {
|
||||
const tabBarUrl = systemTabBarList[i];
|
||||
@@ -897,7 +922,7 @@ export default {
|
||||
}
|
||||
|
||||
if (!isObject(obj)) {
|
||||
throw new Error('obj 不是一个对象!')
|
||||
throw new Error(Lang.lang('util.deepCloneNotObject'))
|
||||
}
|
||||
//判断传进来的是对象还是数组
|
||||
let isArray = Array.isArray(obj)
|
||||
@@ -968,7 +993,7 @@ export default {
|
||||
// #ifdef MP
|
||||
this.redirectTo('/pages_tool/webview/webview', {
|
||||
...link,
|
||||
src: encodeURIComponent(url)
|
||||
src: url
|
||||
});
|
||||
// #endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user