mirror of
https://github.com/PlayEdu/backend
synced 2025-06-22 14:02:48 +08:00
resolve conflict
This commit is contained in:
parent
2309710f27
commit
6bfef38146
@ -14,6 +14,7 @@
|
|||||||
"@types/node": "^16.7.13",
|
"@types/node": "^16.7.13",
|
||||||
"@types/react": "^18.0.0",
|
"@types/react": "^18.0.0",
|
||||||
"@types/react-dom": "^18.0.0",
|
"@types/react-dom": "^18.0.0",
|
||||||
|
"@uppy/react": "^3.1.0",
|
||||||
"antd": "^5.2.3",
|
"antd": "^5.2.3",
|
||||||
"axios": "^1.3.4",
|
"axios": "^1.3.4",
|
||||||
"babel-jest": "^27.4.2",
|
"babel-jest": "^27.4.2",
|
||||||
@ -59,6 +60,7 @@
|
|||||||
"redux-thunk": "^2.4.2",
|
"redux-thunk": "^2.4.2",
|
||||||
"resolve": "^1.20.0",
|
"resolve": "^1.20.0",
|
||||||
"resolve-url-loader": "^4.0.0",
|
"resolve-url-loader": "^4.0.0",
|
||||||
|
"resumablejs": "^1.1.0",
|
||||||
"sass-loader": "^12.3.0",
|
"sass-loader": "^12.3.0",
|
||||||
"semver": "^7.3.5",
|
"semver": "^7.3.5",
|
||||||
"source-map-loader": "^3.0.0",
|
"source-map-loader": "^3.0.0",
|
||||||
|
212
src/compenents/upload-video-button/index.tsx
Normal file
212
src/compenents/upload-video-button/index.tsx
Normal file
@ -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<FileItem[]>([]);
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={() => {
|
||||||
|
setShowModal(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
上传视频
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<div className="none">
|
||||||
|
{fileList.length > 0 &&
|
||||||
|
fileList.map((item) => (
|
||||||
|
<video
|
||||||
|
key={item.id}
|
||||||
|
src={URL.createObjectURL(item.file)}
|
||||||
|
onCanPlayThrough={(e: any) => {
|
||||||
|
item.duration = parseInt(e.target.duration);
|
||||||
|
item.loading = false;
|
||||||
|
}}
|
||||||
|
></video>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{showModal && (
|
||||||
|
<Modal
|
||||||
|
width={800}
|
||||||
|
title="上传视频"
|
||||||
|
open={true}
|
||||||
|
onCancel={() => {
|
||||||
|
setShowModal(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Row gutter={[0, 10]}>
|
||||||
|
<Col span={24}>
|
||||||
|
<Dragger {...uploadProps}>
|
||||||
|
<p className="ant-upload-drag-icon">
|
||||||
|
<InboxOutlined />
|
||||||
|
</p>
|
||||||
|
<p className="ant-upload-text">请将视频拖拽到此处上传</p>
|
||||||
|
<p className="ant-upload-hint">
|
||||||
|
支持一次上传多个 / 支持 mp4 格式视频
|
||||||
|
</p>
|
||||||
|
</Dragger>
|
||||||
|
</Col>
|
||||||
|
<Col span={24}>
|
||||||
|
<Table
|
||||||
|
pagination={false}
|
||||||
|
rowKey="id"
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
title: "视频",
|
||||||
|
dataIndex: "name",
|
||||||
|
key: "name",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "大小",
|
||||||
|
dataIndex: "size",
|
||||||
|
key: "size",
|
||||||
|
render: (_, record) => (
|
||||||
|
<span>{(record.size / 1024 / 1024).toFixed(2)} M</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "进度",
|
||||||
|
dataIndex: "progress",
|
||||||
|
key: "progress",
|
||||||
|
render: (_, record: FileItem) => (
|
||||||
|
<>
|
||||||
|
{record.progress === 0 && "等待上传"}
|
||||||
|
{record.progress > 0 && (
|
||||||
|
<Progress
|
||||||
|
size="small"
|
||||||
|
steps={10}
|
||||||
|
percent={record.progress}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "操作",
|
||||||
|
key: "action",
|
||||||
|
render: (index, record) => (
|
||||||
|
<>
|
||||||
|
{record.progress === 0 && (
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
fileList.splice(index, 1);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
dataSource={fileList}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Modal>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -140,3 +140,7 @@ code {
|
|||||||
textarea.ant-input {
|
textarea.ant-input {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.none {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { message } from "antd";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { UploadImageButton } from "../../compenents";
|
import { UploadVideoButton } from "../../compenents/upload-video-button";
|
||||||
|
|
||||||
export const TestPage: React.FC = () => {
|
export const TestPage: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<UploadImageButton
|
<UploadVideoButton
|
||||||
onSelected={(url) => {
|
categoryId={0}
|
||||||
message.success("选择了:" + url);
|
onUpdate={() => {
|
||||||
|
console.log(123);
|
||||||
}}
|
}}
|
||||||
></UploadImageButton>
|
></UploadVideoButton>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -15,3 +15,13 @@ export function clearToken() {
|
|||||||
export function dateFormat(dateStr: string) {
|
export function dateFormat(dateStr: string) {
|
||||||
return moment(dateStr).format("YYYY-MM-DD HH:mm");
|
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;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user