104 lines
2.6 KiB
TypeScript
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;
|