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

535 lines
12 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>