Files
mp-10584/src/views/shop/shopDealerWithdraw/index.vue
赵忠林 dde5f20402 feat(search): 添加搜索组件导出功能
- 在搜索组件中添加导出XLS按钮
- 集成xlsx库实现数据导出功能
- 添加货币格式化工具函数toMoney
- 添加状态转换工具函数toApplyStatus和toPayType
- 实现handleExport方法查询并导出数据为Excel文件
- 更新搜索表单参数配置添加分页限制
- 添加表格列配置设置最小宽度
- 修改状态标签显示文本将"用户取消"改为"已驳回"
- 添加applyStatus为50的已取消状态标签显示
2026-02-01 09:57:34 +08:00

461 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<a-page-header :title="getPageTitle()" @back="() => $router.go(-1)">
<a-card :bordered="false" :body-style="{ padding: '16px' }">
<ele-pro-table
ref="tableRef"
row-key="shopDealerWithdrawId"
:columns="columns"
:datasource="datasource"
:customRow="customRow"
tool-class="ele-toolbar-form"
class="sys-org-table"
>
<template #toolbar>
<search
@search="reload"
:selection="selection"
@add="openEdit"
@remove="removeBatch"
@batchMove="openMove"
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'applyStatus'">
<a-tag v-if="record.applyStatus === 10" color="orange"
>待审核</a-tag
>
<a-tag v-if="record.applyStatus === 20" color="success"
>审核通过</a-tag
>
<a-tag v-if="record.applyStatus === 30" color="error">已驳回</a-tag>
<a-tag v-if="record.applyStatus === 40">已打款</a-tag>
<a-tag v-if="record.applyStatus === 50" color="error">已取消</a-tag>
</template>
<template v-if="column.key === 'userInfo'">
<a-space>
<a-avatar :src="record.avatar" />
<div class="flex flex-col">
<div>
<span>{{ record.realName || '未实名认证' }}</span>
<span class="text-gray-400">ID{{ record.userId }}</span>
</div>
<div><span class="text-gray-400">{{ record.phone }}</span></div>
</div>
</a-space>
</template>
<template v-if="column.key === 'paymentInfo'">
<template v-if="record.payType === 10">
<a-space direction="vertical">
<a-tag color="blue">商家转账</a-tag>
</a-space>
</template>
</template>
<template v-if="column.key === 'comments'">
<template v-if="record.applyStatus === 30">
<div class="text-red-500"
>驳回原因{{ record.rejectReason }}</div
>
</template>
<template v-if="record.applyStatus === 40 && record.image">
<a-image
v-for="(item, index) in JSON.parse(record.image)"
:key="index"
:src="item"
:width="50"
:height="50"
/>
</template>
</template>
<template v-if="column.key === 'createTime'">
<a-space direction="vertical">
<a-tooltip title="创建时间">{{ record.createTime }}</a-tooltip>
<a-tooltip title="审核/打款时间" class="text-green-500">{{
record.auditTime
}}</a-tooltip>
</a-space>
</template>
<template v-if="column.key === 'action'">
<template v-if="record.applyStatus !== 40">
<a @click="openEdit(record)" class="ele-text-primary">
<EditOutlined />
编辑
</a>
<a-divider type="vertical" />
<a-popconfirm
title="确定要删除此提现记录吗?"
@confirm="remove(record)"
placement="topRight"
>
<a class="ele-text-danger">
<DeleteOutlined />
删除
</a>
</a-popconfirm>
</template>
</template>
</template>
</ele-pro-table>
</a-card>
<!-- 编辑弹窗 -->
<ShopDealerWithdrawEdit
v-model:visible="showEdit"
:data="current"
@done="reload"
/>
</a-page-header>
</template>
<script lang="ts" setup>
import { createVNode, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import {
ExclamationCircleOutlined,
CheckOutlined,
CloseOutlined,
DollarOutlined,
EditOutlined,
DeleteOutlined
} from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
} from 'ele-admin-pro/es/ele-pro-table/types';
import Search from './components/search.vue';
import { getPageTitle } from '@/utils/common';
import ShopDealerWithdrawEdit from './components/shopDealerWithdrawEdit.vue';
import {
pageShopDealerWithdraw,
removeShopDealerWithdraw,
removeBatchShopDealerWithdraw,
updateShopDealerWithdraw
} from '@/api/shop/shopDealerWithdraw';
import type {
ShopDealerWithdraw,
ShopDealerWithdrawParam
} from '@/api/shop/shopDealerWithdraw/model';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
// 表格选中数据
const selection = ref<ShopDealerWithdraw[]>([]);
// 当前编辑数据
const current = ref<ShopDealerWithdraw | null>(null);
// 是否显示编辑弹窗
const showEdit = ref(false);
// 是否显示批量移动弹窗
const showMove = ref(false);
// 加载状态
const loading = ref(true);
// 表格数据源
const datasource: DatasourceFunction = ({
page,
limit,
where,
orders,
filters
}) => {
if (filters) {
where.status = filters.status;
}
return pageShopDealerWithdraw({
...where,
...orders,
page,
limit
});
};
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: '订单号',
dataIndex: 'id',
key: 'id',
align: 'center',
width: 90,
fixed: 'left'
},
// {
// title: '用户ID',
// dataIndex: 'userId',
// key: 'userId',
// align: 'center',
// width: 90,
// fixed: 'left'
// },
{
title: '收款方式',
dataIndex: 'paymentInfo',
key: 'paymentInfo',
align: 'center',
width: 180
},
{
title: '用户信息',
dataIndex: 'userInfo',
key: 'userInfo'
},
{
title: '转账金额',
dataIndex: 'money',
key: 'money',
align: 'center',
customRender: ({ text }) => {
const amount = parseFloat(text || '0').toFixed(2);
return {
type: 'span',
children: `¥${amount}`
};
}
},
// {
// title: '审核时间',
// dataIndex: 'auditTime',
// key: 'auditTime',
// align: 'center',
// width: 120,
// customRender: ({ text }) => text ? toDateString(new Date(text), 'yyyy-MM-dd HH:mm') : '-'
// },
// {
// title: '驳回原因',
// dataIndex: 'rejectReason',
// key: 'rejectReason',
// align: 'left',
// ellipsis: true,
// customRender: ({ text }) => text || '-'
// },
// {
// title: '来源平台',
// dataIndex: 'platform',
// key: 'platform',
// align: 'center',
// width: 100,
// customRender: ({ text }) => text || '-'
// },
{
title: '备注',
dataIndex: 'comments',
key: 'comments'
},
{
title: '状态',
dataIndex: 'applyStatus',
key: 'applyStatus',
align: 'center',
width: 150
},
// {
// title: '驳回原因',
// dataIndex: 'rejectReason',
// key: 'rejectReason',
// align: 'center',
// },
// {
// title: '来源客户端',
// dataIndex: 'platform',
// key: 'platform',
// align: 'center',
// },
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
width: 180,
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd HH:mm:ss')
}
// {
// title: '操作',
// key: 'action',
// width: 180,
// fixed: 'right',
// align: 'center',
// hideInSetting: true
// }
]);
/* 搜索 */
const reload = (where?: ShopDealerWithdrawParam) => {
selection.value = [];
tableRef?.value?.reload({ where: where });
};
/* 审核通过 */
const approveWithdraw = (row: ShopDealerWithdraw) => {
Modal.confirm({
title: '审核通过确认',
content: `已核对信息进行核对,正确无误!`,
icon: createVNode(CheckOutlined),
okText: '确认通过',
okType: 'primary',
cancelText: '取消',
onOk: () => {
const hide = message.loading('正在处理审核...', 0);
// 这里需要调用审核通过的API
setTimeout(() => {
hide();
updateShopDealerWithdraw({
id: row.id,
applyStatus: 20
});
message.success('审核通过成功');
reload();
}, 1000);
}
});
};
/* 审核驳回 */
const rejectWithdraw = (row: ShopDealerWithdraw) => {
let rejectReason = '';
Modal.confirm({
title: '审核驳回',
content: createVNode('div', null, [
createVNode('p', null, `用户ID: ${row.userId}`),
createVNode(
'p',
null,
`提现金额: ¥${parseFloat(row.money || '0').toFixed(2)}`
),
createVNode('p', { style: 'margin-top: 12px;' }, '请输入驳回原因:'),
createVNode('textarea', {
placeholder: '请输入驳回原因...',
style:
'width: 100%; height: 80px; margin-top: 8px; padding: 8px; border: 1px solid #d9d9d9; border-radius: 4px;',
onInput: (e: any) => {
rejectReason = e.target.value;
}
})
]),
icon: createVNode(CloseOutlined),
okText: '确认驳回',
okType: 'danger',
cancelText: '取消',
onOk: () => {
if (!rejectReason.trim()) {
message.error('请输入驳回原因');
return Promise.reject();
}
const hide = message.loading('正在处理审核...', 0);
setTimeout(() => {
hide();
message.success('审核驳回成功');
reload();
}, 1000);
}
});
};
/* 确认打款 */
const confirmPayment = (row: ShopDealerWithdraw) => {
Modal.confirm({
title: '确认打款',
content: `确定已向用户${row.bankAccount}完成打款?此操作不可撤销`,
icon: createVNode(DollarOutlined),
okText: '确认打款',
okType: 'primary',
cancelText: '取消',
onOk: () => {
const hide = message.loading('正在确认打款...', 0);
setTimeout(() => {
updateShopDealerWithdraw({
id: row.id,
applyStatus: 40
});
hide();
message.success('打款确认成功');
reload();
}, 1000);
}
});
};
/* 打开编辑弹窗 */
const openEdit = (row?: ShopDealerWithdraw) => {
current.value = row ?? null;
showEdit.value = true;
};
/* 打开批量移动弹窗 */
const openMove = () => {
showMove.value = true;
};
/* 删除单个 */
const remove = (row: ShopDealerWithdraw) => {
const hide = message.loading('请求中..', 0);
removeShopDealerWithdraw(row.id)
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
};
/* 批量删除 */
const removeBatch = () => {
if (!selection.value.length) {
message.error('请至少选择一条数据');
return;
}
Modal.confirm({
title: '提示',
content: '确定要删除选中的记录吗?',
icon: createVNode(ExclamationCircleOutlined),
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchShopDealerWithdraw(selection.value.map((d) => d.id))
.then((msg) => {
hide();
message.success(msg);
reload();
})
.catch((e) => {
hide();
message.error(e.message);
});
}
});
};
/* 查询 */
const query = () => {
loading.value = true;
};
/* 自定义行属性 */
const customRow = (record: ShopDealerWithdraw) => {
return {
// 行点击事件
onClick: () => {
// console.log(record);
},
// 行双击事件
onDblclick: () => {
openEdit(record);
}
};
};
query();
</script>
<script lang="ts">
export default {
name: 'ShopDealerWithdraw'
};
</script>
<style lang="less" scoped></style>