Browse Source

✨ feat(uploader): 增强MinioUploader组件功能

- 添加上传模式选择,支持'dragdrop'(拖放)和'traditional'(传统)两种模式
- 新增上传文件列表控制选项,包括显示开关和自定义标题
- 为传统模式添加卡片式布局,优化不同模式的视觉体验
- 增加uploadMode、showUploadList和uploadListTitle三个新属性,提升组件灵活性
yourname 4 months ago
parent
commit
990631f70f
1 changed files with 85 additions and 41 deletions
  1. 85 41
      src/client/admin-shadcn/components/MinioUploader.tsx

+ 85 - 41
src/client/admin-shadcn/components/MinioUploader.tsx

@@ -24,6 +24,12 @@ interface MinioUploaderProps {
   buttonText?: string;
   buttonText?: string;
   /** 自定义提示文本 */
   /** 自定义提示文本 */
   tipText?: string;
   tipText?: string;
+  /** 上传模式:拖放模式或传统模式 */
+  uploadMode?: 'dragdrop' | 'traditional';
+  /** 是否显示已上传文件列表 */
+  showUploadList?: boolean;
+  /** 已上传文件列表标题 */
+  uploadListTitle?: string;
   /** 组件尺寸模式 */
   /** 组件尺寸模式 */
   size?: 'default' | 'compact' | 'minimal';
   size?: 'default' | 'compact' | 'minimal';
 }
 }
@@ -49,6 +55,9 @@ const MinioUploader: React.FC<MinioUploaderProps> = ({
   onUploadError,
   onUploadError,
   buttonText = '点击或拖拽上传文件',
   buttonText = '点击或拖拽上传文件',
   tipText = '支持单文件或多文件上传,单个文件大小不超过500MB',
   tipText = '支持单文件或多文件上传,单个文件大小不超过500MB',
+  uploadMode = 'dragdrop',
+  showUploadList = true,
+  uploadListTitle = '上传进度',
   size = 'default'
   size = 'default'
 }) => {
 }) => {
   const [fileList, setFileList] = useState<UploadFile[]>([]);
   const [fileList, setFileList] = useState<UploadFile[]>([]);
@@ -308,53 +317,88 @@ const MinioUploader: React.FC<MinioUploaderProps> = ({
 
 
   return (
   return (
     <div className={sizeConfig.spacing}>
     <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>
           </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>
-      </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>
         <Card>
           <CardContent className={sizeConfig.cardPadding}>
           <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}>
             <div className={sizeConfig.fileList}>
               {fileList.map(item => (
               {fileList.map(item => (
                 <div key={item.uid} className={`flex items-center space-x-3 p-3 border rounded-lg ${size === 'minimal' ? 'text-sm' : ''}`}>
                 <div key={item.uid} className={`flex items-center space-x-3 p-3 border rounded-lg ${size === 'minimal' ? 'text-sm' : ''}`}>