535 lines
12 KiB
Vue
535 lines
12 KiB
Vue
|
|
<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>
|