Files
cunkebao_v3/nkebao/src/components/Upload/VideoUpload.tsx

154 lines
3.8 KiB
TypeScript
Raw Normal View History

import React, { useState } from "react";
import { Upload, message } from "antd";
import { LoadingOutlined, PlusOutlined } from "@ant-design/icons";
import type { UploadProps, UploadFile } from "antd/es/upload/interface";
import request from "@/api/request";
import style from "./index.module.scss";
interface VideoUploadProps {
value?: string;
onChange?: (url: string) => void;
disabled?: boolean;
className?: string;
}
const VideoUpload: React.FC<VideoUploadProps> = ({
value = "",
onChange,
disabled = false,
className,
}) => {
const [loading, setLoading] = useState(false);
const [fileList, setFileList] = useState<UploadFile[]>([]);
// 将value转换为fileList格式
React.useEffect(() => {
if (value) {
const file: UploadFile = {
uid: "-1",
name: "video",
status: "done",
url: value,
};
setFileList([file]);
} else {
setFileList([]);
}
}, [value]);
// 文件验证
const beforeUpload = (file: File) => {
const isVideo = file.type.startsWith("video/");
if (!isVideo) {
message.error("只能上传视频文件!");
return false;
}
const isLt50M = file.size / 1024 / 1024 < 50;
if (!isLt50M) {
message.error("视频大小不能超过50MB");
return false;
}
return false; // 阻止自动上传
};
// 处理文件变化
const handleChange: UploadProps["onChange"] = async info => {
if (info.file.status === "uploading") {
setLoading(true);
// 在这里处理文件上传
try {
const formData = new FormData();
formData.append("file", info.file.originFileObj as File);
const response = await request(
"/v1/attachment/upload",
formData,
"POST",
);
if (response) {
const uploadedUrl =
typeof response === "string" ? response : response.url || response;
// 更新文件状态
const updatedFile = {
...info.file,
status: "done" as const,
url: uploadedUrl,
};
// 更新fileList
setFileList([updatedFile]);
// 调用onChange
onChange?.(uploadedUrl);
setLoading(false);
message.success("上传成功");
} else {
throw new Error("上传失败");
}
} catch (error) {
console.error("上传失败:", error);
message.error("上传失败,请重试");
setLoading(false);
}
return;
}
if (info.file.status === "done") {
setLoading(false);
// 更新fileList
setFileList([info.file]);
// 调用onChange
onChange?.(info.file.url || "");
}
};
// 删除文件
const handleRemove = () => {
setFileList([]);
onChange?.("");
return true;
};
const uploadButton = (
<div className={style["upload-button"]}>
{loading ? (
<div className={style["uploading"]}>
<LoadingOutlined className={style["upload-icon"]} />
<div className={style["upload-text"]}>...</div>
</div>
) : (
<>
<PlusOutlined className={style["upload-icon"]} />
<div className={style["upload-text"]}></div>
</>
)}
</div>
);
return (
<div className={`${style["upload-container"]} ${className || ""}`}>
<Upload
name="file"
multiple={false}
fileList={fileList}
accept="video/*"
listType="text"
showUploadList={true}
disabled={disabled || loading}
beforeUpload={beforeUpload}
onChange={handleChange}
onRemove={handleRemove}
>
{fileList.length >= 1 ? null : uploadButton}
</Upload>
</div>
);
};
export default VideoUpload;