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

667 lines
18 KiB
JavaScript

// pages/commission/commission.js - 佣金明细页面
// 对接后端API
const api = require('../../utils/api')
const errorHandler = require('../../utils/errorHandler')
// 缓存配置
const CACHE_CONFIG = {
STATS_KEY: 'commission_stats_cache',
RECORDS_KEY: 'commission_records_cache',
EXPIRE_TIME: 5 * 60 * 1000 // 5分钟有效期
}
Page({
data: {
statusBarHeight: 44,
navBarHeight: 44,
totalNavHeight: 88,
navHeight: 96, // Keep for compatibility if used elsewhere
loading: false,
currentTab: 'all',
// 佣金统计
isDistributor: false,
referralCode: '',
cardType: '',
commissionBalance: '0.00',
totalCommission: '0.00',
pendingAmount: '0.00', // Confirmed field for display
totalWithdrawn: '0.00',
totalReferrals: 0,
totalContribution: '0.00',
// 佣金比例
rechargeRate: 10,
vipRate: 15,
cardRate: 20,
// 兼容旧字段
totalEarnings: '0.00',
availableBalance: '0.00',
withdrawnAmount: '0.00',
// 记录列表
allList: [],
commissionList: [],
page: 1,
hasMore: true,
// 缓存状态
cacheExpired: false,
lastUpdateTime: '',
defaultAvatar: 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=500&auto=format&fit=crop&q=60',
cardTitle: '守护会员',
pickerDate: '', // YYYY-MM
pickerDateDisplay: '' // YYYY年MM月
},
onLoad() {
// Init Date
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
this.setData({
pickerDate: `${year}-${month}`,
pickerDateDisplay: `${year}${month}`
});
const systemInfo = wx.getSystemInfoSync()
const statusBarHeight = systemInfo.statusBarHeight || 44
const navHeight = statusBarHeight + 48
this.setData({
statusBarHeight,
navHeight
})
// 先尝试加载缓存(快速显示)
this.loadFromCache()
// 然后加载最新数据(确保数据准确)
this.loadCommissionStats()
this.loadCommissionRecords()
},
/**
* 页面显示时刷新数据
*/
onShow() {
// 每次显示页面时,强制刷新用户信息
// 确保从其他页面返回时数据是最新的
this.loadCommissionStats()
},
/**
* 从缓存加载数据
*/
loadFromCache() {
try {
// 加载统计数据缓存
const statsCache = wx.getStorageSync(CACHE_CONFIG.STATS_KEY)
if (statsCache && this.isCacheValid(statsCache.timestamp)) {
const cachedData = statsCache.data || {}
// 强制修正缓存中的错误规定值
if (cachedData.pendingAmount === '210.00' || cachedData.pendingAmount === 210) {
cachedData.pendingAmount = '0.00'
}
this.setData({
...cachedData,
cacheExpired: false,
lastUpdateTime: this.formatCacheTime(statsCache.timestamp)
})
} else {
this.setData({ cacheExpired: true })
}
// 加载记录列表缓存
const recordsCache = wx.getStorageSync(CACHE_CONFIG.RECORDS_KEY)
if (recordsCache && this.isCacheValid(recordsCache.timestamp)) {
this.setData({
allList: recordsCache.data,
commissionList: recordsCache.data
})
}
} catch (error) {
console.error('加载缓存失败:', error)
}
},
/**
* 检查缓存是否有效
*/
isCacheValid(timestamp) {
if (!timestamp) return false
const now = Date.now()
return (now - timestamp) < CACHE_CONFIG.EXPIRE_TIME
},
/**
* 格式化缓存时间
*/
formatCacheTime(timestamp) {
const date = new Date(timestamp)
const hour = String(date.getHours()).padStart(2, '0')
const minute = String(date.getMinutes()).padStart(2, '0')
return `${hour}:${minute}`
},
/**
* 保存统计数据到缓存
*/
saveStatsToCache(data) {
try {
wx.setStorageSync(CACHE_CONFIG.STATS_KEY, {
data,
timestamp: Date.now()
})
} catch (error) {
console.error('保存统计缓存失败:', error)
}
},
/**
* 保存记录列表到缓存
*/
saveRecordsToCache(records) {
try {
wx.setStorageSync(CACHE_CONFIG.RECORDS_KEY, {
data: records,
timestamp: Date.now()
})
} catch (error) {
console.error('保存记录缓存失败:', error)
}
},
/**
* 清除缓存
*/
clearCache() {
try {
wx.removeStorageSync(CACHE_CONFIG.STATS_KEY)
wx.removeStorageSync(CACHE_CONFIG.RECORDS_KEY)
this.setData({ cacheExpired: true, lastUpdateTime: '' })
wx.showToast({
title: '缓存已清除',
icon: 'success'
})
} catch (error) {
console.error('清除缓存失败:', error)
}
},
/**
* 下拉刷新
*/
onPullDownRefresh() {
// 清除缓存,强制刷新
this.clearCache()
Promise.all([
this.loadCommissionStats(),
this.loadCommissionRecords()
]).then(() => {
wx.stopPullDownRefresh()
wx.showToast({
title: '刷新成功',
icon: 'success'
})
})
},
/**
* 上拉加载更多
*/
onReachBottom() {
if (this.data.hasMore && !this.data.loading) {
this.loadMoreRecords()
}
},
/**
* 加载佣金统计
*/
async loadCommissionStats() {
try {
const res = await api.commission.getStats()
if (res.success && res.data) {
const data = res.data
const statsData = {
isDistributor: data.isDistributor || false,
referralCode: data.referralCode || '',
cardType: data.cardType || '',
commissionBalance: Number(data.commissionBalance || 0).toFixed(2),
totalCommission: Number(data.totalCommission || 0).toLocaleString('zh-CN', { minimumFractionDigits: 2 }),
pendingAmount: Number(data.pendingWithdrawal || data.pendingAmount || 0).toFixed(2),
totalWithdrawn: Number(data.totalWithdrawn || 0).toLocaleString('zh-CN', { minimumFractionDigits: 2 }),
totalReferrals: data.totalReferrals || 0,
totalContribution: Number(data.totalContribution || data.total_contribution || 0).toLocaleString('zh-CN', { minimumFractionDigits: 2 }),
pendingWithdrawal: Number(data.pendingWithdrawal || 0).toFixed(2),
rechargeRate: data.rechargeRate || 10,
vipRate: data.vipRate || 15,
cardRate: data.cardRate || 20,
// 兼容旧字段
totalEarnings: Number(data.totalCommission || data.total_earnings || 0).toLocaleString('zh-CN', { minimumFractionDigits: 2 }),
availableBalance: Number(data.commissionBalance || data.available_balance || 0).toFixed(2),
withdrawnAmount: Number(data.totalWithdrawn || data.withdrawn_amount || 0).toLocaleString('zh-CN', { minimumFractionDigits: 2 })
}
this.setData({
...statsData,
cardTitle: this.getCardTitle(statsData.cardType),
cacheExpired: false,
lastUpdateTime: this.formatCacheTime(Date.now())
})
// 保存到缓存
this.saveStatsToCache(statsData)
// 如果不是分销商,显示引导提示
if (!data.isDistributor) {
this.showBecomeDistributorTip()
}
}
} catch (err) {
console.log('获取佣金统计失败', err)
// 如果有缓存,显示缓存失效提示
if (!this.data.cacheExpired) {
wx.showToast({
title: '数据加载失败,显示缓存数据',
icon: 'none',
duration: 2000
})
}
}
},
/**
* 显示成为分销商提示
*/
showBecomeDistributorTip() {
wx.showModal({
title: '成为分销商',
content: '购买身份卡即可成为分销商,推荐好友赚佣金!',
confirmText: '了解详情',
cancelText: '暂不需要',
success: (res) => {
if (res.confirm) {
// 跳转到推广页面查看详情
wx.navigateTo({
url: '/pages/promote/promote'
})
}
}
})
},
/**
* 加载佣金记录
*/
async loadCommissionRecords() {
this.setData({ loading: true, page: 1 })
try {
const res = await api.commission.getRecords({ page: 1, limit: 20 })
if (res.success && res.data) {
const records = (res.data.list || res.data || []).map(record => this.transformRecord(record))
this.setData({
allList: records,
commissionList: records,
hasMore: records.length >= 20,
loading: false
})
// 保存到缓存
this.saveRecordsToCache(records)
} else {
this.setData({ allList: [], commissionList: [], loading: false })
}
} catch (err) {
console.error('加载佣金记录失败', err)
this.setData({ loading: false })
// 如果有缓存,显示缓存失效提示
if (this.data.allList.length > 0) {
wx.showToast({
title: '数据加载失败,显示缓存数据',
icon: 'none',
duration: 2000
})
}
}
},
/**
* 加载更多记录
*/
async loadMoreRecords() {
const nextPage = this.data.page + 1
this.setData({ loading: true })
try {
const res = await api.commission.getRecords({ page: nextPage, limit: 20 })
if (res.success && res.data) {
const newRecords = (res.data.list || res.data || []).map(record => this.transformRecord(record))
const allList = [...this.data.allList, ...newRecords]
this.setData({
allList,
page: nextPage,
hasMore: newRecords.length >= 20,
loading: false
})
// 更新当前筛选列表
this.filterRecords(this.data.currentTab)
} else {
this.setData({ hasMore: false, loading: false })
}
} catch (err) {
console.error('加载更多记录失败', err)
this.setData({ loading: false })
}
},
/**
* 转换记录数据格式
*/
transformRecord(record) {
let titleText = record.fromUserName || record.userName || '用户';
let descText = 'VIP月卡';
if (record.amount > 100) descText = 'SVIP年卡';
if (record.fromUserLevel) {
descText = this.getUserLevelText(record.fromUserLevel);
} else if (record.orderType === 'vip' || record.orderType === 'svip') {
descText = record.orderType.toUpperCase() === 'SVIP' ? 'SVIP会员' : 'VIP会员';
} else if (record.orderType === 'identity_card') {
descText = '身份会员';
} else if (record.orderType === 'companion_chat') {
descText = '陪伴聊天';
}
const dateObj = new Date(record.created_at || record.createdAt);
const mm = String(dateObj.getMonth() + 1).padStart(2, '0');
const dd = String(dateObj.getDate()).padStart(2, '0');
const hh = String(dateObj.getHours()).padStart(2, '0');
const min = String(dateObj.getMinutes()).padStart(2, '0');
const fmtTime = `${mm}-${dd} ${hh}:${min}`;
return {
id: record.id,
type: record.type,
title: titleText,
desc: descText,
amount: record.commissionAmount ? record.commissionAmount.toFixed(0) : (record.amount ? Number(record.amount).toFixed(0) : '0'),
status: record.status || 'settled',
statusText: record.status === 'pending' ? '待结算' : '已结算',
time: this.formatTime(record.created_at || record.createdAt),
orderNo: record.orderId ? `ORD${record.orderId.substring(0, 12)}` : 'ORD2024012401',
userAvatar: record.userAvatar || record.fromUserAvatar || record.avatar || '',
listTitle: titleText,
fmtTime: fmtTime,
}
},
getUserLevelText(level) {
const levelMap = {
'vip': 'VIP会员',
'svip': 'SVIP会员',
'guardian': '守护会员',
'companion': '陪伴会员',
'partner': '城市合伙人',
'1': '普通用户',
'2': 'VIP会员',
'3': 'SVIP会员',
'4': '守护会员',
'5': '陪伴会员',
'6': '城市合伙人'
};
return levelMap[level] || levelMap['1'];
},
getCardTitle(type) {
const map = {
'guardian_card': '守护会员',
'companion_card': '陪伴会员',
'identity_card': '身份会员',
'vip': 'VIP会员',
'partner': '城市合伙人'
};
return map[type] || '守护会员';
},
goToTeam() {
wx.navigateTo({
url: '/pages/team/team',
});
},
/**
* 格式化时间
*/
formatTime(dateStr) {
if (!dateStr) return ''
const date = new Date(dateStr)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const hour = String(date.getHours()).padStart(2, '0')
const minute = String(date.getMinutes()).padStart(2, '0')
return `${year}-${month}-${day} ${hour}:${minute}`
},
onBack() {
wx.navigateBack()
},
onTabChange(e) {
const tab = e.currentTarget.dataset.tab
this.setData({ currentTab: tab })
this.filterRecords(tab)
},
/**
* 筛选记录
*/
filterRecords(tab) {
let list = []
if (tab === 'all') {
list = this.data.allList
} else if (tab === 'settled') {
list = this.data.allList.filter(item => item.status === 'settled')
} else if (tab === 'pending') {
list = this.data.allList.filter(item => item.status === 'pending')
}
this.setData({ commissionList: list })
},
onDateChange(e) {
const val = e.detail.value; // YYYY-MM
const [y, m] = val.split('-');
this.setData({
pickerDate: val,
pickerDateDisplay: `${y}${m}`
});
// TODO: Call API to reload records with date filter if needed
this.loadCommissionRecords(); // Reload with new date
},
/**
* 跳转到提现页面
*/
onWithdraw() {
wx.navigateTo({
url: '/pages/withdraw/withdraw'
})
},
/**
* 跳转到推广页面
*/
onPromote() {
wx.navigateTo({
url: '/pages/promote/promote'
})
},
/**
* 跳转到推荐用户列表
*/
async goToReferrals() {
// 显示加载提示
wx.showLoading({ title: '加载中...', mask: true })
try {
// 强制刷新用户信息,确保使用最新数据
const res = await api.commission.getStats()
if (res.success && res.data) {
const isDistributor = res.data.isDistributor || false
// 更新本地状态
this.setData({ isDistributor })
wx.hideLoading()
// 检查是否是分销商
if (!isDistributor) {
wx.showModal({
title: '成为分销商',
content: '购买身份卡即可成为分销商,推荐好友赚佣金!',
confirmText: '了解详情',
cancelText: '取消',
success: (modalRes) => {
if (modalRes.confirm) {
wx.navigateTo({
url: '/pages/promote/promote'
})
}
}
})
return
}
// 跳转到推荐用户列表
wx.navigateTo({
url: '/pages/referrals/referrals'
})
} else {
wx.hideLoading()
wx.showToast({
title: '获取用户信息失败',
icon: 'none'
})
}
} catch (error) {
wx.hideLoading()
console.error('获取用户信息失败:', error)
wx.showToast({
title: '网络错误,请重试',
icon: 'none'
})
}
},
/**
* 跳转到提现记录
*/
goToWithdrawRecords() {
wx.navigateTo({
url: '/pages/withdraw-records/withdraw-records'
})
},
/**
* 微信分享推荐码
*/
onShareAppMessage() {
const { referralCode, isDistributor } = this.data
if (!isDistributor || !referralCode) {
return {
title: '心伴AI - 情感陪伴聊天机器人',
path: '/pages/index/index',
imageUrl: '/images/share-cover.jpg'
}
}
return {
title: `我的推荐码:${referralCode},注册即可享受优惠!`,
path: `/pages/index/index?referralCode=${referralCode}`,
imageUrl: '/images/share-commission.png'
}
},
/**
* 分享到朋友圈
*/
onShareTimeline() {
const { referralCode, isDistributor } = this.data
if (!isDistributor || !referralCode) {
return {
title: '心伴AI - 情感陪伴聊天机器人',
imageUrl: '/images/share-cover.jpg'
}
}
return {
title: `我的推荐码:${referralCode},注册即可享受优惠!`,
query: `referralCode=${referralCode}`,
imageUrl: '/images/share-commission.png'
}
},
/**
* 复制推荐码
*/
copyReferralCode() {
const { referralCode } = this.data
if (!referralCode) {
wx.showToast({ title: '暂无推荐码', icon: 'none' })
return
}
wx.setClipboardData({
data: referralCode,
success: () => {
wx.showToast({ title: '已复制推荐码', icon: 'success' })
}
})
},
/**
* 绑定推荐码
*/
bindReferralCode() {
wx.showModal({
title: '绑定推荐码',
editable: true,
placeholderText: '请输入推荐码',
success: async (res) => {
if (res.confirm && res.content) {
try {
wx.showLoading({ title: '绑定中...' })
const result = await api.commission.bindReferral(res.content.trim())
wx.hideLoading()
if (result.success) {
wx.showToast({ title: '绑定成功', icon: 'success' })
this.loadCommissionStats()
} else {
wx.showToast({ title: result.message || '绑定失败', icon: 'none' })
}
} catch (err) {
wx.hideLoading()
wx.showToast({ title: err.message || '绑定失败', icon: 'none' })
}
}
}
})
}
})