ai-c/pages/recharge/recharge.js
2026-02-02 18:21:32 +08:00

152 lines
4.2 KiB
JavaScript

const { request } = require('../../utils_new/request');
const { payProduct } = require('../../utils_new/payment');
const api = require('../../utils/api');
Page({
data: {
statusBarHeight: 20,
navBarHeight: 44,
totalNavHeight: 64,
products: [],
vipPackages: [],
modal: {
visible: false,
type: 'product',
id: 0,
orderType: '',
title: '',
price: 0,
benefits: []
}
},
onLoad() {
const systemInfo = wx.getSystemInfoSync()
const statusBarHeight = systemInfo.statusBarHeight || 20
const menuButton = wx.getMenuButtonBoundingClientRect()
const navBarHeight = menuButton.height + (menuButton.top - statusBarHeight) * 2
this.setData({
statusBarHeight,
navBarHeight,
totalNavHeight: statusBarHeight + navBarHeight
})
},
onShow() {
this.loadProducts()
},
async loadProducts() {
try {
const res = await api.payment.getPackages()
const body = res.data || {}
const list = Array.isArray(body) ? body : body?.data || []
if (!list.length) return
const raw = list.map((p) => {
const attrs = p.attributes || {}
const gradientStart = p.gradientStart || attrs.gradient_start || '#60A5FA'
const gradientEnd = p.gradientEnd || attrs.gradient_end || '#2563EB'
const tagColor = p.tagColor || attrs.tag_color || '#1E3A8A'
const tagText = p.tagText || attrs.tag_text || ''
const benefits = p.benefits || attrs.benefits || []
const iconMap = {
first: 'gift',
month: 'gift',
yearly: 'gift',
year: 'crown',
svip: 'diamond',
soulmate: 'heart-filled',
guardian: 'diamond',
companion: 'crown',
listener: 'gift'
}
let vipType = attrs.type || p.vipType || ''
if (vipType === 'monthly') vipType = 'month'
if (vipType === 'yearly') vipType = 'year'
if (vipType === 'lifetime') vipType = 'svip'
return {
id: Number(p.id),
orderType: 'vip',
vipType,
price: Number(p.price) || 0,
originalPrice: Number(p.originalPrice) || 0,
title: p.title,
subtitle: p.subtitle || attrs.subtitle || (benefits[0] || ''),
tagText: tagText,
gradient: `background: linear-gradient(180deg, ${gradientStart}, ${gradientEnd});`,
tagStyle: `color: ${tagColor}; background: rgba(255,255,255,0.25);`,
icon: iconMap[vipType] || 'crown',
iconGradient: `background: linear-gradient(180deg, ${gradientStart}, ${gradientEnd});`,
priceColor: `color: ${gradientEnd};`,
checkColor: tagColor || gradientEnd,
borderStyle: `border-color: rgba(0,0,0,0.06); background: rgba(255,255,255,0.9);`,
btnGradient: `background: linear-gradient(90deg, ${gradientStart}, ${gradientEnd});`,
benefits,
isRecommend: p.isRecommend || attrs.is_recommended || false
}
})
this.setData({
products: raw,
vipPackages: raw
})
} catch (err) {
console.error('Failed to load products:', err)
}
},
onBack() {
wx.navigateBack({ delta: 1 })
},
openProductPay(e) {
const id = Number(e.currentTarget.dataset.id)
const product = this.data.products.find(x => Number(x.id) === id)
if (!product) return
const pkg = this.data.vipPackages.find(x => Number(x.id) === id)
const benefits = pkg?.benefits || []
this.setData({
modal: {
visible: true,
type: 'product',
id: Number(product.id),
orderType: product.orderType,
title: product.title,
price: product.price,
benefits
}
})
},
closeModal() {
this.setData({ 'modal.visible': false })
},
async confirmAction() {
const modal = this.data.modal
wx.showLoading({ title: '发起支付...' })
try {
await payProduct({
productId: modal.id,
orderType: modal.orderType
})
wx.hideLoading()
wx.showToast({ title: '购买成功', icon: 'success' })
this.closeModal()
} catch (err) {
wx.hideLoading()
wx.showToast({ title: err.message || '支付失败', icon: 'none' })
}
}
})