f
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
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
Release Drafter / update_release_draft (push) Has been cancelled
CI / CI OK (push) Has been cancelled
Deploy Website on push / Rerun on failure (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Issue Close Require / close-issues (push) Has been cancelled
Close stale issues / stale (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
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
Release Drafter / update_release_draft (push) Has been cancelled
CI / CI OK (push) Has been cancelled
Deploy Website on push / Rerun on failure (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Issue Close Require / close-issues (push) Has been cancelled
Close stale issues / stale (push) Has been cancelled
This commit is contained in:
101
apps/web-antd/src/views/agent/agent-commission-deduction/data.ts
Normal file
101
apps/web-antd/src/views/agent/agent-commission-deduction/data.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
|
||||
export function useCommissionDeductionColumns(): VxeTableGridOptions['columns'] {
|
||||
return [
|
||||
{
|
||||
title: 'ID',
|
||||
field: 'id',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '代理ID',
|
||||
field: 'agent_id',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '被扣代理ID',
|
||||
field: 'deducted_agent_id',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '抽佣金额',
|
||||
field: 'amount',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }) => `¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
title: '产品名称',
|
||||
field: 'product_name',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '抽佣类型',
|
||||
field: 'type',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }: { cellValue: 'cost' | 'pricing' }) => {
|
||||
const typeMap = {
|
||||
cost: '成本抽佣',
|
||||
pricing: '定价抽佣',
|
||||
};
|
||||
return typeMap[cellValue] || cellValue;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
field: 'status',
|
||||
width: 100,
|
||||
cellRender: {
|
||||
name: 'CellTag',
|
||||
options: [
|
||||
{ value: 0, color: 'warning', label: '待结算' },
|
||||
{ value: 1, color: 'success', label: '已结算' },
|
||||
{ value: 2, color: 'error', label: '已取消' },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
field: 'create_time',
|
||||
width: 180,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export function useCommissionDeductionFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
fieldName: 'product_name',
|
||||
label: '产品名称',
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldName: 'type',
|
||||
label: '抽佣类型',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '成本抽佣', value: 'cost' },
|
||||
{ label: '定价抽佣', value: 'pricing' },
|
||||
],
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldName: 'status',
|
||||
label: '状态',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '待结算', value: 0 },
|
||||
{ label: '已结算', value: 1 },
|
||||
{ label: '已取消', value: 2 },
|
||||
],
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getAgentCommissionDeductionList } from '#/api/agent';
|
||||
|
||||
import {
|
||||
useCommissionDeductionColumns,
|
||||
useCommissionDeductionFormSchema,
|
||||
} from './data';
|
||||
|
||||
interface Props {
|
||||
agentId?: number;
|
||||
}
|
||||
|
||||
interface QueryParams {
|
||||
currentPage: number;
|
||||
pageSize: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const queryParams = computed(() => ({
|
||||
...(props.agentId ? { agent_id: props.agentId } : {}),
|
||||
}));
|
||||
|
||||
const [Grid] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
schema: useCommissionDeductionFormSchema(),
|
||||
submitOnChange: true,
|
||||
},
|
||||
gridOptions: {
|
||||
columns: useCommissionDeductionColumns(),
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({
|
||||
form,
|
||||
page,
|
||||
}: {
|
||||
form: Record<string, any>;
|
||||
page: QueryParams;
|
||||
}) => {
|
||||
return await getAgentCommissionDeductionList({
|
||||
...queryParams.value,
|
||||
...form,
|
||||
page: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
});
|
||||
},
|
||||
},
|
||||
props: {
|
||||
result: 'items',
|
||||
total: 'total',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page :auto-content-height="!agentId">
|
||||
<Grid :table-title="agentId ? '上级抽佣列表' : '所有上级抽佣记录'" />
|
||||
</Page>
|
||||
</template>
|
||||
74
apps/web-antd/src/views/agent/agent-commission/data.ts
Normal file
74
apps/web-antd/src/views/agent/agent-commission/data.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
|
||||
// 佣金记录列表列配置
|
||||
export function useCommissionColumns(): VxeTableGridOptions['columns'] {
|
||||
return [
|
||||
{
|
||||
field: 'agent_id',
|
||||
title: '代理ID',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
field: 'order_id',
|
||||
title: '订单ID',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
field: 'amount',
|
||||
title: '佣金金额',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }: { cellValue: number }) =>
|
||||
`¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'product_name',
|
||||
title: '产品名称',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
title: '状态',
|
||||
width: 100,
|
||||
formatter: ({ cellValue }: { cellValue: number }) => {
|
||||
const statusMap: Record<number, string> = {
|
||||
0: '待结算',
|
||||
1: '已结算',
|
||||
2: '已取消',
|
||||
};
|
||||
return statusMap[cellValue] || '未知';
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'create_time',
|
||||
title: '创建时间',
|
||||
width: 160,
|
||||
sortable: true,
|
||||
sortType: 'string' as const,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// 佣金记录搜索表单配置
|
||||
export function useCommissionFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'product_name',
|
||||
label: '产品名称',
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
fieldName: 'status',
|
||||
label: '状态',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
options: [
|
||||
{ label: '待结算', value: 0 },
|
||||
{ label: '已结算', value: 1 },
|
||||
{ label: '已取消', value: 2 },
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
64
apps/web-antd/src/views/agent/agent-commission/list.vue
Normal file
64
apps/web-antd/src/views/agent/agent-commission/list.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getAgentCommissionList } from '#/api/agent';
|
||||
|
||||
import { useCommissionColumns, useCommissionFormSchema } from './data';
|
||||
|
||||
interface Props {
|
||||
agentId?: number;
|
||||
}
|
||||
|
||||
interface QueryParams {
|
||||
currentPage: number;
|
||||
pageSize: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const queryParams = computed(() => ({
|
||||
...(props.agentId ? { agent_id: props.agentId } : {}),
|
||||
}));
|
||||
|
||||
const [Grid] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
schema: useCommissionFormSchema(),
|
||||
submitOnChange: true,
|
||||
},
|
||||
gridOptions: {
|
||||
columns: useCommissionColumns(),
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({
|
||||
page,
|
||||
form,
|
||||
}: {
|
||||
form: Record<string, any>;
|
||||
page: QueryParams;
|
||||
}) => {
|
||||
return await getAgentCommissionList({
|
||||
...queryParams.value,
|
||||
...form,
|
||||
page: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
});
|
||||
},
|
||||
},
|
||||
props: {
|
||||
result: 'items',
|
||||
total: 'total',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page :auto-content-height="!agentId">
|
||||
<Grid :table-title="agentId ? '佣金记录列表' : '所有佣金记录'" />
|
||||
</Page>
|
||||
</template>
|
||||
51
apps/web-antd/src/views/agent/agent-links/data.ts
Normal file
51
apps/web-antd/src/views/agent/agent-links/data.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
|
||||
// 推广链接列表列配置
|
||||
export function useLinkColumns(): VxeTableGridOptions['columns'] {
|
||||
return [
|
||||
{
|
||||
field: 'agent_id',
|
||||
title: '代理ID',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
field: 'product_name',
|
||||
title: '产品名称',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
field: 'price',
|
||||
title: '价格',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }) => `¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'link_identifier',
|
||||
title: '推广码',
|
||||
},
|
||||
{
|
||||
field: 'create_time',
|
||||
title: '创建时间',
|
||||
width: 160,
|
||||
sortable: true,
|
||||
sortType: 'string' as const,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// 推广链接搜索表单配置
|
||||
export function useLinkFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'product_name',
|
||||
label: '产品名称',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'link_identifier',
|
||||
label: '推广码',
|
||||
},
|
||||
];
|
||||
}
|
||||
64
apps/web-antd/src/views/agent/agent-links/list.vue
Normal file
64
apps/web-antd/src/views/agent/agent-links/list.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getAgentLinkList } from '#/api/agent';
|
||||
|
||||
import { useLinkColumns, useLinkFormSchema } from './data';
|
||||
|
||||
interface Props {
|
||||
agentId?: number;
|
||||
}
|
||||
|
||||
interface QueryParams {
|
||||
currentPage: number;
|
||||
pageSize: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const queryParams = computed(() => ({
|
||||
...(props.agentId ? { agent_id: props.agentId } : {}),
|
||||
}));
|
||||
|
||||
const [Grid] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
schema: useLinkFormSchema(),
|
||||
submitOnChange: true,
|
||||
},
|
||||
gridOptions: {
|
||||
columns: useLinkColumns(),
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({
|
||||
page,
|
||||
form,
|
||||
}: {
|
||||
form: Record<string, any>;
|
||||
page: QueryParams;
|
||||
}) => {
|
||||
return await getAgentLinkList({
|
||||
...queryParams.value,
|
||||
...form,
|
||||
page: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
});
|
||||
},
|
||||
},
|
||||
props: {
|
||||
result: 'items',
|
||||
total: 'total',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page :auto-content-height="!agentId">
|
||||
<Grid :table-title="agentId ? '推广链接列表' : '所有推广链接'" />
|
||||
</Page>
|
||||
</template>
|
||||
436
apps/web-antd/src/views/agent/agent-list/data.ts
Normal file
436
apps/web-antd/src/views/agent/agent-list/data.ts
Normal file
@@ -0,0 +1,436 @@
|
||||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
|
||||
// 表单配置
|
||||
export function useFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'mobile',
|
||||
label: '手机号',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'level_name',
|
||||
label: '等级名称',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'region',
|
||||
label: '区域',
|
||||
rules: 'required',
|
||||
},
|
||||
{
|
||||
component: 'DatePicker',
|
||||
fieldName: 'membership_expiry_time',
|
||||
label: '会员到期时间',
|
||||
rules: 'required',
|
||||
componentProps: {
|
||||
showTime: true,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// 搜索表单配置
|
||||
export function useGridFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'mobile',
|
||||
label: '手机号',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'region',
|
||||
label: '区域',
|
||||
},
|
||||
{
|
||||
component: 'RangePicker',
|
||||
fieldName: 'create_time',
|
||||
label: '创建时间',
|
||||
componentProps: {
|
||||
showTime: true,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
// 表格列配置
|
||||
export function useColumns(): VxeTableGridOptions['columns'] {
|
||||
const columns = [
|
||||
{
|
||||
field: 'id',
|
||||
title: 'ID',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
field: 'user_id',
|
||||
title: '用户ID',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
field: 'level_name',
|
||||
title: '等级名称',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }: { cellValue: string }) => {
|
||||
if (cellValue === '' || cellValue === 'normal') {
|
||||
return '普通代理';
|
||||
}
|
||||
return cellValue;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'region',
|
||||
title: '区域',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
field: 'mobile',
|
||||
title: '手机号',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
cellRender: {
|
||||
name: 'CellTag',
|
||||
options: [
|
||||
{ value: 'approved', color: 'success', label: '已认证' },
|
||||
{ value: 'pending', color: 'warning', label: '审核中' },
|
||||
{ value: 'rejected', color: 'error', label: '已拒绝' },
|
||||
{ value: '', color: 'default', label: '未认证' },
|
||||
],
|
||||
},
|
||||
field: 'real_name_status',
|
||||
title: '实名认证状态',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
field: 'real_name',
|
||||
title: '实名姓名',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }: { cellValue: string }) => {
|
||||
if (!cellValue) return '-';
|
||||
return cellValue;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'id_card',
|
||||
title: '身份证号',
|
||||
width: 180,
|
||||
formatter: ({ cellValue }: { cellValue: string }) => {
|
||||
if (!cellValue) return '-';
|
||||
// 只显示前6位和后4位,中间用*代替
|
||||
return `${cellValue.slice(0, 6)}${'*'.repeat(8)}${cellValue.slice(-4)}`;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'membership_expiry_time',
|
||||
title: '会员到期时间',
|
||||
width: 160,
|
||||
sortable: true,
|
||||
sortType: 'string' as const,
|
||||
},
|
||||
{
|
||||
field: 'balance',
|
||||
title: '钱包余额',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }: { cellValue: number }) =>
|
||||
`¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'total_earnings',
|
||||
title: '累计收益',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }: { cellValue: number }) =>
|
||||
`¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'frozen_balance',
|
||||
title: '冻结余额',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }: { cellValue: number }) =>
|
||||
`¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'withdrawn_amount',
|
||||
title: '提现总额',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }: { cellValue: number }) =>
|
||||
`¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'create_time',
|
||||
title: '成为代理时间',
|
||||
width: 160,
|
||||
sortable: true,
|
||||
sortType: 'string' as const,
|
||||
},
|
||||
{
|
||||
align: 'center' as const,
|
||||
slots: { default: 'operation' },
|
||||
field: 'operation',
|
||||
fixed: 'right' as const,
|
||||
title: '操作',
|
||||
width: 280,
|
||||
},
|
||||
];
|
||||
return columns;
|
||||
}
|
||||
// 推广链接列表列配置
|
||||
export function useLinkColumns(): VxeTableGridOptions['columns'] {
|
||||
return [
|
||||
{
|
||||
field: 'product_name',
|
||||
title: '产品名称',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
field: 'price',
|
||||
title: '价格',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }) => `¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'link_identifier',
|
||||
title: '推广码',
|
||||
},
|
||||
{
|
||||
field: 'create_time',
|
||||
title: '创建时间',
|
||||
width: 160,
|
||||
sortable: true,
|
||||
sortType: 'string' as const,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// 推广链接搜索表单配置
|
||||
export function useLinkFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'product_name',
|
||||
label: '产品名称',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'link_identifier',
|
||||
label: '推广码',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// 佣金记录列表列配置
|
||||
export function useCommissionColumns(): VxeTableGridOptions['columns'] {
|
||||
return [
|
||||
{
|
||||
field: 'id',
|
||||
title: 'ID',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
field: 'agent_id',
|
||||
title: '代理ID',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
field: 'order_id',
|
||||
title: '订单ID',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
field: 'amount',
|
||||
title: '佣金金额',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }: { cellValue: number }) =>
|
||||
`¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'product_name',
|
||||
title: '产品名称',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
title: '状态',
|
||||
width: 100,
|
||||
formatter: ({ cellValue }: { cellValue: number }) => {
|
||||
const statusMap: Record<number, string> = {
|
||||
0: '待结算',
|
||||
1: '已结算',
|
||||
2: '已取消',
|
||||
};
|
||||
return statusMap[cellValue] || '未知';
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'create_time',
|
||||
title: '创建时间',
|
||||
width: 160,
|
||||
sortable: true,
|
||||
},
|
||||
] as const;
|
||||
}
|
||||
|
||||
// 佣金记录搜索表单配置
|
||||
export function useCommissionFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'product_name',
|
||||
label: '产品名称',
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
fieldName: 'status',
|
||||
label: '状态',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
options: [
|
||||
{ label: '待结算', value: 0 },
|
||||
{ label: '已结算', value: 1 },
|
||||
{ label: '已取消', value: 2 },
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// 奖励记录列表列配置
|
||||
export function useRewardColumns(): VxeTableGridOptions['columns'] {
|
||||
return [
|
||||
{
|
||||
field: 'id',
|
||||
title: 'ID',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
field: 'agent_id',
|
||||
title: '代理ID',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
field: 'relation_agent_id',
|
||||
title: '关联代理ID',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
field: 'amount',
|
||||
title: '奖励金额',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }: { cellValue: number }) =>
|
||||
`¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'type',
|
||||
title: '奖励类型',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
field: 'create_time',
|
||||
title: '创建时间',
|
||||
width: 160,
|
||||
sortable: true,
|
||||
},
|
||||
] as const;
|
||||
}
|
||||
|
||||
// 奖励记录搜索表单配置
|
||||
export function useRewardFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'type',
|
||||
label: '奖励类型',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'relation_agent_id',
|
||||
label: '关联代理ID',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// 提现记录列表列配置
|
||||
export function useWithdrawalColumns(): VxeTableGridOptions['columns'] {
|
||||
return [
|
||||
{
|
||||
field: 'id',
|
||||
title: 'ID',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
field: 'agent_id',
|
||||
title: '代理ID',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
field: 'withdraw_no',
|
||||
title: '提现单号',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
field: 'amount',
|
||||
title: '提现金额',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }: { cellValue: number }) =>
|
||||
`¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
title: '状态',
|
||||
width: 100,
|
||||
formatter: ({ cellValue }: { cellValue: number }) => {
|
||||
const statusMap: Record<number, string> = {
|
||||
0: '待审核',
|
||||
1: '已通过',
|
||||
2: '已拒绝',
|
||||
3: '已打款',
|
||||
};
|
||||
return statusMap[cellValue] || '未知';
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'payee_account',
|
||||
title: '收款账户',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
field: 'remark',
|
||||
title: '备注',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
field: 'create_time',
|
||||
title: '创建时间',
|
||||
width: 160,
|
||||
sortable: true,
|
||||
},
|
||||
] as const;
|
||||
}
|
||||
|
||||
// 提现记录搜索表单配置
|
||||
export function useWithdrawalFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'withdraw_no',
|
||||
label: '提现单号',
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
fieldName: 'status',
|
||||
label: '状态',
|
||||
componentProps: {
|
||||
allowClear: true,
|
||||
options: [
|
||||
{ label: '待审核', value: 0 },
|
||||
{ label: '已通过', value: 1 },
|
||||
{ label: '已拒绝', value: 2 },
|
||||
{ label: '已打款', value: 3 },
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
341
apps/web-antd/src/views/agent/agent-list/list.vue
Normal file
341
apps/web-antd/src/views/agent/agent-list/list.vue
Normal file
@@ -0,0 +1,341 @@
|
||||
<script lang="ts" setup>
|
||||
import type {
|
||||
OnActionClickParams,
|
||||
VxeGridListeners,
|
||||
VxeTableGridOptions,
|
||||
} from '#/adapter/vxe-table';
|
||||
import type { AgentApi } from '#/api/agent';
|
||||
|
||||
import { computed } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { Page, useVbenDrawer, useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { Button, Card, Dropdown, Menu } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getAgentList } from '#/api/agent';
|
||||
|
||||
import { useColumns, useGridFormSchema } from './data';
|
||||
import CommissionDeductionModal from './modules/commission-deduction-modal.vue';
|
||||
import CommissionModal from './modules/commission-modal.vue';
|
||||
import Form from './modules/form.vue';
|
||||
import LinkModal from './modules/link-modal.vue';
|
||||
import PlatformDeductionModal from './modules/platform-deduction-modal.vue';
|
||||
import RewardModal from './modules/reward-modal.vue';
|
||||
import WithdrawalModal from './modules/withdrawal-modal.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
// 表单抽屉
|
||||
const [FormDrawer, formDrawerApi] = useVbenDrawer({
|
||||
connectedComponent: Form,
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
// 推广链接弹窗
|
||||
const [LinkModalComponent, linkModalApi] = useVbenModal({
|
||||
connectedComponent: LinkModal,
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
// 佣金记录弹窗
|
||||
const [CommissionModalComponent, commissionModalApi] = useVbenModal({
|
||||
connectedComponent: CommissionModal,
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
// 奖励记录弹窗
|
||||
const [RewardModalComponent, rewardModalApi] = useVbenModal({
|
||||
connectedComponent: RewardModal,
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
// 提现记录弹窗
|
||||
const [WithdrawalModalComponent, withdrawalModalApi] = useVbenModal({
|
||||
connectedComponent: WithdrawalModal,
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
// 上级抽佣弹窗
|
||||
const [CommissionDeductionModalComponent, commissionDeductionModalApi] =
|
||||
useVbenModal({
|
||||
connectedComponent: CommissionDeductionModal,
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
// 平台抽佣弹窗
|
||||
const [PlatformDeductionModalComponent, platformDeductionModalApi] =
|
||||
useVbenModal({
|
||||
connectedComponent: PlatformDeductionModal,
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
// 表格配置
|
||||
const [Grid, gridApi] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
fieldMappingTime: [
|
||||
['create_time', ['create_time_start', 'create_time_end']],
|
||||
],
|
||||
schema: useGridFormSchema(),
|
||||
submitOnChange: true,
|
||||
},
|
||||
gridEvents: {
|
||||
sortChange: () => {
|
||||
gridApi.query();
|
||||
},
|
||||
} as VxeGridListeners<AgentApi.AgentListItem>,
|
||||
gridOptions: {
|
||||
columns: useColumns(),
|
||||
height: 'auto',
|
||||
keepSource: true,
|
||||
sortConfig: {
|
||||
remote: true,
|
||||
multiple: false,
|
||||
trigger: 'default',
|
||||
orders: ['asc', 'desc', null],
|
||||
resetPage: true,
|
||||
},
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({ page, sort }, formValues) => {
|
||||
const sortParams = sort
|
||||
? {
|
||||
order_by: sort.field,
|
||||
order_type: sort.order,
|
||||
}
|
||||
: {};
|
||||
|
||||
const res = await getAgentList({
|
||||
page: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
...formValues,
|
||||
...sortParams,
|
||||
parent_agent_id: route.query.parent_agent_id
|
||||
? Number(route.query.parent_agent_id)
|
||||
: undefined,
|
||||
});
|
||||
|
||||
return {
|
||||
...res,
|
||||
sort: sort || null,
|
||||
};
|
||||
},
|
||||
},
|
||||
props: {
|
||||
result: 'items',
|
||||
total: 'total',
|
||||
},
|
||||
autoLoad: true,
|
||||
},
|
||||
rowConfig: {
|
||||
keyField: 'id',
|
||||
},
|
||||
toolbarConfig: {
|
||||
custom: true,
|
||||
export: false,
|
||||
refresh: { code: 'query' },
|
||||
search: true,
|
||||
zoom: true,
|
||||
},
|
||||
} as VxeTableGridOptions<AgentApi.AgentListItem>,
|
||||
});
|
||||
|
||||
// 更多操作菜单项
|
||||
const moreMenuItems = [
|
||||
{
|
||||
key: 'links',
|
||||
label: '推广链接',
|
||||
},
|
||||
// {
|
||||
// key: 'commission',
|
||||
// label: '佣金记录',
|
||||
// },
|
||||
// {
|
||||
// key: 'commission-deduction',
|
||||
// label: '上级抽佣',
|
||||
// },
|
||||
// {
|
||||
// key: 'platform-deduction',
|
||||
// label: '平台抽佣',
|
||||
// },
|
||||
{
|
||||
key: 'reward',
|
||||
label: '奖励记录',
|
||||
},
|
||||
{
|
||||
key: 'withdrawal',
|
||||
label: '提现记录',
|
||||
},
|
||||
];
|
||||
|
||||
// 上级代理信息
|
||||
const parentAgentId = computed(() => route.query.parent_agent_id);
|
||||
|
||||
// 返回上级列表
|
||||
function onBackToParent() {
|
||||
router.replace({
|
||||
query: {
|
||||
...route.query,
|
||||
parent_agent_id: undefined,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 操作处理函数
|
||||
function onActionClick(
|
||||
e:
|
||||
| OnActionClickParams<AgentApi.AgentListItem>
|
||||
| { code: string; row: AgentApi.AgentListItem },
|
||||
) {
|
||||
switch (e.code) {
|
||||
case 'commission': {
|
||||
onViewCommission(e.row);
|
||||
break;
|
||||
}
|
||||
case 'commission-deduction': {
|
||||
onViewCommissionDeduction(e.row);
|
||||
break;
|
||||
}
|
||||
case 'edit': {
|
||||
onEdit(e.row);
|
||||
break;
|
||||
}
|
||||
case 'links': {
|
||||
onViewLinks(e.row);
|
||||
break;
|
||||
}
|
||||
case 'platform-deduction': {
|
||||
onViewPlatformDeduction(e.row);
|
||||
break;
|
||||
}
|
||||
case 'reward': {
|
||||
onViewReward(e.row);
|
||||
break;
|
||||
}
|
||||
case 'view-sub-agent': {
|
||||
router.replace({
|
||||
query: {
|
||||
...route.query,
|
||||
parent_agent_id: e.row.id,
|
||||
},
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'withdrawal': {
|
||||
onViewWithdrawal(e.row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑处理
|
||||
function onEdit(row: AgentApi.AgentListItem) {
|
||||
formDrawerApi.setData(row).open();
|
||||
}
|
||||
|
||||
// 查看推广链接
|
||||
function onViewLinks(row: AgentApi.AgentListItem) {
|
||||
linkModalApi.setData({ agentId: row.id }).open();
|
||||
}
|
||||
|
||||
// 查看佣金记录
|
||||
function onViewCommission(row: AgentApi.AgentListItem) {
|
||||
commissionModalApi.setData({ agentId: row.id }).open();
|
||||
}
|
||||
|
||||
// 查看奖励记录
|
||||
function onViewReward(row: AgentApi.AgentListItem) {
|
||||
rewardModalApi.setData({ agentId: row.id }).open();
|
||||
}
|
||||
|
||||
// 查看提现记录
|
||||
function onViewWithdrawal(row: AgentApi.AgentListItem) {
|
||||
withdrawalModalApi.setData({ agentId: row.id }).open();
|
||||
}
|
||||
|
||||
// 查看上级抽佣记录
|
||||
function onViewCommissionDeduction(row: AgentApi.AgentListItem) {
|
||||
commissionDeductionModalApi.setData({ agentId: row.id }).open();
|
||||
}
|
||||
|
||||
// 查看平台抽佣记录
|
||||
function onViewPlatformDeduction(row: AgentApi.AgentListItem) {
|
||||
platformDeductionModalApi.setData({ agentId: row.id }).open();
|
||||
}
|
||||
|
||||
// 刷新处理
|
||||
function onRefresh() {
|
||||
gridApi.query();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page auto-content-height>
|
||||
<FormDrawer @success="onRefresh" />
|
||||
<LinkModalComponent />
|
||||
<CommissionModalComponent />
|
||||
<CommissionDeductionModalComponent />
|
||||
<PlatformDeductionModalComponent />
|
||||
<RewardModalComponent />
|
||||
<WithdrawalModalComponent />
|
||||
|
||||
<!-- 上级代理信息卡片 -->
|
||||
<Card v-if="parentAgentId" class="mb-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<Button @click="onBackToParent">返回上级列表</Button>
|
||||
<div>上级代理ID:{{ parentAgentId }}</div>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Grid table-title="代理列表">
|
||||
<template #operation="{ row }">
|
||||
<div class="operation-buttons">
|
||||
<Button type="link" @click="onActionClick({ code: 'edit', row })">
|
||||
编辑
|
||||
</Button>
|
||||
<Button
|
||||
type="link"
|
||||
@click="onActionClick({ code: 'view-sub-agent', row })"
|
||||
>
|
||||
查看下级
|
||||
</Button>
|
||||
<!-- <Button
|
||||
type="link"
|
||||
@click="onActionClick({ code: 'order-record', row })"
|
||||
>
|
||||
订单记录
|
||||
</Button> -->
|
||||
<Dropdown>
|
||||
<Button type="link">更多操作</Button>
|
||||
<template #overlay>
|
||||
<Menu
|
||||
:items="moreMenuItems"
|
||||
@click="(e) => onActionClick({ code: String(e.key), row })"
|
||||
/>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</template>
|
||||
</Grid>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.parent-agent-card {
|
||||
margin-bottom: 16px;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.operation-buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
gap: 4px;
|
||||
|
||||
:deep(.ant-btn-link) {
|
||||
padding: 0 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,32 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import CommissionDeductionList from '../../agent-commission-deduction/list.vue';
|
||||
|
||||
interface ModalData {
|
||||
agentId: number;
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
title: '上级抽佣记录',
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
const modalData = computed(() => modalApi.getData<ModalData>());
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[calc(100vw-200px)]" :footer="false">
|
||||
<div class="agent-commission-deduction-modal">
|
||||
<CommissionDeductionList :agent-id="modalData?.agentId" />
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.agent-commission-deduction-modal {
|
||||
padding: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,32 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import CommissionList from '../../agent-commission/list.vue';
|
||||
|
||||
interface ModalData {
|
||||
agentId: number;
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
title: '佣金记录列表',
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
const modalData = computed(() => modalApi.getData<ModalData>());
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[calc(100vw-200px)]" :footer="false">
|
||||
<div class="agent-commission-modal">
|
||||
<CommissionList :agent-id="modalData?.agentId" />
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.agent-commission-modal {
|
||||
padding: 16px;
|
||||
}
|
||||
</style>
|
||||
62
apps/web-antd/src/views/agent/agent-list/modules/form.vue
Normal file
62
apps/web-antd/src/views/agent/agent-list/modules/form.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<script lang="ts" setup>
|
||||
import type { AgentApi } from '#/api/agent';
|
||||
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { useVbenDrawer } from '@vben/common-ui';
|
||||
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
|
||||
import { useFormSchema } from '../data';
|
||||
|
||||
const emit = defineEmits(['success']);
|
||||
|
||||
const formData = ref<AgentApi.AgentListItem>();
|
||||
|
||||
const [Form, formApi] = useVbenForm({
|
||||
schema: useFormSchema(),
|
||||
showDefaultActions: false,
|
||||
});
|
||||
|
||||
const id = ref();
|
||||
const [Drawer, drawerApi] = useVbenDrawer({
|
||||
async onConfirm() {
|
||||
const { valid } = await formApi.validate();
|
||||
if (!valid) return;
|
||||
const values = await formApi.getValues();
|
||||
drawerApi.lock();
|
||||
// TODO: 实现更新代理信息的接口
|
||||
// updateAgent(id.value, values as AgentApi.UpdateAgentRequest)
|
||||
// .then(() => {
|
||||
// emit('success');
|
||||
// drawerApi.close();
|
||||
// })
|
||||
// .catch(() => {
|
||||
// drawerApi.unlock();
|
||||
// });
|
||||
},
|
||||
onOpenChange(isOpen) {
|
||||
if (isOpen) {
|
||||
const data = drawerApi.getData<AgentApi.AgentListItem>();
|
||||
formApi.resetForm();
|
||||
if (data) {
|
||||
formData.value = data;
|
||||
id.value = data.id;
|
||||
formApi.setValues(data);
|
||||
} else {
|
||||
id.value = undefined;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const getDrawerTitle = computed(() => {
|
||||
return formData.value?.id ? '编辑代理' : '创建代理';
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Drawer :title="getDrawerTitle">
|
||||
<Form />
|
||||
</Drawer>
|
||||
</template>
|
||||
@@ -0,0 +1,32 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import LinkList from '../../agent-links/list.vue';
|
||||
|
||||
interface ModalData {
|
||||
agentId: number;
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
title: '推广链接列表',
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
const modalData = computed(() => modalApi.getData<ModalData>());
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[calc(100vw-200px)]" :footer="false">
|
||||
<div class="agent-link-modal">
|
||||
<LinkList :agent-id="modalData?.agentId" />
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.agent-link-modal {
|
||||
padding: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,31 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import PlatformDeductionList from '../../agent-platform-deduction/list.vue';
|
||||
|
||||
interface ModalData {
|
||||
agentId: number;
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
title: '平台抽佣记录',
|
||||
width: 1000,
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
const modalData = computed(() => modalApi.getData<ModalData>());
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal>
|
||||
<PlatformDeductionList v-if="modalData" :agent-id="modalData.agentId" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.ant-modal-body) {
|
||||
padding: 24px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,32 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import RewardList from '../../agent-reward/list.vue';
|
||||
|
||||
interface ModalData {
|
||||
agentId: number;
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
title: '奖励记录',
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
const modalData = computed(() => modalApi.getData<ModalData>());
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[calc(100vw-200px)]" :footer="false">
|
||||
<div class="agent-reward-modal">
|
||||
<RewardList :agent-id="modalData?.agentId" />
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.agent-reward-modal {
|
||||
padding: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,32 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import WithdrawalList from '../../agent-withdrawal/list.vue';
|
||||
|
||||
interface ModalData {
|
||||
agentId: number;
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
title: '提现记录',
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
const modalData = computed(() => modalApi.getData<ModalData>());
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[calc(100vw-200px)]" :footer="false">
|
||||
<div class="agent-withdrawal-modal">
|
||||
<WithdrawalList :agent-id="modalData?.agentId" />
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.agent-withdrawal-modal {
|
||||
padding: 16px;
|
||||
}
|
||||
</style>
|
||||
254
apps/web-antd/src/views/agent/agent-membership-config/data.ts
Normal file
254
apps/web-antd/src/views/agent/agent-membership-config/data.ts
Normal file
@@ -0,0 +1,254 @@
|
||||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
|
||||
// 会员等级选项
|
||||
export const levelNameOptions = [
|
||||
{ label: '普通会员', value: 'normal' },
|
||||
{ label: 'VIP会员', value: 'VIP' },
|
||||
{ label: 'SVIP会员', value: 'SVIP' },
|
||||
];
|
||||
|
||||
// 代理会员配置列表列配置
|
||||
export function useColumns(): VxeTableGridOptions['columns'] {
|
||||
return [
|
||||
{ field: 'id', title: 'ID', width: 80 },
|
||||
{
|
||||
field: 'level_name',
|
||||
title: '会员等级',
|
||||
formatter: ({ cellValue }) => {
|
||||
const option = levelNameOptions.find(
|
||||
(item) => item.value === cellValue,
|
||||
);
|
||||
return option?.label || cellValue;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'price',
|
||||
title: '会员年费',
|
||||
formatter: ({ cellValue }) =>
|
||||
cellValue !== null && cellValue !== undefined
|
||||
? `¥${cellValue.toFixed(2)}`
|
||||
: '-',
|
||||
},
|
||||
{
|
||||
field: 'report_commission',
|
||||
title: '直推报告收益',
|
||||
formatter: ({ cellValue }) =>
|
||||
cellValue !== null && cellValue !== undefined
|
||||
? `¥${cellValue.toFixed(2)}`
|
||||
: '-',
|
||||
},
|
||||
{
|
||||
field: 'lower_activity_reward',
|
||||
title: '下级活跃奖励',
|
||||
formatter: ({ cellValue }) =>
|
||||
cellValue !== null && cellValue !== undefined
|
||||
? `¥${cellValue.toFixed(2)}`
|
||||
: '-',
|
||||
},
|
||||
{
|
||||
field: 'new_activity_reward',
|
||||
title: '新增活跃奖励',
|
||||
formatter: ({ cellValue }) =>
|
||||
cellValue !== null && cellValue !== undefined
|
||||
? `¥${cellValue.toFixed(2)}`
|
||||
: '-',
|
||||
},
|
||||
{
|
||||
field: 'lower_standard_count',
|
||||
title: '活跃下级达标数',
|
||||
formatter: ({ cellValue }) => cellValue ?? '-',
|
||||
},
|
||||
{
|
||||
field: 'new_lower_standard_count',
|
||||
title: '新增活跃下级达标数',
|
||||
formatter: ({ cellValue }) => cellValue ?? '-',
|
||||
},
|
||||
{
|
||||
field: 'lower_withdraw_reward_ratio',
|
||||
title: '下级提现奖励比例',
|
||||
formatter: ({ cellValue }) =>
|
||||
cellValue !== null && cellValue !== undefined
|
||||
? `${(cellValue * 100).toFixed(2)}%`
|
||||
: '-',
|
||||
},
|
||||
{
|
||||
field: 'create_time',
|
||||
title: '创建时间',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
slots: { default: 'operation' },
|
||||
field: 'operation',
|
||||
fixed: 'right',
|
||||
title: '操作',
|
||||
width: 120,
|
||||
},
|
||||
] as const;
|
||||
}
|
||||
|
||||
// 代理会员配置搜索表单配置
|
||||
export function useGridFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'Select',
|
||||
fieldName: 'level_name',
|
||||
label: '会员等级',
|
||||
componentProps: {
|
||||
placeholder: '请选择会员等级',
|
||||
options: levelNameOptions,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// 代理会员配置编辑表单配置
|
||||
export function useFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'Select',
|
||||
fieldName: 'level_name',
|
||||
label: '会员等级',
|
||||
rules: 'required',
|
||||
componentProps: {
|
||||
options: levelNameOptions,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'price',
|
||||
label: '会员年费',
|
||||
rules: 'required',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'report_commission',
|
||||
label: '直推报告收益',
|
||||
rules: 'required',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'lower_activity_reward',
|
||||
label: '下级活跃奖励',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'new_activity_reward',
|
||||
label: '新增活跃奖励',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'lower_standard_count',
|
||||
label: '活跃下级达标数',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'new_lower_standard_count',
|
||||
label: '新增活跃下级达标数',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'lower_withdraw_reward_ratio',
|
||||
label: '下级提现奖励比例',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
addonAfter: '%',
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'lower_convert_vip_reward',
|
||||
label: '下级转化VIP奖励',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'lower_convert_svip_reward',
|
||||
label: '下级转化SVIP奖励',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'exemption_amount',
|
||||
label: '免责金额',
|
||||
rules: 'required',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'price_increase_max',
|
||||
label: '提价最高金额',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'price_ratio',
|
||||
label: '提价区间收取比例',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
addonAfter: '%',
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'price_increase_amount',
|
||||
label: '加价金额',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
105
apps/web-antd/src/views/agent/agent-membership-config/list.vue
Normal file
105
apps/web-antd/src/views/agent/agent-membership-config/list.vue
Normal file
@@ -0,0 +1,105 @@
|
||||
<script lang="ts" setup>
|
||||
import type {
|
||||
OnActionClickParams,
|
||||
VxeGridListeners,
|
||||
VxeTableGridOptions,
|
||||
} from '#/adapter/vxe-table';
|
||||
import type { AgentApi } from '#/api/agent';
|
||||
|
||||
import { Page, useVbenDrawer } from '@vben/common-ui';
|
||||
|
||||
import { Button, Space } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getAgentMembershipConfigList } from '#/api/agent';
|
||||
|
||||
import { useColumns, useGridFormSchema } from './data';
|
||||
import Form from './modules/form.vue';
|
||||
|
||||
// 表单抽屉
|
||||
const [FormDrawer, formDrawerApi] = useVbenDrawer({
|
||||
connectedComponent: Form,
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
// 表格配置
|
||||
const [Grid, gridApi] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
schema: useGridFormSchema(),
|
||||
submitOnChange: true,
|
||||
},
|
||||
gridEvents: {
|
||||
sortChange: () => {
|
||||
gridApi.query();
|
||||
},
|
||||
} as VxeGridListeners<AgentApi.AgentMembershipConfigListItem>,
|
||||
gridOptions: {
|
||||
columns: useColumns(),
|
||||
height: 'auto',
|
||||
keepSource: true,
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({ page }, formValues) => {
|
||||
const res = await getAgentMembershipConfigList({
|
||||
page: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
level_name: formValues.level_name,
|
||||
});
|
||||
return res;
|
||||
},
|
||||
},
|
||||
props: {
|
||||
result: 'items',
|
||||
total: 'total',
|
||||
},
|
||||
},
|
||||
rowConfig: {
|
||||
keyField: 'id',
|
||||
},
|
||||
toolbarConfig: {
|
||||
custom: true,
|
||||
export: false,
|
||||
refresh: { code: 'query' },
|
||||
search: true,
|
||||
zoom: true,
|
||||
},
|
||||
} as VxeTableGridOptions<AgentApi.AgentMembershipConfigListItem>,
|
||||
});
|
||||
|
||||
// 操作处理函数
|
||||
function onActionClick(
|
||||
e: OnActionClickParams<AgentApi.AgentMembershipConfigListItem>,
|
||||
) {
|
||||
switch (e.code) {
|
||||
case 'edit': {
|
||||
onEdit(e.row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑处理
|
||||
function onEdit(row: AgentApi.AgentMembershipConfigListItem) {
|
||||
formDrawerApi.setData(row).open();
|
||||
}
|
||||
|
||||
// 刷新处理
|
||||
function onRefresh() {
|
||||
gridApi.query();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page auto-content-height>
|
||||
<FormDrawer @success="onRefresh" />
|
||||
<Grid table-title="代理会员配置列表">
|
||||
<template #operation="{ row }">
|
||||
<Space>
|
||||
<Button type="link" @click="onActionClick({ code: 'edit', row })">
|
||||
配置
|
||||
</Button>
|
||||
</Space>
|
||||
</template>
|
||||
</Grid>
|
||||
</Page>
|
||||
</template>
|
||||
@@ -0,0 +1,88 @@
|
||||
<script lang="ts" setup>
|
||||
import type { AgentApi } from '#/api/agent';
|
||||
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { useVbenDrawer, useVbenForm } from '@vben/common-ui';
|
||||
|
||||
import { updateAgentMembershipConfig } from '#/api/agent';
|
||||
|
||||
import { useFormSchema } from '../data';
|
||||
|
||||
const emit = defineEmits(['success']);
|
||||
|
||||
const formData = ref<AgentApi.AgentMembershipConfigListItem>();
|
||||
const id = ref<number>();
|
||||
|
||||
const [Form, formApi] = useVbenForm({
|
||||
schema: useFormSchema(),
|
||||
showDefaultActions: false,
|
||||
});
|
||||
|
||||
const drawerTitle = ref('会员配置');
|
||||
|
||||
const [Drawer, drawerApi] = useVbenDrawer({
|
||||
title: drawerTitle.value,
|
||||
destroyOnClose: true,
|
||||
async onConfirm() {
|
||||
const valid = await formApi.validate();
|
||||
if (!valid || !id.value) return;
|
||||
|
||||
const values = await formApi.getValues();
|
||||
const params: AgentApi.UpdateAgentMembershipConfigParams = {
|
||||
id: id.value,
|
||||
level_name: values.level_name,
|
||||
price: values.price,
|
||||
report_commission: values.report_commission,
|
||||
lower_activity_reward: values.lower_activity_reward ?? null,
|
||||
new_activity_reward: values.new_activity_reward ?? null,
|
||||
lower_standard_count: values.lower_standard_count ?? null,
|
||||
new_lower_standard_count: values.new_lower_standard_count ?? null,
|
||||
lower_withdraw_reward_ratio:
|
||||
values.lower_withdraw_reward_ratio !== null &&
|
||||
values.lower_withdraw_reward_ratio !== undefined
|
||||
? values.lower_withdraw_reward_ratio / 100
|
||||
: null,
|
||||
lower_convert_vip_reward: values.lower_convert_vip_reward ?? null,
|
||||
lower_convert_svip_reward: values.lower_convert_svip_reward ?? null,
|
||||
exemption_amount: values.exemption_amount ?? null,
|
||||
price_increase_max: values.price_increase_max ?? null,
|
||||
price_ratio:
|
||||
values.price_ratio !== null && values.price_ratio !== undefined
|
||||
? values.price_ratio / 100
|
||||
: null,
|
||||
price_increase_amount: values.price_increase_amount ?? null,
|
||||
};
|
||||
|
||||
await updateAgentMembershipConfig(params);
|
||||
|
||||
emit('success');
|
||||
drawerApi.close();
|
||||
},
|
||||
onOpenChange(isOpen) {
|
||||
if (isOpen) {
|
||||
const data = drawerApi.getData<AgentApi.AgentMembershipConfigListItem>();
|
||||
formApi.resetForm();
|
||||
if (data) {
|
||||
formData.value = data;
|
||||
id.value = data.id;
|
||||
formApi.setValues({
|
||||
...data,
|
||||
lower_withdraw_reward_ratio: data.lower_withdraw_reward_ratio
|
||||
? data.lower_withdraw_reward_ratio * 100
|
||||
: null,
|
||||
price_ratio: data.price_ratio ? data.price_ratio * 100 : null,
|
||||
});
|
||||
} else {
|
||||
id.value = undefined;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Drawer :title="drawerTitle">
|
||||
<Form />
|
||||
</Drawer>
|
||||
</template>
|
||||
@@ -0,0 +1,134 @@
|
||||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
|
||||
// 支付方式选项
|
||||
export const paymentMethodOptions = [
|
||||
{ label: '支付宝', value: 'alipay' },
|
||||
{ label: '微信', value: 'wechat' },
|
||||
{ label: '苹果支付', value: 'appleiap' },
|
||||
{ label: '其他', value: 'other' },
|
||||
];
|
||||
|
||||
// 会员等级选项
|
||||
export const levelNameOptions = [
|
||||
{ label: '普通会员', value: '' },
|
||||
{ label: 'VIP会员', value: 'VIP' },
|
||||
{ label: 'SVIP会员', value: 'SVIP' },
|
||||
];
|
||||
|
||||
// 状态选项
|
||||
export const statusOptions = [
|
||||
{ label: '待支付', value: 'pending' },
|
||||
{ label: '支付成功', value: 'success' },
|
||||
{ label: '支付失败', value: 'failed' },
|
||||
{ label: '已取消', value: 'cancelled' },
|
||||
];
|
||||
|
||||
// 列表列配置
|
||||
export function useMembershipRechargeOrderColumns(): VxeTableGridOptions['columns'] {
|
||||
return [
|
||||
{ field: 'id', title: 'ID', width: 80 },
|
||||
{ field: 'user_id', title: '用户ID', width: 100 },
|
||||
{ field: 'agent_id', title: '代理ID', width: 100 },
|
||||
{
|
||||
field: 'level_name',
|
||||
title: '会员等级',
|
||||
width: 100,
|
||||
formatter: ({ cellValue }) => {
|
||||
const option = levelNameOptions.find(
|
||||
(item) => item.value === cellValue,
|
||||
);
|
||||
return option?.label || '普通会员';
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'amount',
|
||||
title: '金额',
|
||||
width: 100,
|
||||
formatter: ({ cellValue }) => `¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'payment_method',
|
||||
title: '支付方式',
|
||||
width: 100,
|
||||
formatter: ({ cellValue }) => {
|
||||
const option = paymentMethodOptions.find(
|
||||
(item) => item.value === cellValue,
|
||||
);
|
||||
return option?.label || cellValue;
|
||||
},
|
||||
},
|
||||
{ field: 'order_no', title: '订单号', width: 180 },
|
||||
{ field: 'platform_order_id', title: '平台订单号', width: 180 },
|
||||
{
|
||||
field: 'status',
|
||||
title: '状态',
|
||||
width: 100,
|
||||
formatter: ({ cellValue }) => {
|
||||
const option = statusOptions.find((item) => item.value === cellValue);
|
||||
return option?.label || cellValue;
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'create_time',
|
||||
title: '创建时间',
|
||||
width: 180,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// 搜索表单配置
|
||||
export function useMembershipRechargeOrderFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'user_id',
|
||||
label: '用户ID',
|
||||
componentProps: {
|
||||
placeholder: '请输入用户ID',
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'agent_id',
|
||||
label: '代理ID',
|
||||
componentProps: {
|
||||
placeholder: '请输入代理ID',
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'order_no',
|
||||
label: '订单号',
|
||||
componentProps: {
|
||||
placeholder: '请输入订单号',
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'platform_order_id',
|
||||
label: '平台订单号',
|
||||
componentProps: {
|
||||
placeholder: '请输入平台订单号',
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
fieldName: 'status',
|
||||
label: '状态',
|
||||
componentProps: {
|
||||
placeholder: '请选择状态',
|
||||
options: statusOptions,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
fieldName: 'payment_method',
|
||||
label: '支付方式',
|
||||
componentProps: {
|
||||
placeholder: '请选择支付方式',
|
||||
options: paymentMethodOptions,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<script lang="ts" setup>
|
||||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||
import type { AgentApi } from '#/api/agent/agent';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getMembershipRechargeOrderList } from '#/api/agent';
|
||||
|
||||
import {
|
||||
useMembershipRechargeOrderColumns,
|
||||
useMembershipRechargeOrderFormSchema,
|
||||
} from './data';
|
||||
|
||||
const [Grid, _gridApi] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
schema: useMembershipRechargeOrderFormSchema(),
|
||||
submitOnChange: true,
|
||||
},
|
||||
gridOptions: {
|
||||
columns: useMembershipRechargeOrderColumns(),
|
||||
height: 'auto',
|
||||
keepSource: true,
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async (
|
||||
{ page }: { page: { currentPage: number; pageSize: number } },
|
||||
formValues: Record<string, any>,
|
||||
) => {
|
||||
const res = await getMembershipRechargeOrderList({
|
||||
page: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
...formValues,
|
||||
});
|
||||
return { items: res.items, total: res.total };
|
||||
},
|
||||
},
|
||||
},
|
||||
rowConfig: {
|
||||
keyField: 'id',
|
||||
},
|
||||
toolbarConfig: {
|
||||
custom: true,
|
||||
export: false,
|
||||
refresh: { code: 'query' },
|
||||
search: true,
|
||||
zoom: true,
|
||||
},
|
||||
} as VxeGridProps<AgentApi.MembershipRechargeOrderListItem>,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page auto-content-height>
|
||||
<Grid table-title="会员充值订单列表" />
|
||||
</Page>
|
||||
</template>
|
||||
@@ -0,0 +1,96 @@
|
||||
import type { VbenFormSchema } from '@vben/common-ui';
|
||||
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { AgentApi } from '#/api/agent';
|
||||
|
||||
// 平台抽佣列表列配置
|
||||
export function usePlatformDeductionColumns(): VxeTableGridOptions['columns'] {
|
||||
return [
|
||||
{
|
||||
title: 'ID',
|
||||
field: 'id',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '代理ID',
|
||||
field: 'agent_id',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '抽佣金额',
|
||||
field: 'amount',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }) => {
|
||||
return `¥${cellValue.toFixed(2)}`;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '抽佣类型',
|
||||
field: 'type',
|
||||
width: 120,
|
||||
formatter: ({
|
||||
cellValue,
|
||||
}: {
|
||||
cellValue: AgentApi.AgentPlatformDeductionListItem['type'];
|
||||
}) => {
|
||||
const typeMap = {
|
||||
cost: '成本抽佣',
|
||||
pricing: '定价抽佣',
|
||||
};
|
||||
return typeMap[cellValue] || cellValue;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
field: 'status',
|
||||
width: 100,
|
||||
formatter: ({ cellValue }) => {
|
||||
const statusMap = {
|
||||
0: { text: '待处理', type: 'warning' },
|
||||
1: { text: '已处理', type: 'success' },
|
||||
2: { text: '已取消', type: 'error' },
|
||||
};
|
||||
const status = statusMap[cellValue as keyof typeof statusMap];
|
||||
return status
|
||||
? `<a-tag color="${status.type}">${status.text}</a-tag>`
|
||||
: cellValue;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
field: 'create_time',
|
||||
width: 180,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// 平台抽佣列表搜索表单配置
|
||||
export function usePlatformDeductionFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'Select',
|
||||
fieldName: 'type',
|
||||
label: '抽佣类型',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '成本抽佣', value: 'cost' },
|
||||
{ label: '定价抽佣', value: 'pricing' },
|
||||
],
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
fieldName: 'status',
|
||||
label: '状态',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '待处理', value: 0 },
|
||||
{ label: '已处理', value: 1 },
|
||||
{ label: '已取消', value: 2 },
|
||||
],
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getAgentPlatformDeductionList } from '#/api/agent';
|
||||
|
||||
import {
|
||||
usePlatformDeductionColumns,
|
||||
usePlatformDeductionFormSchema,
|
||||
} from './data';
|
||||
|
||||
interface Props {
|
||||
agentId?: number;
|
||||
}
|
||||
|
||||
interface QueryParams {
|
||||
currentPage: number;
|
||||
pageSize: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const queryParams = computed(() => ({
|
||||
...(props.agentId ? { agent_id: props.agentId } : {}),
|
||||
}));
|
||||
|
||||
const [Grid] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
schema: usePlatformDeductionFormSchema(),
|
||||
submitOnChange: true,
|
||||
},
|
||||
gridOptions: {
|
||||
columns: usePlatformDeductionColumns(),
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({
|
||||
form,
|
||||
page,
|
||||
}: {
|
||||
form: Record<string, any>;
|
||||
page: QueryParams;
|
||||
}) => {
|
||||
return await getAgentPlatformDeductionList({
|
||||
...queryParams.value,
|
||||
...form,
|
||||
page: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
});
|
||||
},
|
||||
},
|
||||
props: {
|
||||
result: 'items',
|
||||
total: 'total',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page :auto-content-height="!agentId">
|
||||
<Grid :table-title="agentId ? '平台抽佣列表' : '所有平台抽佣记录'" />
|
||||
</Page>
|
||||
</template>
|
||||
131
apps/web-antd/src/views/agent/agent-product-config/data.ts
Normal file
131
apps/web-antd/src/views/agent/agent-product-config/data.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
|
||||
// 代理产品配置列表列配置
|
||||
export function useColumns(): VxeTableGridOptions['columns'] {
|
||||
return [
|
||||
{
|
||||
field: 'id',
|
||||
title: 'ID',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
field: 'product_name',
|
||||
title: '产品名称',
|
||||
},
|
||||
{
|
||||
field: 'cost_price',
|
||||
title: '成本',
|
||||
formatter: ({ cellValue }: { cellValue: number }) =>
|
||||
`¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'price_range_min',
|
||||
title: '最低定价',
|
||||
formatter: ({ cellValue }: { cellValue: number }) =>
|
||||
`¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'price_range_max',
|
||||
title: '最高定价',
|
||||
formatter: ({ cellValue }: { cellValue: number }) =>
|
||||
`¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'pricing_standard',
|
||||
title: '定价标准',
|
||||
formatter: ({ cellValue }: { cellValue: number }) =>
|
||||
`¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
field: 'overpricing_ratio',
|
||||
title: '超标抽佣比例',
|
||||
formatter: ({ cellValue }: { cellValue: number }) =>
|
||||
`${(cellValue * 100).toFixed(2)}%`,
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
slots: { default: 'operation' },
|
||||
field: 'operation',
|
||||
fixed: 'right',
|
||||
title: '操作',
|
||||
width: 120,
|
||||
},
|
||||
] as const;
|
||||
}
|
||||
|
||||
// 代理产品配置搜索表单配置
|
||||
export function useGridFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'product_name',
|
||||
label: '产品名称',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// 代理产品配置编辑表单配置
|
||||
export function useFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'cost_price',
|
||||
label: '成本',
|
||||
rules: 'required',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'price_range_min',
|
||||
label: '最低定价',
|
||||
rules: 'required',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'price_range_max',
|
||||
label: '最高定价',
|
||||
rules: 'required',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'pricing_standard',
|
||||
label: '定价标准',
|
||||
rules: 'required',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'InputNumber',
|
||||
fieldName: 'overpricing_ratio',
|
||||
label: '超标抽佣比例',
|
||||
rules: 'required',
|
||||
componentProps: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
precision: 2,
|
||||
step: 0.01,
|
||||
addonAfter: '%',
|
||||
controls: true,
|
||||
validateTrigger: ['blur', 'change'],
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
127
apps/web-antd/src/views/agent/agent-product-config/list.vue
Normal file
127
apps/web-antd/src/views/agent/agent-product-config/list.vue
Normal file
@@ -0,0 +1,127 @@
|
||||
<script lang="ts" setup>
|
||||
import type {
|
||||
OnActionClickParams,
|
||||
VxeGridListeners,
|
||||
VxeTableGridOptions,
|
||||
} from '#/adapter/vxe-table';
|
||||
import type { AgentApi } from '#/api/agent';
|
||||
|
||||
import { Page, useVbenDrawer } from '@vben/common-ui';
|
||||
|
||||
import { Button, Space } from 'ant-design-vue';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getAgentProductionConfigList } from '#/api/agent';
|
||||
|
||||
import { useColumns, useGridFormSchema } from './data';
|
||||
import Form from './modules/form.vue';
|
||||
|
||||
// 表单抽屉
|
||||
const [FormDrawer, formDrawerApi] = useVbenDrawer({
|
||||
connectedComponent: Form,
|
||||
destroyOnClose: true,
|
||||
});
|
||||
|
||||
// 表格配置
|
||||
const [Grid, gridApi] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
schema: useGridFormSchema(),
|
||||
submitOnChange: true,
|
||||
},
|
||||
gridEvents: {
|
||||
sortChange: () => {
|
||||
gridApi.query();
|
||||
},
|
||||
} as VxeGridListeners<AgentApi.AgentProductionConfigItem>,
|
||||
gridOptions: {
|
||||
columns: useColumns(),
|
||||
height: 'auto',
|
||||
keepSource: true,
|
||||
sortConfig: {
|
||||
remote: true,
|
||||
multiple: false,
|
||||
trigger: 'default',
|
||||
orders: ['asc', 'desc', null],
|
||||
resetPage: true,
|
||||
},
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({ page, sort }, formValues) => {
|
||||
const sortParams = sort
|
||||
? {
|
||||
order_by: sort.field,
|
||||
order_type: sort.order,
|
||||
}
|
||||
: {};
|
||||
|
||||
const params: AgentApi.GetAgentProductionConfigListParams = {
|
||||
page: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
product_name: formValues.product_name,
|
||||
...sortParams,
|
||||
};
|
||||
|
||||
const res = await getAgentProductionConfigList(params);
|
||||
|
||||
return {
|
||||
...res,
|
||||
sort: sort || null,
|
||||
};
|
||||
},
|
||||
},
|
||||
props: {
|
||||
result: 'items',
|
||||
total: 'total',
|
||||
},
|
||||
autoLoad: true,
|
||||
},
|
||||
rowConfig: {
|
||||
keyField: 'id',
|
||||
},
|
||||
toolbarConfig: {
|
||||
custom: true,
|
||||
export: false,
|
||||
refresh: { code: 'query' },
|
||||
search: true,
|
||||
zoom: true,
|
||||
},
|
||||
} as VxeTableGridOptions<AgentApi.AgentProductionConfigItem>,
|
||||
});
|
||||
|
||||
// 操作处理函数
|
||||
function onActionClick(
|
||||
e: OnActionClickParams<AgentApi.AgentProductionConfigItem>,
|
||||
) {
|
||||
switch (e.code) {
|
||||
case 'edit': {
|
||||
onEdit(e.row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 编辑处理
|
||||
function onEdit(row: AgentApi.AgentProductionConfigItem) {
|
||||
formDrawerApi.setData(row).open();
|
||||
}
|
||||
|
||||
// 刷新处理
|
||||
function onRefresh() {
|
||||
gridApi.query();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page auto-content-height>
|
||||
<FormDrawer @success="onRefresh" />
|
||||
<Grid table-title="代理产品配置列表">
|
||||
<template #operation="{ row }">
|
||||
<Space>
|
||||
<Button type="link" @click="onActionClick({ code: 'edit', row })">
|
||||
配置
|
||||
</Button>
|
||||
</Space>
|
||||
</template>
|
||||
</Grid>
|
||||
</Page>
|
||||
</template>
|
||||
@@ -0,0 +1,68 @@
|
||||
<script lang="ts" setup>
|
||||
import type { AgentApi } from '#/api/agent';
|
||||
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { useVbenDrawer, useVbenForm } from '@vben/common-ui';
|
||||
|
||||
import { updateAgentProductionConfig } from '#/api/agent';
|
||||
|
||||
import { useFormSchema } from '../data';
|
||||
|
||||
const emit = defineEmits(['success']);
|
||||
|
||||
const formData = ref<AgentApi.AgentProductionConfigItem>();
|
||||
const id = ref<number>();
|
||||
|
||||
const [Form, formApi] = useVbenForm({
|
||||
schema: useFormSchema(),
|
||||
showDefaultActions: false,
|
||||
});
|
||||
const drawerTitle = ref('产品配置');
|
||||
|
||||
const [Drawer, drawerApi] = useVbenDrawer({
|
||||
title: drawerTitle.value,
|
||||
destroyOnClose: true,
|
||||
async onConfirm() {
|
||||
const valid = await formApi.validate();
|
||||
if (!valid || !id.value) return;
|
||||
|
||||
const values = await formApi.getValues();
|
||||
const params: AgentApi.UpdateAgentProductionConfigParams = {
|
||||
id: id.value,
|
||||
cost_price: values.cost_price,
|
||||
price_range_min: values.price_range_min,
|
||||
price_range_max: values.price_range_max,
|
||||
pricing_standard: values.pricing_standard,
|
||||
overpricing_ratio: values.overpricing_ratio / 100,
|
||||
};
|
||||
|
||||
await updateAgentProductionConfig(params);
|
||||
|
||||
emit('success');
|
||||
drawerApi.close();
|
||||
},
|
||||
onOpenChange(isOpen) {
|
||||
if (isOpen) {
|
||||
const data = drawerApi.getData<AgentApi.AgentProductionConfigItem>();
|
||||
formApi.resetForm();
|
||||
if (data) {
|
||||
formData.value = data;
|
||||
id.value = data.id;
|
||||
formApi.setValues({
|
||||
...data,
|
||||
overpricing_ratio: data.overpricing_ratio * 100,
|
||||
});
|
||||
} else {
|
||||
id.value = undefined;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Drawer :title="drawerTitle">
|
||||
<Form />
|
||||
</Drawer>
|
||||
</template>
|
||||
74
apps/web-antd/src/views/agent/agent-reward/data.ts
Normal file
74
apps/web-antd/src/views/agent/agent-reward/data.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
|
||||
export function useRewardColumns(): VxeTableGridOptions['columns'] {
|
||||
return [
|
||||
{
|
||||
title: '代理ID',
|
||||
field: 'agent_id',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '奖励类型',
|
||||
field: 'type',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '奖励金额',
|
||||
field: 'amount',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }) => `¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
title: '关联订单',
|
||||
field: 'order_id',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
field: 'status',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
field: 'create_time',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '发放时间',
|
||||
field: 'pay_time',
|
||||
width: 180,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export function useRewardFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
fieldName: 'type',
|
||||
label: '奖励类型',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '注册奖励', value: 'register' },
|
||||
{ label: '首单奖励', value: 'first_order' },
|
||||
{ label: '升级奖励', value: 'level_up' },
|
||||
],
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldName: 'status',
|
||||
label: '状态',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '待发放', value: 'pending' },
|
||||
{ label: '已发放', value: 'paid' },
|
||||
{ label: '发放失败', value: 'failed' },
|
||||
],
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
64
apps/web-antd/src/views/agent/agent-reward/list.vue
Normal file
64
apps/web-antd/src/views/agent/agent-reward/list.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getAgentRewardList } from '#/api/agent';
|
||||
|
||||
import { useRewardColumns, useRewardFormSchema } from './data';
|
||||
|
||||
interface Props {
|
||||
agentId?: number;
|
||||
}
|
||||
|
||||
interface QueryParams {
|
||||
currentPage: number;
|
||||
pageSize: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const queryParams = computed(() => ({
|
||||
...(props.agentId ? { agent_id: props.agentId } : {}),
|
||||
}));
|
||||
|
||||
const [Grid] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
schema: useRewardFormSchema(),
|
||||
submitOnChange: true,
|
||||
},
|
||||
gridOptions: {
|
||||
columns: useRewardColumns(),
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({
|
||||
page,
|
||||
form,
|
||||
}: {
|
||||
form: Record<string, any>;
|
||||
page: QueryParams;
|
||||
}) => {
|
||||
return await getAgentRewardList({
|
||||
...queryParams.value,
|
||||
...form,
|
||||
page: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
});
|
||||
},
|
||||
},
|
||||
props: {
|
||||
result: 'items',
|
||||
total: 'total',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page :auto-content-height="!agentId">
|
||||
<Grid :table-title="agentId ? '奖励记录列表' : '所有奖励记录'" />
|
||||
</Page>
|
||||
</template>
|
||||
107
apps/web-antd/src/views/agent/agent-withdrawal/data.ts
Normal file
107
apps/web-antd/src/views/agent/agent-withdrawal/data.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
|
||||
type WithdrawalMethod = 'alipay' | 'bank' | 'wechat';
|
||||
type WithdrawalStatus = 'approved' | 'failed' | 'paid' | 'pending' | 'rejected';
|
||||
|
||||
export function useWithdrawalColumns(): VxeTableGridOptions['columns'] {
|
||||
return [
|
||||
{
|
||||
title: '代理ID',
|
||||
field: 'agent_id',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '提现金额',
|
||||
field: 'amount',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }) => `¥${cellValue.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
title: '提现方式',
|
||||
field: 'method',
|
||||
width: 120,
|
||||
formatter: ({ cellValue }: { cellValue: WithdrawalMethod }) => {
|
||||
const methodMap: Record<WithdrawalMethod, string> = {
|
||||
alipay: '支付宝',
|
||||
wechat: '微信',
|
||||
bank: '银行卡',
|
||||
};
|
||||
return methodMap[cellValue] || cellValue;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '收款账号',
|
||||
field: 'account',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
field: 'status',
|
||||
width: 100,
|
||||
formatter: ({ cellValue }: { cellValue: WithdrawalStatus }) => {
|
||||
const statusMap: Record<WithdrawalStatus, string> = {
|
||||
pending: '待审核',
|
||||
approved: '已通过',
|
||||
rejected: '已拒绝',
|
||||
paid: '已打款',
|
||||
failed: '打款失败',
|
||||
};
|
||||
return statusMap[cellValue] || cellValue;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '申请时间',
|
||||
field: 'create_time',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '审核时间',
|
||||
field: 'audit_time',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '打款时间',
|
||||
field: 'pay_time',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
field: 'remark',
|
||||
width: 200,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export function useWithdrawalFormSchema(): VbenFormSchema[] {
|
||||
return [
|
||||
{
|
||||
fieldName: 'method',
|
||||
label: '提现方式',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '支付宝', value: 'alipay' },
|
||||
{ label: '微信', value: 'wechat' },
|
||||
{ label: '银行卡', value: 'bank' },
|
||||
],
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldName: 'status',
|
||||
label: '状态',
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '待审核', value: 'pending' },
|
||||
{ label: '已通过', value: 'approved' },
|
||||
{ label: '已拒绝', value: 'rejected' },
|
||||
{ label: '已打款', value: 'paid' },
|
||||
{ label: '打款失败', value: 'failed' },
|
||||
],
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
64
apps/web-antd/src/views/agent/agent-withdrawal/list.vue
Normal file
64
apps/web-antd/src/views/agent/agent-withdrawal/list.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import { getAgentWithdrawalList } from '#/api/agent';
|
||||
|
||||
import { useWithdrawalColumns, useWithdrawalFormSchema } from './data';
|
||||
|
||||
interface Props {
|
||||
agentId?: number;
|
||||
}
|
||||
|
||||
interface QueryParams {
|
||||
currentPage: number;
|
||||
pageSize: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const queryParams = computed(() => ({
|
||||
...(props.agentId ? { agent_id: props.agentId } : {}),
|
||||
}));
|
||||
|
||||
const [Grid] = useVbenVxeGrid({
|
||||
formOptions: {
|
||||
schema: useWithdrawalFormSchema(),
|
||||
submitOnChange: true,
|
||||
},
|
||||
gridOptions: {
|
||||
columns: useWithdrawalColumns(),
|
||||
proxyConfig: {
|
||||
ajax: {
|
||||
query: async ({
|
||||
page,
|
||||
form,
|
||||
}: {
|
||||
page: QueryParams;
|
||||
form: Record<string, any>;
|
||||
}) => {
|
||||
return await getAgentWithdrawalList({
|
||||
...queryParams.value,
|
||||
...form,
|
||||
page: page.currentPage,
|
||||
pageSize: page.pageSize,
|
||||
});
|
||||
},
|
||||
},
|
||||
props: {
|
||||
result: 'items',
|
||||
total: 'total',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page :auto-content-height="!agentId">
|
||||
<Grid :table-title="agentId ? '提现记录列表' : '所有提现记录'" />
|
||||
</Page>
|
||||
</template>
|
||||
Reference in New Issue
Block a user