feat: 添加收款方式和提现订单功能,整合支付和提现组件至用户界面

This commit is contained in:
2026-01-19 18:56:12 +07:00
parent 1f4acce75a
commit 53b7f55eb7
3 changed files with 265 additions and 2 deletions

View File

@@ -0,0 +1,67 @@
<script lang="ts" setup>
import { useTemplateRef } from 'vue';
import { client, safeClient } from '@/service/api';
import type { TableBaseColumns, TableFetchData, TableInst } from '@/components/table';
defineOptions({
name: 'PaymentDialog'
});
const props = defineProps<{
userId: string;
}>();
const tableInst = useTemplateRef<TableInst>('tableInst');
const fetchData: TableFetchData = ({ pagination, filter }) => {
return safeClient(() =>
client.api.admin.receipt_method.get({ query: { userId: props.userId, ...pagination, ...filter } })
);
};
const columns: TableBaseColumns = [
{
key: 'type',
title: '收款方式类型',
render: row => {
return row.type === 'bank_card' ? '银行卡' : '支付宝';
}
},
{
key: 'fullName',
title: '收款人姓名'
},
{
key: 'bankName',
title: '银行名称'
},
{
key: 'bankCardNumber',
title: '银行卡号'
},
{
key: 'bankBranchName',
title: '支行名称'
},
{
key: 'alipayName',
title: '支付宝名称'
},
{
key: 'alipayAccount',
title: '支付宝账号'
}
];
</script>
<template>
<TableBase
ref="tableInst"
:fetch-data="fetchData"
:columns="columns"
:scroll-x="800"
:show-header-operation="false"
/>
</template>
<style lang="css" scoped></style>

View File

@@ -0,0 +1,154 @@
<script lang="ts" setup>
import { useTemplateRef } from 'vue';
import dayjs from 'dayjs';
import { client, safeClient } from '@/service/api';
import type { TableBaseColumns, TableFetchData, TableInst } from '@/components/table';
defineOptions({
name: 'WithdrawDialog'
});
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();
}
});
}
}
]
}
];
</script>
<template>
<TableBase
ref="tableInst"
:fetch-data="fetchData"
:columns="columns"
:scroll-x="800"
:show-header-operation="false"
/>
</template>
<style lang="css" scoped></style>

View File

@@ -3,9 +3,11 @@ import { h, useTemplateRef } from 'vue';
import { useDialog } from 'naive-ui'; import { useDialog } from 'naive-ui';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { client, safeClient } from '@/service/api'; import { client, safeClient } from '@/service/api';
import type { TableBaseColumns, TableFetchData, TableInst } from '@/components/table'; import type { TableBaseColumns, TableFetchData, TableFilterColumns, TableInst } from '@/components/table';
import Wallet from './components/wallet.vue'; import Wallet from './components/wallet.vue';
import Address from './components/address.vue'; import Address from './components/address.vue';
import Payment from './components/payment.vue';
import Withdraw from './components/withdraw.vue';
const dialog = useDialog(); const dialog = useDialog();
@@ -50,7 +52,7 @@ const columns: TableBaseColumns = [
{ {
key: 'operations', key: 'operations',
title: '操作', title: '操作',
width: 200, width: 300,
fixed: 'right', fixed: 'right',
operations: (row: any) => [ operations: (row: any) => [
{ {
@@ -76,10 +78,49 @@ const columns: TableBaseColumns = [
content: () => h(Address, { userId: row.userId }) content: () => h(Address, { userId: row.userId })
}); });
} }
},
{
contentText: '收款方式',
size: 'small',
onClick: () => {
dialog.create({
title: '收款方式',
showIcon: false,
style: { width: '1000px' },
content: () => h(Payment, { userId: row.userId })
});
}
},
{
contentText: '提现订单',
size: 'small',
onClick: () => {
dialog.create({
title: '提现订单',
showIcon: false,
style: { width: '1000px' },
content: () => h(Withdraw, { userId: row.userId })
});
}
} }
] ]
} }
]; ];
const filterColumns: TableFilterColumns = [
{
key: 'uid',
title: 'UID'
},
{
key: 'username',
title: '手机号'
},
{
key: 'name',
title: '姓名'
}
];
</script> </script>
<template> <template>
@@ -87,6 +128,7 @@ const columns: TableBaseColumns = [
ref="tableInst" ref="tableInst"
:fetch-data="fetchData" :fetch-data="fetchData"
:columns="columns" :columns="columns"
:filter-columns="filterColumns"
:scroll-x="800" :scroll-x="800"
:header-operations="{ :header-operations="{
add: false, add: false,