kra/web/src/components/Upload/CommonUpload.tsx

104 lines
2.6 KiB
TypeScript

/**
* KRA - Common Upload Component
* Basic file upload with progress and drag-drop support
*/
import React, { useState } from 'react';
import { Upload, Button, message } from 'antd';
import { UploadOutlined, InboxOutlined } from '@ant-design/icons';
import type { UploadProps, UploadFile } from 'antd';
import { getToken } from '@/utils/auth';
interface CommonUploadProps {
action?: string;
classId?: number;
accept?: string;
maxSize?: number; // MB
multiple?: boolean;
drag?: boolean;
showFileList?: boolean;
onSuccess?: (url: string, file: UploadFile) => void;
onError?: (error: Error) => void;
children?: React.ReactNode;
}
const CommonUpload: React.FC<CommonUploadProps> = ({
action = '/api/fileUploadAndDownload/upload',
classId = 0,
accept,
maxSize = 5,
multiple = true,
drag = false,
showFileList = false,
onSuccess,
onError,
children,
}) => {
const [loading, setLoading] = useState(false);
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
const isLtMaxSize = file.size / 1024 / 1024 < maxSize;
if (!isLtMaxSize) {
message.error(`文件大小不能超过 ${maxSize}MB`);
return false;
}
setLoading(true);
return true;
};
const handleChange: UploadProps['onChange'] = (info) => {
if (info.file.status === 'done') {
setLoading(false);
const { response } = info.file;
if (response?.code === 0 && response?.data?.file) {
message.success('上传成功');
onSuccess?.(response.data.file.url, info.file);
} else {
message.error(response?.msg || '上传失败');
}
} else if (info.file.status === 'error') {
setLoading(false);
message.error('上传失败');
onError?.(new Error('Upload failed'));
}
};
const uploadProps: UploadProps = {
action,
headers: { 'x-token': getToken() || '' },
data: { classId },
accept,
multiple,
showUploadList: showFileList,
beforeUpload,
onChange: handleChange,
};
if (drag) {
return (
<Upload.Dragger {...uploadProps}>
{children || (
<>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p className="ant-upload-text"></p>
<p className="ant-upload-hint"></p>
</>
)}
</Upload.Dragger>
);
}
return (
<Upload {...uploadProps}>
{children || (
<Button icon={<UploadOutlined />} loading={loading}>
</Button>
)}
</Upload>
);
};
export default CommonUpload;