优化匹配页面,新增好友优惠展示逻辑,支持通过推荐码获取折扣。调整价格计算方式,确保用户在购买时能看到实际优惠。更新页面样式以提升用户体验,并修复部分逻辑问题。

This commit is contained in:
乘风
2026-02-12 17:34:50 +08:00
parent 543a465682
commit a71e14d2e6
6 changed files with 113 additions and 42 deletions

View File

@@ -80,12 +80,36 @@ Page({
// 匹配价格(可配置)
matchPrice: 1,
extraMatches: 0
extraMatches: 0,
// 好友优惠展示(与 read 页一致)
userDiscount: 5,
hasReferralDiscount: false,
showDiscountHint: false,
displayMatchPrice: 1
},
onLoad() {
onLoad(options = {}) {
// ref支持 query.ref 或 scene 中的 ref=xxx分享进入时
let ref = options.ref
if (!ref && options.scene) {
const sceneStr = (typeof options.scene === 'string' ? decodeURIComponent(options.scene) : '').trim()
const parts = sceneStr.split(/[&_]/)
for (const part of parts) {
const eq = part.indexOf('=')
if (eq > 0) {
const k = part.slice(0, eq)
const v = part.slice(eq + 1)
if (k === 'ref' && v) { ref = v; break }
}
}
}
if (ref) {
wx.setStorageSync('referral_code', ref)
app.handleReferralCode({ query: { ref } })
}
this.setData({
statusBarHeight: app.globalData.statusBarHeight || 44
statusBarHeight: app.globalData.statusBarHeight || 44,
_ref: ref
})
this.loadMatchConfig()
this.loadStoredContact()
@@ -105,31 +129,39 @@ Page({
this.refreshMatchCountAndStatus()
},
// 加载匹配配置
// 加载匹配配置(含 userDiscount 用于好友优惠展示)
async loadMatchConfig() {
try {
const res = await app.request('/api/miniprogram/match/config', {
method: 'GET'
const userId = app.globalData.userInfo?.id
const [matchRes, configRes] = await Promise.all([
app.request('/api/miniprogram/match/config', { method: 'GET' }),
app.request('/api/miniprogram/config', { method: 'GET' })
])
const matchPrice = matchRes?.success && matchRes?.data ? (matchRes.data.matchPrice || 1) : 1
const userDiscount = configRes?.userDiscount ?? 5
const hasReferral = !!(wx.getStorageSync('referral_code') || this.data._ref)
const hasReferralDiscount = hasReferral && userDiscount > 0
const displayMatchPrice = hasReferralDiscount
? Math.round(matchPrice * (1 - userDiscount / 100) * 100) / 100
: matchPrice
if (matchRes?.success && matchRes?.data) {
MATCH_TYPES = matchRes.data.matchTypes || MATCH_TYPES
FREE_MATCH_LIMIT = matchRes.data.freeMatchLimit || FREE_MATCH_LIMIT
}
this.setData({
matchTypes: MATCH_TYPES,
totalMatchesAllowed: FREE_MATCH_LIMIT,
matchPrice,
userDiscount,
hasReferralDiscount,
showDiscountHint: userDiscount > 0,
displayMatchPrice
})
if (res.success && res.data) {
// 更新全局配置
MATCH_TYPES = res.data.matchTypes || MATCH_TYPES
FREE_MATCH_LIMIT = res.data.freeMatchLimit || FREE_MATCH_LIMIT
const matchPrice = res.data.matchPrice || 1
this.setData({
matchTypes: MATCH_TYPES,
totalMatchesAllowed: FREE_MATCH_LIMIT,
matchPrice: matchPrice
})
console.log('[Match] 加载匹配配置成功:', {
types: MATCH_TYPES.length,
freeLimit: FREE_MATCH_LIMIT,
price: matchPrice
})
}
console.log('[Match] 加载匹配配置成功:', { matchPrice, userDiscount, hasReferralDiscount, displayMatchPrice })
} catch (e) {
console.log('[Match] 加载匹配配置失败,使用默认配置:', e)
}
@@ -155,6 +187,15 @@ Page({
if (res.success && res.data) {
app.globalData.matchCount = res.data.matchCount ?? 0
app.globalData.matchQuota = res.data.matchQuota || null
// 根据 hasReferrer 更新优惠展示(与 read 页一致)
const hasReferral = !!(wx.getStorageSync('referral_code') || this.data._ref || res.data.hasReferrer)
const matchPrice = this.data.matchPrice ?? 1
const userDiscount = this.data.userDiscount ?? 5
const hasReferralDiscount = hasReferral && userDiscount > 0
const displayMatchPrice = hasReferralDiscount
? Math.round(matchPrice * (1 - userDiscount / 100) * 100) / 100
: matchPrice
this.setData({ hasReferralDiscount, displayMatchPrice })
}
} catch (e) {
console.log('[Match] 拉取 matchQuota 失败:', e)
@@ -254,8 +295,8 @@ Page({
return
}
// 创业合伙类型 - 真正的匹配功能(仅当登录且服务端确认次数用尽时,弹出购买)
if (this.data.showQuotaExhausted) {
// 创业合伙类型 - 超过匹配次数时直接弹出付费弹窗
if (this.data.showQuotaExhausted || this.data.needPayToMatch) {
this.setData({ showUnlockModal: true })
return
}
@@ -355,17 +396,9 @@ Page({
setTimeout(() => {
clearInterval(timer)
// 次数用尽(后端校验)
// 次数用尽(后端校验)- 直接弹出付费弹窗
if (quotaExceeded) {
this.setData({ isMatching: false })
wx.showModal({
title: '今日匹配次数已用完',
content: '请购买更多次数继续匹配',
confirmText: '去购买',
success: (r) => {
if (r.confirm) this.setData({ showUnlockModal: true })
}
})
this.setData({ isMatching: false, showUnlockModal: true })
this.refreshMatchCountAndStatus()
return
}

View File

@@ -39,7 +39,7 @@
<block wx:if="{{needPayToMatch}}">
<text class="sphere-icon">⚡</text>
<text class="sphere-title gold-text">购买次数</text>
<text class="sphere-desc">¥1 = 1次匹配</text>
<text class="sphere-desc">¥{{displayMatchPrice || matchPrice || 1}} = 1次匹配</text>
</block>
<block wx:else>
<text class="sphere-icon">👥</text>
@@ -344,7 +344,16 @@
<view class="unlock-info">
<view class="info-row">
<text class="info-label">单价</text>
<text class="info-value text-brand">¥{{matchPrice || 1}} / 次</text>
<view class="info-value-row" wx:if="{{hasReferralDiscount}}">
<text class="info-original">¥{{matchPrice || 1}}</text>
<text class="info-value text-brand">¥{{displayMatchPrice || matchPrice || 1}} / 次</text>
<text class="info-discount">省{{userDiscount}}%</text>
</view>
<view class="info-value-row" wx:elif="{{showDiscountHint}}">
<text class="info-value text-brand">¥{{matchPrice || 1}} / 次</text>
<text class="info-discount-hint">好友链接立省{{userDiscount}}%</text>
</view>
<text wx:else class="info-value text-brand">¥{{matchPrice || 1}} / 次</text>
</view>
<view class="info-row">
<text class="info-label">已购买</text>
@@ -353,7 +362,7 @@
</view>
<view class="unlock-buttons">
<view class="btn-gold" bindtap="buyMatchCount">立即购买 ¥{{matchPrice || 1}}</view>
<view class="btn-gold" bindtap="buyMatchCount">立即购买 ¥{{hasReferralDiscount ? (displayMatchPrice || matchPrice || 1) : (matchPrice || 1)}}</view>
<view class="btn-ghost" bindtap="closeUnlockModal">明天再来</view>
</view>
</view>

View File

@@ -1110,6 +1110,28 @@
color: #ffffff;
}
.info-value-row {
display: flex;
align-items: center;
gap: 12rpx;
}
.info-original {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.5);
text-decoration: line-through;
}
.info-discount {
font-size: 22rpx;
color: #00CED1;
}
.info-discount-hint {
font-size: 22rpx;
color: rgba(255, 255, 255, 0.5);
}
.unlock-buttons {
display: flex;
flex-direction: column;

View File

@@ -45,7 +45,7 @@ Page({
if (isLoggedIn && userInfo) {
// 从本地存储或用户信息中获取绑定数据
const phoneNumber = wx.getStorageSync('user_phone') || userInfo.phone || ''
const wechatId = wx.getStorageSync('user_wechat') || userInfo.wechat || ''
const wechatId = wx.getStorageSync('user_wechat') || userInfo.wechatId || userInfo.wechat || ''
const alipayAccount = wx.getStorageSync('user_alipay') || userInfo.alipay || ''
const address = wx.getStorageSync('user_address') || userInfo.address || ''
// 默认开启自动提现

View File

@@ -24,12 +24,19 @@
"miniprogram": {
"list": [
{
"name": "pages/referral/referral",
"pathName": "pages/referral/referral",
"name": "pages/addresses/addresses",
"pathName": "pages/addresses/addresses",
"query": "",
"scene": null,
"launchMode": "default"
},
{
"name": "pages/referral/referral",
"pathName": "pages/referral/referral",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "pages/read/read",
"pathName": "pages/read/read",

Binary file not shown.