feat: 添加提现管理功能,整合提现页面及相关路由,支持提现请求的审核与管理
This commit is contained in:
@@ -231,7 +231,8 @@ const local: App.I18n.Schema = {
|
|||||||
home: 'Home',
|
home: 'Home',
|
||||||
product: 'Product',
|
product: 'Product',
|
||||||
user: ' User',
|
user: ' User',
|
||||||
news: 'News'
|
news: 'News',
|
||||||
|
withdraw: 'Withdraw'
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
login: {
|
login: {
|
||||||
|
|||||||
@@ -227,7 +227,8 @@ const local: App.I18n.Schema = {
|
|||||||
home: '首页',
|
home: '首页',
|
||||||
product: '产品管理',
|
product: '产品管理',
|
||||||
user: '用户管理',
|
user: '用户管理',
|
||||||
news: '新闻管理'
|
news: '新闻管理',
|
||||||
|
withdraw: '提现管理'
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
login: {
|
login: {
|
||||||
|
|||||||
@@ -24,4 +24,5 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
|
|||||||
news: () => import("@/views/news/index.vue"),
|
news: () => import("@/views/news/index.vue"),
|
||||||
product: () => import("@/views/product/index.vue"),
|
product: () => import("@/views/product/index.vue"),
|
||||||
user: () => import("@/views/user/index.vue"),
|
user: () => import("@/views/user/index.vue"),
|
||||||
|
withdraw: () => import("@/views/withdraw/index.vue"),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -99,5 +99,14 @@ export const generatedRoutes: GeneratedRoute[] = [
|
|||||||
title: 'user',
|
title: 'user',
|
||||||
i18nKey: 'route.user'
|
i18nKey: 'route.user'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'withdraw',
|
||||||
|
path: '/withdraw',
|
||||||
|
component: 'layout.base$view.withdraw',
|
||||||
|
meta: {
|
||||||
|
title: 'withdraw',
|
||||||
|
i18nKey: 'route.withdraw'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -171,7 +171,8 @@ const routeMap: RouteMap = {
|
|||||||
"login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?",
|
"login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?",
|
||||||
"news": "/news",
|
"news": "/news",
|
||||||
"product": "/product",
|
"product": "/product",
|
||||||
"user": "/user"
|
"user": "/user",
|
||||||
|
"withdraw": "/withdraw"
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
3
src/typings/elegant-router.d.ts
vendored
3
src/typings/elegant-router.d.ts
vendored
@@ -26,6 +26,7 @@ declare module "@elegant-router/types" {
|
|||||||
"news": "/news";
|
"news": "/news";
|
||||||
"product": "/product";
|
"product": "/product";
|
||||||
"user": "/user";
|
"user": "/user";
|
||||||
|
"withdraw": "/withdraw";
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,6 +67,7 @@ declare module "@elegant-router/types" {
|
|||||||
| "news"
|
| "news"
|
||||||
| "product"
|
| "product"
|
||||||
| "user"
|
| "user"
|
||||||
|
| "withdraw"
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,6 +93,7 @@ declare module "@elegant-router/types" {
|
|||||||
| "news"
|
| "news"
|
||||||
| "product"
|
| "product"
|
||||||
| "user"
|
| "user"
|
||||||
|
| "withdraw"
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,154 +1,17 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useTemplateRef } from 'vue';
|
import WithdrawPage from '@/views/withdraw/index.vue';
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import { client, safeClient } from '@/service/api';
|
|
||||||
import type { TableBaseColumns, TableFetchData, TableInst } from '@/components/table';
|
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'WithdrawDialog'
|
name: 'WithdrawDialog'
|
||||||
});
|
});
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
userId: string;
|
userId?: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
enum WithdrawStatus {
|
|
||||||
pending_review = '审核中',
|
|
||||||
pending_payout = '待打款',
|
|
||||||
completed = '已完成',
|
|
||||||
rejected = '已拒绝'
|
|
||||||
}
|
|
||||||
|
|
||||||
const tableInst = useTemplateRef<TableInst>('tableInst');
|
|
||||||
|
|
||||||
const fetchData: TableFetchData = ({ pagination, filter }) => {
|
|
||||||
return safeClient(() => client.api.admin.withdraw.get({ query: { userId: props.userId, ...pagination, ...filter } }));
|
|
||||||
};
|
|
||||||
|
|
||||||
const columns: TableBaseColumns = [
|
|
||||||
{
|
|
||||||
key: 'walletTypeId',
|
|
||||||
title: '收款方式类型'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'orderNo',
|
|
||||||
title: '订单号'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'amount',
|
|
||||||
title: '金额(元)',
|
|
||||||
render: (row: any) => {
|
|
||||||
return Number(row.amount);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'receiptMethodId',
|
|
||||||
title: '收款方式ID'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'createdAt',
|
|
||||||
title: '创建时间',
|
|
||||||
render: (row: any) => {
|
|
||||||
return dayjs(row.createdAt).format('YYYY-MM-DD HH:mm');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'status',
|
|
||||||
title: '状态',
|
|
||||||
render: (row: any) => {
|
|
||||||
return WithdrawStatus[row.status];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'operations',
|
|
||||||
title: '操作',
|
|
||||||
width: 150,
|
|
||||||
fixed: 'right',
|
|
||||||
operations: (row: any) => [
|
|
||||||
{
|
|
||||||
contentText: '通过',
|
|
||||||
size: 'small',
|
|
||||||
ghost: true,
|
|
||||||
type: 'primary',
|
|
||||||
visible: row.status === 'pending_review',
|
|
||||||
onClick: async () => {
|
|
||||||
window.$dialog?.create({
|
|
||||||
title: '确认通过该提现请求吗?',
|
|
||||||
content: '通过后将无法撤销',
|
|
||||||
type: 'warning',
|
|
||||||
positiveText: '确认通过',
|
|
||||||
negativeText: '取消',
|
|
||||||
onPositiveClick: async () => {
|
|
||||||
await safeClient(() =>
|
|
||||||
client.api.admin.withdraw({ orderId: row.orderNo }).approve.post({
|
|
||||||
reviewNote: `管理员通过于 ${dayjs().format('YYYY-MM-DD HH:mm:ss')}`
|
|
||||||
})
|
|
||||||
);
|
|
||||||
window.$message?.success('操作成功');
|
|
||||||
tableInst.value?.reload();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
contentText: '拒绝',
|
|
||||||
size: 'small',
|
|
||||||
ghost: true,
|
|
||||||
type: 'error',
|
|
||||||
visible: row.status === 'pending_review',
|
|
||||||
onClick: async () => {
|
|
||||||
window.$dialog?.create({
|
|
||||||
title: '确认拒绝该提现请求吗?',
|
|
||||||
content: '拒绝后将无法撤销',
|
|
||||||
type: 'warning',
|
|
||||||
positiveText: '确认拒绝',
|
|
||||||
negativeText: '取消',
|
|
||||||
onPositiveClick: async () => {
|
|
||||||
await safeClient(() =>
|
|
||||||
client.api.admin.withdraw({ orderId: row.orderNo }).reject.post({
|
|
||||||
rejectReason: `管理员拒绝于 ${dayjs().format('YYYY-MM-DD HH:mm:ss')}`
|
|
||||||
})
|
|
||||||
);
|
|
||||||
window.$message?.success('操作成功');
|
|
||||||
tableInst.value?.reload();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
contentText: '已打款',
|
|
||||||
size: 'small',
|
|
||||||
ghost: true,
|
|
||||||
type: 'success',
|
|
||||||
visible: row.status === 'pending_payout',
|
|
||||||
onClick: async () => {
|
|
||||||
window.$dialog?.create({
|
|
||||||
title: '确认已打款该提现请求吗?',
|
|
||||||
content: '确认后将无法撤销',
|
|
||||||
type: 'warning',
|
|
||||||
positiveText: '确认已打款',
|
|
||||||
negativeText: '取消',
|
|
||||||
onPositiveClick: async () => {
|
|
||||||
await safeClient(() => client.api.admin.withdraw({ orderId: row.orderNo }).paid.post());
|
|
||||||
window.$message?.success('操作成功');
|
|
||||||
tableInst.value?.reload();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<TableBase
|
<WithdrawPage :user-id="userId" :scroll-x="800" :show-header-operation="false" />
|
||||||
ref="tableInst"
|
|
||||||
:fetch-data="fetchData"
|
|
||||||
:columns="columns"
|
|
||||||
:scroll-x="800"
|
|
||||||
:show-header-operation="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="css" scoped></style>
|
<style lang="css" scoped></style>
|
||||||
|
|||||||
186
src/views/withdraw/index.vue
Normal file
186
src/views/withdraw/index.vue
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useTemplateRef } from 'vue';
|
||||||
|
import { NSelect } from 'naive-ui';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { client, safeClient } from '@/service/api';
|
||||||
|
import type { TableBaseColumns, TableFetchData, TableFilterColumns, TableInst } from '@/components/table';
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'WithdrawPage'
|
||||||
|
});
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
userId?: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
enum WithdrawStatus {
|
||||||
|
pending_review = '审核中',
|
||||||
|
pending_payout = '待打款',
|
||||||
|
completed = '已完成',
|
||||||
|
rejected = '已拒绝'
|
||||||
|
}
|
||||||
|
|
||||||
|
const tableInst = useTemplateRef<TableInst>('tableInst');
|
||||||
|
|
||||||
|
const fetchData: TableFetchData = ({ pagination, filter }) => {
|
||||||
|
return safeClient(() => client.api.admin.withdraw.get({ query: { userId: props.userId, ...pagination, ...filter } }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns: TableBaseColumns = [
|
||||||
|
{
|
||||||
|
key: 'walletTypeId',
|
||||||
|
title: '收款方式类型'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'orderNo',
|
||||||
|
title: '订单号'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'amount',
|
||||||
|
title: '金额(元)',
|
||||||
|
render: (row: any) => {
|
||||||
|
return Number(row.amount);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'receiptMethodId',
|
||||||
|
title: '收款方式ID'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'createdAt',
|
||||||
|
title: '创建时间',
|
||||||
|
render: (row: any) => {
|
||||||
|
return dayjs(row.createdAt).format('YYYY-MM-DD HH:mm');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'status',
|
||||||
|
title: '状态',
|
||||||
|
render: (row: any) => {
|
||||||
|
return WithdrawStatus[row.status];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'operations',
|
||||||
|
title: '操作',
|
||||||
|
width: 150,
|
||||||
|
fixed: 'right',
|
||||||
|
operations: (row: any) => [
|
||||||
|
{
|
||||||
|
contentText: '通过',
|
||||||
|
size: 'small',
|
||||||
|
ghost: true,
|
||||||
|
type: 'primary',
|
||||||
|
visible: row.status === 'pending_review',
|
||||||
|
onClick: async () => {
|
||||||
|
window.$dialog?.create({
|
||||||
|
title: '确认通过该提现请求吗?',
|
||||||
|
content: '通过后将无法撤销',
|
||||||
|
type: 'warning',
|
||||||
|
positiveText: '确认通过',
|
||||||
|
negativeText: '取消',
|
||||||
|
onPositiveClick: async () => {
|
||||||
|
await safeClient(() =>
|
||||||
|
client.api.admin.withdraw({ orderId: row.orderNo }).approve.post({
|
||||||
|
reviewNote: `管理员通过于 ${dayjs().format('YYYY-MM-DD HH:mm:ss')}`
|
||||||
|
})
|
||||||
|
);
|
||||||
|
window.$message?.success('操作成功');
|
||||||
|
tableInst.value?.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contentText: '拒绝',
|
||||||
|
size: 'small',
|
||||||
|
ghost: true,
|
||||||
|
type: 'error',
|
||||||
|
visible: row.status === 'pending_review',
|
||||||
|
onClick: async () => {
|
||||||
|
window.$dialog?.create({
|
||||||
|
title: '确认拒绝该提现请求吗?',
|
||||||
|
content: '拒绝后将无法撤销',
|
||||||
|
type: 'warning',
|
||||||
|
positiveText: '确认拒绝',
|
||||||
|
negativeText: '取消',
|
||||||
|
onPositiveClick: async () => {
|
||||||
|
await safeClient(() =>
|
||||||
|
client.api.admin.withdraw({ orderId: row.orderNo }).reject.post({
|
||||||
|
rejectReason: `管理员拒绝于 ${dayjs().format('YYYY-MM-DD HH:mm:ss')}`
|
||||||
|
})
|
||||||
|
);
|
||||||
|
window.$message?.success('操作成功');
|
||||||
|
tableInst.value?.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contentText: '已打款',
|
||||||
|
size: 'small',
|
||||||
|
ghost: true,
|
||||||
|
type: 'success',
|
||||||
|
visible: row.status === 'pending_payout',
|
||||||
|
onClick: async () => {
|
||||||
|
window.$dialog?.create({
|
||||||
|
title: '确认已打款该提现请求吗?',
|
||||||
|
content: '确认后将无法撤销',
|
||||||
|
type: 'warning',
|
||||||
|
positiveText: '确认已打款',
|
||||||
|
negativeText: '取消',
|
||||||
|
onPositiveClick: async () => {
|
||||||
|
await safeClient(() => client.api.admin.withdraw({ orderId: row.orderNo }).paid.post());
|
||||||
|
window.$message?.success('操作成功');
|
||||||
|
tableInst.value?.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const filterColumns: TableFilterColumns = [
|
||||||
|
{
|
||||||
|
key: 'uid',
|
||||||
|
title: '用户UID'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'orderNo',
|
||||||
|
title: '订单号'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'status',
|
||||||
|
title: '状态',
|
||||||
|
component: NSelect,
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ label: '审核中', value: 'pending_review' },
|
||||||
|
{ label: '待打款', value: 'pending_payout' },
|
||||||
|
{ label: '已完成', value: 'completed' },
|
||||||
|
{ label: '已拒绝', value: 'rejected' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<TableBase
|
||||||
|
ref="tableInst"
|
||||||
|
:fetch-data="fetchData"
|
||||||
|
:columns="columns"
|
||||||
|
:filter-columns="filterColumns"
|
||||||
|
:scroll-x="1000"
|
||||||
|
:show-header-operation="true"
|
||||||
|
:header-operations="{
|
||||||
|
add: false,
|
||||||
|
refresh: true,
|
||||||
|
columns: true
|
||||||
|
}"
|
||||||
|
v-bind="{ ...$attrs }"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped></style>
|
||||||
Reference in New Issue
Block a user