|
|
@@ -7,10 +7,18 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/client/components/ui
|
|
|
import { Progress } from "@/client/components/ui/progress";
|
|
|
import { Badge } from "@/client/components/ui/badge";
|
|
|
|
|
|
+enum UploadStatus {
|
|
|
+ PENDING = "pending",
|
|
|
+ UPLOADING = "uploading",
|
|
|
+ SUCCESS = "success",
|
|
|
+ ERROR = "error",
|
|
|
+ CANCELED = "canceled"
|
|
|
+}
|
|
|
+
|
|
|
interface UploadTask {
|
|
|
file: File;
|
|
|
progress: number;
|
|
|
- status: "pending" | "uploading" | "success" | "error" | "canceled";
|
|
|
+ status: UploadStatus;
|
|
|
fileId?: string;
|
|
|
videoUrl?: string;
|
|
|
coverUrl?: string;
|
|
|
@@ -76,7 +84,7 @@ export const VodUpload: React.FC<VodUploadProps> = ({
|
|
|
const newTask: UploadTask = {
|
|
|
file: selectedVideo,
|
|
|
progress: 0,
|
|
|
- status: "pending",
|
|
|
+ status: UploadStatus.PENDING,
|
|
|
};
|
|
|
|
|
|
setUploadTasks((prev) => [...prev, newTask]);
|
|
|
@@ -89,13 +97,13 @@ export const VodUpload: React.FC<VodUploadProps> = ({
|
|
|
|
|
|
const updatedTask: UploadTask = {
|
|
|
...newTask,
|
|
|
- status: "uploading",
|
|
|
+ status: UploadStatus.UPLOADING,
|
|
|
cancel: () => {
|
|
|
uploader.cancel();
|
|
|
setUploadTasks((prev) =>
|
|
|
prev.map((task) =>
|
|
|
task.file === newTask.file
|
|
|
- ? { ...task, status: "canceled" }
|
|
|
+ ? { ...task, status: UploadStatus.CANCELED }
|
|
|
: task
|
|
|
)
|
|
|
);
|
|
|
@@ -121,7 +129,7 @@ export const VodUpload: React.FC<VodUploadProps> = ({
|
|
|
uploader.on("media_upload", (info) => {
|
|
|
setUploadTasks((prev) =>
|
|
|
prev.map((task) =>
|
|
|
- task.file === newTask.file ? { ...task, status: "success" } : task
|
|
|
+ task.file === newTask.file ? { ...task, status: UploadStatus.SUCCESS } : task
|
|
|
)
|
|
|
);
|
|
|
});
|
|
|
@@ -134,7 +142,7 @@ export const VodUpload: React.FC<VodUploadProps> = ({
|
|
|
fileId: result.fileId,
|
|
|
videoUrl: result.video.url,
|
|
|
coverUrl: result.cover?.url,
|
|
|
- status: "success",
|
|
|
+ status: UploadStatus.SUCCESS,
|
|
|
};
|
|
|
|
|
|
setUploadTasks((prev) =>
|
|
|
@@ -156,7 +164,7 @@ export const VodUpload: React.FC<VodUploadProps> = ({
|
|
|
} catch (error) {
|
|
|
setUploadTasks((prev) =>
|
|
|
prev.map((task) =>
|
|
|
- task.file === newTask.file ? { ...task, status: "error" } : task
|
|
|
+ task.file === newTask.file ? { ...task, status: UploadStatus.ERROR } : task
|
|
|
)
|
|
|
);
|
|
|
toast.error("视频上传失败");
|
|
|
@@ -174,17 +182,17 @@ export const VodUpload: React.FC<VodUploadProps> = ({
|
|
|
};
|
|
|
|
|
|
// 渲染上传状态标签
|
|
|
- const renderStatusTag = (status: UploadTask["status"]) => {
|
|
|
+ const renderStatusTag = (status: UploadStatus) => {
|
|
|
switch (status) {
|
|
|
- case "pending":
|
|
|
+ case UploadStatus.PENDING:
|
|
|
return <Badge variant="outline">等待上传</Badge>;
|
|
|
- case "uploading":
|
|
|
+ case UploadStatus.UPLOADING:
|
|
|
return <Badge variant="secondary">上传中</Badge>;
|
|
|
- case "success":
|
|
|
+ case UploadStatus.SUCCESS:
|
|
|
return <Badge variant="default">上传成功</Badge>;
|
|
|
- case "error":
|
|
|
+ case UploadStatus.ERROR:
|
|
|
return <Badge variant="destructive">上传失败</Badge>;
|
|
|
- case "canceled":
|
|
|
+ case UploadStatus.CANCELED:
|
|
|
return <Badge variant="outline">已取消</Badge>;
|
|
|
default:
|
|
|
return <Badge variant="outline">未知状态</Badge>;
|
|
|
@@ -244,7 +252,7 @@ export const VodUpload: React.FC<VodUploadProps> = ({
|
|
|
<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 && (
|
|
|
+ {task.status === UploadStatus.UPLOADING && task.cancel && (
|
|
|
<Button
|
|
|
variant="ghost"
|
|
|
size="sm"
|
|
|
@@ -255,7 +263,7 @@ export const VodUpload: React.FC<VodUploadProps> = ({
|
|
|
</Button>
|
|
|
)}
|
|
|
</div>
|
|
|
- {task.status === "uploading" && (
|
|
|
+ {task.status === UploadStatus.UPLOADING && (
|
|
|
<Progress value={task.progress} className="w-full" />
|
|
|
)}
|
|
|
{task.fileId && (
|