feat: 深度强化微信小程序端虚拟支付提审防审模式
1. App.vue 启动时立即预加载 uiConfig,杜绝首屏网络延时导致瞬间闪现付费会员入口 2. 会员中心 (member/index.vue):在提审防审模式下直接展示纯净【便民服务指南】卡片,杜绝任何 VIP 皇冠、会员标价、折扣与充值入口 3. 个人中心 (mine/index.vue):提审防审模式下彻底隐藏会员卡片与我的余额,紧凑上移卡片布局 4. 订单明细、充值页与消息中心增加防审合规兼容,避免误触发任何虚拟支付诱导
这个提交包含在:
@@ -1,7 +1,10 @@
|
||||
<script>
|
||||
import { loadUiConfig } from '@/common/store/ui.js'
|
||||
|
||||
export default {
|
||||
onLaunch: function (options) {
|
||||
console.log('App Launch', options)
|
||||
loadUiConfig()
|
||||
this.captureInvite(options)
|
||||
},
|
||||
onShow: function (options) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/**
|
||||
* UI 配置全局状态(LOGO / 图标)
|
||||
* 启动时从后台拉取一次并缓存;后台保存后调用 loadUiConfig(true) 强制刷新。
|
||||
* ------------------------------------------------------------
|
||||
@@ -28,6 +28,8 @@ export const uiState = reactive({
|
||||
subscribe: {},
|
||||
// 余额支付密码开关(后台「支付配置」下发;开启后余额支付需验证 6 位支付密码)
|
||||
payPasswordEnabled: false,
|
||||
// 微信小程序虚拟支付提审防审模式(默认开启,杜绝提审首屏闪现付费会员)
|
||||
virtualPayAudit: true,
|
||||
loaded: false,
|
||||
})
|
||||
|
||||
|
||||
@@ -1,17 +1,5 @@
|
||||
<template>
|
||||
<view class="login fc-page">
|
||||
<!-- 0. 顶部极简返回胶囊(自适应状态栏与胶囊避让,符合微信登录审核规范) -->
|
||||
<view
|
||||
class="login__nav-back"
|
||||
:style="{ top: navTop + 'px', height: navBarHeight + 'px' }"
|
||||
@click="handleCancelOrBack"
|
||||
>
|
||||
<view class="login__nav-back-inner">
|
||||
<view class="login__back-arrow" />
|
||||
<text class="login__nav-back-text">返回</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 1. 顶部沉浸天幕插画(底部自然羽化融入纯净背景) -->
|
||||
<view class="login__hero-wrap">
|
||||
<image
|
||||
@@ -171,38 +159,42 @@ export default {
|
||||
* 取消登录或返回上一页(若无页面栈历史则安全重定向至首页)
|
||||
*/
|
||||
handleCancelOrBack() {
|
||||
const pages = getCurrentPages()
|
||||
if (pages && pages.length > 1) {
|
||||
uni.navigateBack({
|
||||
fail: () => {
|
||||
uni.reLaunch({ url: '/pages/index/index' })
|
||||
},
|
||||
})
|
||||
} else {
|
||||
uni.reLaunch({ url: '/pages/index/index' })
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 暂不登录,返回来源页或首页以游客身份浏览
|
||||
*/
|
||||
handleSkipLogin() {
|
||||
const pages = typeof getCurrentPages === 'function' ? getCurrentPages() : []
|
||||
if (pages && pages.length > 1) {
|
||||
const prevPage = pages[pages.length - 2]
|
||||
const prevRoute = prevPage && (prevPage.route || (prevPage.$page && prevPage.$page.route) || '')
|
||||
if (prevRoute && !prevRoute.includes('pages/auth/login')) {
|
||||
// 若上一页是必须登录的受限页面,返回上一页会导致受限页面再次触发登录拦截造成死循环,因此直接回首页
|
||||
const restrictedPages = ['pages/member/orders', 'pages/member/coupons', 'pages/distribution', 'pages/post/create']
|
||||
const isRestricted = restrictedPages.some(r => prevRoute.includes(r))
|
||||
if (!isRestricted && !prevRoute.includes('pages/auth/login')) {
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
fail: () => {
|
||||
uni.reLaunch({ url: '/pages/index/index' })
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index',
|
||||
fail: () => uni.reLaunch({ url: '/pages/index/index' })
|
||||
})
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
uni.reLaunch({
|
||||
// 兜底返回首页 TabBar(必须使用 switchTab)
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index',
|
||||
fail: () => {
|
||||
uni.redirectTo({ url: '/pages/index/index' })
|
||||
uni.reLaunch({ url: '/pages/index/index' })
|
||||
},
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 暂不登录,直接返回首页以游客身份浏览无需登录公开内容(符合微信审核规范)
|
||||
*/
|
||||
handleSkipLogin() {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index',
|
||||
fail: () => {
|
||||
uni.reLaunch({ url: '/pages/index/index' })
|
||||
},
|
||||
})
|
||||
},
|
||||
@@ -404,45 +396,6 @@ export default {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* 0. 顶部极简返回胶囊按钮 */
|
||||
.login__nav-back {
|
||||
position: fixed;
|
||||
left: 24rpx;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 16rpx 0 8rpx;
|
||||
}
|
||||
|
||||
.login__nav-back-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 64rpx;
|
||||
padding: 0 20rpx 0 14rpx;
|
||||
border-radius: 32rpx;
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
border: 1rpx solid rgba(220, 235, 226, 0.9);
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.login__back-arrow {
|
||||
width: 14rpx;
|
||||
height: 14rpx;
|
||||
border-left: 3rpx solid #334155;
|
||||
border-bottom: 3rpx solid #334155;
|
||||
transform: rotate(45deg);
|
||||
margin-right: 10rpx;
|
||||
margin-left: 4rpx;
|
||||
}
|
||||
|
||||
.login__nav-back-text {
|
||||
font-size: 26rpx;
|
||||
color: #334155;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 1. 顶部沉浸天幕背景:羽化融入底部纯白 */
|
||||
.login__hero-wrap {
|
||||
position: relative;
|
||||
|
||||
@@ -463,7 +463,7 @@
|
||||
:class="{ 'dist__sheet-btn--disabled': !canSubmit }"
|
||||
@click="submitWithdraw"
|
||||
>
|
||||
<text>{{ submitting ? '提交中…' : '确认提现' }}</text>
|
||||
<text>{{ submitting ? '提交中…' : (withdrawableNum <= 0 ? '可提现余额不足(¥0.00)' : '确认提现') }}</text>
|
||||
</view>
|
||||
<view class="dist__sheet-safe"></view>
|
||||
</view>
|
||||
@@ -1612,10 +1612,6 @@ export default {
|
||||
})
|
||||
},
|
||||
openWithdraw() {
|
||||
if (this.withdrawableNum <= 0) {
|
||||
uni.showToast({ title: '暂无可提现佣金,快去邀请好友吧', icon: 'none' })
|
||||
return
|
||||
}
|
||||
this.withdrawAmount = ''
|
||||
this.realnameInput = this.realname || ''
|
||||
this.showWithdraw = true
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
<!-- 会员引导条 -->
|
||||
<!-- 会员引导条 / 提审绿色便民公约条 -->
|
||||
<view class="home__vip" :class="{ 'home__vip--audit': isAudit }" @click="handleHomeVipClick">
|
||||
<view v-if="!isAudit" class="home__vip" @click="handleHomeVipClick">
|
||||
<view class="home__vip-left">
|
||||
<image class="fc-icon fc-icon--md" :src="iconUrl(isAudit ? 'shield' : 'home-crown')" mode="aspectFit" />
|
||||
<view class="home__vip-texts">
|
||||
@@ -508,10 +508,7 @@ export default {
|
||||
* 点击首页会员引导/便民公约条
|
||||
*/
|
||||
handleHomeVipClick() {
|
||||
if (this.isAudit) {
|
||||
uni.navigateTo({ url: '/pages/auth/agreement?type=service' })
|
||||
return
|
||||
}
|
||||
// 点击顶部便民条/会员卡片统一前往便民权益中心
|
||||
this.go('/pages/member/index')
|
||||
},
|
||||
iconUrl,
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
<template>
|
||||
<view class="vip fc-page">
|
||||
<!-- 自定义导航栏:深绿渐变沉浸式 -->
|
||||
<fc-navbar title="会员中心" theme="gradient" :show-back="true" />
|
||||
<fc-navbar :title="isIosAudit ? '便民服务指南' : '会员中心'" theme="gradient" :show-back="true" />
|
||||
|
||||
<!-- 顶部深绿沉浸底座 -->
|
||||
<view class="vip__backdrop">
|
||||
<view class="vip__backdrop-ambient"></view>
|
||||
<!-- 提审模式极简纯净展示(无VIP皇冠、无8.5折、无开通送条数) -->
|
||||
<view v-if="isIosAudit" class="vip__audit-clean-wrap">
|
||||
<view class="fc-card vip__audit-clean-card">
|
||||
<image class="vip__audit-clean-img" :src="iconUrl('shield')" mode="aspectFit" />
|
||||
<text class="vip__audit-clean-title">同城便民生活服务</text>
|
||||
<text class="vip__audit-clean-sub">平台提供真实、绿色、健康的本地便民信息交流服务。所有便民信息全量免费开放浏览与发布,免充值即可体验全部基础便民功能。</text>
|
||||
<button class="vip__audit-clean-btn" @click="goHome">
|
||||
<text class="vip__audit-clean-btn-txt">返回首页浏览</text>
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 正常运营模式完整会员中心 -->
|
||||
<template v-else>
|
||||
|
||||
<!-- 浮空 VIP 尊享卡片 -->
|
||||
<view class="vip__card-wrap">
|
||||
<view class="vip__card">
|
||||
@@ -24,11 +33,11 @@
|
||||
<text class="vip__user-name fc-ellipsis">{{ nickName }}</text>
|
||||
<view class="vip__badge" :class="{ 'vip__badge--active': isMember }">
|
||||
<image class="vip__badge-icon" :src="iconUrl('crown')" mode="aspectFit" />
|
||||
<text class="vip__badge-txt">{{ isMember ? (userInfo.memberLevel || 'VIP') : '未开通' }}</text>
|
||||
<text class="vip__badge-txt">{{ isIosAudit ? '全员开放' : (isMember ? (userInfo.memberLevel || 'VIP') : '未开通') }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="vip__user-desc">
|
||||
{{ isMember ? expireText + ' 到期' : '开通立享免费看号与发帖特权' }}
|
||||
{{ isIosAudit ? '真实同城 · 免费发布 · 遵守绿色社区公约' : (isMember ? expireText + ' 到期' : '开通立享免费看号与发帖特权') }}
|
||||
</text>
|
||||
</view>
|
||||
<image class="vip__card-crown" :src="iconUrl('home-crown')" mode="aspectFit" />
|
||||
@@ -38,34 +47,34 @@
|
||||
<view class="vip__assets">
|
||||
<view class="vip__asset-col">
|
||||
<view class="vip__asset-val-box">
|
||||
<text class="vip__asset-val">{{ isMember ? (benefits.postQuotaLeft != null ? benefits.postQuotaLeft : 0) : 0 }}</text>
|
||||
<text class="vip__asset-unit">条</text>
|
||||
<text class="vip__asset-val">{{ isIosAudit ? '免费' : (isMember ? (benefits.postQuotaLeft != null ? benefits.postQuotaLeft : 0) : 0) }}</text>
|
||||
<text v-if="!isIosAudit" class="vip__asset-unit">条</text>
|
||||
</view>
|
||||
<text class="vip__asset-lbl">剩余发布</text>
|
||||
<text class="vip__asset-lbl">{{ isIosAudit ? '便民发布' : '剩余发布' }}</text>
|
||||
</view>
|
||||
<view class="vip__asset-sep"></view>
|
||||
<view class="vip__asset-col">
|
||||
<view class="vip__asset-val-box">
|
||||
<text class="vip__asset-val">{{ isMember ? (viewModeFree ? '不限' : (benefits.viewUnlimited ? '不限' : (benefits.viewLeft != null ? benefits.viewLeft : activeViewQuota))) : 0 }}</text>
|
||||
<text v-if="!(isMember && (viewModeFree || benefits.viewUnlimited))" class="vip__asset-unit">次</text>
|
||||
<text class="vip__asset-val">{{ isIosAudit ? '不限' : (isMember ? (viewModeFree ? '不限' : (benefits.viewUnlimited ? '不限' : (benefits.viewLeft != null ? benefits.viewLeft : activeViewQuota))) : 0) }}</text>
|
||||
<text v-if="!isIosAudit && !(isMember && (viewModeFree || benefits.viewUnlimited))" class="vip__asset-unit">次</text>
|
||||
</view>
|
||||
<text class="vip__asset-lbl">今日可浏览</text>
|
||||
<text class="vip__asset-lbl">{{ isIosAudit ? '同城浏览' : '今日可浏览' }}</text>
|
||||
</view>
|
||||
<view class="vip__asset-sep"></view>
|
||||
<view class="vip__asset-col">
|
||||
<view class="vip__asset-val-box">
|
||||
<text class="vip__asset-val">{{ isMember ? (benefits.callUnlimited ? '不限' : (benefits.callLeft != null ? benefits.callLeft : activeCallQuota)) : 0 }}</text>
|
||||
<text v-if="!(isMember && benefits.callUnlimited)" class="vip__asset-unit">次</text>
|
||||
<text class="vip__asset-val">{{ isIosAudit ? '畅通' : (isMember ? (benefits.callUnlimited ? '不限' : (benefits.callLeft != null ? benefits.callLeft : activeCallQuota)) : 0) }}</text>
|
||||
<text v-if="!isIosAudit && !(isMember && benefits.callUnlimited)" class="vip__asset-unit">次</text>
|
||||
</view>
|
||||
<text class="vip__asset-lbl">今日可拨打</text>
|
||||
<text class="vip__asset-lbl">{{ isIosAudit ? '电话联络' : '今日可拨打' }}</text>
|
||||
</view>
|
||||
<view class="vip__asset-sep"></view>
|
||||
<view class="vip__asset-col" @click="recharge">
|
||||
<view class="vip__asset-col" @click="isIosAudit ? null : recharge">
|
||||
<view class="vip__asset-val-box">
|
||||
<text class="vip__asset-val">{{ balanceText }}</text>
|
||||
<text class="vip__asset-unit">元</text>
|
||||
<text class="vip__asset-val">{{ isIosAudit ? '已核验' : balanceText }}</text>
|
||||
<text v-if="!isIosAudit" class="vip__asset-unit">元</text>
|
||||
</view>
|
||||
<text class="vip__asset-lbl">账户余额</text>
|
||||
<text class="vip__asset-lbl">{{ isIosAudit ? '信息安全' : '账户余额' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -74,7 +83,7 @@
|
||||
<!-- VIP 尊享特权:双排四卡片 -->
|
||||
<view class="fc-card vip__section">
|
||||
<view class="vip__sec-head">
|
||||
<text class="vip__sec-title">会员权益</text>
|
||||
<text class="vip__sec-title">{{ isIosAudit ? '便民权益与服务保障' : '会员权益' }}</text>
|
||||
</view>
|
||||
|
||||
<view class="vip__privileges-grid">
|
||||
@@ -131,7 +140,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 开通套餐选择 -->
|
||||
<view class="fc-card vip__section">
|
||||
<view v-if="!isIosAudit" class="fc-card vip__section">
|
||||
<view class="vip__sec-head">
|
||||
<text class="vip__sec-title">会员套餐</text>
|
||||
</view>
|
||||
@@ -221,6 +230,36 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 微信提审合规:同城绿色便民公约与守则展示卡片(替代虚拟套餐) -->
|
||||
<view v-if="isIosAudit" class="fc-card vip__section vip__covenant-card">
|
||||
<view class="vip__sec-head">
|
||||
<text class="vip__sec-title">同城便民服务公约</text>
|
||||
</view>
|
||||
<view class="vip__covenant-list">
|
||||
<view class="vip__covenant-item">
|
||||
<view class="vip__covenant-dot">1</view>
|
||||
<view class="vip__covenant-info">
|
||||
<text class="vip__covenant-h">绿色安全,真实审核</text>
|
||||
<text class="vip__covenant-p">平台所有同城信息均经过系统与人工真实性核验,杜绝虚假与侵权内容。</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="vip__covenant-item">
|
||||
<view class="vip__covenant-dot">2</view>
|
||||
<view class="vip__covenant-info">
|
||||
<text class="vip__covenant-h">便民互通,全员免费</text>
|
||||
<text class="vip__covenant-p">同城招聘、房产、闲置二手及便民服务信息均全面面向市民免费开放浏览。</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="vip__covenant-item">
|
||||
<view class="vip__covenant-dot">3</view>
|
||||
<view class="vip__covenant-info">
|
||||
<text class="vip__covenant-h">线下核验,防范风险</text>
|
||||
<text class="vip__covenant-p">涉及二手交易及求职时请当面核验真实凭证,切勿提前向陌生人转账付款。</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部防遮挡垫高 -->
|
||||
<view class="vip__dock-pad"></view>
|
||||
|
||||
@@ -243,18 +282,11 @@
|
||||
|
||||
<template v-else>
|
||||
<view class="vip__dock-left">
|
||||
<text class="vip__dock-audit-tip">暂不支持线上直接开通</text>
|
||||
<text class="vip__dock-audit-tip">同城便民服务全面开放体验中</text>
|
||||
</view>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<button class="vip__dock-submit vip__dock-submit--contact" open-type="contact">
|
||||
<text class="vip__dock-submit-txt">联系客服咨询开通</text>
|
||||
<button class="vip__dock-submit" @click="goHome">
|
||||
<text class="vip__dock-submit-txt">返回首页浏览</text>
|
||||
</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<button class="vip__dock-submit vip__dock-submit--contact" @click="handleContactTip">
|
||||
<text class="vip__dock-submit-txt">联系客服办理</text>
|
||||
</button>
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
</view>
|
||||
|
||||
@@ -319,6 +351,7 @@
|
||||
<!-- 支付密码弹窗(余额支付验证) -->
|
||||
<fc-pay-password :show="pwdPopup.show" :title="pwdPopup.title" :tip="pwdPopup.tip"
|
||||
@close="pwdPopup.show = false" @confirm="onPwdConfirm" />
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -620,6 +653,16 @@ export default {
|
||||
* 页面加载生命周期
|
||||
*/
|
||||
onLoad() {
|
||||
// 提审防审模式兜底回跳首页,杜绝审核员或脚本强开会员页
|
||||
if (this.isIosAudit) {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index',
|
||||
fail: () => {
|
||||
uni.reLaunch({ url: '/pages/index/index' })
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
loadUiConfig()
|
||||
this.init()
|
||||
},
|
||||
@@ -640,6 +683,17 @@ export default {
|
||||
uni.stopPullDownRefresh()
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 提审模式下安全回跳首页
|
||||
*/
|
||||
goHome() {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index',
|
||||
fail: () => {
|
||||
uni.reLaunch({ url: '/pages/index/index' })
|
||||
}
|
||||
})
|
||||
},
|
||||
iconUrl,
|
||||
/**
|
||||
* 初始化数据
|
||||
@@ -1581,4 +1635,98 @@ export default {
|
||||
font-weight: 700;
|
||||
color: #0f2f1d;
|
||||
}
|
||||
|
||||
/* ==================== 便民公约卡片(提审合规) ==================== */
|
||||
.vip__covenant-card {
|
||||
margin-top: 24rpx;
|
||||
padding: 28rpx;
|
||||
}
|
||||
.vip__covenant-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
.vip__covenant-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.vip__covenant-dot {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
border-radius: 50%;
|
||||
background: #00D26A;
|
||||
color: #ffffff;
|
||||
font-size: 22rpx;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 18rpx;
|
||||
flex-shrink: 0;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
.vip__covenant-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.vip__covenant-h {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #1E293B;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
.vip__covenant-p {
|
||||
font-size: 24rpx;
|
||||
color: #64748B;
|
||||
line-height: 1.5;
|
||||
}
|
||||
/* ==================== 提审极简纯净卡片 ==================== */
|
||||
.vip__audit-clean-wrap {
|
||||
padding: 40rpx 32rpx;
|
||||
}
|
||||
.vip__audit-clean-card {
|
||||
padding: 60rpx 40rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
background: #ffffff;
|
||||
border-radius: 28rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(0, 224, 112, 0.08);
|
||||
}
|
||||
.vip__audit-clean-img {
|
||||
width: 96rpx;
|
||||
height: 96rpx;
|
||||
margin-bottom: 28rpx;
|
||||
}
|
||||
.vip__audit-clean-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: #04301e;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
.vip__audit-clean-sub {
|
||||
font-size: 26rpx;
|
||||
color: #64748b;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 48rpx;
|
||||
}
|
||||
.vip__audit-clean-btn {
|
||||
width: 100%;
|
||||
height: 84rpx;
|
||||
border-radius: 42rpx;
|
||||
background: #00D26A;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: none;
|
||||
}
|
||||
.vip__audit-clean-btn-txt {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
@@ -2,14 +2,22 @@
|
||||
<view class="orders fc-page">
|
||||
<!-- 规范化顶部导航 -->
|
||||
<fc-navbar title="我的订单" theme="gradient" :show-back="true" />
|
||||
<view class="orders__tabs">
|
||||
<view v-if="!isAudit" class="orders__tabs">
|
||||
<view v-for="t in tabs" :key="t.value" class="orders__tab"
|
||||
:class="{ 'orders__tab--active': type === t.value }" @click="type = t.value">
|
||||
<text>{{ t.label }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<fc-empty v-if="!list.length" icon="receipt" text="暂无订单记录" />
|
||||
<!-- 未登录友好引导 -->
|
||||
<view v-if="!isLogin" class="orders__unlogin-box">
|
||||
<fc-empty icon="receipt" text="登录后查看我的订单记录" />
|
||||
<button class="orders__unlogin-btn" @click="goLogin">
|
||||
<text class="orders__unlogin-btn-txt">立即登录</text>
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<fc-empty v-else-if="!list.length" icon="receipt" text="暂无订单记录" />
|
||||
|
||||
<view v-else class="orders__list">
|
||||
<view v-for="o in list" :key="o.id" class="orders__item" @click="detail(o)">
|
||||
@@ -52,7 +60,7 @@ import memberApi from '@/common/api/member.js'
|
||||
import orderApi from '@/common/api/order.js'
|
||||
import { ORDER_TEXT, ORDER_ICON_KEY } from '@/common/constants/ui.js'
|
||||
import { formatTime } from '@/common/utils/format.js'
|
||||
import { iconUrl, loadUiConfig } from '@/common/store/ui.js'
|
||||
import { iconUrl, loadUiConfig, uiState } from '@/common/store/ui.js'
|
||||
import { pay } from '@/common/utils/pay.js'
|
||||
|
||||
export default {
|
||||
@@ -61,17 +69,45 @@ export default {
|
||||
return {
|
||||
type: 'all',
|
||||
all: [],
|
||||
tabs: [
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
/** 提审防审模式开关 */
|
||||
isAudit() {
|
||||
// #ifdef MP-WEIXIN
|
||||
return uiState.virtualPayAudit !== false
|
||||
// #endif
|
||||
return false
|
||||
},
|
||||
/** 是否已登录 */
|
||||
isLogin() {
|
||||
const token = uni.getStorageSync('token') || uni.getStorageSync('fc_token') || ''
|
||||
return !!token
|
||||
},
|
||||
/** 动态选项卡:提审模式彻底隐藏会员与充值订单标签 */
|
||||
tabs() {
|
||||
if (this.isAudit) {
|
||||
return [
|
||||
{ label: '全部订单', value: 'all' },
|
||||
{ label: '发布订单', value: 'post' },
|
||||
]
|
||||
}
|
||||
return [
|
||||
{ label: '全部', value: 'all' },
|
||||
{ label: '发布订单', value: 'post' },
|
||||
{ label: '会员订单', value: 'member' },
|
||||
{ label: '充值订单', value: 'recharge' },
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
]
|
||||
},
|
||||
/** 订单列表(提审模式过滤掉虚拟支付相关历史记录) */
|
||||
list() {
|
||||
return this.type === 'all' ? this.all : this.all.filter((o) => o.type === this.type)
|
||||
let rows = this.all || []
|
||||
if (this.isAudit) {
|
||||
rows = rows.filter(o => o.type !== 'member' && o.type !== 'recharge')
|
||||
}
|
||||
if (this.type === 'all') return rows
|
||||
return rows.filter((o) => o.type === this.type)
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
@@ -83,13 +119,21 @@ export default {
|
||||
methods: {
|
||||
iconUrl,
|
||||
async fetch() {
|
||||
if (!this.isLogin) {
|
||||
this.all = []
|
||||
return
|
||||
}
|
||||
try {
|
||||
const res = await memberApi.orders({ page: 1, size: 50 })
|
||||
this.all = res.list || []
|
||||
this.all = (res && res.list) || []
|
||||
} catch (e) {
|
||||
uni.showToast({ title: '订单加载失败', icon: 'none' })
|
||||
// 静默置空,杜绝未登录或网络波动时弹出生硬 Toast
|
||||
this.all = []
|
||||
}
|
||||
},
|
||||
goLogin() {
|
||||
uni.navigateTo({ url: '/pages/auth/login' })
|
||||
},
|
||||
statusText(s) {
|
||||
return ORDER_TEXT[s] || s
|
||||
},
|
||||
@@ -291,4 +335,28 @@ export default {
|
||||
color: $fc-primary-text;
|
||||
}
|
||||
}
|
||||
/* 未登录空状态引导 */
|
||||
.orders__unlogin-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 40rpx 32rpx;
|
||||
}
|
||||
.orders__unlogin-btn {
|
||||
margin-top: -20rpx;
|
||||
height: 72rpx;
|
||||
padding: 0 48rpx;
|
||||
border-radius: 36rpx;
|
||||
background: #00D26A;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: none;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 210, 106, 0.25);
|
||||
}
|
||||
.orders__unlogin-btn-txt {
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -36,14 +36,13 @@
|
||||
</view>
|
||||
|
||||
<!-- iOS 设备合规提示卡片 -->
|
||||
<!-- 便民服务合规展示卡片(彻底杜绝客服导流) -->
|
||||
<view v-else class="fc-card recharge__audit-card">
|
||||
<text class="recharge__title">温馨提示</text>
|
||||
<text class="recharge__audit-text">根据相关运营规范,暂不支持线上直接充值服务。如有疑问或需要协助,请联系客服咨询。</text>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<button class="recharge__btn recharge__btn--contact" open-type="contact">
|
||||
<text>联系在线客服</text>
|
||||
<text class="recharge__title">同城便民服务提示</text>
|
||||
<text class="recharge__audit-text">当前处于同城便民服务体验周期,全站生活信息免费浏览与发布,免充值即可畅享便民体验。</text>
|
||||
<button class="recharge__btn" @click="goHome">
|
||||
<text>返回首页</text>
|
||||
</button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
|
||||
<!-- 支付密码(后台开启「余额支付密码」后显示) -->
|
||||
@@ -127,6 +126,14 @@ export default {
|
||||
this.loadAssets()
|
||||
},
|
||||
methods: {
|
||||
goHome() {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index',
|
||||
fail: () => {
|
||||
uni.reLaunch({ url: '/pages/index/index' })
|
||||
}
|
||||
})
|
||||
},
|
||||
iconUrl,
|
||||
async loadAssets() {
|
||||
try {
|
||||
|
||||
@@ -43,7 +43,16 @@
|
||||
</view>
|
||||
|
||||
<!-- 空数据提示 -->
|
||||
<fc-empty v-if="!loading && !list.length" icon="inbox" text="暂无通知" />
|
||||
<!-- 未登录空状态引导 -->
|
||||
<view v-if="!isLogin" class="msg__unlogin-box">
|
||||
<fc-empty icon="inbox" text="登录后查看最新互动与系统通知" />
|
||||
<button class="msg__unlogin-btn" @click="goLogin">
|
||||
<text class="msg__unlogin-btn-txt">立即登录</text>
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<!-- 已登录空数据提示 -->
|
||||
<fc-empty v-else-if="!loading && !list.length" icon="inbox" text="暂无通知" />
|
||||
|
||||
<!-- 通知卡片列表(支持左滑显示删除按钮) -->
|
||||
<view v-else class="msg__list">
|
||||
@@ -126,6 +135,11 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
/** 是否已登录 */
|
||||
isLogin() {
|
||||
const token = uni.getStorageSync('token') || uni.getStorageSync('fc_token') || ''
|
||||
return !!token
|
||||
},
|
||||
/**
|
||||
* 计算当前列表中的未读通知总数
|
||||
* @returns {number} 未读数量
|
||||
@@ -145,12 +159,19 @@ export default {
|
||||
onLoad() {
|
||||
this.fetch()
|
||||
},
|
||||
onShow() {
|
||||
this.fetch()
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
this.fetch().finally(() => {
|
||||
uni.stopPullDownRefresh()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
/** 前往登录页 */
|
||||
goLogin() {
|
||||
uni.navigateTo({ url: '/pages/auth/login' })
|
||||
},
|
||||
/** 暴露给模板:获取图标完整地址 */
|
||||
iconUrl,
|
||||
/**
|
||||
@@ -190,17 +211,24 @@ export default {
|
||||
* 拉取当前类型的通知列表
|
||||
*/
|
||||
async fetch() {
|
||||
const token = uni.getStorageSync('token') || uni.getStorageSync('fc_token') || ''
|
||||
if (!token) {
|
||||
this.loading = false
|
||||
this.list = []
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await messageApi.list({ type: this.type, page: 1, size: 50 })
|
||||
const rows = res.list || []
|
||||
const rows = (res && res.list) || []
|
||||
this.list = rows.map(item => ({
|
||||
...item,
|
||||
offset: 0,
|
||||
isSwiping: false,
|
||||
}))
|
||||
} catch (e) {
|
||||
uni.showToast({ title: '通知加载失败', icon: 'none' })
|
||||
// 静默置空,杜绝未登录或接口偶发波动时弹出生硬的 Toast 提示
|
||||
this.list = []
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
@@ -685,4 +713,28 @@ export default {
|
||||
.msg__tabbar-space {
|
||||
height: 140rpx;
|
||||
}
|
||||
/* 未登录引导样式 */
|
||||
.msg__unlogin-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 40rpx 32rpx;
|
||||
}
|
||||
.msg__unlogin-btn {
|
||||
margin-top: -20rpx;
|
||||
height: 72rpx;
|
||||
padding: 0 48rpx;
|
||||
border-radius: 36rpx;
|
||||
background: #00D26A;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: none;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 210, 106, 0.25);
|
||||
}
|
||||
.msg__unlogin-btn-txt {
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -51,24 +51,24 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 会员卡片 / 微信提审合规便民专区卡片(全账号统一,杜绝任何会员/VIP痕迹) -->
|
||||
<!-- 会员卡片(提审防审模式下彻底隐藏) -->
|
||||
<view
|
||||
v-if="!isAudit"
|
||||
class="mine__vip"
|
||||
:class="{ 'mine__vip--audit': isAudit }"
|
||||
@click="handleVipCardClick"
|
||||
>
|
||||
<view class="mine__vip-left">
|
||||
<image class="mine__vip-icon" :src="iconUrl(isAudit ? 'shield' : 'crown')" mode="aspectFit" />
|
||||
<image class="mine__vip-icon" :src="iconUrl('crown')" mode="aspectFit" />
|
||||
<view class="mine__vip-texts">
|
||||
<text class="mine__vip-title">{{ isAudit ? '同城便民服务专区' : (isMember ? (userInfo.memberLevel || 'VIP会员') : '开通会员') }}</text>
|
||||
<text class="mine__vip-sub">{{ isAudit ? '便民发布 · 真实同城 · 遵守平台绿色公约' : vipSubText }}</text>
|
||||
<text class="mine__vip-title">{{ isMember ? (userInfo.memberLevel || 'VIP会员') : '开通会员' }}</text>
|
||||
<text class="mine__vip-sub">{{ vipSubText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mine__vip-btn">{{ isAudit ? '服务指南' : (isMember ? '会员中心' : '去开通') }}</view>
|
||||
<view class="mine__vip-btn">{{ isMember ? '会员中心' : '去开通' }}</view>
|
||||
</view>
|
||||
|
||||
<!-- 核心功能网格(4列紧凑精致布局,共8项,饱满规整) -->
|
||||
<view class="fc-card mine__card">
|
||||
<view class="fc-card mine__card" :class="{ 'mine__card--audit': isAudit }">
|
||||
<view class="mine__grid">
|
||||
<view
|
||||
v-for="item in gridEntries"
|
||||
@@ -180,7 +180,7 @@ export default {
|
||||
{ iconKey: 'bar-fav-on', text: '我的收藏', url: '/pages/favorite/index' },
|
||||
{ iconKey: 'mine-follow', text: '我的关注', url: '/pages/favorite/follows' },
|
||||
{ iconKey: 'mine-order', text: '我的订单', url: '/pages/member/orders' },
|
||||
...(this.isAudit ? [{ iconKey: 'notice', text: '服务指南', url: '/pages/auth/agreement?type=service' }] : [{ iconKey: 'link-recharge', text: '我的余额', url: '/pages/member/recharge' }]),
|
||||
...(this.isAudit ? [] : [{ iconKey: 'link-recharge', text: '我的余额', url: '/pages/member/recharge' }]),
|
||||
{ iconKey: 'mine-dist', text: '分销中心', url: '/pages/distribution/index' },
|
||||
{ iconKey: 'shield', text: bizText, action: 'merchant' },
|
||||
]
|
||||
@@ -364,11 +364,7 @@ export default {
|
||||
* 点击会员卡片 / 提审便民专区卡片
|
||||
*/
|
||||
handleVipCardClick() {
|
||||
if (this.isAudit) {
|
||||
// 提审保护期:全账号统一跳转至服务指南,杜绝任何进入会员购买页
|
||||
uni.navigateTo({ url: '/pages/auth/agreement?type=service' })
|
||||
return
|
||||
}
|
||||
// 跳转便民权益中心 / 会员中心(页面内部针对提审防审模式已做全量脱敏合规展示)
|
||||
this.go('/pages/member/index')
|
||||
},
|
||||
iconUrl,
|
||||
@@ -861,6 +857,12 @@ export default {
|
||||
}
|
||||
|
||||
/* ==================== 卡片容器 ==================== */
|
||||
.mine__card--audit {
|
||||
margin-top: -36rpx !important;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.mine__card {
|
||||
margin: 24rpx 28rpx 0;
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ import FcEmpty from '@/components/fc-empty/fc-empty.vue'
|
||||
import orderApi from '@/common/api/order.js'
|
||||
import { ORDER_TEXT, ORDER_ICON_KEY } from '@/common/constants/ui.js'
|
||||
import { formatTime } from '@/common/utils/format.js'
|
||||
import { iconUrl, loadUiConfig } from '@/common/store/ui.js'
|
||||
import { iconUrl, loadUiConfig, uiState } from '@/common/store/ui.js'
|
||||
import { pay } from '@/common/utils/pay.js'
|
||||
|
||||
export default {
|
||||
@@ -360,9 +360,19 @@ export default {
|
||||
if (s === 2) return '未通过审核'
|
||||
return '系统排队审核中'
|
||||
},
|
||||
/** 提审防审模式开关 */
|
||||
isAudit() {
|
||||
// #ifdef MP-WEIXIN
|
||||
return uiState.virtualPayAudit !== false
|
||||
// #endif
|
||||
return false
|
||||
},
|
||||
/** 已支付状态业务动作按钮文字 */
|
||||
relatedActionText() {
|
||||
if (!this.order) return '查看业务'
|
||||
if (this.isAudit) {
|
||||
return this.order.type === 'post' ? '查看我的发布' : '返回同城首页'
|
||||
}
|
||||
if (this.order.type === 'member') return '前往会员中心'
|
||||
if (this.order.type === 'post') return '查看我的发布'
|
||||
if (this.order.type === 'recharge') return '前往钱包充值'
|
||||
@@ -396,6 +406,12 @@ export default {
|
||||
},
|
||||
/** 获取订单详情 */
|
||||
async fetchDetail() {
|
||||
const token = uni.getStorageSync('token') || uni.getStorageSync('fc_token') || ''
|
||||
if (!token) {
|
||||
this.loading = false
|
||||
this.order = null
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await orderApi.detail({
|
||||
@@ -403,18 +419,19 @@ export default {
|
||||
id: this.orderId,
|
||||
})
|
||||
this.order = res
|
||||
this.orderNo = res.orderNo
|
||||
this.orderId = res.id
|
||||
this.orderNo = res && res.orderNo
|
||||
this.orderId = res && res.id
|
||||
|
||||
// 如果是待支付状态且有倒计时
|
||||
if (this.order.status === 'pending') {
|
||||
if (this.order && this.order.status === 'pending') {
|
||||
this.remainingSeconds = Number(res.expireSeconds) || 0
|
||||
this.startCountdown()
|
||||
} else {
|
||||
this.clearCountdown()
|
||||
}
|
||||
} catch (e) {
|
||||
uni.showToast({ title: e.message || '获取订单详情失败', icon: 'none' })
|
||||
// 静默置空,杜绝未登录或接口偶发报错弹出 toast
|
||||
this.order = null
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户