|
|
@@ -24,6 +24,12 @@ interface MinioUploaderProps {
|
|
|
buttonText?: string;
|
|
|
/** 自定义提示文本 */
|
|
|
tipText?: string;
|
|
|
+ /** 上传模式:拖放模式或传统模式 */
|
|
|
+ uploadMode?: 'dragdrop' | 'traditional';
|
|
|
+ /** 是否显示已上传文件列表 */
|
|
|
+ showUploadList?: boolean;
|
|
|
+ /** 已上传文件列表标题 */
|
|
|
+ uploadListTitle?: string;
|
|
|
/** 组件尺寸模式 */
|
|
|
size?: 'default' | 'compact' | 'minimal';
|
|
|
}
|
|
|
@@ -49,6 +55,9 @@ const MinioUploader: React.FC<MinioUploaderProps> = ({
|
|
|
onUploadError,
|
|
|
buttonText = '点击或拖拽上传文件',
|
|
|
tipText = '支持单文件或多文件上传,单个文件大小不超过500MB',
|
|
|
+ uploadMode = 'dragdrop',
|
|
|
+ showUploadList = true,
|
|
|
+ uploadListTitle = '上传进度',
|
|
|
size = 'default'
|
|
|
}) => {
|
|
|
const [fileList, setFileList] = useState<UploadFile[]>([]);
|
|
|
@@ -308,53 +317,88 @@ const MinioUploader: React.FC<MinioUploaderProps> = ({
|
|
|
|
|
|
return (
|
|
|
<div className={sizeConfig.spacing}>
|
|
|
- {/* 拖拽上传区域 */}
|
|
|
- <div
|
|
|
- className={`relative border-2 border-dashed rounded-lg transition-all ${
|
|
|
- dragActive
|
|
|
- ? 'border-primary bg-primary/5'
|
|
|
- : 'border-gray-300 hover:border-primary/50'
|
|
|
- } ${sizeConfig.container}`}
|
|
|
- onDragEnter={handleDrag}
|
|
|
- onDragLeave={handleDrag}
|
|
|
- onDragOver={handleDrag}
|
|
|
- onDrop={handleDrop}
|
|
|
- >
|
|
|
- <div className={`flex flex-col items-center justify-center ${sizeConfig.spacing}`}>
|
|
|
- <Upload className={`${sizeConfig.icon} ${dragActive ? 'text-primary' : 'text-gray-400'}`} />
|
|
|
- <div className="text-center">
|
|
|
- <p className={`${sizeConfig.title} font-medium`}>{buttonText}</p>
|
|
|
- {size !== 'minimal' && (
|
|
|
- <p className={`${sizeConfig.description} text-gray-500 mt-1`}>{tipText}</p>
|
|
|
- )}
|
|
|
+ {/* 上传区域 - 根据模式显示不同界面 */}
|
|
|
+ {uploadMode === 'dragdrop' ? (
|
|
|
+ <div
|
|
|
+ className={`relative border-2 border-dashed rounded-lg transition-all ${
|
|
|
+ dragActive
|
|
|
+ ? 'border-primary bg-primary/5'
|
|
|
+ : 'border-gray-300 hover:border-primary/50'
|
|
|
+ } ${sizeConfig.container}`}
|
|
|
+ onDragEnter={handleDrag}
|
|
|
+ onDragLeave={handleDrag}
|
|
|
+ onDragOver={handleDrag}
|
|
|
+ onDrop={handleDrop}
|
|
|
+ >
|
|
|
+ <div className={`flex flex-col items-center justify-center ${sizeConfig.spacing}`}>
|
|
|
+ <Upload className={`${sizeConfig.icon} ${dragActive ? 'text-primary' : 'text-gray-400'}`} />
|
|
|
+ <div className="text-center">
|
|
|
+ <p className={`${sizeConfig.title} font-medium`}>{buttonText}</p>
|
|
|
+ {size !== 'minimal' && (
|
|
|
+ <p className={`${sizeConfig.description} text-gray-500 mt-1`}>{tipText}</p>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ <Button
|
|
|
+ type="button"
|
|
|
+ variant="outline"
|
|
|
+ size={size === 'minimal' ? 'sm' : size === 'compact' ? 'sm' : 'default'}
|
|
|
+ onClick={() => {
|
|
|
+ const input = document.createElement('input');
|
|
|
+ input.type = 'file';
|
|
|
+ input.accept = accept || '';
|
|
|
+ input.multiple = multiple;
|
|
|
+ input.onchange = (e) => {
|
|
|
+ const files = (e.target as HTMLInputElement).files;
|
|
|
+ if (files) handleFileSelect(files);
|
|
|
+ };
|
|
|
+ input.click();
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Upload className="h-4 w-4 mr-2" />
|
|
|
+ 选择文件
|
|
|
+ </Button>
|
|
|
</div>
|
|
|
- <Button
|
|
|
- type="button"
|
|
|
- variant="outline"
|
|
|
- size={size === 'minimal' ? 'sm' : size === 'compact' ? 'sm' : 'default'}
|
|
|
- onClick={() => {
|
|
|
- const input = document.createElement('input');
|
|
|
- input.type = 'file';
|
|
|
- input.accept = accept || '';
|
|
|
- input.multiple = multiple;
|
|
|
- input.onchange = (e) => {
|
|
|
- const files = (e.target as HTMLInputElement).files;
|
|
|
- if (files) handleFileSelect(files);
|
|
|
- };
|
|
|
- input.click();
|
|
|
- }}
|
|
|
- >
|
|
|
- <Upload className="h-4 w-4 mr-2" />
|
|
|
- 选择文件
|
|
|
- </Button>
|
|
|
</div>
|
|
|
- </div>
|
|
|
+ ) : (
|
|
|
+ <Card>
|
|
|
+ <CardContent className={sizeConfig.cardPadding}>
|
|
|
+ <div className={`flex flex-col items-center justify-center ${sizeConfig.spacing}`}>
|
|
|
+ <Upload className={`${sizeConfig.icon} text-gray-400`} />
|
|
|
+ <div className="text-center">
|
|
|
+ <p className={`${sizeConfig.title} font-medium`}>{buttonText}</p>
|
|
|
+ {size !== 'minimal' && (
|
|
|
+ <p className={`${sizeConfig.description} text-gray-500 mt-1`}>{tipText}</p>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ <Button
|
|
|
+ type="button"
|
|
|
+ variant="outline"
|
|
|
+ size={size === 'minimal' ? 'sm' : size === 'compact' ? 'sm' : 'default'}
|
|
|
+ onClick={() => {
|
|
|
+ const input = document.createElement('input');
|
|
|
+ input.type = 'file';
|
|
|
+ input.accept = accept || '';
|
|
|
+ input.multiple = multiple;
|
|
|
+ input.onchange = (e) => {
|
|
|
+ const files = (e.target as HTMLInputElement).files;
|
|
|
+ if (files) handleFileSelect(files);
|
|
|
+ };
|
|
|
+ input.click();
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Upload className="h-4 w-4 mr-2" />
|
|
|
+ 选择文件
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </CardContent>
|
|
|
+ </Card>
|
|
|
+ )}
|
|
|
|
|
|
{/* 上传进度列表 */}
|
|
|
- {fileList.length > 0 && (
|
|
|
+ {showUploadList && fileList.length > 0 && (
|
|
|
<Card>
|
|
|
<CardContent className={sizeConfig.cardPadding}>
|
|
|
- <h3 className={`${sizeConfig.title} font-semibold mb-3`}>上传进度</h3>
|
|
|
+ <h3 className={`${sizeConfig.title} font-semibold mb-3`}>{uploadListTitle}</h3>
|
|
|
<div className={sizeConfig.fileList}>
|
|
|
{fileList.map(item => (
|
|
|
<div key={item.uid} className={`flex items-center space-x-3 p-3 border rounded-lg ${size === 'minimal' ? 'text-sm' : ''}`}>
|