279 lines
6.8 KiB
Vue
279 lines
6.8 KiB
Vue
<script lang="ts" setup>
|
||
import { computed, ref } from 'vue';
|
||
|
||
import { useVbenDrawer } from '@vben/common-ui';
|
||
|
||
import { message } from 'ant-design-vue';
|
||
|
||
import { useVbenForm } from '#/adapter/form';
|
||
import { reviewBankCardWithdrawal } from '#/api/agent';
|
||
import type { VbenFormSchema } from '#/adapter/form';
|
||
|
||
const emit = defineEmits<{
|
||
(e: 'success'): void;
|
||
}>();
|
||
|
||
const formData = ref<any>(null);
|
||
|
||
// 表单配置(包含所有字段)
|
||
const getFormSchema = (): VbenFormSchema[] => [
|
||
{
|
||
component: 'Input',
|
||
fieldName: 'withdraw_no',
|
||
label: '提现单号',
|
||
componentProps: {
|
||
disabled: true,
|
||
},
|
||
},
|
||
{
|
||
component: 'Input',
|
||
fieldName: 'withdraw_type',
|
||
label: '提现类型',
|
||
componentProps: {
|
||
disabled: true,
|
||
},
|
||
},
|
||
{
|
||
component: 'InputNumber',
|
||
fieldName: 'amount',
|
||
label: '提现金额',
|
||
componentProps: {
|
||
disabled: true,
|
||
min: 0,
|
||
precision: 2,
|
||
style: { width: '100%' },
|
||
addonBefore: '¥',
|
||
},
|
||
},
|
||
// 银行卡和支付宝通用字段:扣税金额
|
||
{
|
||
component: 'InputNumber' ,
|
||
fieldName: 'tax_amount',
|
||
label: '扣税金额',
|
||
componentProps: {
|
||
disabled: true,
|
||
min: 0,
|
||
precision: 2,
|
||
style: { width: '100%' },
|
||
addonBefore: '¥',
|
||
},
|
||
},
|
||
// 银行卡和支付宝通用字段:实际转账金额
|
||
{
|
||
component: 'InputNumber',
|
||
fieldName: 'actual_amount',
|
||
label: '实际转账金额',
|
||
componentProps: {
|
||
disabled: true,
|
||
min: 0,
|
||
precision: 2,
|
||
style: { width: '100%' },
|
||
addonBefore: '¥',
|
||
},
|
||
},
|
||
// 银行卡和支付宝都有:收款账号
|
||
{
|
||
component: 'Input',
|
||
fieldName: 'payee_account',
|
||
label: '收款账号',
|
||
componentProps: {
|
||
disabled: true,
|
||
},
|
||
},
|
||
// 银行卡提现特有字段:开户支行
|
||
{
|
||
component: 'Input',
|
||
fieldName: 'bank_name',
|
||
label: '开户支行',
|
||
componentProps: {
|
||
disabled: true,
|
||
},
|
||
dependencies: {
|
||
show: (values) => values.withdraw_type === '银行卡',
|
||
triggerFields: ['withdraw_type'],
|
||
},
|
||
},
|
||
// 银行卡提现特有字段:收款人姓名
|
||
{
|
||
component: 'Input',
|
||
fieldName: 'payee_name',
|
||
label: '收款人姓名',
|
||
componentProps: {
|
||
disabled: true,
|
||
},
|
||
dependencies: {
|
||
show: (values) => values.withdraw_type === '银行卡',
|
||
triggerFields: ['withdraw_type'],
|
||
},
|
||
},
|
||
{
|
||
component: 'RadioGroup',
|
||
fieldName: 'action',
|
||
label: '审核操作',
|
||
defaultValue: 1,
|
||
componentProps: {
|
||
options: [
|
||
{ label: '确认提现', value: 1 },
|
||
{ label: '拒绝提现', value: 2 },
|
||
],
|
||
},
|
||
rules: 'required',
|
||
},
|
||
// 确认时可编辑扣税比例,默认 6%
|
||
{
|
||
component: 'InputNumber',
|
||
fieldName: 'tax_rate_percent',
|
||
label: '扣税比例(%)',
|
||
defaultValue: 6,
|
||
componentProps: {
|
||
min: 0,
|
||
max: 100,
|
||
step: 0.5,
|
||
precision: 1,
|
||
style: { width: '100%' },
|
||
addonAfter: '%',
|
||
placeholder: '默认 6',
|
||
},
|
||
dependencies: {
|
||
show: (values) => values.action === 1,
|
||
triggerFields: ['action'],
|
||
},
|
||
},
|
||
{
|
||
component: 'Textarea',
|
||
fieldName: 'remark',
|
||
label: '备注',
|
||
componentProps: {
|
||
rows: 4,
|
||
placeholder: '拒绝提现时,请填写拒绝原因',
|
||
maxLength: 200,
|
||
showCount: true,
|
||
style: { width: '100%' },
|
||
},
|
||
},
|
||
];
|
||
|
||
const [Form, formApi] = useVbenForm({
|
||
schema: getFormSchema(),
|
||
showDefaultActions: false,
|
||
wrapperClass: 'agent-withdrawal-form-wrapper',
|
||
});
|
||
|
||
const [Drawer, drawerApi] = useVbenDrawer({
|
||
class: 'agent-withdrawal-review-drawer',
|
||
async onConfirm() {
|
||
const { valid } = await formApi.validate();
|
||
if (!valid) return;
|
||
|
||
if (!formData.value?.id) {
|
||
message.error('提现记录ID不存在');
|
||
return;
|
||
}
|
||
|
||
const values = await formApi.getValues<{
|
||
action: 1 | 2;
|
||
remark: string;
|
||
tax_rate_percent?: number;
|
||
}>();
|
||
|
||
// 验证拒绝时必须填写原因
|
||
if (values.action === 2 && !values.remark?.trim()) {
|
||
message.error('拒绝提现必须填写拒绝原因');
|
||
return;
|
||
}
|
||
|
||
// 确认时:扣税比例(%)转成小数,如 6 -> 0.06,不传则默认 6%
|
||
const taxRate =
|
||
values.action === 1 && values.tax_rate_percent != null
|
||
? Number(values.tax_rate_percent) / 100
|
||
: undefined;
|
||
|
||
try {
|
||
await reviewBankCardWithdrawal({
|
||
action: values.action,
|
||
remark: values.remark || '',
|
||
withdrawal_id: formData.value.id,
|
||
...(taxRate != null && { tax_rate: taxRate }),
|
||
});
|
||
message.success(values.action === 1 ? '确认提现成功' : '拒绝提现成功');
|
||
drawerApi.close();
|
||
emit('success');
|
||
} catch (error: any) {
|
||
message.error(error?.message || '操作失败');
|
||
}
|
||
},
|
||
onOpenChange(isOpen) {
|
||
if (isOpen) {
|
||
const data = drawerApi.getData<any>();
|
||
formApi.resetForm();
|
||
if (data) {
|
||
formData.value = data;
|
||
|
||
// 根据提现类型设置不同的表单初始值
|
||
const typeMap: Record<number, string> = {
|
||
1: '支付宝',
|
||
2: '银行卡',
|
||
};
|
||
const initialValues: any = {
|
||
withdraw_no: data.withdraw_no || '',
|
||
withdraw_type: typeMap[data.withdraw_type] || '未知',
|
||
amount: data.amount || 0,
|
||
action: 1, // 默认选择确认
|
||
tax_rate_percent: 6, // 扣税比例默认 6%
|
||
remark: '',
|
||
};
|
||
|
||
// 银行卡提现特有字段
|
||
if (data.withdraw_type === 2) {
|
||
initialValues.tax_amount = data.tax_amount || 0;
|
||
initialValues.actual_amount = data.actual_amount || 0;
|
||
initialValues.payee_account = data.bank_card_no || '';
|
||
initialValues.bank_name = data.bank_name || '';
|
||
initialValues.payee_name = data.payee_name || '';
|
||
} else {
|
||
// 支付宝提现
|
||
initialValues.tax_amount = data.tax_amount || 0;
|
||
initialValues.actual_amount = data.actual_amount || 0;
|
||
initialValues.payee_account = data.payee_account || '';
|
||
}
|
||
|
||
formApi.setValues(initialValues);
|
||
}
|
||
}
|
||
},
|
||
});
|
||
|
||
const getDrawerTitle = computed(() => {
|
||
const typeMap: Record<number, string> = {
|
||
1: '支付宝',
|
||
2: '银行卡',
|
||
};
|
||
const typeName = typeMap[formData.value?.withdraw_type] || '未知';
|
||
return `${typeName}提现审核 ${formData.value?.withdraw_no || ''}`;
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<Drawer :title="getDrawerTitle" :width="800">
|
||
<div class="agent-withdrawal-review-content">
|
||
<Form />
|
||
</div>
|
||
</Drawer>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.agent-withdrawal-review-content {
|
||
padding: 0 4px;
|
||
max-height: calc(100vh - 120px);
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.agent-withdrawal-review-content :deep(.ant-form-item) {
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.agent-withdrawal-review-content :deep(.ant-form-item-label) {
|
||
padding-bottom: 4px;
|
||
}
|
||
</style>
|