1. 链接人和事:补充CKB_OPEN_API_KEY/ACCOUNT配置,新增fix-ckb批量创建获客计划API 2. 规则配置:打通DB规则与ruleEngine,新增/api/miniprogram/user-rules接口, ruleEngine改为从API动态加载规则并按enabled状态执行 3. 获客计划:修复获客数统计中personId/token不匹配导致永远为0的bug, 管理端新增"修复CKB密钥"按钮 4. 支付问题:修复钱包充值和代付分享中openId缺失导致400错误, 添加getOpenId()兜底逻辑 5. 朋友圈分享:shareToMoments改为复制文章前200字+省略号+手指箭头emoji Made-with: Cursor
178 lines
5.7 KiB
JavaScript
178 lines
5.7 KiB
JavaScript
const app = getApp()
|
|
const { trackClick } = require('../../utils/trackClick')
|
|
|
|
Page({
|
|
data: {
|
|
statusBarHeight: 0,
|
|
balance: 0,
|
|
balanceText: '0.00',
|
|
totalRecharged: '0.00',
|
|
totalGifted: '0.00',
|
|
totalRefunded: '0.00',
|
|
transactions: [],
|
|
loading: true,
|
|
rechargeAmounts: [10, 30, 50, 1000],
|
|
selectedAmount: 30,
|
|
},
|
|
|
|
onLoad() {
|
|
this.setData({ statusBarHeight: app.globalData.statusBarHeight || 44 })
|
|
this.loadBalance()
|
|
this.loadTransactions()
|
|
},
|
|
|
|
async loadBalance() {
|
|
if (!app.globalData.isLoggedIn || !app.globalData.userInfo) return
|
|
const userId = app.globalData.userInfo.id
|
|
try {
|
|
const res = await app.request({ url: `/api/miniprogram/balance?userId=${userId}`, silent: true })
|
|
if (res && res.data) {
|
|
this.setData({
|
|
balance: res.data.balance || 0,
|
|
balanceText: (res.data.balance || 0).toFixed(2),
|
|
totalRecharged: (res.data.totalRecharged || 0).toFixed(2),
|
|
totalGifted: (res.data.totalGifted || 0).toFixed(2),
|
|
totalRefunded: (res.data.totalRefunded || 0).toFixed(2),
|
|
loading: false,
|
|
})
|
|
}
|
|
} catch (e) {
|
|
this.setData({ loading: false })
|
|
}
|
|
},
|
|
|
|
async loadTransactions() {
|
|
if (!app.globalData.isLoggedIn || !app.globalData.userInfo) return
|
|
const userId = app.globalData.userInfo.id
|
|
try {
|
|
const res = await app.request({ url: `/api/miniprogram/balance/transactions?userId=${userId}`, silent: true })
|
|
if (res && res.data) {
|
|
const list = (res.data || []).map(t => ({
|
|
...t,
|
|
amountText: (t.amount || 0).toFixed(2),
|
|
amountSign: (t.amount || 0) >= 0 ? '+' : '',
|
|
description: t.description || (t.type === 'recharge' ? '充值' : t.type === 'gift' ? '赠送' : t.type === 'refund' ? '退款' : t.type === 'consume' ? '阅读消费' : '其他'),
|
|
}))
|
|
this.setData({ transactions: list })
|
|
}
|
|
} catch (e) {
|
|
console.warn('[Wallet] load transactions failed', e)
|
|
}
|
|
},
|
|
|
|
selectAmount(e) {
|
|
trackClick('wallet', 'tab_click', '选择金额' + (e.currentTarget.dataset.amount || ''))
|
|
this.setData({ selectedAmount: parseInt(e.currentTarget.dataset.amount) })
|
|
},
|
|
|
|
async handleRecharge() {
|
|
trackClick('wallet', 'btn_click', '充值')
|
|
if (!app.globalData.isLoggedIn || !app.globalData.userInfo) {
|
|
wx.showToast({ title: '请先登录', icon: 'none' })
|
|
return
|
|
}
|
|
const userId = app.globalData.userInfo.id
|
|
const amount = this.data.selectedAmount
|
|
|
|
let openId = app.globalData.openId
|
|
if (!openId) {
|
|
openId = await app.getOpenId()
|
|
}
|
|
if (!openId) {
|
|
wx.showToast({ title: '获取支付凭证失败,请重新登录', icon: 'none', duration: 2500 })
|
|
return
|
|
}
|
|
|
|
wx.showLoading({ title: '创建订单...' })
|
|
try {
|
|
const res = await app.request({
|
|
url: '/api/miniprogram/balance/recharge',
|
|
method: 'POST',
|
|
data: { userId, amount }
|
|
})
|
|
wx.hideLoading()
|
|
if (res && res.data && res.data.orderSn) {
|
|
const payRes = await app.request({
|
|
url: '/api/miniprogram/pay',
|
|
method: 'POST',
|
|
data: {
|
|
openId: openId,
|
|
productType: 'balance_recharge',
|
|
productId: res.data.orderSn,
|
|
amount: amount,
|
|
description: `余额充值 ¥${amount}`,
|
|
userId: userId,
|
|
}
|
|
})
|
|
const params = (payRes && payRes.data && payRes.data.payParams) ? payRes.data.payParams : (payRes && payRes.payParams ? payRes.payParams : null)
|
|
if (params) {
|
|
wx.requestPayment({
|
|
...params,
|
|
success: async () => {
|
|
// Confirm the recharge
|
|
await app.request({
|
|
url: '/api/miniprogram/balance/recharge/confirm',
|
|
method: 'POST',
|
|
data: { orderSn: res.data.orderSn }
|
|
})
|
|
wx.showToast({ title: '充值成功', icon: 'success' })
|
|
this.loadBalance()
|
|
this.loadTransactions()
|
|
},
|
|
fail: () => {
|
|
wx.showToast({ title: '支付取消', icon: 'none' })
|
|
}
|
|
})
|
|
} else {
|
|
wx.showToast({ title: '创建支付失败', icon: 'none' })
|
|
}
|
|
}
|
|
} catch (e) {
|
|
wx.hideLoading()
|
|
console.error('[Wallet] recharge error:', e)
|
|
wx.showToast({ title: '充值失败:' + (e.message || e.errMsg || '网络异常'), icon: 'none', duration: 3000 })
|
|
}
|
|
},
|
|
|
|
async handleRefund() {
|
|
trackClick('wallet', 'btn_click', '退款')
|
|
if (this.data.balance <= 0) {
|
|
wx.showToast({ title: '余额为零', icon: 'none' })
|
|
return
|
|
}
|
|
const userId = app.globalData.userInfo.id
|
|
const balance = this.data.balance
|
|
|
|
wx.showModal({
|
|
title: '余额退款',
|
|
content: `退回全部余额 ¥${balance.toFixed(2)}\n\n退款将在1-3个工作日内原路返回`,
|
|
confirmText: '确认退款',
|
|
cancelText: '取消',
|
|
success: async (res) => {
|
|
if (!res.confirm) return
|
|
wx.showLoading({ title: '处理中...' })
|
|
try {
|
|
const result = await app.request({
|
|
url: '/api/miniprogram/balance/refund',
|
|
method: 'POST',
|
|
data: { userId, amount: balance }
|
|
})
|
|
wx.hideLoading()
|
|
if (result && result.data) {
|
|
wx.showToast({ title: result.data.message || '退款成功', icon: 'success' })
|
|
this.loadBalance()
|
|
this.loadTransactions()
|
|
}
|
|
} catch (e) {
|
|
wx.hideLoading()
|
|
wx.showToast({ title: '退款失败', icon: 'none' })
|
|
}
|
|
}
|
|
})
|
|
},
|
|
|
|
goBack() {
|
|
wx.navigateBack()
|
|
},
|
|
})
|