feat: 优化UI

This commit is contained in:
Blizzard
2026-03-05 17:04:40 +08:00
parent 0a61c4ddec
commit 7f51b2a0a8
28 changed files with 1773 additions and 964 deletions
+111 -16
View File
@@ -37,7 +37,6 @@ Page({
const quarterly = (parseFloat(options.quarterlyPrice) || 0) / 100
const annual = (parseFloat(options.annualPrice) || 0) / 100
// 默认选中包年,否则最合算的
let defaultPlan = 'monthly'
let defaultPrice = monthly
if (annual > 0) { defaultPlan = 'annual'; defaultPrice = annual }
@@ -59,15 +58,42 @@ Page({
})
} else {
// ─── VIP 会员模式 ───
const gd = app.globalData
this.setData({
mode: 'vip',
isVip: app.globalData.isVip,
isVip: gd.isVip,
selectedPlan: 'vip-all',
currentPrice: '19.9'
currentPrice: '--',
vipExpireAt: gd.vipExpireAt ? gd.vipExpireAt.substring(0, 10) : ''
})
// 从后端拉 VIP 配置
this._loadVipConfig()
}
},
_loadVipConfig() {
const self = this
api.getVipConfig().then(function (res) {
if (res.code === 200 && res.data) {
var cfg = res.data
// 后端单位:分 → 元
var price = cfg.discountedPrice > 0 ? (cfg.discountedPrice / 100).toFixed(2) : (cfg.price / 100).toFixed(2)
var originalPrice = cfg.price > 0 ? (cfg.price / 100).toFixed(2) : ''
var hasDiscount = cfg.discountedPrice > 0 && cfg.discountedPrice < cfg.price
self.setData({
currentPrice: price,
vipPrice: price,
vipOriginalPrice: hasDiscount ? originalPrice : '',
vipRemark: cfg.remark || ''
})
}
}).catch(function (err) {
console.error('[VIP] 获取配置失败:', err)
// 容错:使用默认价格
self.setData({ currentPrice: '19.90', vipPrice: '19.90', vipOriginalPrice: '29.90' })
})
},
onShow() {
if (this.data.mode === 'vip') {
this.setData({ isVip: app.globalData.isVip })
@@ -95,20 +121,42 @@ Page({
const { mode, selectedPlan, currentPrice, channelId } = this.data
if (mode === 'vip') {
// ── VIP 全频道(模拟,后续接入时替换) ──
wx.showModal({
title: '确认支付',
content: `即将支付 ¥${currentPrice} 开通全频道会员`,
success(res) {
if (res.confirm) {
app.upgradeVip()
wx.showToast({ title: '开通成功!', icon: 'success' })
setTimeout(function () {
self.setData({ isVip: true })
}, 500)
// ── VIP 永久会员:调后端预支付接口 ──
wx.showLoading({ title: '获取支付信息...' })
api.initiateVipPayment()
.then(function (res) {
if (res.code !== 200 || !res.data || !res.data.payments) {
wx.hideLoading()
wx.showToast({ title: res.msg || '获取支付信息失败', icon: 'none' })
return
}
}
})
const payments = res.data.payments
const outTradeNo = res.data.outTradeNo
wx.hideLoading()
wx.requestPayment({
timeStamp: payments.timeStamp,
nonceStr: payments.nonceStr,
package: payments.package,
signType: payments.signType || 'RSA',
paySign: payments.paySign,
success() {
self._pollVipStatus(outTradeNo, 3, 2000)
},
fail(err) {
if (err.errMsg && err.errMsg.indexOf('cancel') > -1) return
wx.showToast({ title: '支付失败,请重试', icon: 'none' })
console.error('[VIP支付] wx.requestPayment 失败:', err)
}
})
})
.catch(function (err) {
wx.hideLoading()
console.error('[VIP支付] 接口请求失败:', err)
wx.showToast({ title: '网络异常,请重试', icon: 'none' })
})
return
}
@@ -216,6 +264,53 @@ Page({
})
},
/**
* 轮询 VIP 支付状态
* 成功后更新全局 isVip + 触发 vipChange 事件
*/
_pollVipStatus(outTradeNo, retries, interval) {
const self = this
wx.showLoading({ title: '验证中...' })
api.queryPayStatus(outTradeNo)
.then(function (paid) {
if (paid) {
// ✅ VIP 开通确认成功
wx.hideLoading()
// 更新全局状态
app.globalData.isVip = true
app.emit('vipChange', { isVip: true })
self.setData({ isVip: true })
wx.showToast({ title: '🎉 VIP 开通成功!', icon: 'none' })
setTimeout(function () { wx.navigateBack() }, 1500)
} else if (retries > 1) {
// 🔄 尚未到账,等待后重试
setTimeout(function () {
self._pollVipStatus(outTradeNo, retries - 1, interval)
}, interval)
} else {
// ⏳ 重试耗尽,乐观提示
wx.hideLoading()
wx.showModal({
title: '支付处理中',
content: 'VIP 开通已提交,正在确认中,稍后请重新进入查看',
showCancel: false,
success: function () { wx.navigateBack() }
})
}
})
.catch(function (err) {
wx.hideLoading()
console.error('[VIP支付] 查询状态失败:', err)
wx.showModal({
title: '支付处理中',
content: 'VIP 开通已提交,稍后请刷新查看是否生效',
showCancel: false,
success: function () { wx.navigateBack() }
})
})
},
goBack() {
wx.navigateBack()
}