peixue-dev/peidu/uniapp/distributor-package/pages/distributor/commission.vue

535 lines
12 KiB
Vue
Raw Normal View History

<template>
<view class="commission-page">
<!-- 佣金总览卡片 -->
<view class="overview-card gradient-bg">
<view class="card-header">
<text class="card-title">我的佣金</text>
</view>
<view class="balance-display">
<text class="balance-label">可提现金额</text>
<text class="balance-amount">{{ availableCommission }}</text>
</view>
<view class="balance-stats">
<view class="stat-item">
<text class="stat-label">累计佣金</text>
<text class="stat-value">¥{{ totalCommission }}</text>
</view>
<view class="stat-divider"></view>
<view class="stat-item">
<text class="stat-label">已提现</text>
<text class="stat-value">¥{{ withdrawnCommission }}</text>
</view>
</view>
<button class="withdraw-btn" @click="goWithdraw" :disabled="availableCommission <= 0">
立即提现
</button>
</view>
<!-- 佣金明细 -->
<view class="detail-section">
<view class="section-header">
<text class="section-title">佣金明细</text>
<picker mode="selector" :range="monthOptions" @change="onMonthChange">
<view class="month-picker">
<text>{{ selectedMonth }}</text>
<text class="arrow"></text>
</view>
</picker>
</view>
<view class="detail-list">
<view class="detail-item" v-for="item in commissionList" :key="item.id">
<view class="item-left">
<text class="item-title">{{ item.title }}</text>
<text class="item-time">{{ item.time }}</text>
<text class="item-order">订单号{{ item.orderNo }}</text>
</view>
<view class="item-right">
<text class="item-amount" :class="{ income: item.type === 'income', expense: item.type === 'expense' }">
{{ item.type === 'income' ? '+' : '-' }}¥{{ item.amount }}
</text>
<text class="item-status" :class="'status-' + item.status">{{ getStatusText(item.status) }}</text>
</view>
</view>
</view>
<!-- 空状态 -->
<view class="empty-state" v-if="commissionList.length === 0">
<text class="empty-icon">💰</text>
<text class="empty-text">暂无佣金记录</text>
</view>
</view>
<!-- 提现记录 -->
<view class="withdraw-section">
<view class="section-header">
<text class="section-title">提现记录</text>
<text class="section-more" @click="goWithdrawList">查看全部 </text>
</view>
<view class="withdraw-list">
<view class="withdraw-item" v-for="item in withdrawList" :key="item.id">
<view class="item-info">
<text class="item-amount">¥{{ item.amount }}</text>
<text class="item-time">{{ item.time }}</text>
</view>
<text class="item-status" :class="'status-' + item.status">{{ getWithdrawStatusText(item.status) }}</text>
</view>
</view>
</view>
<!-- 佣金规则说明 -->
<view class="rule-section">
<view class="section-header">
<text class="section-title">佣金规则</text>
</view>
<view class="rule-content">
<view class="rule-item">
<text class="rule-icon">🥇</text>
<view class="rule-text">
<text class="rule-title">一级分销</text>
<text class="rule-desc">直接推广客户享受10-15%佣金</text>
</view>
</view>
<view class="rule-item">
<text class="rule-icon">🥈</text>
<view class="rule-text">
<text class="rule-title">二级分销</text>
<text class="rule-desc">下级推广客户享受5-7%佣金</text>
</view>
</view>
<view class="rule-item">
<text class="rule-icon">💳</text>
<view class="rule-text">
<text class="rule-title">提现规则</text>
<text class="rule-desc">满100元可提现1-3个工作日到账</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { distributorApi } from '@/api/index.js'
export default {
data() {
return {
availableCommission: 0,
totalCommission: 0,
withdrawnCommission: 0,
selectedMonth: '',
monthOptions: [],
commissionList: [],
withdrawList: []
}
},
onLoad() {
this.initMonthOptions()
this.loadCommissionData()
this.loadCommissionList()
this.loadWithdrawList()
},
methods: {
// 初始化月份选项最近12个月
initMonthOptions() {
const options = []
const now = new Date()
for (let i = 0; i < 12; i++) {
const date = new Date(now.getFullYear(), now.getMonth() - i, 1)
const year = date.getFullYear()
const month = date.getMonth() + 1
options.push(`${year}${month}`)
}
this.monthOptions = options
this.selectedMonth = options[0] // 默认选择当前月份
},
async loadCommissionData() {
try {
// 调用API获取佣金数据
const res = await distributorApi.getCommissionStats()
if (res.code === 200 && res.data) {
this.availableCommission = res.data.availableBalance || 0
this.totalCommission = res.data.totalCommission || 0
this.withdrawnCommission = res.data.withdrawnCommission || 0
}
} catch (error) {
console.error('加载佣金数据失败:', error)
uni.showToast({
title: '加载佣金数据失败',
icon: 'none'
})
}
},
async loadCommissionList() {
try {
// 解析选中的年月
const match = this.selectedMonth.match(/(\d+)年(\d+)月/)
if (!match) return
const year = match[1]
const month = match[2]
// 调用API获取佣金明细
const res = await distributorApi.getCommissionList({
year: year,
month: month
})
if (res.code === 200 && res.data) {
this.commissionList = res.data.list || res.data.records || []
}
} catch (error) {
console.error('加载佣金明细失败:', error)
// 如果API失败显示空列表
this.commissionList = []
}
},
async loadWithdrawList() {
try {
// 调用API获取提现记录最近5条
const res = await distributorApi.getWithdrawRecords({ pageSize: 5 })
if (res.code === 200 && res.data) {
this.withdrawList = res.data.list || res.data.records || []
}
} catch (error) {
console.error('加载提现记录失败:', error)
// 如果API失败显示空列表
this.withdrawList = []
}
},
onMonthChange(e) {
this.selectedMonth = this.monthOptions[e.detail.value]
this.loadCommissionList()
},
getStatusText(status) {
const statusMap = {
pending: '待结算',
settled: '已结算',
withdrawn: '已提现'
}
return statusMap[status] || '未知'
},
getWithdrawStatusText(status) {
const statusMap = {
pending: '待审核',
processing: '处理中',
completed: '已完成',
rejected: '已拒绝'
}
return statusMap[status] || '未知'
},
goWithdraw() {
if (this.availableCommission < 100) {
uni.showToast({
title: '可提现金额不足100元',
icon: 'none'
})
return
}
uni.navigateTo({
url: '/pages/distributor/withdraw'
})
},
goWithdrawList() {
uni.navigateTo({
url: '/pages/distributor/withdraw-list'
})
}
}
}
</script>
<style lang="scss" scoped>
.commission-page {
min-height: 100vh;
background: #f0f9f7;
padding: 20rpx;
}
.gradient-bg {
background: linear-gradient(135deg, #7dd3c0 0%, #5fb8a8 100%);
}
.overview-card {
border-radius: 20rpx;
padding: 40rpx;
margin-bottom: 20rpx;
box-shadow: 0 8rpx 24rpx rgba(125, 211, 192, 0.3);
}
.card-header {
margin-bottom: 30rpx;
}
.card-title {
font-size: 32rpx;
font-weight: bold;
color: #ffffff;
}
.balance-display {
display: flex;
flex-direction: column;
align-items: center;
gap: 20rpx;
margin-bottom: 40rpx;
}
.balance-label {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.9);
}
.balance-amount {
font-size: 72rpx;
font-weight: bold;
color: #ffffff;
}
.balance-stats {
display: flex;
align-items: center;
justify-content: space-around;
padding: 30rpx 0;
margin-bottom: 30rpx;
}
.stat-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 10rpx;
}
.stat-label {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.9);
}
.stat-value {
font-size: 32rpx;
font-weight: bold;
color: #ffffff;
}
.stat-divider {
width: 2rpx;
height: 60rpx;
background: rgba(255, 255, 255, 0.3);
}
.withdraw-btn {
width: 100%;
padding: 28rpx;
background: #ffffff;
color: #7dd3c0;
border-radius: 50rpx;
font-size: 32rpx;
font-weight: bold;
border: none;
&[disabled] {
opacity: 0.5;
}
}
.detail-section, .withdraw-section, .rule-section {
background: #ffffff;
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 20rpx;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333333;
}
.section-more {
font-size: 26rpx;
color: #7dd3c0;
}
.month-picker {
display: flex;
align-items: center;
gap: 10rpx;
padding: 12rpx 20rpx;
background: #f0f9f7;
border-radius: 8rpx;
font-size: 26rpx;
color: #666666;
}
.arrow {
font-size: 20rpx;
}
.detail-list, .withdraw-list {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.detail-item {
display: flex;
justify-content: space-between;
padding: 30rpx;
background: #f0f9f7;
border-radius: 16rpx;
}
.item-left {
flex: 1;
display: flex;
flex-direction: column;
gap: 10rpx;
}
.item-title {
font-size: 30rpx;
font-weight: bold;
color: #333333;
}
.item-time, .item-order {
font-size: 24rpx;
color: #999999;
}
.item-right {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 10rpx;
}
.item-amount {
font-size: 36rpx;
font-weight: bold;
&.income {
color: #ff6b6b;
}
&.expense {
color: #999999;
}
}
.item-status {
font-size: 24rpx;
padding: 6rpx 12rpx;
border-radius: 8rpx;
&.status-pending {
background: #fff3e0;
color: #ff9800;
}
&.status-settled {
background: #e3f2fd;
color: #2196f3;
}
&.status-withdrawn {
background: #e8f5e9;
color: #4caf50;
}
}
.withdraw-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
background: #f0f9f7;
border-radius: 16rpx;
}
.item-info {
display: flex;
flex-direction: column;
gap: 10rpx;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
}
.empty-icon {
font-size: 100rpx;
margin-bottom: 20rpx;
}
.empty-text {
font-size: 28rpx;
color: #999999;
}
.rule-content {
display: flex;
flex-direction: column;
gap: 30rpx;
}
.rule-item {
display: flex;
gap: 20rpx;
}
.rule-icon {
font-size: 48rpx;
flex-shrink: 0;
}
.rule-text {
flex: 1;
display: flex;
flex-direction: column;
gap: 10rpx;
}
.rule-title {
font-size: 28rpx;
font-weight: bold;
color: #333333;
}
.rule-desc {
font-size: 24rpx;
color: #666666;
line-height: 1.6;
}
</style>