pay-admin/src/common/components/layout/MyImportModal.tsx
2025-08-27 11:24:29 +08:00

108 lines
3.5 KiB
TypeScript

import { MyResponseType } from '@/common';
import { ImportOutlined, InboxOutlined } from '@ant-design/icons';
import { Button, Flex, Modal, Upload, message } from 'antd';
import { useState } from 'react';
type MyImportModalType = {
title?: string;
type?: any;
params?: Record<string, any>;
templateApi?: () => Promise<MyResponseType>;
importApi: (data: any) => Promise<MyResponseType>;
reload?: () => void;
};
export function MyImportModal(props: MyImportModalType) {
const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false);
const [formData, setFormData] = useState<FormData | undefined>(undefined);
const { title = '批量导入', params = {}, type = 'primary' } = props;
return (
<>
{type === 'danger' ? (
<Button onClick={() => setOpen(true)} type="primary" danger>
<ImportOutlined />
{title}
</Button>
) : (
<Button onClick={() => setOpen(true)} type="primary">
<ImportOutlined />
{title}
</Button>
)}
<Modal
title={title}
open={open}
onCancel={() => setOpen(false)}
onOk={() => {
if (!formData) return;
setLoading(true);
props
?.importApi(formData)
.then(() => {
message.success('导入操作成功');
setLoading(false);
setOpen(false);
props.reload?.();
return true;
})
.catch(() => {
setLoading(false);
});
}}
confirmLoading={loading}
// 使用 destroyOnClose 已弃用,建议使用 afterClose 处理清理逻辑
afterClose={() => {
setFormData(undefined);
}}
maskClosable={false}
footer={(dom) => {
return (
<Flex style={{ width: '100%' }} justify="space-between">
<Button onClick={() => props?.templateApi?.()}></Button>
<div>{dom}</div>
</Flex>
);
}}
>
<Upload.Dragger
accept=".xls,.xlsx,text/csv,.csv,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
maxCount={1}
beforeUpload={(file) => {
const isExcelFile =
file.type === 'application/vnd.ms-excel' ||
file.type ===
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
const isCSVFile = file.type === 'text/csv';
if (!isExcelFile && !isCSVFile) {
message.error(`${file.name} is not an Excel or CSV file`);
return Upload.LIST_IGNORE;
}
return true;
}}
customRequest={({ file }) => {
const formData = new FormData();
formData.append('upload_file', file);
Object.entries(params).forEach(([key, value]) => {
formData.append(key, value);
});
setFormData(formData);
console.log('formData', formData, file);
}}
>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p className="ant-upload-text"></p>
<p className="ant-upload-hint">
</p>
</Upload.Dragger>
</Modal>
</>
);
}