add 修改余额
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CI / CI OK (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Deploy Website on push / Rerun on failure (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CI / CI OK (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Deploy Website on push / Rerun on failure (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
This commit is contained in:
@@ -341,6 +341,19 @@ export interface GetAgentLinkProductStatisticsParams {}
|
|||||||
frozen_balance: number; // 冻结余额
|
frozen_balance: number; // 冻结余额
|
||||||
total_earnings: number; // 总收益
|
total_earnings: number; // 总收益
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 修改代理钱包余额请求
|
||||||
|
export interface UpdateAgentWalletBalanceReq {
|
||||||
|
agent_id: number; // 代理ID
|
||||||
|
amount: number; // 修改金额(正数增加,负数减少)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改代理钱包余额响应
|
||||||
|
export interface UpdateAgentWalletBalanceResp {
|
||||||
|
success: boolean; // 是否成功
|
||||||
|
balance: number; // 修改后的余额
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -588,6 +601,18 @@ async function getAgentWallet(agentId: number) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改代理钱包余额
|
||||||
|
*/
|
||||||
|
async function updateAgentWalletBalance(params: AgentApi.UpdateAgentWalletBalanceReq) {
|
||||||
|
return requestClient.post<AgentApi.UpdateAgentWalletBalanceResp>(
|
||||||
|
'/agent/wallet/update-balance',
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
batchUnfreezeAgentCommission,
|
batchUnfreezeAgentCommission,
|
||||||
getAgentCommissionDeductionList,
|
getAgentCommissionDeductionList,
|
||||||
@@ -609,4 +634,5 @@ export {
|
|||||||
updateAgentCommissionStatus,
|
updateAgentCommissionStatus,
|
||||||
updateAgentMembershipConfig,
|
updateAgentMembershipConfig,
|
||||||
updateAgentProductionConfig,
|
updateAgentProductionConfig,
|
||||||
|
updateAgentWalletBalance,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ import { getAgentList } from '#/api/agent';
|
|||||||
import { useColumns, useGridFormSchema } from './data';
|
import { useColumns, useGridFormSchema } from './data';
|
||||||
import CommissionDeductionModal from './modules/commission-deduction-modal.vue';
|
import CommissionDeductionModal from './modules/commission-deduction-modal.vue';
|
||||||
import CommissionModal from './modules/commission-modal.vue';
|
import CommissionModal from './modules/commission-modal.vue';
|
||||||
|
import CommissionHistoryModal from './modules/commission-history-modal.vue';
|
||||||
import Form from './modules/form.vue';
|
import Form from './modules/form.vue';
|
||||||
import LinkModal from './modules/link-modal.vue';
|
import LinkModal from './modules/link-modal.vue';
|
||||||
import PlatformDeductionModal from './modules/platform-deduction-modal.vue';
|
import PlatformDeductionModal from './modules/platform-deduction-modal.vue';
|
||||||
import RewardModal from './modules/reward-modal.vue';
|
import RewardModal from './modules/reward-modal.vue';
|
||||||
import WithdrawalModal from './modules/withdrawal-modal.vue';
|
import WithdrawalModal from './modules/withdrawal-modal.vue';
|
||||||
|
import BalanceModal from './modules/balance-modal.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -72,6 +74,18 @@ const [PlatformDeductionModalComponent, platformDeductionModalApi] =
|
|||||||
destroyOnClose: true,
|
destroyOnClose: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 修改余额弹窗
|
||||||
|
const [BalanceModalComponent, balanceModalApi] = useVbenModal({
|
||||||
|
connectedComponent: BalanceModal,
|
||||||
|
destroyOnClose: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 历史佣金记录弹窗
|
||||||
|
const [CommissionHistoryModalComponent, commissionHistoryModalApi] = useVbenModal({
|
||||||
|
connectedComponent: CommissionHistoryModal,
|
||||||
|
destroyOnClose: true,
|
||||||
|
});
|
||||||
|
|
||||||
// 表格配置
|
// 表格配置
|
||||||
const [Grid, gridApi] = useVbenVxeGrid({
|
const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
formOptions: {
|
formOptions: {
|
||||||
@@ -144,10 +158,19 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
|
|
||||||
// 更多操作菜单项
|
// 更多操作菜单项
|
||||||
const moreMenuItems = [
|
const moreMenuItems = [
|
||||||
|
{
|
||||||
|
key: 'update-balance',
|
||||||
|
label: '修改余额',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'commission-history',
|
||||||
|
label: '历史佣金记录',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'links',
|
key: 'links',
|
||||||
label: '推广链接',
|
label: '推广链接',
|
||||||
},
|
},
|
||||||
|
|
||||||
// {
|
// {
|
||||||
// key: 'commission',
|
// key: 'commission',
|
||||||
// label: '佣金记录',
|
// label: '佣金记录',
|
||||||
@@ -194,6 +217,10 @@ function onActionClick(
|
|||||||
onViewCommission(e.row);
|
onViewCommission(e.row);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'commission-history': {
|
||||||
|
onViewCommissionHistory(e.row);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'commission-deduction': {
|
case 'commission-deduction': {
|
||||||
onViewCommissionDeduction(e.row);
|
onViewCommissionDeduction(e.row);
|
||||||
break;
|
break;
|
||||||
@@ -214,6 +241,10 @@ function onActionClick(
|
|||||||
onViewReward(e.row);
|
onViewReward(e.row);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'update-balance': {
|
||||||
|
onUpdateBalance(e.row);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'view-sub-agent': {
|
case 'view-sub-agent': {
|
||||||
router.replace({
|
router.replace({
|
||||||
query: {
|
query: {
|
||||||
@@ -240,6 +271,11 @@ function onViewLinks(row: AgentApi.AgentListItem) {
|
|||||||
linkModalApi.setData({ agentId: row.id }).open();
|
linkModalApi.setData({ agentId: row.id }).open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 修改余额
|
||||||
|
function onUpdateBalance(row: AgentApi.AgentListItem) {
|
||||||
|
balanceModalApi.setData({ agentId: row.id }).open();
|
||||||
|
}
|
||||||
|
|
||||||
// 查看佣金记录
|
// 查看佣金记录
|
||||||
function onViewCommission(row: AgentApi.AgentListItem) {
|
function onViewCommission(row: AgentApi.AgentListItem) {
|
||||||
commissionModalApi.setData({ agentId: row.id }).open();
|
commissionModalApi.setData({ agentId: row.id }).open();
|
||||||
@@ -265,6 +301,11 @@ function onViewPlatformDeduction(row: AgentApi.AgentListItem) {
|
|||||||
platformDeductionModalApi.setData({ agentId: row.id }).open();
|
platformDeductionModalApi.setData({ agentId: row.id }).open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查看历史佣金记录
|
||||||
|
function onViewCommissionHistory(row: AgentApi.AgentListItem) {
|
||||||
|
commissionHistoryModalApi.setData({ agentId: row.id }).open();
|
||||||
|
}
|
||||||
|
|
||||||
// 刷新处理
|
// 刷新处理
|
||||||
function onRefresh() {
|
function onRefresh() {
|
||||||
gridApi.query();
|
gridApi.query();
|
||||||
@@ -276,10 +317,12 @@ function onRefresh() {
|
|||||||
<FormDrawer @success="onRefresh" />
|
<FormDrawer @success="onRefresh" />
|
||||||
<LinkModalComponent />
|
<LinkModalComponent />
|
||||||
<CommissionModalComponent />
|
<CommissionModalComponent />
|
||||||
|
<CommissionHistoryModalComponent />
|
||||||
<CommissionDeductionModalComponent />
|
<CommissionDeductionModalComponent />
|
||||||
<PlatformDeductionModalComponent />
|
<PlatformDeductionModalComponent />
|
||||||
<RewardModalComponent />
|
<RewardModalComponent />
|
||||||
<WithdrawalModalComponent />
|
<WithdrawalModalComponent />
|
||||||
|
<BalanceModalComponent @success="onRefresh" />
|
||||||
|
|
||||||
<!-- 上级代理信息卡片 -->
|
<!-- 上级代理信息卡片 -->
|
||||||
<Card v-if="parentAgentId" class="mb-4">
|
<Card v-if="parentAgentId" class="mb-4">
|
||||||
|
|||||||
@@ -0,0 +1,161 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
|
||||||
|
import { message, Modal } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
import { useVbenForm } from '#/adapter/form';
|
||||||
|
import { getAgentWallet, updateAgentWalletBalance } from '#/api/agent';
|
||||||
|
import type { AgentApi } from '#/api/agent';
|
||||||
|
|
||||||
|
interface ModalData {
|
||||||
|
agentId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 钱包信息
|
||||||
|
const walletInfo = ref<AgentApi.AgentWalletInfo>({
|
||||||
|
balance: 0,
|
||||||
|
frozen_balance: 0,
|
||||||
|
total_earnings: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'success'): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const [ModalComponent, modalApi] = useVbenModal({
|
||||||
|
title: '修改余额',
|
||||||
|
destroyOnClose: true,
|
||||||
|
onOpenChange(isOpen) {
|
||||||
|
if (isOpen) {
|
||||||
|
fetchWalletInfo();
|
||||||
|
// 重置表单
|
||||||
|
formApi.setValues({
|
||||||
|
operation_type: 'add',
|
||||||
|
amount: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const modalData = computed(() => modalApi.getData<ModalData>());
|
||||||
|
|
||||||
|
// 获取钱包信息
|
||||||
|
async function fetchWalletInfo() {
|
||||||
|
const agentId = modalData.value?.agentId;
|
||||||
|
if (!agentId) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const data = await getAgentWallet(agentId);
|
||||||
|
walletInfo.value = data;
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '获取钱包信息失败');
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表单引用
|
||||||
|
const [Form, formApi] = useVbenForm({
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
component: 'RadioGroup',
|
||||||
|
fieldName: 'operation_type',
|
||||||
|
label: '操作类型',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: '增加余额', value: 'add' },
|
||||||
|
{ label: '减少余额', value: 'subtract' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
rules: 'required',
|
||||||
|
defaultValue: 'add',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'InputNumber',
|
||||||
|
fieldName: 'amount',
|
||||||
|
label: '金额',
|
||||||
|
componentProps: {
|
||||||
|
precision: 2,
|
||||||
|
min: 0.01,
|
||||||
|
placeholder: '请输入金额',
|
||||||
|
style: { width: '100%' },
|
||||||
|
},
|
||||||
|
rules: 'required',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
showDefaultActions: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 提交前确认
|
||||||
|
async function handleSubmit() {
|
||||||
|
try {
|
||||||
|
const { valid } = await formApi.validate();
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
const values = await formApi.getValues();
|
||||||
|
if (!values) return;
|
||||||
|
|
||||||
|
// 根据操作类型确定金额正负
|
||||||
|
const finalAmount = values.operation_type === 'subtract' ? -Math.abs(values.amount) : Math.abs(values.amount);
|
||||||
|
|
||||||
|
// 二次确认
|
||||||
|
Modal.confirm({
|
||||||
|
title: '确认修改余额',
|
||||||
|
content: `您确定要${values.operation_type === 'add' ? '增加' : '减少'} ¥${Math.abs(values.amount).toFixed(2)} 的余额吗?`,
|
||||||
|
onOk: async () => {
|
||||||
|
try {
|
||||||
|
await updateAgentWalletBalance({
|
||||||
|
agent_id: modalData.value?.agentId || 0,
|
||||||
|
amount: finalAmount,
|
||||||
|
});
|
||||||
|
|
||||||
|
message.success('修改余额成功');
|
||||||
|
modalApi.close();
|
||||||
|
emit('success');
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.message || '修改余额失败');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// 表单验证失败,不处理
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置表单
|
||||||
|
function handleReset() {
|
||||||
|
formApi.setValues({
|
||||||
|
operation_type: 'add',
|
||||||
|
amount: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ModalComponent width="500px" :footer="false">
|
||||||
|
<div class="balance-modal">
|
||||||
|
<Form />
|
||||||
|
<div class="form-actions">
|
||||||
|
<a-button @click="handleReset">重置</a-button>
|
||||||
|
<a-button type="primary" @click="handleSubmit">确认修改</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalComponent>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.balance-modal {
|
||||||
|
padding: 16px 0;
|
||||||
|
|
||||||
|
.form-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,316 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, ref, watch } from 'vue';
|
||||||
|
|
||||||
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
import { Card, Statistic, Row, Col, DatePicker, Button, Space } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
|
import { getAgentCommissionList } from '#/api/agent';
|
||||||
|
import type { AgentApi } from '#/api';
|
||||||
|
import dayjs, { Dayjs } from 'dayjs';
|
||||||
|
|
||||||
|
interface ModalData {
|
||||||
|
agentId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [Modal, modalApi] = useVbenModal({
|
||||||
|
title: '历史佣金记录',
|
||||||
|
destroyOnClose: true,
|
||||||
|
footer: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const modalData = computed(() => modalApi.getData<ModalData>());
|
||||||
|
|
||||||
|
// 时间范围选择
|
||||||
|
const dateRange = ref<[Dayjs, Dayjs] | undefined>(undefined);
|
||||||
|
|
||||||
|
// 统计数据
|
||||||
|
const statistics = ref({
|
||||||
|
totalAmount: 0,
|
||||||
|
settledAmount: 0,
|
||||||
|
frozenAmount: 0,
|
||||||
|
refundedAmount: 0,
|
||||||
|
totalCount: 0,
|
||||||
|
settledCount: 0,
|
||||||
|
frozenCount: 0,
|
||||||
|
refundedCount: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 快捷时间范围选择
|
||||||
|
function selectTimeRange(range: string) {
|
||||||
|
const now = dayjs();
|
||||||
|
let startDate: Dayjs;
|
||||||
|
|
||||||
|
switch (range) {
|
||||||
|
case '7d':
|
||||||
|
startDate = now.subtract(7, 'day');
|
||||||
|
break;
|
||||||
|
case '1m':
|
||||||
|
startDate = now.subtract(1, 'month');
|
||||||
|
break;
|
||||||
|
case '3m':
|
||||||
|
startDate = now.subtract(3, 'month');
|
||||||
|
break;
|
||||||
|
case '1y':
|
||||||
|
startDate = now.subtract(1, 'year');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dateRange.value = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dateRange.value = [startDate, now];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置时间范围
|
||||||
|
function resetTimeRange() {
|
||||||
|
dateRange.value = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 表格配置
|
||||||
|
const [Grid, gridApi] = useVbenVxeGrid({
|
||||||
|
formOptions: {
|
||||||
|
fieldMappingTime: [['create_time', ['create_time_start', 'create_time_end']]],
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
component: 'InputNumber',
|
||||||
|
fieldName: 'order_id',
|
||||||
|
label: '订单ID',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入订单ID',
|
||||||
|
style: { width: '100%' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'product_name',
|
||||||
|
label: '产品名称',
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入产品名称',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Select',
|
||||||
|
fieldName: 'status',
|
||||||
|
label: '状态',
|
||||||
|
componentProps: {
|
||||||
|
allowClear: true,
|
||||||
|
placeholder: '请选择状态',
|
||||||
|
options: [
|
||||||
|
{ label: '已结算', value: 0 },
|
||||||
|
{ label: '冻结中', value: 1 },
|
||||||
|
{ label: '已退款', value: 2 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
submitOnChange: true,
|
||||||
|
},
|
||||||
|
gridOptions: {
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
field: 'id',
|
||||||
|
title: 'ID',
|
||||||
|
width: 80,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'order_id',
|
||||||
|
title: '订单ID',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'amount',
|
||||||
|
title: '佣金金额',
|
||||||
|
width: 120,
|
||||||
|
formatter: ({ cellValue }: { cellValue: number }) =>
|
||||||
|
`¥${cellValue.toFixed(2)}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'product_name',
|
||||||
|
title: '产品名称',
|
||||||
|
width: 180,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
title: '状态',
|
||||||
|
width: 100,
|
||||||
|
formatter: ({ cellValue }: { cellValue: number }) => {
|
||||||
|
const statusMap: Record<number, string> = {
|
||||||
|
0: '已结算',
|
||||||
|
1: '冻结中',
|
||||||
|
2: '已退款',
|
||||||
|
};
|
||||||
|
return statusMap[cellValue] || '未知';
|
||||||
|
},
|
||||||
|
className: ({ cellValue }: { cellValue: number }) => {
|
||||||
|
if (cellValue === 0) return 'text-green-600';
|
||||||
|
if (cellValue === 1) return 'text-orange-600';
|
||||||
|
if (cellValue === 2) return 'text-red-600';
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'create_time',
|
||||||
|
title: '创建时间',
|
||||||
|
width: 160,
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
height: 'auto',
|
||||||
|
keepSource: true,
|
||||||
|
rowConfig: {
|
||||||
|
keyField: 'id',
|
||||||
|
},
|
||||||
|
toolbarConfig: {
|
||||||
|
custom: true,
|
||||||
|
export: false,
|
||||||
|
refresh: { code: 'query' },
|
||||||
|
search: true,
|
||||||
|
zoom: true,
|
||||||
|
},
|
||||||
|
proxyConfig: {
|
||||||
|
ajax: {
|
||||||
|
query: async ({ page }: { page: { currentPage: number; pageSize: number } }, formValues: Record<string, any>) => {
|
||||||
|
const params: any = {
|
||||||
|
agent_id: modalData.value?.agentId,
|
||||||
|
...formValues,
|
||||||
|
page: page.currentPage,
|
||||||
|
pageSize: page.pageSize,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加时间范围参数
|
||||||
|
if (dateRange.value && dateRange.value[0] && dateRange.value[1]) {
|
||||||
|
params.create_time_start = dateRange.value[0].format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
params.create_time_end = dateRange.value[1].format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await getAgentCommissionList(params);
|
||||||
|
|
||||||
|
// 更新统计数据
|
||||||
|
updateStatistics(result.items || []);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
result: 'items',
|
||||||
|
total: 'total',
|
||||||
|
},
|
||||||
|
autoLoad: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新统计数据
|
||||||
|
function updateStatistics(items: AgentApi.AgentCommissionListItem[]) {
|
||||||
|
statistics.value = {
|
||||||
|
totalCount: items.length,
|
||||||
|
totalAmount: items.reduce((sum, item) => sum + item.amount, 0),
|
||||||
|
settledCount: items.filter(item => item.status === 0).length,
|
||||||
|
settledAmount: items.filter(item => item.status === 0).reduce((sum, item) => sum + item.amount, 0),
|
||||||
|
frozenCount: items.filter(item => item.status === 1).length,
|
||||||
|
frozenAmount: items.filter(item => item.status === 1).reduce((sum, item) => sum + item.amount, 0),
|
||||||
|
refundedCount: items.filter(item => item.status === 2).length,
|
||||||
|
refundedAmount: items.filter(item => item.status === 2).reduce((sum, item) => sum + item.amount, 0),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听时间范围变化,自动刷新表格
|
||||||
|
watch(dateRange, () => {
|
||||||
|
if (gridApi) {
|
||||||
|
gridApi.query();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Modal class="w-[calc(100vw-200px)]">
|
||||||
|
<div class="commission-history-modal">
|
||||||
|
<!-- 时间范围选择 -->
|
||||||
|
<Card class="mb-4" title="时间范围选择">
|
||||||
|
<Space :size="12">
|
||||||
|
<span class="text-sm text-gray-600">快速选择:</span>
|
||||||
|
<Button size="small" @click="selectTimeRange('7d')">近7日</Button>
|
||||||
|
<Button size="small" @click="selectTimeRange('1m')">近1月</Button>
|
||||||
|
<Button size="small" @click="selectTimeRange('3m')">近3月</Button>
|
||||||
|
<Button size="small" @click="selectTimeRange('1y')">近1年</Button>
|
||||||
|
<Button size="small" type="default" @click="resetTimeRange">全部</Button>
|
||||||
|
<span class="text-sm text-gray-400 ml-4">|</span>
|
||||||
|
<span class="text-sm text-gray-600">自定义:</span>
|
||||||
|
<DatePicker.RangePicker
|
||||||
|
v-model:value="dateRange"
|
||||||
|
show-time
|
||||||
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
:placeholder="['开始时间', '结束时间']"
|
||||||
|
style="width: 380px"
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<!-- 统计卡片 -->
|
||||||
|
<Card class="mb-4" title="统计信息">
|
||||||
|
<Row :gutter="[16, 16]">
|
||||||
|
<Col :span="6">
|
||||||
|
<Statistic title="总记录数" :value="statistics.totalCount" />
|
||||||
|
</Col>
|
||||||
|
<Col :span="6">
|
||||||
|
<Statistic
|
||||||
|
title="总佣金金额"
|
||||||
|
:value="statistics.totalAmount"
|
||||||
|
:precision="2"
|
||||||
|
prefix="¥"
|
||||||
|
:value-style="{ color: '#1890ff' }"
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col :span="6">
|
||||||
|
<Statistic
|
||||||
|
title="已结算金额"
|
||||||
|
:value="statistics.settledAmount"
|
||||||
|
:precision="2"
|
||||||
|
prefix="¥"
|
||||||
|
:value-style="{ color: '#52c41a' }"
|
||||||
|
/>
|
||||||
|
<div class="text-sm text-gray-500 mt-1">
|
||||||
|
{{ statistics.settledCount }} 条记录
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
<Col :span="6">
|
||||||
|
<Statistic
|
||||||
|
title="冻结中金额"
|
||||||
|
:value="statistics.frozenAmount"
|
||||||
|
:precision="2"
|
||||||
|
prefix="¥"
|
||||||
|
:value-style="{ color: '#fa8c16' }"
|
||||||
|
/>
|
||||||
|
<div class="text-sm text-gray-500 mt-1">
|
||||||
|
{{ statistics.frozenCount }} 条记录
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row :gutter="[16, 16]" class="mt-4">
|
||||||
|
<Col :span="12">
|
||||||
|
<Statistic
|
||||||
|
title="已退款金额"
|
||||||
|
:value="statistics.refundedAmount"
|
||||||
|
:precision="2"
|
||||||
|
prefix="¥"
|
||||||
|
:value-style="{ color: '#f5222d' }"
|
||||||
|
/>
|
||||||
|
<div class="text-sm text-gray-500 mt-1">
|
||||||
|
{{ statistics.refundedCount }} 条记录
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<!-- 佣金记录列表 -->
|
||||||
|
<Grid :table-title="`代理商 ID: ${modalData?.agentId} 的历史佣金记录`" />
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.commission-history-modal {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
import { Page, useVbenDrawer } from '@vben/common-ui';
|
import { Page, useVbenDrawer } from '@vben/common-ui';
|
||||||
import { Button, Space } from 'ant-design-vue';
|
import { Button, Space } from 'ant-design-vue';
|
||||||
@@ -54,7 +54,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
submitOnChange: true,
|
submitOnChange: true,
|
||||||
},
|
},
|
||||||
gridOptions: {
|
gridOptions: {
|
||||||
columns: useWithdrawalColumns(onActionClick),
|
columns: useWithdrawalColumns(),
|
||||||
proxyConfig: {
|
proxyConfig: {
|
||||||
ajax: {
|
ajax: {
|
||||||
query: async ({
|
query: async ({
|
||||||
@@ -64,9 +64,16 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
page: QueryParams;
|
page: QueryParams;
|
||||||
form: Record<string, any>;
|
form: Record<string, any>;
|
||||||
}) => {
|
}) => {
|
||||||
|
// 过滤掉 undefined 和 null 值
|
||||||
|
const filteredForm = Object.fromEntries(
|
||||||
|
Object.entries(form).filter(
|
||||||
|
([_, value]) => value !== undefined && value !== null && value !== '',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
return await getAgentWithdrawalList({
|
return await getAgentWithdrawalList({
|
||||||
...queryParams.value,
|
...queryParams.value,
|
||||||
...form,
|
...filteredForm,
|
||||||
page: page.currentPage,
|
page: page.currentPage,
|
||||||
pageSize: page.pageSize,
|
pageSize: page.pageSize,
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user