Files
soul-yongping/miniprogram/pages/vip/vip.js

194 lines
6.7 KiB
JavaScript
Raw Normal View History

const accessManager = require('../../utils/chapterAccessManager')
const app = getApp()
const { trackClick } = require('../../utils/trackClick')
const { checkAndExecute } = require('../../utils/ruleEngine')
Page({
data: {
statusBarHeight: 44,
isVip: false,
daysRemaining: 0,
expireDateStr: '',
price: 1980,
originalPrice: 6980,
/* 按 premium_membership_landing_v1 设计稿 */
contentRights: [
{ title: '解锁章节', desc: '全部章节365天畅读', icon: '📖' },
{ title: '创业项目', desc: '查看最新创业项目', icon: '📚' },
{ title: '每日纪要', desc: '专属团队每日总结', icon: '💡' },
{ title: '文内链接', desc: '文章提到你可被链接', icon: '📁' }
],
socialRights: [
{ title: '匹配伙伴', desc: '1980次创业伙伴匹配', icon: '👥' },
{ title: '获得客资', desc: '加入创业伙伴获客资', icon: '🔗' },
{ title: '老板排行', desc: '项目曝光超级个体', icon: '📊' },
{ title: 'VIP标识', desc: '金色尊享光圈特权', icon: '✓' }
],
purchasing: false
},
onLoad() {
wx.showShareMenu({ withShareTimeline: true })
this.setData({ statusBarHeight: app.globalData.statusBarHeight })
this.loadVipInfo()
},
async loadVipInfo() {
const userId = app.globalData.userInfo?.id
if (!userId) return
try {
const res = await app.request({ url: `/api/miniprogram/vip/status?userId=${userId}`, silent: true })
if (res?.success) {
const d = res.data
let expStr = ''
if (d.expireDate) {
const dt = new Date(d.expireDate)
expStr = `${dt.getFullYear()}-${String(dt.getMonth()+1).padStart(2,'0')}-${String(dt.getDate()).padStart(2,'0')}`
}
// 同步 VIP 状态到全局(与「我的」页保持一致)
const isVip = !!d.isVip
app.globalData.isVip = isVip
app.globalData.vipExpireDate = d.expireDate || expStr || ''
const userInfo = app.globalData.userInfo || {}
userInfo.isVip = isVip
userInfo.vipExpireDate = app.globalData.vipExpireDate
app.globalData.userInfo = userInfo
wx.setStorageSync('userInfo', userInfo)
this.setData({
isVip,
daysRemaining: d.daysRemaining,
expireDateStr: expStr,
price: d.price || 1980
})
}
} catch (e) { console.log('[VIP] 加载失败', e) }
},
async handlePurchase() {
trackClick('vip', 'btn_click', '购买VIP')
let userId = app.globalData.userInfo?.id
let openId = app.globalData.openId || app.globalData.userInfo?.open_id
if (!userId || !openId) {
wx.showLoading({ title: '登录中...', mask: true })
try {
await app.login()
userId = app.globalData.userInfo?.id
openId = app.globalData.openId || app.globalData.userInfo?.open_id
wx.hideLoading()
if (!userId || !openId) {
wx.showToast({ title: '登录失败,请重试', icon: 'none' })
return
}
} catch (e) {
wx.hideLoading()
wx.showToast({ title: '登录失败', icon: 'none' })
return
}
}
this.setData({ purchasing: true })
const amount = this.data.price
try {
// 0. 尝试余额支付(若余额足够)
const referralCode = wx.getStorageSync('referral_code') || ''
try {
const balanceRes = await app.request({ url: `/api/miniprogram/balance?userId=${userId}`, silent: true })
const balance = balanceRes?.data?.balance || 0
if (balance >= amount) {
const consumeRes = await app.request({
url: '/api/miniprogram/balance/consume',
method: 'POST',
data: {
userId,
productType: 'vip',
productId: 'vip_annual',
amount,
referralCode: referralCode || undefined
}
})
if (consumeRes?.success) {
this.setData({ purchasing: false })
wx.showToast({ title: 'VIP开通成功', icon: 'success' })
await this._onVipPaymentSuccess()
return
}
}
} catch (e) {
console.warn('[VIP] 余额支付失败,改用微信支付:', e)
}
// 1. 微信支付
const payRes = await app.request('/api/miniprogram/pay', {
method: 'POST',
data: {
openId,
userId,
productType: 'vip',
productId: 'vip_annual',
amount,
description: '卡若创业派对VIP年度会员365天'
}
})
if (payRes?.success && payRes.data?.payParams) {
wx.requestPayment({
...payRes.data.payParams,
success: async () => {
wx.showToast({ title: 'VIP开通成功', icon: 'success' })
await this._onVipPaymentSuccess()
},
fail: () => wx.showToast({ title: '支付取消', icon: 'none' })
})
} else {
wx.showToast({ title: payRes?.error || '支付参数获取失败', icon: 'none' })
}
} catch (e) {
console.error('[VIP] 购买失败', e)
wx.showToast({ title: '购买失败,请稍后重试', icon: 'none' })
} finally { this.setData({ purchasing: false }) }
},
async _onVipPaymentSuccess() {
wx.showLoading({ title: '同步权益中...', mask: true })
try {
await new Promise(r => setTimeout(r, 1500))
await accessManager.refreshUserPurchaseStatus()
// 重新拉取 VIP 状态并同步到全局
await this.loadVipInfo()
const pages = getCurrentPages()
pages.forEach(p => {
if (typeof p.initUserStatus === 'function') p.initUserStatus()
else if (typeof p.updateUserStatus === 'function') p.updateUserStatus()
})
// 记录购买行为到 user_tracks
const uid = app.globalData.userInfo?.id
if (uid) {
app.request('/api/miniprogram/track', {
method: 'POST',
data: { userId: uid, action: 'purchase', target: 'vip_annual', extraData: { amount: this.data.price } },
silent: true
}).catch(() => {})
}
// 购买后规则:引导填写完整信息
checkAndExecute('after_pay', this)
} catch (e) {
console.error('[VIP] 支付后同步失败:', e)
}
wx.hideLoading()
},
goBack() { getApp().goBackOrToHome() },
onShareAppMessage() {
const ref = app.getMyReferralCode()
return {
title: 'Soul创业派对 - VIP会员',
path: ref ? `/pages/vip/vip?ref=${ref}` : '/pages/vip/vip'
}
},
onShareTimeline() {
const ref = app.getMyReferralCode()
return { title: 'Soul创业派对 - VIP会员', query: ref ? `ref=${ref}` : '' }
}
})