feat: 新增多语言文案、优化导航及工具函数,修复部分业务逻辑

1. 新增多语言资源文件,覆盖文章、预约日期、会员信息、优惠券、表单、购物车、积分商城、分销、AI聊天等多个模块
2. 优化底部导航组件,使用多语言配置替代硬编码文案
3. 重构工具函数,新增从后端数据提取多语言文案的工具方法
4. 修复邀请好友页面的保存提示文案,替换为多语言版本
5. 修复商品SKU组件的提示文案,使用多语言配置
6. 重构AI聊天页面的帮助文档和回复模板,使用多语言配置
7. 优化空状态组件,支持多语言默认文案
8. 修复跳转逻辑,补全参数传递
9. 新增本地开发环境配置
This commit is contained in:
2026-06-25 18:15:31 +08:00
parent ca4e7fd170
commit 2d8846c64c
82 changed files with 3497 additions and 1062 deletions

View File

@@ -13,7 +13,7 @@
<view class="image" :class="fenXiaoAgreement.agreement.img ? '' : 'color-base-bg'">
<image v-if="fenXiaoAgreement.agreement.img" class="apply-adv" :src="$util.img(fenXiaoAgreement.agreement.img)" mode="widthFix" style="width: 100%;" show-menu-by-longpress/>
<view class="bg ns-gradient-otherpages-fenxiao-apply-apply-bg" v-else>
<view class="bg-title"><text>请填写申请信息</text></view>
<view class="bg-title"><text>{{ $lang('pleaseFillApplyInfo') }}</text></view>
<view class="bg-img">
<image :src="$util.img('public/uniapp/fenxiao/apply/edit.png')" mode="scaleToFill" show-menu-by-longpress></image>
</view>
@@ -24,44 +24,44 @@
<view class="app-info">
<view class="info">
<view class="apply-item">
<view class="title">邀请人</view>
<text class="shuru">{{ sourceMemberInfo.fenxiao_name }}</text>
<view class="title">{{ $lang('inviter') }}</view>
<text class="shuru">{{ sourceMemberInfo.fenxiao_name || $lang('none') }}</text>
</view>
<view class="apply-item">
<view class="title">{{ fenxiaoWords.fenxiao_name }}名称</view>
<input class="input" type="text" maxlength="30" :placeholder="'请输入' + fenxiaoWords.fenxiao_name + '名称'" v-model="formData.fenXiaoName" placeholder-class="pla-cla" />
<view class="title">{{ fenxiaoWords.fenxiao_name }}{{ $lang('nameLabel') }}</view>
<input class="input" type="text" maxlength="30" :placeholder="$lang('namePlaceholder', { name: fenxiaoWords.fenxiao_name })" v-model="formData.fenXiaoName" placeholder-class="pla-cla" />
</view>
<view class="apply-item">
<view class="title">手机号</view>
<input class="input" type="number" placeholder="请输入手机号" maxlength="11" v-model="formData.mobile" placeholder-class="pla-cla" />
<view class="title">{{ $lang('mobile') }}</view>
<input class="input" type="number" :placeholder="$lang('mobilePlaceholder')" maxlength="11" v-model="formData.mobile" placeholder-class="pla-cla" />
</view>
<view class="apply-xy" v-if="isAgreement" @click="ckeckedRuler()">
<view class="iconfont" :class="isChecked ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'">
</view>
我已阅读并了解
<text class="color-base-text" @click.stop="openPopup">【{{ fenxiaoWords.fenxiao_name }}申请协议】</text>
{{ $lang('haveReadAndUnderstand') }}
<text class="color-base-text" @click.stop="openPopup">{{ $lang('applyAgreement', { name: fenxiaoWords.fenxiao_name }) }}</text>
</view>
<view class="apply-btn">
<button @click="applyFenXiao" class="color-base-bg">申请成为{{ fenxiaoWords.fenxiao_name }}</button>
<button @click="applyFenXiao" class="color-base-bg">{{ $lang('applyBecome', { name: fenxiaoWords.fenxiao_name }) }}</button>
</view>
</view>
</view>
<view class="apply-message-wrap" v-if="fenxiaoConfig.fenxiao_condition == 2 || fenxiaoConfig.fenxiao_condition == 3">
<view class="apply-message">
<view class="apply-message-title color-base-bg-before">分销商申请条件</view>
<view class="apply-message-title color-base-bg-before">{{ $lang('applyConditionTitle') }}</view>
<text class="apply-message-info font-size-goods-tag" v-if="fenxiaoConfig.fenxiao_condition == 2">
申请成为{{ fenxiaoWords.fenxiao_name }},需要您的消费次数需要达到{{ fenxiaoConfig.consume_count }}次
{{ $lang('conditionConsumeCount', { name: fenxiaoWords.fenxiao_name, count: fenxiaoConfig.consume_count }) }}
</text>
<text class="apply-message-info font-size-goods-tag" v-if="fenxiaoConfig.fenxiao_condition == 3">
申请成为{{ fenxiaoWords.fenxiao_name }},需要您的消费金额需要达到{{ fenxiaoConfig.consume_money }}元
{{ $lang('conditionConsumeMoney', { name: fenxiaoWords.fenxiao_name, money: fenxiaoConfig.consume_money }) }}
</text>
</view>
</view>
<view class="app-info-list" v-if="fenxiaoConfig.fenxiao_condition == 4">
<view class="apply-message">
<view class="apply-message-title color-base-bg-before">分销商申请条件</view>
<text class="apply-message-info font-size-goods-tag">申请成为{{ fenxiaoWords.fenxiao_name }},需要购买以下指定商品(任选其一)</text>
<view class="apply-message-title color-base-bg-before">{{ $lang('applyConditionTitle') }}</view>
<text class="apply-message-info font-size-goods-tag">{{ $lang('conditionBuyGoods', { name: fenxiaoWords.fenxiao_name }) }}</text>
</view>
<view class="goods-list" v-for="(item, index) in goodsList" :key="index" @click="toDetail(item)">
<view class="goods-img">
@@ -79,7 +79,7 @@
</view>
</view>
<view class="content-lists" v-if="isShow" @click="onOpen()">
{{ isOpen ? '展开更多' : '收起' }}
{{ isOpen ? $lang('expandMore') : $lang('collapse') }}
<text class="iconfont icon-unfold" style="font-weight: bold;" v-if="isOpen"></text>
<text class="iconfont icon-fold" v-else></text>
</view>
@@ -89,16 +89,16 @@
<view class="empty" v-else-if="basicsConfig.is_apply == 0" style="margin-top:40rpx;">
<block v-if="fenxiaoConfig.fenxiao_condition == 2 || fenxiaoConfig.fenxiao_condition == 3">
<image :src="$util.img('public/uniapp/fenxiao/index/no-fenxiao.png')" mode="widthFix" show-menu-by-longpress></image>
<text v-if="fenxiaoConfig.fenxiao_condition == 2">申请成为{{ fenxiaoWords.fenxiao_name }},需要您的消费次数需要达到{{ fenxiaoConfig.consume_count }}次</text>
<text v-if="fenxiaoConfig.fenxiao_condition == 2">{{ $lang('conditionConsumeCount', { name: fenxiaoWords.fenxiao_name, count: fenxiaoConfig.consume_count }) }}</text>
<text v-if="fenxiaoConfig.fenxiao_condition == 3">
申请成为{{ fenxiaoWords.fenxiao_name }},需要您的消费金额需要达到{{ fenxiaoConfig.consume_money | moneyFormat }}元
{{ $lang('conditionConsumeMoney', { name: fenxiaoWords.fenxiao_name, money: fenxiaoConfig.consume_money | moneyFormat }) }}
</text>
</block>
<view class="apply-wrap" v-if="fenxiaoConfig.fenxiao_condition == 4">
<view class="app-info-list">
<view class="apply-message">
<view class="apply-message-title color-base-bg-before">成为分销商的条件</view>
<text class="apply-message-info font-size-goods-tag">成为{{ fenxiaoWords.fenxiao_name }},需要购买以下指定商品(任选其一)</text>
<view class="apply-message-title color-base-bg-before">{{ $lang('becomeConditionTitle') }}</view>
<text class="apply-message-info font-size-goods-tag">{{ $lang('becomeConditionBuyGoods', { name: fenxiaoWords.fenxiao_name }) }}</text>
</view>
<view class="goods-list" v-for="(item, index) in goodsList" :key="index" @click="toDetail(item)">
<view class="goods-img">
@@ -114,7 +114,7 @@
</view>
</view>
<view class="content-lists" v-if="isShow" @click="onOpen()">
{{ isOpen ? '展开更多' : '收起' }}
{{ isOpen ? $lang('expandMore') : $lang('collapse') }}
<text class="iconfont icon-unfold" style="font-weight: bold;" v-if="isOpen"></text>
<text class="iconfont icon-fold" v-else></text>
</view>
@@ -123,15 +123,15 @@
</view>
<view class="empty" v-else>
<image :src="$util.img('public/uniapp/fenxiao/index/no-fenxiao.png')" mode="widthFix" show-menu-by-longpress></image>
<text>您还不是分销商</text>
<text>{{ $lang('notFenxiao') }}</text>
</view>
</view>
<view class="empty" v-else>
<image :src="$util.img('public/uniapp/fenxiao/index/no-fenxiao.png')" mode="widthFix" show-menu-by-longpress></image>
<text v-if="status == 1">您已提交{{ fenxiaoWords.fenxiao_name }}申请,等待平台审核</text>
<text v-if="status == 1">{{ $lang('applyPending', { name: fenxiaoWords.fenxiao_name }) }}</text>
<block v-else-if="status == -1">
<text>您提交的{{ fenxiaoWords.fenxiao_name }}申请,已被拒绝,请再接再厉</text>
<view class="again-btn color-base-bg" @click="againApply">重新申请</view>
<text>{{ $lang('applyRejected', { name: fenxiaoWords.fenxiao_name }) }}</text>
<view class="again-btn color-base-bg" @click="againApply">{{ $lang('reapply') }}</view>
</block>
</view>
<view @touchmove.prevent v-if="fenXiaoAgreement.document">
@@ -162,8 +162,8 @@
isShow: true,
isIphoneX: false,
// 推荐人信息
sourceMemberInfo: {
fenxiao_name: '无'
sourceMemberInfo: {
fenxiao_name: ''
},
formData: {
fenXiaoName: '',
@@ -191,7 +191,7 @@
setTimeout( () => {
if (!this.addonIsExist.fenxiao) {
this.$util.showToast({
title: '商家未开启分销',
title: this.$lang('merchantNotOpenFenxiao'),
mask: true,
duration: 2000
});
@@ -207,7 +207,7 @@
async onShow() {
this.isIphoneX = this.$util.uniappIsIPhoneX();
if (this.fenxiaoWords && this.fenxiaoWords.fenxiao_name) this.$langConfig.title(this.fenxiaoWords.fenxiao_name + '申请');
if (this.fenxiaoWords && this.fenxiaoWords.fenxiao_name) this.$langConfig.title(this.fenxiaoWords.fenxiao_name + this.$lang('applySuffix'));
if (this.storeToken) {
this.applyStatus();
@@ -275,7 +275,7 @@
if (!this.fenXiaoValidata()) return;
if (this.isAgreement && !this.isChecked) {
this.$util.showToast({
title: '请仔细阅读协议,并勾选'
title: this.$lang('pleaseReadAndCheckAgreement')
});
return;
}
@@ -326,22 +326,22 @@
closePopup() {
this.$refs.applyPopup.close();
},
fenXiaoValidata() {
let rule = [{
name: 'fenXiaoName',
checkType: 'required',
errorMsg: '请输入' + this.fenxiaoWords.fenxiao_name + '名称'
},
{
name: 'mobile',
checkType: 'required',
errorMsg: '请输入手机号'
},
{
name: 'mobile',
checkType: 'phoneno',
errorMsg: '请输入正确的手机号'
}
fenXiaoValidata() {
let rule = [{
name: 'fenXiaoName',
checkType: 'required',
errorMsg: this.$lang('pleaseEnterName', { name: this.fenxiaoWords.fenxiao_name })
},
{
name: 'mobile',
checkType: 'required',
errorMsg: this.$lang('pleaseEnterMobile')
},
{
name: 'mobile',
checkType: 'phoneno',
errorMsg: this.$lang('pleaseEnterValidMobile')
}
];
var checkRes = validate.check(this.formData, rule);
if (checkRes) {