const app = getApp() Page({ data: { statusBarHeight: 44, isVip: false, daysRemaining: 0, expireDateStr: '', price: 1980, originalPrice: 6980, contentRights: [ { title: '解锁全部章节', desc: '365天全部章节内容' }, { title: '案例库', desc: '30-100个创业项目案例' }, { title: '智能纪要', desc: '每天推送派对精华' }, { title: '会议纪要库', desc: '之前所有场次的会议纪要' } ], socialRights: [ { title: '匹配创业伙伴', desc: '匹配所有创业伙伴' }, { title: '创业老板排行', desc: '排行榜展示您的项目' }, { title: '链接资源', desc: '进群聊天、链接资源的权利' }, { title: '专属VIP标识', desc: '头像金色VIP光圈' } ], profile: { vipName: '', vipProject: '', vipContact: '', vipAvatar: '', vipBio: '' }, 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')}` } this.setData({ isVip: d.isVip, daysRemaining: d.daysRemaining, expireDateStr: expStr, price: d.price || 1980 }) if (d.isVip) this.loadProfile(userId) } } catch (e) { console.log('[VIP] 加载失败', e) } }, async loadProfile(userId) { try { const res = await app.request(`/api/miniprogram/vip/profile?userId=${userId}`) if (res?.success) { const p = res.data // 头像若为相对路径则补全 if (p.vipAvatar && !p.vipAvatar.startsWith('http')) { p.vipAvatar = app.globalData.baseUrl.replace(/\/$/, '') + (p.vipAvatar.startsWith('/') ? p.vipAvatar : '/' + p.vipAvatar) } this.setData({ profile: p }) } } catch (e) { console.log('[VIP] 资料加载失败', e) } }, async onChooseVipAvatar() { wx.chooseMedia({ count: 1, mediaType: ['image'], sourceType: ['album', 'camera'], success: async (res) => { const tempPath = res.tempFiles[0].tempFilePath wx.showLoading({ title: '上传中...', mask: true }) try { const uploadRes = await new Promise((resolve, reject) => { wx.uploadFile({ url: app.globalData.baseUrl + '/api/miniprogram/upload', filePath: tempPath, name: 'file', formData: { folder: 'avatars' }, success: (r) => { try { const d = JSON.parse(r.data) d.success ? resolve(d) : reject(new Error(d.error || '上传失败')) } catch { reject(new Error('解析失败')) } }, fail: reject }) }) const path = uploadRes.url || uploadRes.data?.url || '' const avatarUrl = path.startsWith('http') ? path : (app.globalData.baseUrl.replace(/\/$/, '') + (path.startsWith('/') ? path : '/' + path)) this.setData({ 'profile.vipAvatar': avatarUrl }) wx.hideLoading() wx.showToast({ title: '头像已更新', icon: 'success' }) } catch (e) { wx.hideLoading() wx.showToast({ title: e.message || '上传失败', icon: 'none' }) } } }) }, async handlePurchase() { 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 }) try { const payRes = await app.request('/api/miniprogram/pay', { method: 'POST', data: { openId, userId, productType: 'vip', productId: 'vip_annual', amount: this.data.price, description: '卡若创业派对VIP年度会员(365天)' } }) if (payRes?.success && payRes.data?.payParams) { wx.requestPayment({ ...payRes.data.payParams, success: () => { wx.showToast({ title: 'VIP开通成功', icon: 'success' }) this.loadVipInfo() }, 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 }) } }, onVipNameInput(e) { this.setData({ 'profile.vipName': e.detail.value }) }, onVipProjectInput(e) { this.setData({ 'profile.vipProject': e.detail.value }) }, onVipContactInput(e) { this.setData({ 'profile.vipContact': e.detail.value }) }, onVipBioInput(e) { this.setData({ 'profile.vipBio': e.detail.value }) }, async saveProfile() { const userId = app.globalData.userInfo?.id if (!userId) return const p = this.data.profile try { const res = await app.request('/api/miniprogram/vip/profile', { method: 'POST', data: { userId, vipName: p.vipName, vipProject: p.vipProject, vipContact: p.vipContact, vipAvatar: p.vipAvatar, vipBio: p.vipBio } }) if (res?.success) wx.showToast({ title: '资料已保存', icon: 'success' }) else wx.showToast({ title: res?.error || '保存失败', icon: 'none' }) } catch (e) { wx.showToast({ title: '保存失败', icon: 'none' }) } }, goBack() { wx.navigateBack() }, 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}` : '' } } })