Kaynağa Gözat

✨ feat(files): 重构文件上传功能为对话框模式

- 将MinioUploader组件从页面直接显示改为通过对话框打开
- 添加上传按钮与Upload图标,点击打开上传对话框
- 上传成功后自动关闭对话框,提升用户体验

🐛 fix(upload): 移除文件上传成功/失败的重复提示

- 注释掉MinioUploader组件内部的toast提示,避免与页面提示重复
yourname 4 ay önce
ebeveyn
işleme
93fef395d0

+ 2 - 2
src/client/admin-shadcn/components/MinioUploader.tsx

@@ -136,7 +136,7 @@ const MinioUploader: React.FC<MinioUploaderProps> = ({
       return newSet;
     });
     
-    toast.success(`文件 "${file.name}" 上传成功`);
+    // toast.success(`文件 "${file.name}" 上传成功`);
     onUploadSuccess?.(result.fileKey, result.fileUrl, file);
   }, [onUploadSuccess]);
 
@@ -162,7 +162,7 @@ const MinioUploader: React.FC<MinioUploaderProps> = ({
       return newSet;
     });
     
-    toast.error(`文件 "${file.name}" 上传失败: ${error.message}`);
+    // toast.error(`文件 "${file.name}" 上传失败: ${error.message}`);
     onUploadError?.(error, file);
   }, [onUploadError]);
 

+ 40 - 13
src/client/admin-shadcn/pages/Files.tsx

@@ -11,7 +11,7 @@ import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
 import { useForm } from 'react-hook-form';
 import { zodResolver } from '@hookform/resolvers/zod';
 import { toast } from 'sonner';
-import { Eye, Download, Edit, Trash2, Search, FileText } from 'lucide-react';
+import { Eye, Download, Edit, Trash2, Search, FileText, Upload } from 'lucide-react';
 import { fileClient } from '@/client/api';
 import type { InferResponseType, InferRequestType } from 'hono/client';
 import dayjs from 'dayjs';
@@ -27,6 +27,7 @@ type FileFormData = z.infer<typeof UpdateFileDto>;
 
 export const FilesPage: React.FC = () => {
   const [isModalOpen, setIsModalOpen] = useState(false);
+  const [isUploadModalOpen, setIsUploadModalOpen] = useState(false);
   const [editingFile, setEditingFile] = useState<FileItem | null>(null);
   const [searchText, setSearchText] = useState('');
   const [pagination, setPagination] = useState({
@@ -188,19 +189,11 @@ export const FilesPage: React.FC = () => {
     <div className="p-6 space-y-6">
       <div className="flex justify-between items-center">
         <h1 className="text-3xl font-bold">文件管理</h1>
+        <Button onClick={() => setIsUploadModalOpen(true)}>
+          <Upload className="h-4 w-4 mr-2" />
+          上传文件
+        </Button>
       </div>
-
-      {/* MinioUploader 文件上传组件 */}
-      <MinioUploader
-        uploadPath="/files"
-        maxSize={500}
-        multiple={false}
-        onUploadSuccess={handleUploadSuccess}
-        onUploadError={handleUploadError}
-        buttonText="点击或拖拽上传文件"
-        tipText="支持单文件上传,单个文件大小不超过500MB"
-        size="minimal"
-      />
       
       <Card>
         <CardHeader>
@@ -353,6 +346,40 @@ export const FilesPage: React.FC = () => {
         </CardContent>
       </Card>
 
+      {/* 上传文件对话框 */}
+      <Dialog open={isUploadModalOpen} onOpenChange={setIsUploadModalOpen}>
+        <DialogContent className="sm:max-w-[600px]">
+          <DialogHeader>
+            <DialogTitle>上传文件</DialogTitle>
+            <DialogDescription>
+              选择要上传的文件,支持拖拽上传
+            </DialogDescription>
+          </DialogHeader>
+          
+          <div className="py-4">
+            <MinioUploader
+              uploadPath="/files"
+              maxSize={500}
+              multiple={false}
+              onUploadSuccess={(fileKey, fileUrl, file) => {
+                handleUploadSuccess(fileKey, fileUrl, file);
+                setIsUploadModalOpen(false);
+              }}
+              onUploadError={handleUploadError}
+              buttonText="点击或拖拽上传文件"
+              tipText="支持单文件上传,单个文件大小不超过500MB"
+              size="default"
+            />
+          </div>
+          
+          <DialogFooter>
+            <Button variant="outline" onClick={() => setIsUploadModalOpen(false)}>
+              取消
+            </Button>
+          </DialogFooter>
+        </DialogContent>
+      </Dialog>
+
       {/* 编辑对话框 */}
       <Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
         <DialogContent className="sm:max-w-[500px]">