Initial commit: One Pipe System
完整的管理系统,包含账户管理、卡片管理、套餐管理、财务管理等功能模块。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
441
src/views/account-management/customer-commission/index.vue
Normal file
441
src/views/account-management/customer-commission/index.vue
Normal file
@@ -0,0 +1,441 @@
|
||||
<template>
|
||||
<div class="page-content">
|
||||
<!-- 统计卡片 -->
|
||||
<ElRow :gutter="20" style="margin-bottom: 20px">
|
||||
<ElCol :xs="24" :sm="12" :lg="6">
|
||||
<ElCard shadow="hover" class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-label">客户总数</div>
|
||||
<div class="stat-value">{{ statistics.totalCustomers }}</div>
|
||||
</div>
|
||||
<el-icon class="stat-icon" style="color: var(--el-color-primary)"><User /></el-icon>
|
||||
</ElCard>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :lg="6">
|
||||
<ElCard shadow="hover" class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-label">累计佣金</div>
|
||||
<div class="stat-value" style="color: var(--el-color-success)">
|
||||
¥{{ statistics.totalCommission.toFixed(2) }}
|
||||
</div>
|
||||
</div>
|
||||
<el-icon class="stat-icon" style="color: var(--el-color-success)"><Money /></el-icon>
|
||||
</ElCard>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :lg="6">
|
||||
<ElCard shadow="hover" class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-label">已提现</div>
|
||||
<div class="stat-value" style="color: var(--el-color-warning)">
|
||||
¥{{ statistics.totalWithdrawn.toFixed(2) }}
|
||||
</div>
|
||||
</div>
|
||||
<el-icon class="stat-icon" style="color: var(--el-color-warning)"><WalletFilled /></el-icon>
|
||||
</ElCard>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :lg="6">
|
||||
<ElCard shadow="hover" class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-label">待提现</div>
|
||||
<div class="stat-value" style="color: var(--el-color-danger)">
|
||||
¥{{ statistics.pendingWithdrawal.toFixed(2) }}
|
||||
</div>
|
||||
</div>
|
||||
<el-icon class="stat-icon" style="color: var(--el-color-danger)"><Wallet /></el-icon>
|
||||
</ElCard>
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
|
||||
<!-- 搜索和筛选区 -->
|
||||
<ElRow :gutter="12">
|
||||
<ElCol :xs="24" :sm="12" :lg="6">
|
||||
<ElInput v-model="searchQuery" placeholder="客户名称/手机号" clearable />
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :lg="6">
|
||||
<ElSelect v-model="customerTypeFilter" placeholder="客户类型" clearable style="width: 100%">
|
||||
<ElOption label="全部" value="" />
|
||||
<ElOption label="代理商" value="agent" />
|
||||
<ElOption label="企业客户" value="enterprise" />
|
||||
</ElSelect>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :lg="6">
|
||||
<ElSelect v-model="commissionRangeFilter" placeholder="佣金范围" clearable style="width: 100%">
|
||||
<ElOption label="全部" value="" />
|
||||
<ElOption label="0-1000元" value="0-1000" />
|
||||
<ElOption label="1000-5000元" value="1000-5000" />
|
||||
<ElOption label="5000-10000元" value="5000-10000" />
|
||||
<ElOption label="10000元以上" value="10000+" />
|
||||
</ElSelect>
|
||||
</ElCol>
|
||||
<ElCol :xs="24" :sm="12" :lg="6" class="el-col2">
|
||||
<ElButton v-ripple @click="handleSearch">搜索</ElButton>
|
||||
<ElButton v-ripple @click="exportData">导出</ElButton>
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
|
||||
<!-- 客户佣金列表 -->
|
||||
<ArtTable :data="filteredData" index style="margin-top: 20px">
|
||||
<template #default>
|
||||
<ElTableColumn label="客户名称" prop="customerName" min-width="150" show-overflow-tooltip />
|
||||
<ElTableColumn label="客户类型" prop="customerType" width="120">
|
||||
<template #default="scope">
|
||||
<ElTag :type="scope.row.customerType === 'agent' ? 'warning' : 'primary'">
|
||||
{{ scope.row.customerType === 'agent' ? '代理商' : '企业客户' }}
|
||||
</ElTag>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="联系电话" prop="phone" width="130" />
|
||||
<ElTableColumn label="累计佣金" prop="totalCommission" width="130" sortable>
|
||||
<template #default="scope">
|
||||
<span style="color: var(--el-color-success); font-weight: 600">
|
||||
¥{{ scope.row.totalCommission.toFixed(2) }}
|
||||
</span>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="已提现" prop="withdrawnAmount" width="130" sortable>
|
||||
<template #default="scope">
|
||||
<span style="color: var(--el-color-warning)">
|
||||
¥{{ scope.row.withdrawnAmount.toFixed(2) }}
|
||||
</span>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="待提现" prop="pendingAmount" width="130" sortable>
|
||||
<template #default="scope">
|
||||
<span style="color: var(--el-color-danger); font-weight: 600">
|
||||
¥{{ scope.row.pendingAmount.toFixed(2) }}
|
||||
</span>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="提现次数" prop="withdrawalCount" width="100" align="center" />
|
||||
<ElTableColumn label="卡片数量" prop="cardCount" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<span style="color: var(--el-color-primary)">{{ scope.row.cardCount }}</span>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="最近提现" prop="lastWithdrawalTime" width="180" />
|
||||
<ElTableColumn label="注册时间" prop="registerTime" width="180" />
|
||||
<ElTableColumn fixed="right" label="操作" width="220">
|
||||
<template #default="scope">
|
||||
<el-button link :icon="View" @click="viewCommissionDetail(scope.row)">佣金详情</el-button>
|
||||
<el-button link :icon="List" @click="viewWithdrawalHistory(scope.row)">提现记录</el-button>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
</template>
|
||||
</ArtTable>
|
||||
|
||||
<!-- 佣金详情对话框 -->
|
||||
<ElDialog v-model="commissionDialogVisible" title="佣金详情" width="900px" align-center>
|
||||
<ElDescriptions :column="2" border style="margin-bottom: 20px">
|
||||
<ElDescriptionsItem label="客户名称">{{ currentCustomer.customerName }}</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="客户类型">
|
||||
<ElTag :type="currentCustomer.customerType === 'agent' ? 'warning' : 'primary'">
|
||||
{{ currentCustomer.customerType === 'agent' ? '代理商' : '企业客户' }}
|
||||
</ElTag>
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="累计佣金">
|
||||
<span style="color: var(--el-color-success); font-weight: 600">
|
||||
¥{{ currentCustomer.totalCommission.toFixed(2) }}
|
||||
</span>
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="已提现">
|
||||
<span style="color: var(--el-color-warning)">
|
||||
¥{{ currentCustomer.withdrawnAmount.toFixed(2) }}
|
||||
</span>
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="待提现">
|
||||
<span style="color: var(--el-color-danger); font-weight: 600">
|
||||
¥{{ currentCustomer.pendingAmount.toFixed(2) }}
|
||||
</span>
|
||||
</ElDescriptionsItem>
|
||||
<ElDescriptionsItem label="提现次数">{{ currentCustomer.withdrawalCount }}</ElDescriptionsItem>
|
||||
</ElDescriptions>
|
||||
|
||||
<ElDivider content-position="left">佣金明细</ElDivider>
|
||||
<ArtTable :data="commissionDetails" index>
|
||||
<template #default>
|
||||
<ElTableColumn label="来源" prop="source" width="120" />
|
||||
<ElTableColumn label="订单号" prop="orderNo" width="180" />
|
||||
<ElTableColumn label="佣金金额" prop="amount" width="120">
|
||||
<template #default="scope">
|
||||
<span style="color: var(--el-color-success)">+¥{{ scope.row.amount.toFixed(2) }}</span>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="佣金比例" prop="rate" width="100" />
|
||||
<ElTableColumn label="订单金额" prop="orderAmount" width="120" />
|
||||
<ElTableColumn label="获得时间" prop="createTime" width="180" />
|
||||
<ElTableColumn label="状态" prop="status" width="100">
|
||||
<template #default="scope">
|
||||
<ElTag v-if="scope.row.status === 'completed'" type="success">已结算</ElTag>
|
||||
<ElTag v-else-if="scope.row.status === 'pending'" type="warning">待结算</ElTag>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
</template>
|
||||
</ArtTable>
|
||||
|
||||
<template #footer>
|
||||
<ElButton @click="commissionDialogVisible = false">关闭</ElButton>
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<!-- 提现记录对话框 -->
|
||||
<ElDialog v-model="withdrawalDialogVisible" title="提现记录" width="900px" align-center>
|
||||
<ArtTable :data="withdrawalHistory" index>
|
||||
<template #default>
|
||||
<ElTableColumn label="提现单号" prop="withdrawalNo" width="180" />
|
||||
<ElTableColumn label="提现金额" prop="amount" width="120">
|
||||
<template #default="scope">
|
||||
<span style="color: var(--el-color-danger); font-weight: 600">
|
||||
¥{{ scope.row.amount.toFixed(2) }}
|
||||
</span>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="手续费" prop="fee" width="100">
|
||||
<template #default="scope"> ¥{{ scope.row.fee.toFixed(2) }} </template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="实际到账" prop="actualAmount" width="120">
|
||||
<template #default="scope">
|
||||
<span style="color: var(--el-color-success)">
|
||||
¥{{ scope.row.actualAmount.toFixed(2) }}
|
||||
</span>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="提现方式" prop="method" width="100" />
|
||||
<ElTableColumn label="状态" prop="status" width="100">
|
||||
<template #default="scope">
|
||||
<ElTag v-if="scope.row.status === 'completed'" type="success">已完成</ElTag>
|
||||
<ElTag v-else-if="scope.row.status === 'processing'" type="warning">处理中</ElTag>
|
||||
<ElTag v-else-if="scope.row.status === 'pending'" type="info">待审核</ElTag>
|
||||
<ElTag v-else type="danger">已拒绝</ElTag>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="申请时间" prop="applyTime" width="180" />
|
||||
<ElTableColumn label="完成时间" prop="completeTime" width="180">
|
||||
<template #default="scope">
|
||||
{{ scope.row.completeTime || '-' }}
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
</template>
|
||||
</ArtTable>
|
||||
|
||||
<template #footer>
|
||||
<ElButton @click="withdrawalDialogVisible = false">关闭</ElButton>
|
||||
</template>
|
||||
</ElDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { View, List, User, Money, WalletFilled, Wallet } from '@element-plus/icons-vue'
|
||||
|
||||
defineOptions({ name: 'CustomerCommission' })
|
||||
|
||||
interface CustomerCommission {
|
||||
id: string
|
||||
customerName: string
|
||||
customerType: 'agent' | 'enterprise'
|
||||
phone: string
|
||||
totalCommission: number
|
||||
withdrawnAmount: number
|
||||
pendingAmount: number
|
||||
withdrawalCount: number
|
||||
cardCount: number
|
||||
lastWithdrawalTime: string
|
||||
registerTime: string
|
||||
}
|
||||
|
||||
const searchQuery = ref('')
|
||||
const customerTypeFilter = ref('')
|
||||
const commissionRangeFilter = ref('')
|
||||
const commissionDialogVisible = ref(false)
|
||||
const withdrawalDialogVisible = ref(false)
|
||||
|
||||
const statistics = reactive({
|
||||
totalCustomers: 156,
|
||||
totalCommission: 580000.00,
|
||||
totalWithdrawn: 420000.00,
|
||||
pendingWithdrawal: 160000.00
|
||||
})
|
||||
|
||||
const mockData = ref<CustomerCommission[]>([
|
||||
{
|
||||
id: '1',
|
||||
customerName: '华东区总代理',
|
||||
customerType: 'agent',
|
||||
phone: '13800138000',
|
||||
totalCommission: 85000.00,
|
||||
withdrawnAmount: 70000.00,
|
||||
pendingAmount: 15000.00,
|
||||
withdrawalCount: 12,
|
||||
cardCount: 500,
|
||||
lastWithdrawalTime: '2026-01-08 10:00:00',
|
||||
registerTime: '2025-06-01 09:00:00'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
customerName: '深圳市科技有限公司',
|
||||
customerType: 'enterprise',
|
||||
phone: '13900139000',
|
||||
totalCommission: 45000.00,
|
||||
withdrawnAmount: 30000.00,
|
||||
pendingAmount: 15000.00,
|
||||
withdrawalCount: 8,
|
||||
cardCount: 300,
|
||||
lastWithdrawalTime: '2026-01-05 14:30:00',
|
||||
registerTime: '2025-07-15 10:00:00'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
customerName: '北京智能制造',
|
||||
customerType: 'enterprise',
|
||||
phone: '13700137000',
|
||||
totalCommission: 68000.00,
|
||||
withdrawnAmount: 55000.00,
|
||||
pendingAmount: 13000.00,
|
||||
withdrawalCount: 10,
|
||||
cardCount: 450,
|
||||
lastWithdrawalTime: '2026-01-07 16:00:00',
|
||||
registerTime: '2025-08-20 11:00:00'
|
||||
}
|
||||
])
|
||||
|
||||
const currentCustomer = ref<CustomerCommission>({
|
||||
id: '',
|
||||
customerName: '',
|
||||
customerType: 'agent',
|
||||
phone: '',
|
||||
totalCommission: 0,
|
||||
withdrawnAmount: 0,
|
||||
pendingAmount: 0,
|
||||
withdrawalCount: 0,
|
||||
cardCount: 0,
|
||||
lastWithdrawalTime: '',
|
||||
registerTime: ''
|
||||
})
|
||||
|
||||
const commissionDetails = ref([
|
||||
{
|
||||
id: '1',
|
||||
source: '套餐销售',
|
||||
orderNo: 'ORD202601090001',
|
||||
amount: 150.00,
|
||||
rate: '10%',
|
||||
orderAmount: '¥1,500.00',
|
||||
createTime: '2026-01-09 09:30:00',
|
||||
status: 'completed'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
source: '卡片激活',
|
||||
orderNo: 'ORD202601080025',
|
||||
amount: 80.00,
|
||||
rate: '8%',
|
||||
orderAmount: '¥1,000.00',
|
||||
createTime: '2026-01-08 15:20:00',
|
||||
status: 'completed'
|
||||
}
|
||||
])
|
||||
|
||||
const withdrawalHistory = ref([
|
||||
{
|
||||
id: '1',
|
||||
withdrawalNo: 'WD202601080001',
|
||||
amount: 10000.00,
|
||||
fee: 20.00,
|
||||
actualAmount: 9980.00,
|
||||
method: '银行卡',
|
||||
status: 'completed',
|
||||
applyTime: '2026-01-08 10:00:00',
|
||||
completeTime: '2026-01-08 15:30:00'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
withdrawalNo: 'WD202601050002',
|
||||
amount: 5000.00,
|
||||
fee: 10.00,
|
||||
actualAmount: 4990.00,
|
||||
method: '支付宝',
|
||||
status: 'completed',
|
||||
applyTime: '2026-01-05 14:00:00',
|
||||
completeTime: '2026-01-05 18:20:00'
|
||||
}
|
||||
])
|
||||
|
||||
const filteredData = computed(() => {
|
||||
let data = mockData.value
|
||||
|
||||
if (searchQuery.value) {
|
||||
data = data.filter(
|
||||
(item) =>
|
||||
item.customerName.includes(searchQuery.value) ||
|
||||
item.phone.includes(searchQuery.value)
|
||||
)
|
||||
}
|
||||
|
||||
if (customerTypeFilter.value) {
|
||||
data = data.filter((item) => item.customerType === customerTypeFilter.value)
|
||||
}
|
||||
|
||||
if (commissionRangeFilter.value) {
|
||||
data = data.filter((item) => {
|
||||
const commission = item.totalCommission
|
||||
if (commissionRangeFilter.value === '0-1000') return commission >= 0 && commission < 1000
|
||||
if (commissionRangeFilter.value === '1000-5000') return commission >= 1000 && commission < 5000
|
||||
if (commissionRangeFilter.value === '5000-10000') return commission >= 5000 && commission < 10000
|
||||
if (commissionRangeFilter.value === '10000+') return commission >= 10000
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
return data
|
||||
})
|
||||
|
||||
const handleSearch = () => {}
|
||||
|
||||
const exportData = () => {
|
||||
ElMessage.success('数据导出中...')
|
||||
}
|
||||
|
||||
const viewCommissionDetail = (row: CustomerCommission) => {
|
||||
currentCustomer.value = { ...row }
|
||||
commissionDialogVisible.value = true
|
||||
}
|
||||
|
||||
const viewWithdrawalHistory = (row: CustomerCommission) => {
|
||||
currentCustomer.value = { ...row }
|
||||
withdrawalDialogVisible.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-content {
|
||||
.stat-card {
|
||||
:deep(.el-card__body) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
color: var(--el-text-color-secondary);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
font-size: 40px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user