Przeglądaj źródła

✨ feat(vod): 重构视频上传组件UI与交互

- 替换UI组件库,从antd迁移到自定义组件库
- 使用toast替代message组件优化通知体验
- 重构卡片布局,使用CardHeader、CardContent等组件增强结构
- 优化按钮样式与交互状态,使用variant属性替代type
- 改进文件选择区域布局,增加flex样式与间距
- 重构上传任务列表样式,添加边框与内边距提升可读性
- 优化进度条展示样式,调整状态标签为Badge组件
- 添加响应式设计支持,使用flex-wrap与gap属性优化布局
- 改进链接样式,添加hover效果与文本溢出处理
yourname 6 miesięcy temu
rodzic
commit
75aa49201e
1 zmienionych plików z 38 dodań i 31 usunięć
  1. 38 31
      src/client/admin/components/vod/VodUpload.tsx

+ 38 - 31
src/client/admin/components/vod/VodUpload.tsx

@@ -1,7 +1,11 @@
 import React, { useRef, useState } from "react";
-import { Button, Card, message, Progress, Space, Tag } from "antd";
 import TcVod from "vod-js-sdk-v6";
+import { toast } from "sonner";
 import { vodClient } from "@/client/api";
+import { Button } from "@/client/components/ui/button";
+import { Card, CardContent, CardHeader, CardTitle } from "@/client/components/ui/card";
+import { Progress } from "@/client/components/ui/progress";
+import { Badge } from "@/client/components/ui/badge";
 
 interface UploadTask {
   file: File;
@@ -38,7 +42,7 @@ export const VodUpload: React.FC<VodUploadProps> = ({
       const { signature } = await response.json();
       return signature;
     } catch (error) {
-      message.error("获取上传签名失败");
+      toast.error("获取上传签名失败");
       throw error;
     }
   };
@@ -65,7 +69,7 @@ export const VodUpload: React.FC<VodUploadProps> = ({
   // 开始上传
   const startUpload = async () => {
     if (!selectedVideo) {
-      message.warning("请先选择视频文件");
+      toast.warning("请先选择视频文件");
       return;
     }
 
@@ -139,7 +143,7 @@ export const VodUpload: React.FC<VodUploadProps> = ({
         )
       );
 
-      message.success("视频上传成功");
+      toast.success("视频上传成功");
       
       // 调用成功回调
       if (onUploadSuccess) {
@@ -155,7 +159,7 @@ export const VodUpload: React.FC<VodUploadProps> = ({
           task.file === newTask.file ? { ...task, status: "error" } : task
         )
       );
-      message.error("视频上传失败");
+      toast.error("视频上传失败");
       
       // 调用错误回调
       if (onUploadError) {
@@ -173,34 +177,37 @@ export const VodUpload: React.FC<VodUploadProps> = ({
   const renderStatusTag = (status: UploadTask["status"]) => {
     switch (status) {
       case "pending":
-        return <Tag color="default">等待上传</Tag>;
+        return <Badge variant="outline">等待上传</Badge>;
       case "uploading":
-        return <Tag color="processing">上传中</Tag>;
+        return <Badge variant="secondary">上传中</Badge>;
       case "success":
-        return <Tag color="success">上传成功</Tag>;
+        return <Badge variant="default">上传成功</Badge>;
       case "error":
-        return <Tag color="error">上传失败</Tag>;
+        return <Badge variant="destructive">上传失败</Badge>;
       case "canceled":
-        return <Tag color="warning">已取消</Tag>;
+        return <Badge variant="outline">已取消</Badge>;
       default:
-        return <Tag color="default">未知状态</Tag>;
+        return <Badge variant="outline">未知状态</Badge>;
     }
   };
 
   return (
-    <Card title="视频上传" className="mb-4">
-      <Space direction="vertical" style={{ width: "100%" }}>
-        <div>
+    <Card className="mb-6">
+      <CardHeader>
+        <CardTitle>视频上传</CardTitle>
+      </CardHeader>
+      <CardContent className="space-y-4">
+        <div className="flex flex-wrap items-center gap-3">
           <input
             type="file"
             ref={videoInputRef}
             onChange={handleVideoSelect}
             accept="video/*"
-            style={{ display: "none" }}
+            className="hidden"
           />
           <Button
             onClick={() => videoInputRef.current?.click()}
-            type="primary"
+            variant="default"
           >
             {selectedVideo ? selectedVideo.name : "选择视频文件"}
           </Button>
@@ -210,48 +217,46 @@ export const VodUpload: React.FC<VodUploadProps> = ({
             ref={coverInputRef}
             onChange={handleCoverSelect}
             accept="image/*"
-            style={{ display: "none", marginLeft: 16 }}
+            className="hidden"
           />
           <Button
             onClick={() => coverInputRef.current?.click()}
-            style={{ marginLeft: 16 }}
+            variant="outline"
           >
             {selectedCover ? selectedCover.name : "选择封面(可选)"}
           </Button>
 
           <Button
-            type="primary"
             onClick={startUpload}
             disabled={!selectedVideo}
-            style={{ marginLeft: 16 }}
           >
             开始上传
           </Button>
         </div>
 
-        <div style={{ marginTop: 24 }}>
+        <div className="space-y-4">
           {uploadTasks.map((task, index) => (
-            <div key={index} style={{ marginBottom: 16 }}>
-              <div style={{ marginBottom: 8 }}>
-                <span style={{ marginRight: 8 }}>{task.file.name}</span>
+            <div key={index} className="border rounded-lg p-4">
+              <div className="flex items-center gap-2 mb-3">
+                <span className="font-medium">{task.file.name}</span>
                 {renderStatusTag(task.status)}
                 {task.status === "uploading" && task.cancel && (
                   <Button
-                    type="link"
-                    danger
+                    variant="ghost"
+                    size="sm"
                     onClick={task.cancel}
-                    style={{ marginLeft: 8 }}
+                    className="text-destructive hover:text-destructive"
                   >
                     取消上传
                   </Button>
                 )}
               </div>
               {task.status === "uploading" && (
-                <Progress percent={task.progress} status="active" />
+                <Progress value={task.progress} className="w-full" />
               )}
               {task.fileId && (
-                <div style={{ marginTop: 8 }}>
-                  <div>File ID: {task.fileId}</div>
+                <div className="space-y-2 text-sm mt-3">
+                  <div className="font-medium">File ID: {task.fileId}</div>
                   {task.videoUrl && (
                     <div>
                       视频地址:{" "}
@@ -259,6 +264,7 @@ export const VodUpload: React.FC<VodUploadProps> = ({
                         href={task.videoUrl}
                         target="_blank"
                         rel="noreferrer"
+                        className="text-primary hover:underline break-all"
                       >
                         {task.videoUrl}
                       </a>
@@ -271,6 +277,7 @@ export const VodUpload: React.FC<VodUploadProps> = ({
                         href={task.coverUrl}
                         target="_blank"
                         rel="noreferrer"
+                        className="text-primary hover:underline break-all"
                       >
                         {task.coverUrl}
                       </a>
@@ -281,7 +288,7 @@ export const VodUpload: React.FC<VodUploadProps> = ({
             </div>
           ))}
         </div>
-      </Space>
+      </CardContent>
     </Card>
   );
 };