From 4ae21c5d7af5e7f9ba12691f5497e6f155479a22 Mon Sep 17 00:00:00 2001 From: ZF sun <34314687@qq.com> Date: Fri, 26 Jun 2026 17:32:35 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=AE=8C=E6=88=90=E5=A4=9A?= =?UTF-8?q?=E8=AF=AD=E8=A8=80=E5=9B=BD=E9=99=85=E5=8C=96=E5=85=A8=E9=87=8F?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E4=B8=8E=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增大量中英文语言包文件,覆盖自定义组件、页面、工具类的文案 2. 替换硬编码文本为多语言调用,统一全局文案管理 3. 优化语言包结构,拆分公共模块与业务模块 4. 修复部分语言加载与国际化适配问题 --- App.vue | 8 +- common/js/config-external.js | 2 +- common/js/config.js | 8 +- common/js/customer-service.js | 2 +- common/js/golbalConfig.js | 4 + common/js/navigation.js | 2 +- common/js/platform.js | 30 +- common/js/util.js | 51 +- components-diy/diy-goods-list.vue | 6 +- components-diy/diy-index-page.vue | 13 +- components-diy/diy-notice.vue | 4 +- components-diy/diy-video.vue | 4 +- components/mescroll/mescroll-uni-option.js | 72 +-- components/mescroll/mescroll-uni.js | 22 +- components/yuyue-date/yuyue-date.vue | 36 +- lang/en-us/ai-chat/index.js | 19 +- lang/en-us/article/detail.js | 10 +- lang/en-us/article/list.js | 6 +- lang/en-us/common.js | 43 +- lang/en-us/components-diy/diy-category.js | 19 +- lang/en-us/components-diy/diy-goods-list.js | 7 + lang/en-us/components-diy/diy-index-page.js | 14 + lang/en-us/components-diy/diy-notice.js | 4 + lang/en-us/components-diy/diy-store.js | 18 +- lang/en-us/components-diy/diy-video.js | 6 + lang/en-us/components/mescroll.js | 22 + lang/en-us/fenxiao/child_fenxiao.js | 14 + lang/en-us/files/list.js | 5 + lang/en-us/form/form.js | 15 + lang/en-us/member/bind_mobile.js | 48 ++ lang/en-us/member/cancellation.js | 5 +- lang/en-us/member/card_log.js | 25 + lang/en-us/member/collection.js | 7 +- lang/en-us/member/modify_face.js | 9 +- lang/en-us/member/withdrawal.js | 3 +- lang/en-us/merch/list.js | 31 ++ lang/en-us/order/activist.js | 5 + lang/en-us/order/invoice.js | 91 ++++ lang/en-us/order/logistics.js | 18 +- lang/en-us/order/refund_detail.js | 6 + lang/en-us/seal/medium/detail.js | 36 +- lang/en-us/seal/medium/search.js | 16 +- lang/zh-cn/ai-chat/index.js | 19 +- lang/zh-cn/article/detail.js | 8 +- lang/zh-cn/article/list.js | 2 +- lang/zh-cn/common.js | 67 ++- lang/zh-cn/components-diy/diy-category.js | 19 +- lang/zh-cn/components-diy/diy-goods-list.js | 7 + lang/zh-cn/components-diy/diy-index-page.js | 14 + lang/zh-cn/components-diy/diy-notice.js | 4 + lang/zh-cn/components-diy/diy-store.js | 18 +- lang/zh-cn/components-diy/diy-video.js | 6 + lang/zh-cn/components/mescroll.js | 22 + lang/zh-cn/fenxiao/child_fenxiao.js | 14 + lang/zh-cn/files/list.js | 5 + lang/zh-cn/form/form.js | 15 + lang/zh-cn/member/bind_mobile.js | 48 ++ lang/zh-cn/member/cancellation.js | 9 +- lang/zh-cn/member/card_log.js | 25 + lang/zh-cn/member/collection.js | 5 +- lang/zh-cn/member/modify_face.js | 7 +- lang/zh-cn/member/withdrawal.js | 3 +- lang/zh-cn/merch/list.js | 31 ++ lang/zh-cn/order/activist.js | 5 + lang/zh-cn/order/invoice.js | 91 ++++ lang/zh-cn/order/logistics.js | 14 +- lang/zh-cn/order/refund_detail.js | 6 + lang/zh-cn/seal/medium/detail.js | 36 +- lang/zh-cn/seal/medium/search.js | 16 +- pages_order/list.vue | 10 +- pages_promotion/fenxiao/child_fenxiao.vue | 12 +- pages_promotion/merch/list.vue | 289 +++++++++++ pages_tool/ai-chat/ai-chat-message.vue | 12 +- pages_tool/ai-chat/index.vue | 14 +- pages_tool/article/detail.vue | 6 +- pages_tool/article/list.vue | 8 +- pages_tool/files/list.vue | 10 +- pages_tool/form/form.vue | 8 +- pages_tool/member/bind_mobile.vue | 380 ++++++++++++++ pages_tool/member/cancellation.vue | 6 +- pages_tool/member/card_log.vue | 314 ++++++++++++ pages_tool/member/collection.vue | 4 +- pages_tool/member/modify_face.vue | 12 +- pages_tool/member/public/js/collection.js | 2 +- pages_tool/member/withdrawal.vue | 2 +- pages_tool/order/activist.vue | 4 +- pages_tool/order/invoice.vue | 518 ++++++++++++++++++++ pages_tool/order/logistics.vue | 6 +- pages_tool/order/public/js/refundMethod.js | 4 +- pages_tool/seal/medium/detail.vue | 20 +- scripts/i18n-check.js | 8 +- 91 files changed, 2650 insertions(+), 281 deletions(-) create mode 100644 lang/en-us/components-diy/diy-goods-list.js create mode 100644 lang/en-us/components-diy/diy-index-page.js create mode 100644 lang/en-us/components-diy/diy-notice.js create mode 100644 lang/en-us/components-diy/diy-video.js create mode 100644 lang/en-us/components/mescroll.js create mode 100644 lang/en-us/form/form.js create mode 100644 lang/en-us/member/bind_mobile.js create mode 100644 lang/en-us/member/card_log.js create mode 100644 lang/en-us/order/invoice.js create mode 100644 lang/zh-cn/components-diy/diy-goods-list.js create mode 100644 lang/zh-cn/components-diy/diy-index-page.js create mode 100644 lang/zh-cn/components-diy/diy-notice.js create mode 100644 lang/zh-cn/components-diy/diy-video.js create mode 100644 lang/zh-cn/components/mescroll.js create mode 100644 lang/zh-cn/form/form.js create mode 100644 lang/zh-cn/member/bind_mobile.js create mode 100644 lang/zh-cn/member/card_log.js create mode 100644 lang/zh-cn/order/invoice.js create mode 100644 pages_promotion/merch/list.vue create mode 100644 pages_tool/member/bind_mobile.vue create mode 100644 pages_tool/member/card_log.vue create mode 100644 pages_tool/order/invoice.vue diff --git a/App.vue b/App.vue index 9945a8b..3605199 100644 --- a/App.vue +++ b/App.vue @@ -91,8 +91,8 @@ updateManager.onUpdateReady(function(res) { uni.showModal({ - title: '更新提示', - content: '新版本已经准备好,是否重启应用?', + title: Lang.lang('common.updateTip'), + content: Lang.lang('common.updateReady'), success(res) { if (res.confirm) { // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启 @@ -118,8 +118,8 @@ uni.onNetworkStatusChange(function(res) { if (!res.isConnected) { uni.showModal({ - title: '网络失去链接', - content: '请检查网络链接', + title: Lang.lang('common.networkLost'), + content: Lang.lang('common.networkCheck'), showCancel: false }); } diff --git a/common/js/config-external.js b/common/js/config-external.js index 14cf379..f63185c 100644 --- a/common/js/config-external.js +++ b/common/js/config-external.js @@ -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'(预加载) diff --git a/common/js/config.js b/common/js/config.js index 9ff879e..6ec955d 100644 --- a/common/js/config.js +++ b/common/js/config.js @@ -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 diff --git a/common/js/customer-service.js b/common/js/customer-service.js index efdb244..507eed2 100644 --- a/common/js/customer-service.js +++ b/common/js/customer-service.js @@ -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; } diff --git a/common/js/golbalConfig.js b/common/js/golbalConfig.js index 6890626..98fb276 100644 --- a/common/js/golbalConfig.js +++ b/common/js/golbalConfig.js @@ -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; diff --git a/common/js/navigation.js b/common/js/navigation.js index b0e1fd9..00e0f70 100644 --- a/common/js/navigation.js +++ b/common/js/navigation.js @@ -261,7 +261,7 @@ export class NavigationHelper { } // 显示用户友好的错误信息 - this.showError(Lang.lang('navigation.serviceUnavailable')) + this.showError(Lang.lang('common.navigation.serviceUnavailable')) } // 显示错误提示 diff --git a/common/js/platform.js b/common/js/platform.js index 4da83d4..8dfafb2 100644 --- a/common/js/platform.js +++ b/common/js/platform.js @@ -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; }, diff --git a/common/js/util.js b/common/js/util.js index 5ef1be1..b37e28b 100644 --- a/common/js/util.js +++ b/common/js/util.js @@ -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 diff --git a/components-diy/diy-goods-list.vue b/components-diy/diy-goods-list.vue index 61ea2d1..5a4b10f 100644 --- a/components-diy/diy-goods-list.vue +++ b/components-diy/diy-goods-list.vue @@ -60,7 +60,7 @@ - 已售{{ item.sale_num }}{{ item.unit ? item.unit : '件' }} + {{ $lang('components-diy.diyGoodsList.soldCount', { count: item.sale_num, unit: item.unit || $lang('components-diy.diyGoodsList.soldUnit') }) }} @@ -168,7 +168,7 @@ - 已售{{ item.sale_num }}{{ item.unit ? item.unit : '件' }} + {{ $lang('components-diy.diyGoodsList.soldCount', { count: item.sale_num, unit: item.unit || $lang('components-diy.diyGoodsList.soldUnit') }) }} @@ -238,7 +238,7 @@ - 已售{{ dataItem.sale_num }}{{ dataItem.unit ? dataItem.unit : '件' }} + {{ $lang('components-diy.diyGoodsList.soldCount', { count: dataItem.sale_num, unit: dataItem.unit || $lang('components-diy.diyGoodsList.soldUnit') }) }} diff --git a/components-diy/diy-index-page.vue b/components-diy/diy-index-page.vue index 46f032d..d45207b 100644 --- a/components-diy/diy-index-page.vue +++ b/components-diy/diy-index-page.vue @@ -146,14 +146,14 @@ {{ $lang('common.currencySymbol') }} {{ showMarketPrice(item) }} - 已售{{ - item.sale_num }}{{ item.unit ? item.unit : '件' }} + {{ + $lang('components-diy.diyIndexPage.soldCount', { count: item.sale_num, unit: item.unit || $lang('components-diy.diyIndexPage.soldUnit') }) }} - + @@ -193,7 +193,7 @@ export default { pageIndex: 0, //当前选中分类id cateList: [{ //header分类 - category_name: '首页' + category_name: '' }], twoCategorylist: [], //二级分类 twoCategorylistId: 0, //二级分类所在的swiper @@ -258,6 +258,9 @@ export default { return data; } }, + created() { + this.cateList[0].category_name = this.$lang('components-diy.diyIndexPage.home'); + }, watch: { type(newVal, oldVal) { if (newVal) { @@ -323,7 +326,7 @@ export default { let obj = { list: [] }; - obj.category_name = this.value.title ? this.value.title : '首页'; + obj.category_name = this.value.title ? this.value.title : this.$lang('components-diy.diyIndexPage.home'); arr.push(obj); this.cateList = arr.concat(res.data); Object.keys(this.cateList).forEach((key, index) => { diff --git a/components-diy/diy-notice.vue b/components-diy/diy-notice.vue index 34d0db0..1689cd6 100644 --- a/components-diy/diy-notice.vue +++ b/components-diy/diy-notice.vue @@ -42,11 +42,11 @@ - 公告 + {{ $lang('components-diy.diyNotice.notice') }} {{ notice }} - + diff --git a/components-diy/diy-video.vue b/components-diy/diy-video.vue index 7cec6a8..75a6658 100644 --- a/components-diy/diy-video.vue +++ b/components-diy/diy-video.vue @@ -143,7 +143,7 @@ export default { }); video.addEventListener('error', (e) => { - console.error('H5端预加载视频失败:', e); + console.error(this.$lang('components-diy.diyVideo.h5PreloadFailed') + ':', e); }); // 触发加载 @@ -184,7 +184,7 @@ export default { // 视频错误事件 onVideoError(event) { - console.error('视频加载失败:', event); + console.error(this.$lang('components-diy.diyVideo.videoLoadFailed') + ':', event); }, async handlerClick(videoUrl) { diff --git a/components/mescroll/mescroll-uni-option.js b/components/mescroll/mescroll-uni-option.js index a701ad1..adafc9a 100644 --- a/components/mescroll/mescroll-uni-option.js +++ b/components/mescroll/mescroll-uni-option.js @@ -1,35 +1,37 @@ -// 全局配置 -// mescroll-body 和 mescroll-uni 通用 -const GlobalOption = { - down: { - // 其他down的配置参数也可以写,这里只展示了常用的配置: - textInOffset: '下拉刷新', // 下拉的距离在offset范围内的提示文本 - textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本 - textLoading: '加载中 ...', // 加载中的提示文本 - offset: 80, // 在列表顶部,下拉大于80px,松手即可触发下拉刷新的回调 - native: false // 是否使用系统自带的下拉刷新; 默认false; 仅在mescroll-body生效 (值为true时,还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例) - }, - up: { - // 其他up的配置参数也可以写,这里只展示了常用的配置: - textLoading: '加载中 ...', // 加载中的提示文本 - textNoMore: '', // 没有更多数据的提示文本 - // textNoMore: '— 我是有底线的 —', // 没有更多数据的提示文本 - offset: 80, // 距底部多远时,触发upCallback - isBounce: false, // 默认禁止橡皮筋的回弹效果, 必读事项: http://www.mescroll.com/qa.html?v=190725#q25 - toTop: { - // 回到顶部按钮,需配置src才显示 - src: "https://www.mescroll.com/img/mescroll-totop.png?v=1", // 图片路径 (建议放入static目录, 如 /static/img/mescroll-totop.png ) - offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000px - right: 20, // 到右边的距离, 默认20 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx) - bottom: 120, // 到底部的距离, 默认120 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx) - width: 72 // 回到顶部图标的宽度, 默认72 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx) - }, - empty: { - use: true, // 是否显示空布局 - icon: "https://www.mescroll.com/img/mescroll-empty.png?v=1", // 图标路径 (建议放入static目录, 如 /static/img/mescroll-empty.png ) - tip: '~ 暂无相关数据 ~' // 提示 - } - } -} - -export default GlobalOption +// 全局配置 +// mescroll-body 和 mescroll-uni 通用 +import Lang from '@/common/js/lang.js'; + +const GlobalOption = { + down: { + // 其他down的配置参数也可以写,这里只展示了常用的配置: + textInOffset: Lang.lang('components.mescroll.down.textInOffset', '下拉刷新'), // 下拉的距离在offset范围内的提示文本 + textOutOffset: Lang.lang('components.mescroll.down.textOutOffset', '释放更新'), // 下拉的距离大于offset范围的提示文本 + textLoading: Lang.lang('components.mescroll.down.textLoading', '加载中 ...'), // 加载中的提示文本 + offset: 80, // 在列表顶部,下拉大于80px,松手即可触发下拉刷新的回调 + native: false // 是否使用系统自带的下拉刷新; 默认false; 仅在mescroll-body生效 (值为true时,还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例) + }, + up: { + // 其他up的配置参数也可以写,这里只展示了常用的配置: + textLoading: Lang.lang('components.mescroll.up.textLoading', '加载中 ...'), // 加载中的提示文本 + textNoMore: '', // 没有更多数据的提示文本 + // textNoMore: '— 我是有底线的 —', // 没有更多数据的提示文本 + offset: 80, // 距底部多远时,触发upCallback + isBounce: false, // 默认禁止橡皮筋的回弹效果, 必读事项: http://www.mescroll.com/qa.html?v=190725#q25 + toTop: { + // 回到顶部按钮,需配置src才显示 + src: "https://www.mescroll.com/img/mescroll-totop.png?v=1", // 图片路径 (建议放入static目录, 如 /static/img/mescroll-totop.png ) + offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000px + right: 20, // 到右边的距离, 默认20 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx) + bottom: 120, // 到底部的距离, 默认120 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx) + width: 72 // 回到顶部图标的宽度, 默认72 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx) + }, + empty: { + use: true, // 是否显示空布局 + icon: "https://www.mescroll.com/img/mescroll-empty.png?v=1", // 图标路径 (建议放入static目录, 如 /static/img/mescroll-empty.png ) + tip: Lang.lang('components.mescroll.empty.tip', '~ 暂无相关数据 ~') // 提示 + } + } +} + +export default GlobalOption diff --git a/components/mescroll/mescroll-uni.js b/components/mescroll/mescroll-uni.js index 1b2eb9d..11ff4d0 100644 --- a/components/mescroll/mescroll-uni.js +++ b/components/mescroll/mescroll-uni.js @@ -4,6 +4,18 @@ * http://www.mescroll.com */ +import Lang from '@/common/js/lang.js'; + +// 国际化文本获取:优先从语言包读取,失败则使用默认值(向后兼容) +function __i18n(key, defaultVal) { + try { + var val = Lang.lang(key, defaultVal); + return val || defaultVal; + } catch (e) { + return defaultVal; + } +} + export default function MeScroll(options, isScrollBody) { let me = this; me.version = '1.2.3'; // mescroll版本号 @@ -52,9 +64,9 @@ MeScroll.prototype.extendDownScroll = function(optDown) { outOffsetRate: 0.2, // 在列表顶部,下拉的距离大于offset时,改变下拉区域高度比例;值小于1且越接近0,高度变化越小,表现为越往下越难拉 bottomOffset: 20, // 当手指touchmove位置在距离body底部20px范围内的时候结束上拉刷新,避免Webview嵌套导致touchend事件不执行 minAngle: 45, // 向下滑动最少偏移的角度,取值区间 [0,90];默认45度,即向下滑动的角度大于45度则触发下拉;而小于45度,将不触发下拉,避免与左右滑动的轮播等组件冲突; - textInOffset: '下拉刷新', // 下拉的距离在offset范围内的提示文本 - textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本 - textLoading: '加载中 ...', // 加载中的提示文本 + textInOffset: __i18n('components.mescroll.down.textInOffset', '下拉刷新'), // 下拉的距离在offset范围内的提示文本 + textOutOffset: __i18n('components.mescroll.down.textOutOffset', '释放更新'), // 下拉的距离大于offset范围的提示文本 + textLoading: __i18n('components.mescroll.down.textLoading', '加载中 ...'), // 加载中的提示文本 inited: null, // 下拉刷新初始化完毕的回调 inOffset: null, // 下拉的距离进入offset范围内那一刻的回调 outOffset: null, // 下拉的距离大于offset那一刻的回调 @@ -87,7 +99,7 @@ MeScroll.prototype.extendUpScroll = function(optUp) { }, noMoreSize: 5, // 如果列表已无数据,可设置列表的总数量要大于等于5条才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看 offset: 80, // 距底部多远时,触发upCallback - textLoading: '加载中 ...', // 加载中的提示文本 + textLoading: __i18n('components.mescroll.up.textLoading', '加载中 ...'), // 加载中的提示文本 textNoMore: '-- END --', // 没有更多数据的提示文本 inited: null, // 初始化完毕的回调 showLoading: null, // 显示加载中的回调 @@ -112,7 +124,7 @@ MeScroll.prototype.extendUpScroll = function(optUp) { empty: { use: true, // 是否显示空布局 icon: null, // 图标路径 - tip: '~ 暂无相关数据 ~', // 提示 + tip: __i18n('components.mescroll.empty.tip', '~ 暂无相关数据 ~'), // 提示 btnText: '', // 按钮 btnClick: null, // 点击按钮的回调 onShow: null, // 是否显示的回调 diff --git a/components/yuyue-date/yuyue-date.vue b/components/yuyue-date/yuyue-date.vue index b2a8c82..b584690 100644 --- a/components/yuyue-date/yuyue-date.vue +++ b/components/yuyue-date/yuyue-date.vue @@ -198,6 +198,23 @@ ? this.undisableText : this.$lang('components.yuyueDate.available'); }, + // 周几名称数组(索引 0-6 对应周日到周六,与 Date.getDay() 返回值一致) + // 用于显示层(Toast 等),会随语言切换 + weekBox() { + return [ + this.$lang('components.yuyueDate.weekSunday'), + this.$lang('components.yuyueDate.weekMonday'), + this.$lang('components.yuyueDate.weekTuesday'), + this.$lang('components.yuyueDate.weekWednesday'), + this.$lang('components.yuyueDate.weekThursday'), + this.$lang('components.yuyueDate.weekFriday'), + this.$lang('components.yuyueDate.weekSaturday'), + ]; + }, + // 中文周几名称数组(用于与 disableWeek prop 做数据匹配,保持兼容性) + weekBoxCn() { + return ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; + }, }, created(props) { this.selectDate = this.nowDate = currentTime().date; @@ -221,11 +238,10 @@ let date = e.split("-"); date = date[1] + "-" + date[2]; if (this.disableWeek.length && date >= weekDate()[0] && date <= weekDate()[1]) { - let weekBox = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; - let index = new Date(e).getDay(); - if (this.disableWeek.indexOf(weekBox[index]) != -1) { + let dayIndex = new Date(e).getDay(); + if (this.disableWeek.indexOf(this.weekBoxCn[dayIndex]) != -1) { uni.showToast({ - title: this.$lang('components.yuyueDate.weekdayCannotBook', { weekday: weekBox[index] }), + title: this.$lang('components.yuyueDate.weekdayCannotBook', { weekday: this.weekBox[dayIndex] }), icon: 'none' }) return false; @@ -243,10 +259,9 @@ // 判断默认是不能选择的周,则都禁止选中 if (this.disableWeek.length && this.selectDate >= weekDate()[0] && this.selectDate <= weekDate()[1]) { - let weekBox = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; let date = currentTime().year + '-' + this.selectDate; - let index = new Date(date).getDay(); - if (this.disableWeek.indexOf(weekBox[index]) != -1) { + let dayIndex = new Date(date).getDay(); + if (this.disableWeek.indexOf(this.weekBoxCn[dayIndex]) != -1) { item.disable = true; } } @@ -309,11 +324,10 @@ // 日期选择事件 selectDateEvent(index, item) { if (this.disableWeek.length && item.date >= weekDate()[0] && item.date <= weekDate()[1]) { - let weekBox = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; - let index = new Date(item.timeStamp).getDay(); - if (this.disableWeek.indexOf(weekBox[index]) != -1) { + let dayIndex = new Date(item.timeStamp).getDay(); + if (this.disableWeek.indexOf(this.weekBoxCn[dayIndex]) != -1) { uni.showToast({ - title: this.$lang('components.yuyueDate.weekdayCannotBook', { weekday: weekBox[index] }), + title: this.$lang('components.yuyueDate.weekdayCannotBook', { weekday: this.weekBox[dayIndex] }), icon: 'none' }) return false; diff --git a/lang/en-us/ai-chat/index.js b/lang/en-us/ai-chat/index.js index bcc767b..81a99f1 100644 --- a/lang/en-us/ai-chat/index.js +++ b/lang/en-us/ai-chat/index.js @@ -42,6 +42,14 @@ export const lang = { loadHistoryFail: 'Failed to load history', about: '0B', + // ====== ai-chat-message - Auto Reply Templates ====== + autoReplyGreeting: 'Hello! I am the AI customer service assistant, glad to serve you! How can I help you?', + autoReplyPrice: 'Our product prices vary by model and configuration. Please check the product detail page for specific prices.', + autoReplyShipping: 'Generally, orders are shipped within 24 hours. Please check the logistics information for specific timelines.', + autoReplyReturn: '7-day no-reason return is supported. Please ensure the product is in good condition.', + autoReplyService: 'Our customer service hours are 9:00-18:00. Feel free to contact us if you have any questions.', + autoReplyDefault: 'Thank you for your inquiry! Regarding your question about "{question}", our professional customer service will answer you as soon as possible. You can also check our help documentation for more information.', + // ====== ai-chat-search ====== searchEntrance: 'Search', searchPlaceholder: 'Search chat history', @@ -118,5 +126,14 @@ export const lang = { menuClearChat: 'Clear Chat', menuExport: 'Export Records', menuSettings: 'Settings', - menuHelp: 'Help' + menuHelp: 'Help', + + // ====== index.vue - Console Logs (for debugging) ====== + logOnShowTriggered: '[AI Chat Page] onShow triggered', + logOnUnloadTriggered: '[AI Chat Page] onUnload triggered', + logKeyboardChangeUnavailable: 'onKeyboardHeightChange unavailable', + logEventHandleError: 'Event handling error', + logInitNavbarFailed: 'Failed to initialize navigation bar', + logChatComponentNotInit: 'Chat component not initialized', + logServicerConfigNotLoaded: '[AI Customer Service] servicerConfig not loaded, retrying after 200ms...' } diff --git a/lang/en-us/article/detail.js b/lang/en-us/article/detail.js index f9511d1..1b3408d 100644 --- a/lang/en-us/article/detail.js +++ b/lang/en-us/article/detail.js @@ -1,4 +1,10 @@ export const lang = { //title为每个页面的标题 - title: 'Article Details' -} \ No newline at end of file + title: 'Article Details', + // publish time label + publishTime: 'Published:', + // read count label + readCount: 'Views: ', + // liked suffix (count + people liked) + likedSuffix: ' likes' +} diff --git a/lang/en-us/article/list.js b/lang/en-us/article/list.js index 1cce3aa..f6a31cc 100644 --- a/lang/en-us/article/list.js +++ b/lang/en-us/article/list.js @@ -1,5 +1,5 @@ export const lang = { - //title为每个页面的标题 + //title is the title of each page title: 'Article List', - emptyText: "No article information available currently" -} \ No newline at end of file + emptyText: 'No articles' +} diff --git a/lang/en-us/common.js b/lang/en-us/common.js index d8dc0e7..6205397 100644 --- a/lang/en-us/common.js +++ b/lang/en-us/common.js @@ -18,7 +18,40 @@ export const lang = { goodsRecommendTitle: 'Guess you like', currencySymbol: '¥', submit: 'Submit', - searchTip: 'Please enter search keywords' + searchTip: 'Please enter search keywords', + // version update + updateTip: 'Update Available', + updateReady: 'A new version is ready, restart the app now?', + // network status + networkLost: 'Network Disconnected', + networkCheck: 'Please check your network connection', + // config related + config: { + siteJsNotConfigured: 'In the mini-program release environment, the site.js file must be configured, otherwise the default configuration will be used, which affects mini-program custom distribution!' + }, + // platform detection + platform: { + wechatOfficialAccount: 'WeChat Official Account', + wechatMiniProgram: 'WeChat Mini Program', + alipayMiniProgram: 'Alipay Mini Program', + baiduMiniProgram: 'Baidu Mini Program', + toutiaoMiniProgram: 'Toutiao Mini Program', + qqMiniProgram: 'QQ Mini Program', + kuaishouMiniProgram: 'Kuaishou Mini Program', + jdMiniProgram: 'JD Mini Program', + miniProgram360: '360 Mini Program', + xhsMiniProgram: 'Xiaohongshu Mini Program', + harmonyService: 'Harmony Service', + app: 'APP', + pc: 'PC', + h5: 'H5', + unknown: 'Unknown Platform', + }, + }, + + // navigation utility + navigation: { + serviceUnavailable: 'Navigation service temporarily unavailable', }, // diy custom page @@ -58,6 +91,7 @@ export const lang = { serviceUnavailable: 'Customer service temporarily unavailable', wxworkLinkNotConfigured: 'WeChat Work link not configured', fromFloatButton: 'Inquiry from floating button', + serviceTypeNotConfigured: 'Customer service type not configured', }, // WeChat Work JS-SDK @@ -153,6 +187,8 @@ export const lang = { weekThursday: 'Thu', weekFriday: 'Fri', weekSaturday: 'Sat', + // error messages + deepCloneNotObject: 'obj is not an object!', }, // AI service @@ -215,11 +251,6 @@ export const lang = { logoutTitle: 'Tip', logoutContent: 'Are you sure you want to log out?', - // navigation utility - navigation: { - serviceUnavailable: 'Navigation service temporarily unavailable', - }, - // WeChat Map JSSDK mapWxJssdk: { // error messages diff --git a/lang/en-us/components-diy/diy-category.js b/lang/en-us/components-diy/diy-category.js index d2eb314..16ef161 100644 --- a/lang/en-us/components-diy/diy-category.js +++ b/lang/en-us/components-diy/diy-category.js @@ -1,7 +1,16 @@ export const lang = { - expand: 'Expand', - clickToCollapse: 'Click to collapse', - reachedBottom: 'Reached the bottom~', - noCategory: 'No categories yet!', - pieceUnit: 'pc(s)', + 'components-diy': { + diyCategory: { + // Expand all categories (button on the right of horizontal scroll) + expand: 'Expand', + // Click to collapse (button at the bottom of expanded popup) + clickToCollapse: 'Click to collapse', + // Scroll to bottom tip + reachedBottom: 'Reached the bottom~', + // No categories (empty state tip) + noCategory: 'No categories yet!', + // Product unit: piece + pieceUnit: 'pc(s)', + }, + }, } diff --git a/lang/en-us/components-diy/diy-goods-list.js b/lang/en-us/components-diy/diy-goods-list.js new file mode 100644 index 0000000..071c158 --- /dev/null +++ b/lang/en-us/components-diy/diy-goods-list.js @@ -0,0 +1,7 @@ +export const lang = { + // Sales text: Sold X units + soldCount: 'Sold {count}{unit}', + + // Sales unit: piece + soldUnit: 'pcs', +} diff --git a/lang/en-us/components-diy/diy-index-page.js b/lang/en-us/components-diy/diy-index-page.js new file mode 100644 index 0000000..adb900a --- /dev/null +++ b/lang/en-us/components-diy/diy-index-page.js @@ -0,0 +1,14 @@ +export const lang = { + 'components-diy': { + diyIndexPage: { + // Home (default category name) + home: 'Home', + // Sales text: Sold X units + soldCount: 'Sold {count}{unit}', + // Sales unit: piece + soldUnit: 'pcs', + // Empty state prompt when no goods in category + noGoodsInCategory: 'No goods in this category', + }, + }, +} diff --git a/lang/en-us/components-diy/diy-notice.js b/lang/en-us/components-diy/diy-notice.js new file mode 100644 index 0000000..b79bbc5 --- /dev/null +++ b/lang/en-us/components-diy/diy-notice.js @@ -0,0 +1,4 @@ +export const lang = { + notice: 'Notice', + gotIt: 'Got it', +} diff --git a/lang/en-us/components-diy/diy-store.js b/lang/en-us/components-diy/diy-store.js index ead4ed2..63ec583 100644 --- a/lang/en-us/components-diy/diy-store.js +++ b/lang/en-us/components-diy/diy-store.js @@ -1,6 +1,14 @@ export const lang = { - switchStore: 'Switch', - locating: 'Locating...', - gettingLocation: 'Getting current location...', - searchPlaceholder: 'Search products', -} + 'components-diy': { + diyStore: { + // Switch store button text + switchStore: 'Switch Store', + // Locating status text + locating: 'Locating', + // Getting location status text for address + gettingLocation: 'Getting location', + // Search input placeholder + searchPlaceholder: 'Search', + }, + }, +}; diff --git a/lang/en-us/components-diy/diy-video.js b/lang/en-us/components-diy/diy-video.js new file mode 100644 index 0000000..1141759 --- /dev/null +++ b/lang/en-us/components-diy/diy-video.js @@ -0,0 +1,6 @@ +export const lang = { + // H5 video preload failed + h5PreloadFailed: 'H5 video preload failed', + // Video load failed + videoLoadFailed: 'Video load failed', +} diff --git a/lang/en-us/components/mescroll.js b/lang/en-us/components/mescroll.js new file mode 100644 index 0000000..591f4a0 --- /dev/null +++ b/lang/en-us/components/mescroll.js @@ -0,0 +1,22 @@ +export const lang = { + // mescroll pull-down refresh / pull-up load component + components: { + mescroll: { + // pull-down refresh text + down: { + textInOffset: 'Pull to refresh', + textOutOffset: 'Release to update', + textLoading: 'Loading ...', + }, + // pull-up load text + up: { + textLoading: 'Loading ...', + textNoMore: '-- END --', + }, + // empty layout tip + empty: { + tip: '~ No data ~', + }, + }, + }, +} diff --git a/lang/en-us/fenxiao/child_fenxiao.js b/lang/en-us/fenxiao/child_fenxiao.js index 4e0368a..8a8e634 100644 --- a/lang/en-us/fenxiao/child_fenxiao.js +++ b/lang/en-us/fenxiao/child_fenxiao.js @@ -1,4 +1,18 @@ export const lang = { //title为每个页面的标题 title: 'Distributors', + + // Member info + joinTime: 'Join Date: ', + + // Stats units + peopleUnit: ' people', + orderUnit: ' orders', + currencyUnit: ' Yuan', + + // Empty state + noData: 'No data', + + // Toast messages + merchantNotOpenFenxiao: 'Merchant has not enabled distribution', } diff --git a/lang/en-us/files/list.js b/lang/en-us/files/list.js index 9055387..967634b 100644 --- a/lang/en-us/files/list.js +++ b/lang/en-us/files/list.js @@ -1,4 +1,9 @@ export const lang = { //title为每个页面的标题 title: 'View Files', + searchPlaceholder: 'Please enter the file name you want to search', + viewPdf: 'View PDF File', + emptyText: 'No files yet', + loading: 'Loading', + fileNotExist: 'File does not exist', } diff --git a/lang/en-us/form/form.js b/lang/en-us/form/form.js new file mode 100644 index 0000000..daabb33 --- /dev/null +++ b/lang/en-us/form/form.js @@ -0,0 +1,15 @@ +export const lang = { + + // Form page + form: { + form: { + // Page title + title: 'Please fill in the form information', + // Submit success message + submitSuccess: 'Submitted successfully', + // Form information not available + noFormInfo: 'Form information not available', + }, + }, + +} diff --git a/lang/en-us/member/bind_mobile.js b/lang/en-us/member/bind_mobile.js new file mode 100644 index 0000000..585e12f --- /dev/null +++ b/lang/en-us/member/bind_mobile.js @@ -0,0 +1,48 @@ +export const lang = { + // title is the page title + title: 'Bind Mobile', + + bindMobile: { + // One-click authorization binding + oneClickAuthBind: 'One-Click Authorization Binding', + // Manual binding + manualBind: 'Manual Binding', + + // Phone number + phoneNumber: 'Phone Number', + // Please enter phone number + pleInputMobile: 'Please enter phone number', + // Please enter a valid phone number + surePhoneNumber: 'Please enter a valid phone number', + + // Verification code + confirmCode: 'Verification Code', + // Please enter verification code + confirmCodeInput: 'Please enter verification code', + + // SMS verification code + smsCode: 'SMS Verification Code', + // Please enter dynamic code + animateCodeInput: 'Please enter dynamic code', + // Get dynamic code + findanimateCode: 'Get Dynamic Code', + // Code sent + codeSent: 'Sent ({seconds}s)', + // Do not click repeatedly + doNotRepeatedlyClick: 'Do not click repeatedly', + + // Save / Bind + save: 'Bind', + // Binding successful + bindSuccess: 'Binding Successful', + // Same as original phone number, no need to modify + alikePhone: 'Same as original phone number, no need to modify', + + // Tip text + tipTitle: 'Notice', + // Enjoy more services after binding your mobile number + bindBenefitTip: 'Enjoy more services after binding your mobile number', + // Send code tip + sendCodeTip: 'Click "Get Dynamic Code" and a verification code will be sent to your mobile number {mobile}', + }, +} diff --git a/lang/en-us/member/cancellation.js b/lang/en-us/member/cancellation.js index 605a8db..8427390 100644 --- a/lang/en-us/member/cancellation.js +++ b/lang/en-us/member/cancellation.js @@ -1,3 +1,6 @@ export const lang = { title: 'Account Cancellation', -} \ No newline at end of file + agreeTermsText: 'Check to indicate you have read and agree to this agreement', + nextStep: 'Next', + pleaseAgreeFirst: 'Please check to agree to the agreement first', +} diff --git a/lang/en-us/member/card_log.js b/lang/en-us/member/card_log.js new file mode 100644 index 0000000..983a6ff --- /dev/null +++ b/lang/en-us/member/card_log.js @@ -0,0 +1,25 @@ +export const lang = { + //title is the title of each page + title: 'Membership Card Log', + + // Stats header + totalConsume: 'Total Consume', + cardBalance: 'Balance', + totalRecharge: 'Total Recharge', + yuanSuffix: ' Yuan', + statUnit: ' ({unit})', + + // Filter tabs + filterAll: 'All', + filterIncome: 'Income', + filterExpense: 'Expense', + filterRecharge: 'Recharge', + filterConsume: 'Consume', + filterGift: 'Gift', + + // Empty state + emptyTips: 'No membership card records', + + // Amount format + amountWithUnit: '{amount} Yuan', +} diff --git a/lang/en-us/member/collection.js b/lang/en-us/member/collection.js index feaf7c6..3182208 100644 --- a/lang/en-us/member/collection.js +++ b/lang/en-us/member/collection.js @@ -1,4 +1,7 @@ export const lang = { //title为每个页面的标题 - title: 'My Favorites' -} \ No newline at end of file + title: 'My Favorites', + emptyText: 'No favorite products yet', + emptySubText: 'Go shopping and follow products you like!', + deleteSuccess: 'Deleted successfully' +} diff --git a/lang/en-us/member/modify_face.js b/lang/en-us/member/modify_face.js index cdca09b..d0c5d8a 100644 --- a/lang/en-us/member/modify_face.js +++ b/lang/en-us/member/modify_face.js @@ -1,4 +1,9 @@ export const lang = { //title为每个页面的标题 - title: 'Modify Avatar' -} \ No newline at end of file + title: 'Modify Avatar', + clickToUpload: 'Click to Upload', + confirmSave: 'Confirm Save', + reupload: 'Reupload', + uploadFailed: 'Avatar upload failed', + modifySuccess: 'Avatar modified successfully' +} diff --git a/lang/en-us/member/withdrawal.js b/lang/en-us/member/withdrawal.js index f4d7936..ef504c0 100644 --- a/lang/en-us/member/withdrawal.js +++ b/lang/en-us/member/withdrawal.js @@ -1,4 +1,5 @@ export const lang = { //title为每个页面的标题 - title: 'Withdrawal Records' + title: 'Withdrawal Records', + emptyTips: 'No withdrawal records' } \ No newline at end of file diff --git a/lang/en-us/merch/list.js b/lang/en-us/merch/list.js index a1f3f43..002842d 100644 --- a/lang/en-us/merch/list.js +++ b/lang/en-us/merch/list.js @@ -1,7 +1,38 @@ export const lang = { + // title is the title of each page + title: 'Product List', + + // Search box placeholder + searchPlaceholder: 'Please enter the product you want to search for', + // Default button text buyText: 'Buy', + // Sort options + sort: { + comprehensive: 'Comprehensive', + sales: 'Sales', + price: 'Price', + filter: 'Filter', + }, + + // Goods list + goods: { + consultNow: 'Consult Now', + sold: 'Sold {num}{unit}', + defaultUnit: 'pcs', + noGoods: 'No products', + }, + + // Filter drawer + filter: { + title: 'Filter', + allCategories: 'All Categories', + all: 'All', + reset: 'Reset', + confirm: 'Confirm', + }, + // Modal dialog modal: { title: 'Notice', diff --git a/lang/en-us/order/activist.js b/lang/en-us/order/activist.js index 6abbae0..e2ddc97 100644 --- a/lang/en-us/order/activist.js +++ b/lang/en-us/order/activist.js @@ -15,5 +15,10 @@ export const lang = { // Toast messages toast: { cancelSuccess: 'Cancelled successfully' + }, + // Cancel refund modal + cancelRefund: { + content: 'After cancellation, this application will be closed. You can reapply if needed.', + cancelText: 'Not Now' } } diff --git a/lang/en-us/order/invoice.js b/lang/en-us/order/invoice.js new file mode 100644 index 0000000..d7f47b6 --- /dev/null +++ b/lang/en-us/order/invoice.js @@ -0,0 +1,91 @@ +export const lang = { + //title for each page + title: 'Invoice Application', + + // ====== Header ====== + header: { + title: 'Invoice Information', + desc: 'Please fill in the invoice information' + }, + + // ====== Invoice Type ====== + invoiceType: { + title: 'Invoice Type', + paper: 'Paper Invoice', + paperDesc: 'Invoice will be mailed to the specified address', + electronic: 'Electronic Invoice', + electronicDesc: 'Invoice will be sent to your email' + }, + + // ====== Invoice Title ====== + invoiceTitle: { + title: 'Invoice Title', + personal: 'Personal', + company: 'Company', + label: 'Invoice Title', + personalPlaceholder: 'Please enter your name', + companyPlaceholder: 'Please enter company name', + taxpayerId: 'Taxpayer ID', + taxpayerIdPlaceholder: 'Please enter taxpayer ID' + }, + + // ====== Invoice Content ====== + invoiceContent: { + title: 'Invoice Content', + label: 'Invoice Content', + placeholder: 'Please select invoice content' + }, + + // ====== Mail Info (Paper Invoice) ====== + mailInfo: { + title: 'Mailing Information', + receiver: 'Recipient', + receiverPlaceholder: 'Please enter recipient name', + mobile: 'Contact Phone', + mobilePlaceholder: 'Please enter phone number', + address: 'Mailing Address', + regionPlaceholder: 'Please select region', + detailAddress: 'Detailed Address', + detailAddressPlaceholder: 'Please enter detailed address' + }, + + // ====== Email Info (Electronic Invoice) ====== + emailInfo: { + title: 'Email Information', + receiverEmail: 'Receiver Email', + emailPlaceholder: 'Please enter the email address to receive the invoice' + }, + + // ====== Fee Section ====== + fee: { + taxFee: 'Invoice Tax', + deliveryFee: 'Delivery Fee' + }, + + // ====== Footer Submit Section ====== + footer: { + tip: 'Tip: Invoice applications will be processed within {days} working days', + submit: 'Submit Application' + }, + + // ====== Form Validation Messages ====== + validation: { + pleaseEnterTitle: 'Please enter invoice title', + pleaseEnterTaxpayerId: 'Please enter taxpayer ID', + pleaseSelectContent: 'Please select invoice content', + pleaseEnterReceiver: 'Please enter recipient name', + pleaseEnterMobile: 'Please enter phone number', + pleaseSelectRegion: 'Please select region', + pleaseEnterAddress: 'Please enter detailed address', + pleaseEnterEmail: 'Please enter receiver email', + invalidEmail: 'Please enter a valid email address' + }, + + // ====== API Messages ====== + api: { + getConfigFailed: 'Failed to get invoice configuration', + submitSuccess: 'Invoice application submitted successfully', + submitFailed: 'Submission failed, please try again later', + networkError: 'Network error, please try again later' + } +} diff --git a/lang/en-us/order/logistics.js b/lang/en-us/order/logistics.js index d5a78de..def812f 100644 --- a/lang/en-us/order/logistics.js +++ b/lang/en-us/order/logistics.js @@ -1,4 +1,16 @@ export const lang = { - //title为每个页面的标题 - title: 'Logistics Information' -} \ No newline at end of file + //title is the title of each page + title: 'Logistics Information', + + // Order logistics info + order: { + logistics: { + // Express company info + expressCompany: 'Carrier: ', + trackingNo: 'Tracking No.: ', + + // Toast messages + orderInfoNotFound: 'Order information not found!' + } + } +} diff --git a/lang/en-us/order/refund_detail.js b/lang/en-us/order/refund_detail.js index 4955039..bc3bd76 100644 --- a/lang/en-us/order/refund_detail.js +++ b/lang/en-us/order/refund_detail.js @@ -64,6 +64,12 @@ export const lang = { cancelSuccess: 'Cancelled successfully' }, + // ====== Cancel Refund Modal ====== + cancelRefund: { + content: 'After cancellation, this application will be closed. You can reapply if needed.', + cancelText: 'Not Now' + }, + // ====== Form Validation ====== validate: { pleaseInputExpressCompany: 'Please enter logistics company', diff --git a/lang/en-us/seal/medium/detail.js b/lang/en-us/seal/medium/detail.js index c348a00..0363494 100644 --- a/lang/en-us/seal/medium/detail.js +++ b/lang/en-us/seal/medium/detail.js @@ -1,17 +1,27 @@ export const lang = { - // page title - title: 'Search Results', - // action buttons - exportImage: 'Export Image', - exportPdf: 'Export PDF', + // Seal detail + seal: { + medium: { + detail: { + // Page title + title: 'Seal Details', + // Export image + exportImage: 'Export Image', + // Export PDF + exportPdf: 'Export PDF', + // Loading + loading: 'Loading', + // File does not exist + fileNotExist: 'File does not exist', + // Save success + saveSuccess: 'Saved successfully', + // Save failed + saveFailed: 'Save failed', + // Download failed + downloadFailed: 'Download failed', + } + } + } - // loading tips - loading: 'Loading', - - // toast messages - fileNotExist: 'File does not exist', - saveSuccess: 'Saved successfully', - saveFailed: 'Save failed, please try again later', - downloadFailed: 'Download failed', } diff --git a/lang/en-us/seal/medium/search.js b/lang/en-us/seal/medium/search.js index 752cf0d..c44bd85 100644 --- a/lang/en-us/seal/medium/search.js +++ b/lang/en-us/seal/medium/search.js @@ -1,23 +1,23 @@ export const lang = { - //title为每个页面的标题 - title: 'Material Search', + // Seal search page seal: { medium: { search: { // Search input placeholder - placeholder: "Enter medium name e.g. 'gasoline'", + placeholder: 'Enter keywords to search', // Search results title searchResult: 'Search Results', - // Empty state text + // Empty data tip noData: 'No Data', // Modal title tip: 'Tip', - // Delete all history confirmation - confirmDeleteAllHistory: 'Confirm delete all history?', - // Delete single history record confirmation - confirmDeleteHistory: 'Confirm delete this history record?', + // Confirm delete all history + confirmDeleteAllHistory: 'Are you sure you want to delete all search history?', + // Confirm delete single history item + confirmDeleteHistory: 'Are you sure you want to delete this search history?', } } } + } diff --git a/lang/zh-cn/ai-chat/index.js b/lang/zh-cn/ai-chat/index.js index c2b2214..7f7c725 100644 --- a/lang/zh-cn/ai-chat/index.js +++ b/lang/zh-cn/ai-chat/index.js @@ -42,6 +42,14 @@ export const lang = { loadHistoryFail: '加载历史失败', about: '0B', + // ====== ai-chat-message - 自动回复模板 ====== + autoReplyGreeting: '您好!我是AI智能客服,很高兴为您服务!有什么可以帮助您的吗?', + autoReplyPrice: '我们的产品价格根据型号和配置有所不同,具体价格请查看商品详情页面。', + autoReplyShipping: '一般情况下,订单会在24小时内发货,具体时效请查看物流信息。', + autoReplyReturn: '支持7天无理由退货,请确保商品完好无损。', + autoReplyService: '我们的客服工作时间是9:00-18:00,有问题可以随时联系我们。', + autoReplyDefault: '感谢您的咨询!关于"{question}"的问题,我们的专业客服会尽快为您解答。您也可以查看我们的帮助文档获取更多信息。', + // ====== ai-chat-search ====== searchEntrance: '搜索', searchPlaceholder: '搜索聊天记录', @@ -118,5 +126,14 @@ export const lang = { menuClearChat: '清空聊天', menuExport: '导出记录', menuSettings: '设置', - menuHelp: '帮助' + menuHelp: '帮助', + + // ====== index.vue - 控制台日志(调试用) ====== + logOnShowTriggered: '[AI Chat Page] onShow 触发', + logOnUnloadTriggered: '[AI Chat Page] onUnload 触发', + logKeyboardChangeUnavailable: 'onKeyboardHeightChange 不可用', + logEventHandleError: '事件处理错误', + logInitNavbarFailed: '初始化导航栏失败', + logChatComponentNotInit: '聊天组件未初始化', + logServicerConfigNotLoaded: '【AI客服】servicerConfig 未加载,200ms后重试...' } diff --git a/lang/zh-cn/article/detail.js b/lang/zh-cn/article/detail.js index 2d9ca88..ebd4eef 100644 --- a/lang/zh-cn/article/detail.js +++ b/lang/zh-cn/article/detail.js @@ -1,4 +1,10 @@ export const lang = { //title为每个页面的标题 - title: '文章详情' + title: '文章详情', + // 发表时间标签 + publishTime: '发表时间:', + // 阅读数标签 + readCount: '阅读:', + // 点赞数后缀(人数+人已赞) + likedSuffix: '人已赞' } diff --git a/lang/zh-cn/article/list.js b/lang/zh-cn/article/list.js index 129277a..2643371 100644 --- a/lang/zh-cn/article/list.js +++ b/lang/zh-cn/article/list.js @@ -1,5 +1,5 @@ export const lang = { //title为每个页面的标题 title: '文章列表', - emptyText:"当前暂无文章信息" + emptyText: '暂无文章' } diff --git a/lang/zh-cn/common.js b/lang/zh-cn/common.js index fe87fef..85bcd41 100644 --- a/lang/zh-cn/common.js +++ b/lang/zh-cn/common.js @@ -8,19 +8,52 @@ export const lang = { member: '个人中心' }, - //公共 - common: { - //语言包名称 - name: '中文', - mescrollTextInOffset: '下拉刷新', - mescrollTextOutOffset: '释放更新', - mescrollEmpty: "暂无相关数据", - goodsRecommendTitle: '猜你喜欢', - currencySymbol: '¥', - submit: '提交', - searchTip: '请输入搜索关键词' - }, - + //公共 + common: { + //语言包名称 + name: '中文', + mescrollTextInOffset: '下拉刷新', + mescrollTextOutOffset: '释放更新', + mescrollEmpty: "暂无相关数据", + goodsRecommendTitle: '猜你喜欢', + currencySymbol: '¥', + submit: '提交', + searchTip: '请输入搜索关键词', + // 版本更新 + updateTip: '更新提示', + updateReady: '新版本已经准备好,是否重启应用?', + // 网络状态 + networkLost: '网络失去链接', + networkCheck: '请检查网络链接', + // 配置相关 + config: { + siteJsNotConfigured: '小程序发行环境下,必须配置site.js文件,不然将使用默认配置,影响小程序定制分发!' + }, + // 平台检测 + platform: { + wechatOfficialAccount: '微信公众号', + wechatMiniProgram: '微信小程序', + alipayMiniProgram: '支付宝小程序', + baiduMiniProgram: '百度小程序', + toutiaoMiniProgram: '头条小程序', + qqMiniProgram: 'QQ小程序', + kuaishouMiniProgram: '快手小程序', + jdMiniProgram: '京东小程序', + miniProgram360: '360小程序', + xhsMiniProgram: '小红书小程序', + harmonyService: '鸿蒙元服务', + app: 'APP', + pc: 'PC端', + h5: 'H5', + unknown: '未知平台', + }, + }, + + // 导航工具 + navigation: { + serviceUnavailable: '导航服务暂时不可用', + }, + //客服 customer: { weChatKefu: '微信客服', @@ -58,6 +91,7 @@ export const lang = { serviceUnavailable: '客服暂不可用', wxworkLinkNotConfigured: '企业微信链接未配置', fromFloatButton: '来自悬浮按钮的咨询', + serviceTypeNotConfigured: '客服类型未配置', }, // 企业微信JS-SDK @@ -153,6 +187,8 @@ export const lang = { weekThursday: '周四', weekFriday: '周五', weekSaturday: '周六', + // 错误消息 + deepCloneNotObject: 'obj 不是一个对象!', }, // AI 客服服务 @@ -212,11 +248,6 @@ export const lang = { logoutTitle: '提示', logoutContent: '确定要退出登录吗', - // 导航工具 - navigation: { - serviceUnavailable: '导航服务暂时不可用', - }, - // 微信地图JSSDK mapWxJssdk: { // 错误提示 diff --git a/lang/zh-cn/components-diy/diy-category.js b/lang/zh-cn/components-diy/diy-category.js index d7f388d..e28ce39 100644 --- a/lang/zh-cn/components-diy/diy-category.js +++ b/lang/zh-cn/components-diy/diy-category.js @@ -1,7 +1,16 @@ export const lang = { - expand: '展开', - clickToCollapse: '点击收起', - reachedBottom: '已经到底了~', - noCategory: '暂时没有分类哦!', - pieceUnit: '件', + 'components-diy': { + diyCategory: { + // 展开全部分类(横向滚动右侧展开按钮) + expand: '展开', + // 点击收起(展开弹窗底部收起按钮) + clickToCollapse: '点击收起', + // 滚动到底部提示 + reachedBottom: '已经到底了~', + // 暂无分类(空状态提示) + noCategory: '暂时没有分类哦!', + // 商品单位:件 + pieceUnit: '件', + }, + }, } diff --git a/lang/zh-cn/components-diy/diy-goods-list.js b/lang/zh-cn/components-diy/diy-goods-list.js new file mode 100644 index 0000000..1430ced --- /dev/null +++ b/lang/zh-cn/components-diy/diy-goods-list.js @@ -0,0 +1,7 @@ +export const lang = { + // 销量文案:已售X件 + soldCount: '已售{count}{unit}', + + // 销量单位:件 + soldUnit: '件', +} diff --git a/lang/zh-cn/components-diy/diy-index-page.js b/lang/zh-cn/components-diy/diy-index-page.js new file mode 100644 index 0000000..05ad7dd --- /dev/null +++ b/lang/zh-cn/components-diy/diy-index-page.js @@ -0,0 +1,14 @@ +export const lang = { + 'components-diy': { + diyIndexPage: { + // 首页(默认分类名称) + home: '首页', + // 销量文案:已售X件 + soldCount: '已售{count}{unit}', + // 销量单位:件 + soldUnit: '件', + // 分类下无商品的空状态提示 + noGoodsInCategory: '该分类下暂无商品', + }, + }, +} diff --git a/lang/zh-cn/components-diy/diy-notice.js b/lang/zh-cn/components-diy/diy-notice.js new file mode 100644 index 0000000..e56c0c4 --- /dev/null +++ b/lang/zh-cn/components-diy/diy-notice.js @@ -0,0 +1,4 @@ +export const lang = { + notice: '公告', + gotIt: '我知道了', +} diff --git a/lang/zh-cn/components-diy/diy-store.js b/lang/zh-cn/components-diy/diy-store.js index 79a2ea5..21b625d 100644 --- a/lang/zh-cn/components-diy/diy-store.js +++ b/lang/zh-cn/components-diy/diy-store.js @@ -1,6 +1,14 @@ export const lang = { - switchStore: '切换', - locating: '定位中...', - gettingLocation: '获取当前位置...', - searchPlaceholder: '商品搜索', -} + 'components-diy': { + diyStore: { + // 切换门店(按钮文案) + switchStore: '切换门店', + // 定位中(加载状态提示) + locating: '定位中', + // 获取位置中(地址加载状态提示) + gettingLocation: '获取位置中', + // 搜索框占位符 + searchPlaceholder: '搜索', + }, + }, +}; diff --git a/lang/zh-cn/components-diy/diy-video.js b/lang/zh-cn/components-diy/diy-video.js new file mode 100644 index 0000000..a45ee64 --- /dev/null +++ b/lang/zh-cn/components-diy/diy-video.js @@ -0,0 +1,6 @@ +export const lang = { + // H5端预加载视频失败 + h5PreloadFailed: 'H5端预加载视频失败', + // 视频加载失败 + videoLoadFailed: '视频加载失败', +} diff --git a/lang/zh-cn/components/mescroll.js b/lang/zh-cn/components/mescroll.js new file mode 100644 index 0000000..c3bfe90 --- /dev/null +++ b/lang/zh-cn/components/mescroll.js @@ -0,0 +1,22 @@ +export const lang = { + // mescroll 下拉刷新/上拉加载组件 + components: { + mescroll: { + // 下拉刷新提示文本 + down: { + textInOffset: '下拉刷新', + textOutOffset: '释放更新', + textLoading: '加载中 ...', + }, + // 上拉加载提示文本 + up: { + textLoading: '加载中 ...', + textNoMore: '-- END --', + }, + // 空布局提示 + empty: { + tip: '~ 暂无相关数据 ~', + }, + }, + }, +} diff --git a/lang/zh-cn/fenxiao/child_fenxiao.js b/lang/zh-cn/fenxiao/child_fenxiao.js index 56472f8..7043725 100644 --- a/lang/zh-cn/fenxiao/child_fenxiao.js +++ b/lang/zh-cn/fenxiao/child_fenxiao.js @@ -1,4 +1,18 @@ export const lang = { //title为每个页面的标题 title: '分销商', + + // 会员信息 + joinTime: '加入时间:', + + // 统计单位 + peopleUnit: '人', + orderUnit: '单', + currencyUnit: '元', + + // 空状态 + noData: '暂无数据', + + // Toast 提示 + merchantNotOpenFenxiao: '商家未开启分销', } diff --git a/lang/zh-cn/files/list.js b/lang/zh-cn/files/list.js index f353d4c..e75baf5 100644 --- a/lang/zh-cn/files/list.js +++ b/lang/zh-cn/files/list.js @@ -1,4 +1,9 @@ export const lang = { //title为每个页面的标题 title: '查看文件', + searchPlaceholder: '请输入您要搜索的文件名称', + viewPdf: '查看PDF文件', + emptyText: '暂无文件', + loading: '正在加载', + fileNotExist: '文件不存在', } diff --git a/lang/zh-cn/form/form.js b/lang/zh-cn/form/form.js new file mode 100644 index 0000000..1d1fadf --- /dev/null +++ b/lang/zh-cn/form/form.js @@ -0,0 +1,15 @@ +export const lang = { + + // 表单页面 + form: { + form: { + // 页面标题 + title: '请填写表单所需信息', + // 提交成功提示 + submitSuccess: '提交成功', + // 未获取到表单信息 + noFormInfo: '未获取到表单信息', + }, + }, + +} diff --git a/lang/zh-cn/member/bind_mobile.js b/lang/zh-cn/member/bind_mobile.js new file mode 100644 index 0000000..2dfc2f0 --- /dev/null +++ b/lang/zh-cn/member/bind_mobile.js @@ -0,0 +1,48 @@ +export const lang = { + // title为每个页面的标题 + title: '绑定手机号', + + bindMobile: { + // 一键授权绑定 + oneClickAuthBind: '一键授权绑定', + // 手动绑定 + manualBind: '手动绑定', + + // 手机号 + phoneNumber: '手机号', + // 请输入手机号 + pleInputMobile: '请输入手机号', + // 请输入正确的手机号 + surePhoneNumber: '请输入正确的手机号', + + // 验证码 + confirmCode: '验证码', + // 请输入验证码 + confirmCodeInput: '请输入验证码', + + // 短信验证码 + smsCode: '短信验证码', + // 请输入动态码 + animateCodeInput: '请输入动态码', + // 获取动态码 + findanimateCode: '获取动态码', + // 已发送 + codeSent: '已发送({seconds}s)', + // 请勿重复点击 + doNotRepeatedlyClick: '请勿重复点击', + + // 保存/绑定 + save: '绑定', + // 绑定成功 + bindSuccess: '绑定成功', + // 与原手机号一致,无需修改 + alikePhone: '与原手机号一致,无需修改', + + // 提示文案 + tipTitle: '温馨提示', + // 绑定手机号后可享受更多服务 + bindBenefitTip: '绑定手机号后可享受更多服务', + // 发送动态码提示 + sendCodeTip: '点击"获取动态码",将会向您的手机号{mobile}发送验证码', + }, +} diff --git a/lang/zh-cn/member/cancellation.js b/lang/zh-cn/member/cancellation.js index 1702e20..2f3a93c 100644 --- a/lang/zh-cn/member/cancellation.js +++ b/lang/zh-cn/member/cancellation.js @@ -1,3 +1,10 @@ export const lang = { + //title为每个页面的标题 title: '账号注销', -} \ No newline at end of file + // 协议勾选提示 + agreeTermsText: '勾选即表示您已阅读并同意本协议', + // 下一步按钮 + nextStep: '下一步', + // 未勾选协议提示 + pleaseAgreeFirst: '请先勾选同意协议', +} diff --git a/lang/zh-cn/member/card_log.js b/lang/zh-cn/member/card_log.js new file mode 100644 index 0000000..883732f --- /dev/null +++ b/lang/zh-cn/member/card_log.js @@ -0,0 +1,25 @@ +export const lang = { + //title为每个页面的标题 + title: '会员卡记录', + + // 顶部统计 + totalConsume: '累计消费', + cardBalance: '卡余额', + totalRecharge: '累计充值', + yuanSuffix: '元', + statUnit: '({unit})', + + // 筛选 tab + filterAll: '全部', + filterIncome: '收入', + filterExpense: '支出', + filterRecharge: '充值', + filterConsume: '消费', + filterGift: '赠送', + + // 空状态 + emptyTips: '暂无会员卡记录', + + // 金额格式 + amountWithUnit: '{amount}元', +} diff --git a/lang/zh-cn/member/collection.js b/lang/zh-cn/member/collection.js index 7ba4f3f..d7e732e 100644 --- a/lang/zh-cn/member/collection.js +++ b/lang/zh-cn/member/collection.js @@ -1,4 +1,7 @@ export const lang = { //title为每个页面的标题 - title: '我的关注' + title: '我的关注', + emptyText: '暂无关注的商品', + emptySubText: '赶紧去逛逛, 关注心仪的商品吧', + deleteSuccess: '删除成功' } diff --git a/lang/zh-cn/member/modify_face.js b/lang/zh-cn/member/modify_face.js index cb7f76f..ffbf15f 100644 --- a/lang/zh-cn/member/modify_face.js +++ b/lang/zh-cn/member/modify_face.js @@ -1,4 +1,9 @@ export const lang = { //title为每个页面的标题 - title: '修改头像' + title: '修改头像', + clickToUpload: '点击上传', + confirmSave: '确认保存', + reupload: '重新上传', + uploadFailed: '头像上传失败', + modifySuccess: '头像修改成功' } diff --git a/lang/zh-cn/member/withdrawal.js b/lang/zh-cn/member/withdrawal.js index 9b99202..f404d90 100644 --- a/lang/zh-cn/member/withdrawal.js +++ b/lang/zh-cn/member/withdrawal.js @@ -1,4 +1,5 @@ export const lang = { //title为每个页面的标题 - title: '提现记录' + title: '提现记录', + emptyTips: '暂无提现记录' } diff --git a/lang/zh-cn/merch/list.js b/lang/zh-cn/merch/list.js index c7c2465..2c1d2da 100644 --- a/lang/zh-cn/merch/list.js +++ b/lang/zh-cn/merch/list.js @@ -1,7 +1,38 @@ export const lang = { + //title为每个页面的标题 + title: '商品列表', + + // 搜索框 placeholder + searchPlaceholder: '请输入您要搜索的商品', + // 按钮默认文本 buyText: '购买', + // 排序 + sort: { + comprehensive: '综合', + sales: '销量', + price: '价格', + filter: '筛选', + }, + + // 商品列表 + goods: { + consultNow: '立即咨询', + sold: '已售{num}{unit}', + defaultUnit: '件', + noGoods: '暂无商品', + }, + + // 筛选弹窗 + filter: { + title: '筛选', + allCategories: '全部分类', + all: '全部', + reset: '重置', + confirm: '确定', + }, + // 弹窗提示 modal: { title: '提示', diff --git a/lang/zh-cn/order/activist.js b/lang/zh-cn/order/activist.js index 968aedc..324261d 100644 --- a/lang/zh-cn/order/activist.js +++ b/lang/zh-cn/order/activist.js @@ -15,5 +15,10 @@ export const lang = { // 提示信息 toast: { cancelSuccess: '撤销成功' + }, + // 撤销退款弹窗 + cancelRefund: { + content: '撤销之后本次申请将会关闭,如后续仍有问题可再次发起申请。', + cancelText: '暂不撤销' } } diff --git a/lang/zh-cn/order/invoice.js b/lang/zh-cn/order/invoice.js new file mode 100644 index 0000000..7e20b5d --- /dev/null +++ b/lang/zh-cn/order/invoice.js @@ -0,0 +1,91 @@ +export const lang = { + //title为每个页面的标题 + title: '发票申请', + + // ====== 页头区 ====== + header: { + title: '发票信息', + desc: '请填写发票相关信息' + }, + + // ====== 发票类型 ====== + invoiceType: { + title: '发票类型', + paper: '纸质发票', + paperDesc: '发票将邮寄到指定地址', + electronic: '电子发票', + electronicDesc: '发票将发送至您的邮箱' + }, + + // ====== 发票抬头 ====== + invoiceTitle: { + title: '发票抬头', + personal: '个人', + company: '企业', + label: '发票抬头', + personalPlaceholder: '请输入个人姓名', + companyPlaceholder: '请输入企业名称', + taxpayerId: '纳税人识别号', + taxpayerIdPlaceholder: '请输入纳税人识别号' + }, + + // ====== 发票内容 ====== + invoiceContent: { + title: '发票内容', + label: '发票内容', + placeholder: '请选择发票内容' + }, + + // ====== 邮寄信息(纸质发票) ====== + mailInfo: { + title: '邮寄信息', + receiver: '收件人', + receiverPlaceholder: '请输入收件人姓名', + mobile: '联系电话', + mobilePlaceholder: '请输入联系电话', + address: '邮寄地址', + regionPlaceholder: '请选择所在地区', + detailAddress: '详细地址', + detailAddressPlaceholder: '请输入详细地址' + }, + + // ====== 邮箱信息(电子发票) ====== + emailInfo: { + title: '邮箱信息', + receiverEmail: '接收邮箱', + emailPlaceholder: '请输入接收发票的邮箱地址' + }, + + // ====== 费用区 ====== + fee: { + taxFee: '发票税费', + deliveryFee: '邮寄费用' + }, + + // ====== 底部提交区 ====== + footer: { + tip: '温馨提示:发票申请提交后将在{days}个工作日内处理', + submit: '提交申请' + }, + + // ====== 表单校验提示 ====== + validation: { + pleaseEnterTitle: '请输入发票抬头', + pleaseEnterTaxpayerId: '请输入纳税人识别号', + pleaseSelectContent: '请选择发票内容', + pleaseEnterReceiver: '请输入收件人姓名', + pleaseEnterMobile: '请输入联系电话', + pleaseSelectRegion: '请选择所在地区', + pleaseEnterAddress: '请输入详细地址', + pleaseEnterEmail: '请输入接收邮箱', + invalidEmail: '请输入正确的邮箱地址' + }, + + // ====== 接口消息 ====== + api: { + getConfigFailed: '获取发票配置失败', + submitSuccess: '发票申请提交成功', + submitFailed: '提交失败,请稍后重试', + networkError: '网络错误,请稍后重试' + } +} diff --git a/lang/zh-cn/order/logistics.js b/lang/zh-cn/order/logistics.js index 3736635..cc68c88 100644 --- a/lang/zh-cn/order/logistics.js +++ b/lang/zh-cn/order/logistics.js @@ -1,4 +1,16 @@ export const lang = { //title为每个页面的标题 - title: '物流信息' + title: '物流信息', + + // 订单物流信息 + order: { + logistics: { + // 快递公司信息 + expressCompany: '承运公司:', + trackingNo: '运单号:', + + // 提示消息 + orderInfoNotFound: '未获取到订单信息!' + } + } } diff --git a/lang/zh-cn/order/refund_detail.js b/lang/zh-cn/order/refund_detail.js index e346b1a..9f6a0a0 100644 --- a/lang/zh-cn/order/refund_detail.js +++ b/lang/zh-cn/order/refund_detail.js @@ -64,6 +64,12 @@ export const lang = { cancelSuccess: '撤销成功' }, + // ====== 撤销退款弹窗 ====== + cancelRefund: { + content: '撤销之后本次申请将会关闭,如后续仍有问题可再次发起申请。', + cancelText: '暂不撤销' + }, + // ====== 表单验证 ====== validate: { pleaseInputExpressCompany: '请输入物流公司', diff --git a/lang/zh-cn/seal/medium/detail.js b/lang/zh-cn/seal/medium/detail.js index 09c7913..99eb0dd 100644 --- a/lang/zh-cn/seal/medium/detail.js +++ b/lang/zh-cn/seal/medium/detail.js @@ -1,17 +1,27 @@ export const lang = { - // 页面标题 - title: '搜索结果', - // 操作按钮 - exportImage: '导出图片', - exportPdf: '导出PDF', + // 印章详情 + seal: { + medium: { + detail: { + // 页面标题 + title: '印章详情', + // 导出图片 + exportImage: '导出图片', + // 导出PDF + exportPdf: '导出PDF', + // 加载中 + loading: '加载中', + // 文件不存在 + fileNotExist: '文件不存在', + // 保存成功 + saveSuccess: '保存成功', + // 保存失败 + saveFailed: '保存失败', + // 下载失败 + downloadFailed: '下载失败', + } + } + } - // 加载提示 - loading: '正在加载', - - // 提示消息 - fileNotExist: '文件不存在', - saveSuccess: '保存成功', - saveFailed: '保存失败,请稍后重试', - downloadFailed: '下载失败', } diff --git a/lang/zh-cn/seal/medium/search.js b/lang/zh-cn/seal/medium/search.js index dd623c6..0c62d1f 100644 --- a/lang/zh-cn/seal/medium/search.js +++ b/lang/zh-cn/seal/medium/search.js @@ -1,23 +1,23 @@ export const lang = { - //title为每个页面的标题 - title: '介质材料搜索', + // 印章搜索页 seal: { medium: { search: { // 搜索框占位符 - placeholder: "请输入介质名称 '如汽油'", + placeholder: '请输入关键词搜索', // 搜索结果标题 searchResult: '搜索结果', - // 空状态文案 + // 空数据提示 noData: '暂无数据', // 弹窗标题 tip: '提示', - // 删除全部历史记录确认 - confirmDeleteAllHistory: '确认删除全部历史记录?', - // 删除单条历史记录确认 - confirmDeleteHistory: '确认删除该条历史记录?', + // 确认删除全部历史记录 + confirmDeleteAllHistory: '确定要删除全部搜索历史吗?', + // 确认删除单条历史记录 + confirmDeleteHistory: '确定要删除这条搜索历史吗?', } } } + } diff --git a/pages_order/list.vue b/pages_order/list.vue index 13adad9..6e46a4a 100644 --- a/pages_order/list.vue +++ b/pages_order/list.vue @@ -289,27 +289,27 @@ export default { getOrderStatus() { this.statusList = [{ status: 'all', - name: '全部', + name: this.$lang('status.all'), id: 'status_0' }, { status: 'waitpay', - name: '待付款', + name: this.$lang('status.waitpay'), id: 'status_1' }, { status: 'waitsend', - name: '待发货', + name: this.$lang('status.waitsend'), id: 'status_2' }, { status: 'waitconfirm', - name: '待收货', + name: this.$lang('status.waitconfirm'), id: 'status_3' }, { status: 'waitrate', - name: '已完成', + name: this.$lang('status.waitrate'), id: 'status_4' }, /*{ diff --git a/pages_promotion/fenxiao/child_fenxiao.vue b/pages_promotion/fenxiao/child_fenxiao.vue index a7acb2c..f543991 100644 --- a/pages_promotion/fenxiao/child_fenxiao.vue +++ b/pages_promotion/fenxiao/child_fenxiao.vue @@ -16,20 +16,20 @@ {{ item.level_name }} - 加入时间:{{ + {{ $lang('joinTime') }}{{ $util.timeStampTurnTime(item.bind_fenxiao_time).substring(0, 10) }} - {{ item.one_child_fenxiao_num + item.one_child_num }} 人 - {{ item.order_num }} 单 - {{ item.order_money | moneyFormat }} 元 + {{ item.one_child_fenxiao_num + item.one_child_num }}{{ $lang('peopleUnit') }} + {{ item.order_num }}{{ $lang('orderUnit') }} + {{ item.order_money | moneyFormat }}{{ $lang('currencyUnit') }} - + @@ -54,7 +54,7 @@ export default { setTimeout(() => { if (!this.addonIsExist.fenxiao) { this.$util.showToast({ - title: '商家未开启分销', + title: this.$lang('merchantNotOpenFenxiao'), mask: true, duration: 2000 }); diff --git a/pages_promotion/merch/list.vue b/pages_promotion/merch/list.vue new file mode 100644 index 0000000..b0a7baf --- /dev/null +++ b/pages_promotion/merch/list.vue @@ -0,0 +1,289 @@ + + + + + + diff --git a/pages_tool/ai-chat/ai-chat-message.vue b/pages_tool/ai-chat/ai-chat-message.vue index 2f9a473..eddb703 100644 --- a/pages_tool/ai-chat/ai-chat-message.vue +++ b/pages_tool/ai-chat/ai-chat-message.vue @@ -1125,18 +1125,18 @@ _handleStreamError(msg) { generateAIResponse(userMessage) { const responses = { - '你好': '您好!我是AI智能客服,很高兴为您服务!有什么可以帮助您的吗?', - '价格': '我们的产品价格根据型号和配置有所不同,具体价格请查看商品详情页面。', - '发货': '一般情况下,订单会在24小时内发货,具体时效请查看物流信息。', - '退货': '支持7天无理由退货,请确保商品完好无损。', - '客服': '我们的客服工作时间是9:00-18:00,有问题可以随时联系我们。' + '你好': this.$lang('autoReplyGreeting'), + '价格': this.$lang('autoReplyPrice'), + '发货': this.$lang('autoReplyShipping'), + '退货': this.$lang('autoReplyReturn'), + '客服': this.$lang('autoReplyService') }; for (let key in responses) { if (userMessage.includes(key)) { return responses[key]; } } - return `感谢您的咨询!关于"${userMessage}"的问题,我们的专业客服会尽快为您解答。您也可以查看我们的帮助文档获取更多信息。`; + return this.$lang('autoReplyDefault', { question: userMessage }); }, diff --git a/pages_tool/ai-chat/index.vue b/pages_tool/ai-chat/index.vue index fd14390..262bc67 100644 --- a/pages_tool/ai-chat/index.vue +++ b/pages_tool/ai-chat/index.vue @@ -143,7 +143,7 @@ export default { }, onShow() { - console.log('[AI Chat Page] onShow 触发'); + console.log(this.$lang('logOnShowTriggered')); // 监听键盘高度变化(H5 可能不支持,try-catch 保护) try { this._keyboardChangeHandler = (res) => { @@ -154,7 +154,7 @@ export default { }; uni.onKeyboardHeightChange(this._keyboardChangeHandler); } catch (e) { - console.warn('onKeyboardHeightChange 不可用:', e.message); + console.warn(this.$lang('logKeyboardChangeUnavailable') + ':', e.message); } // 每次页面显示时尝试加载历史记录(H5可能组件尚未创建,用 nextTick 确保 ref 就绪) this.$nextTick(() => { @@ -177,7 +177,7 @@ export default { }, onUnload() { - console.log('[AI Chat Page] onUnload 触发'); + console.log(this.$lang('logOnUnloadTriggered')); this.cleanup(); aiService.disconnectWebSocket(); }, @@ -233,7 +233,7 @@ export default { }, handleEventError(error, event) { - console.error('事件处理错误:', { + console.error(this.$lang('logEventHandleError') + ':', { error: error.message, eventType: event?.type, component: this. $options.name @@ -263,7 +263,7 @@ export default { this.calculateScrollViewHeight(); this.setupNavigationEvents(); } catch (error) { - console.error('初始化导航栏失败:', error); + console.error(this.$lang('logInitNavbarFailed') + ':', error); this.setFallbackNavigationValues(); } }, @@ -459,7 +459,7 @@ export default { sendProductToAI(product) { if (!this.$refs.chat) { - console.error('聊天组件未初始化') + console.error(this.$lang('logChatComponentNotInit')) return } @@ -503,7 +503,7 @@ export default { // 如果配置未加载,延迟重试(最多3次,防白屏) if (!servicerConfig) { - console.warn('【AI客服】servicerConfig 未加载,200ms后重试...'); + console.warn(this.$lang('logServicerConfigNotLoaded')); setTimeout(() => { this.checkAccessPermission(); }, 200); diff --git a/pages_tool/article/detail.vue b/pages_tool/article/detail.vue index 6f18e5b..8d3a45b 100644 --- a/pages_tool/article/detail.vue +++ b/pages_tool/article/detail.vue @@ -2,17 +2,17 @@ {{ detail.article_title }} - 发表时间: {{ $util.timeStampTurnTime(detail.create_time) }} + {{ $lang('publishTime') }} {{ $util.timeStampTurnTime(detail.create_time) }} - 阅读: + {{ $lang('readCount') }} {{ detail.read_num + detail.initial_read_num }} {{ detail.dianzan_num + detail.initial_dianzan_num }} - 人已赞 + {{ $lang('likedSuffix') }} diff --git a/pages_tool/article/list.vue b/pages_tool/article/list.vue index 253d619..da2f87a 100644 --- a/pages_tool/article/list.vue +++ b/pages_tool/article/list.vue @@ -21,7 +21,7 @@ - + @@ -88,7 +88,7 @@ export default { setPublicShare() { let shareUrl = this.$config.h5Domain + '/pages_tool/article/list'; this.$util.setPublicShare({ - title: '文章列表', + title: this.$lang('title'), desc: '', link: shareUrl, imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) : '' @@ -96,7 +96,7 @@ export default { } }, onShareAppMessage(res) { - var title = '文章列表'; + var title = this.$lang('title'); var path = '/pages_tool/article/list'; return { title: title, @@ -107,7 +107,7 @@ export default { }, //分享到朋友圈 onShareTimeline() { - var title = '文章列表'; + var title = this.$lang('title'); var query = '/pages_tool/article/list'; return { title: title, diff --git a/pages_tool/files/list.vue b/pages_tool/files/list.vue index dbcb7c0..e03f870 100644 --- a/pages_tool/files/list.vue +++ b/pages_tool/files/list.vue @@ -2,7 +2,7 @@ - @@ -20,7 +20,7 @@ {{ item.$orig.files_title }} - 查看PDF文件 + {{ $lang('viewPdf') }} @@ -29,7 +29,7 @@ - + @@ -116,7 +116,7 @@ export default { }, toDetail(item) { uni.showLoading({ - title: '正在加载' + title: this.$lang('loading') }) try { uni.downloadFile({ @@ -141,7 +141,7 @@ export default { complete: res => { if (res.statusCode === 404) { uni.showToast({ - title: '文件不存在', + title: this.$lang('fileNotExist'), icon: 'none' }) } diff --git a/pages_tool/form/form.vue b/pages_tool/form/form.vue index c352bd4..ace58ed 100644 --- a/pages_tool/form/form.vue +++ b/pages_tool/form/form.vue @@ -5,12 +5,12 @@ - 请填写表单所需信息 + {{ $lang('form.form.title') }} - + - + @@ -88,7 +88,7 @@ }, success: res => { if (res.code == 0) { - this.$util.showToast({ title: '提交成功' }) + this.$util.showToast({ title: this.$lang('form.form.submitSuccess') }) setTimeout(() => { this.complete = true; this.detail = null; diff --git a/pages_tool/member/bind_mobile.vue b/pages_tool/member/bind_mobile.vue new file mode 100644 index 0000000..3bc603e --- /dev/null +++ b/pages_tool/member/bind_mobile.vue @@ -0,0 +1,380 @@ + + + + + diff --git a/pages_tool/member/cancellation.vue b/pages_tool/member/cancellation.vue index 15d1e79..189f02b 100644 --- a/pages_tool/member/cancellation.vue +++ b/pages_tool/member/cancellation.vue @@ -10,9 +10,9 @@ - 勾选即表示您已阅读并同意本协议 + {{ $lang('agreeTermsText') }} - + @@ -60,7 +60,7 @@ export default { this.$util.redirectTo('/pages_tool/member/assets'); } else { this.$util.showToast({ - title: '请先勾选同意协议' + title: this.$lang('pleaseAgreeFirst') }); } } diff --git a/pages_tool/member/card_log.vue b/pages_tool/member/card_log.vue new file mode 100644 index 0000000..048064b --- /dev/null +++ b/pages_tool/member/card_log.vue @@ -0,0 +1,314 @@ + + + + + diff --git a/pages_tool/member/collection.vue b/pages_tool/member/collection.vue index 83e0458..db01fb4 100644 --- a/pages_tool/member/collection.vue +++ b/pages_tool/member/collection.vue @@ -13,7 +13,7 @@ {{ item.sku_name }} - ¥ + {{ $lang('common.currencySymbol') }} {{ parseFloat(item.discount_price).toFixed(2).split('.')[0] }} .{{ @@ -30,7 +30,7 @@ - diff --git a/pages_tool/member/modify_face.vue b/pages_tool/member/modify_face.vue index fece095..90d95c0 100644 --- a/pages_tool/member/modify_face.vue +++ b/pages_tool/member/modify_face.vue @@ -11,16 +11,16 @@ - + - + - - + + @@ -92,7 +92,7 @@ export default { }, fail: () => { this.$util.showToast({ - title: '头像上传失败' + title: this.$lang('member.modifyFace.uploadFailed') }); } }); @@ -114,7 +114,7 @@ export default { this.memberInfo.headimg = this.imgurl; this.$store.commit('setMemberInfo', this.memberInfo); this.$util.showToast({ - title: '头像修改成功' + title: this.$lang('member.modifyFace.modifySuccess') }); setTimeout(() => { this.$util.redirectTo('/pages_tool/member/info', {}, 'redirectTo'); diff --git a/pages_tool/member/public/js/collection.js b/pages_tool/member/public/js/collection.js index c941bc6..7d2ecb0 100644 --- a/pages_tool/member/public/js/collection.js +++ b/pages_tool/member/public/js/collection.js @@ -53,7 +53,7 @@ export default { success: res => { if (res.code == 0) { this.$util.showToast({ - title: "删除成功" + title: this.$lang('member.collection.deleteSuccess') }) let array = this.collectionList; let newArray = array.filter((v) => { diff --git a/pages_tool/member/withdrawal.vue b/pages_tool/member/withdrawal.vue index 380d22e..bc448fc 100644 --- a/pages_tool/member/withdrawal.vue +++ b/pages_tool/member/withdrawal.vue @@ -21,7 +21,7 @@ - + diff --git a/pages_tool/order/activist.vue b/pages_tool/order/activist.vue index 1bf466f..e7ea9df 100644 --- a/pages_tool/order/activist.vue +++ b/pages_tool/order/activist.vue @@ -18,12 +18,12 @@ {{ item.refund_status_name }} - ¥{{ item.price }} + {{ $lang('common.currencySymbol') }}{{ item.price }} ×{{ item.num }} - + {{ $lang('totalItems', { num: item.num }) }} diff --git a/pages_tool/order/invoice.vue b/pages_tool/order/invoice.vue new file mode 100644 index 0000000..d3fd910 --- /dev/null +++ b/pages_tool/order/invoice.vue @@ -0,0 +1,518 @@ + + + + + diff --git a/pages_tool/order/logistics.vue b/pages_tool/order/logistics.vue index f4222ae..b021016 100644 --- a/pages_tool/order/logistics.vue +++ b/pages_tool/order/logistics.vue @@ -34,11 +34,11 @@ - 承运公司: {{ packageItem.express_company_name }} + {{ $lang('order.logistics.expressCompany') }}{{ packageItem.express_company_name }} - 运单号: + {{ $lang('order.logistics.trackingNo') }} {{ packageItem.delivery_no }} @@ -124,7 +124,7 @@ export default { if (this.$refs.loadingCover) this.$refs.loadingCover.hide(); } else { this.$util.showToast({ - title: '未获取到订单信息!' + title: this.$lang('order.logistics.orderInfoNotFound') }); setTimeout(() => { this.$util.redirectTo('/pages_order/list'); diff --git a/pages_tool/order/public/js/refundMethod.js b/pages_tool/order/public/js/refundMethod.js index 2feb464..30c52fd 100644 --- a/pages_tool/order/public/js/refundMethod.js +++ b/pages_tool/order/public/js/refundMethod.js @@ -7,8 +7,8 @@ export default { */ cancleRefund(order_goods_id, callback) { uni.showModal({ - content: '撤销之后本次申请将会关闭,如后续仍有问题可再次发起申请。', - cancelText: '暂不撤销', + content: this.$lang('cancelRefund.content'), + cancelText: this.$lang('cancelRefund.cancelText'), cancelColor: '#898989', success: res => { if (res.confirm) { diff --git a/pages_tool/seal/medium/detail.vue b/pages_tool/seal/medium/detail.vue index 21ffada..baa242a 100644 --- a/pages_tool/seal/medium/detail.vue +++ b/pages_tool/seal/medium/detail.vue @@ -14,8 +14,8 @@ - {{ $lang('exportImage') }} - {{ $lang('exportPdf') }} + {{ $lang('seal.medium.detail.exportImage') }} + {{ $lang('seal.medium.detail.exportPdf') }} @@ -39,7 +39,7 @@ export default { } }, onLoad(options) { - this.title = this.$lang('title'); + this.title = this.$lang('seal.medium.detail.title'); if (options.keyword) { this.keyword = options.keyword; } @@ -51,7 +51,7 @@ export default { methods: { generatePdf() { const url = this.$util.img(this.info.files_url); - uni.showLoading({ title: this.$lang('loading') }); + uni.showLoading({ title: this.$lang('seal.medium.detail.loading') }); try { uni.downloadFile({ url: url, @@ -71,7 +71,7 @@ export default { }, complete: (res) => { if (res.statusCode === 404) { - uni.showToast({ title: this.$lang('fileNotExist'), icon: 'none' }); + uni.showToast({ title: this.$lang('seal.medium.detail.fileNotExist'), icon: 'none' }); } } }); @@ -81,7 +81,7 @@ export default { }, generateImage() { const url = this.$util.img(this.info.img_url); - uni.showLoading({ title: this.$lang('loading') }); + uni.showLoading({ title: this.$lang('seal.medium.detail.loading') }); uni.downloadFile({ url: url, success: (res) => { @@ -90,21 +90,21 @@ export default { uni.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success: () => { - this.$util.showToast({ title: this.$lang('saveSuccess') }); + this.$util.showToast({ title: this.$lang('seal.medium.detail.saveSuccess') }); }, fail: (err) => { if (err.errMsg !== 'saveImageToPhotosAlbum:fail auth deny' && err.errMsg !== 'saveImageToPhotosAlbum:fail:auth denied') { - this.$util.showToast({ title: this.$lang('saveFailed') }); + this.$util.showToast({ title: this.$lang('seal.medium.detail.saveFailed') }); } } }); } else { - this.$util.showToast({ title: this.$lang('downloadFailed') }); + this.$util.showToast({ title: this.$lang('seal.medium.detail.downloadFailed') }); } }, fail: (err) => { uni.hideLoading(); - this.$util.showToast({ title: this.$lang('downloadFailed') }); + this.$util.showToast({ title: this.$lang('seal.medium.detail.downloadFailed') }); } }); }, diff --git a/scripts/i18n-check.js b/scripts/i18n-check.js index 2943c6e..fa41875 100644 --- a/scripts/i18n-check.js +++ b/scripts/i18n-check.js @@ -367,10 +367,12 @@ function main() { return { text: result, inBlockComment }; } - // 判断一行是否是 $lang 调用(已经国际化) + // 判断一行是否是国际化调用(已经国际化) function isLangCall(line) { - // 匹配 $lang(' 或 $lang(" - return /\$lang\(\s*['"]/.test(line); + // 匹配 $lang(' 或 $lang(" 或 _t(' 或 _t(" 或 _getLang().lang(' 或 _getLang().lang(" + return /\$lang\(\s*['"]/.test(line) + || /_t\(\s*['"]/.test(line) + || /_getLang\(\)\.lang\(\s*['"]/.test(line); } const hardcodeResults = [];