diff --git a/package.json b/package.json index ad00827..fdf55fc 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@types/node": "^16.7.13", "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", + "@uppy/react": "^3.1.0", "antd": "^5.2.3", "axios": "^1.3.4", "babel-jest": "^27.4.2", @@ -59,6 +60,7 @@ "redux-thunk": "^2.4.2", "resolve": "^1.20.0", "resolve-url-loader": "^4.0.0", + "resumablejs": "^1.1.0", "sass-loader": "^12.3.0", "semver": "^7.3.5", "source-map-loader": "^3.0.0", diff --git a/src/compenents/upload-video-button/index.tsx b/src/compenents/upload-video-button/index.tsx new file mode 100644 index 0000000..fbe0761 --- /dev/null +++ b/src/compenents/upload-video-button/index.tsx @@ -0,0 +1,212 @@ +import { InboxOutlined } from "@ant-design/icons"; +import { + Button, + Col, + message, + Modal, + Progress, + Row, + Table, + Upload, +} from "antd"; +import Dragger from "antd/es/upload/Dragger"; +import { useEffect, useState } from "react"; +import { generateUUID, getToken } from "../../utils"; +import { minioToken } from "../../api/upload"; +import Resumable from "resumablejs"; + +interface PropsInterface { + categoryId: number; + onUpdate: () => void; +} + +interface FileItem { + id: string; + name: string; + duration: number; + size: number; + progress: number; + file: File; + resource_type: string; + loading: boolean; + R: Resumable | undefined; +} + +export const UploadVideoButton = (props: PropsInterface) => { + const [showModal, setShowModal] = useState(false); + const [fileList, setFileList] = useState([]); + + const getMinioConfig = async () => { + let resp: any = await minioToken("mp4"); + return resp.data; + }; + + const r = new Resumable({ + chunkSize: 1 * 1024 * 1024, + fileParameterName: "file", + uploadMethod: "POST", + }); + + const uploadProps = { + multiple: true, + beforeUpload: async (file: File) => { + if (file.type === "video/mp4") { + //添加到本地待上传 + let data = await getMinioConfig(); + let item: FileItem = { + id: generateUUID(), + duration: 0, + name: file.name, + size: file.size, + progress: 0, + file: file, + resource_type: data["resource_type"], + loading: true, + R: undefined, + }; + + // 初始化上传对象 + let r = new Resumable({ + target: data["url"], + chunkSize: 6 * 1024 * 1024, + simultaneousUploads: 1, + uploadMethod: "PUT", + method: "octet", + testChunks: false, //不校验已上传的chunks + chunkNumberParameterName: "partNumber", + query: { + uploadId: item.id, + }, + }); + r.on("fileProgress", (file: Resumable.ResumableFile) => { + item.progress = file.progress(false) * 100; + console.log("进度", item.progress); + }); + r.on("error", (e) => { + console.log("错误", e); + }); + r.addFile(item.file); + + item.R = r; + setTimeout(() => { + if (item.R) { + item.R.upload(); + } + }, 500); + + setFileList([item, ...fileList]); + } else { + message.error(`${file.name} 并不是 mp4 视频文件`); + } + return Upload.LIST_IGNORE; + }, + }; + + return ( + <> + + +
+ {fileList.length > 0 && + fileList.map((item) => ( + + ))} +
+ + {showModal && ( + { + setShowModal(false); + }} + > + + + +

+ +

+

请将视频拖拽到此处上传

+

+ 支持一次上传多个 / 支持 mp4 格式视频 +

+
+ + + ( + {(record.size / 1024 / 1024).toFixed(2)} M + ), + }, + { + title: "进度", + dataIndex: "progress", + key: "progress", + render: (_, record: FileItem) => ( + <> + {record.progress === 0 && "等待上传"} + {record.progress > 0 && ( + + )} + + ), + }, + { + title: "操作", + key: "action", + render: (index, record) => ( + <> + {record.progress === 0 && ( + + )} + + ), + }, + ]} + dataSource={fileList} + /> + + + + )} + + ); +}; diff --git a/src/index.less b/src/index.less index 5bf3d39..82a7b3d 100644 --- a/src/index.less +++ b/src/index.less @@ -140,3 +140,7 @@ code { textarea.ant-input { vertical-align: middle; } + +.none { + display: none; +} diff --git a/src/pages/test/index.tsx b/src/pages/test/index.tsx index 28a2e53..45fa8e5 100644 --- a/src/pages/test/index.tsx +++ b/src/pages/test/index.tsx @@ -1,15 +1,15 @@ -import { message } from "antd"; import React from "react"; -import { UploadImageButton } from "../../compenents"; +import { UploadVideoButton } from "../../compenents/upload-video-button"; export const TestPage: React.FC = () => { return (
- { - message.success("选择了:" + url); + { + console.log(123); }} - > + >
); }; diff --git a/src/utils/index.ts b/src/utils/index.ts index 9a2a951..3a5e40a 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -15,3 +15,13 @@ export function clearToken() { export function dateFormat(dateStr: string) { return moment(dateStr).format("YYYY-MM-DD HH:mm"); } + +export const generateUUID = (): string => { + var guid = ""; + for (var i = 1; i <= 32; i++) { + var n = Math.floor(Math.random() * 16.0).toString(16); + guid += n; + if (i == 8 || i == 12 || i == 16 || i == 20) guid += "-"; + } + return guid; +}; \ No newline at end of file