resolve conflict

This commit is contained in:
none 2023-03-06 16:07:49 +08:00
parent 2309710f27
commit 6bfef38146
5 changed files with 234 additions and 6 deletions

View File

@ -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",

View 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>
)}
</>
);
};

View File

@ -140,3 +140,7 @@ code {
textarea.ant-input { textarea.ant-input {
vertical-align: middle; vertical-align: middle;
} }
.none {
display: none;
}

View File

@ -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>
); );
}; };

View File

@ -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;
};