Commit ba4e2f23 by renmanyi

feat:腾讯云分片上传

parent 4324d0e7
import React from 'react';
import { Modal } from 'antd';
import OSS from 'ali-oss';
import COS from 'cos-js-sdk-v5';
import Service from '@/common/js/service';
import { getEllipsText } from "@/core/util";
import { getEllipsText, randomString } from "@/core/util";
import { DEFAULT_SIZE_UNIT, FileTypeIcon, FileVerifyMap } from "@/common/constants/academic/lessonEnum";
import { getFileTypeByName } from '../components/FolderManage';
......@@ -10,6 +11,7 @@ import User from '@/common/js/user';
import './UploadProgressModal.less';
const UPLOAD_REGION = 'oss-cn-hangzhou';
const TX_UPLOAD_REGION = 'ap-guangzhou';
const UPLOAD_PART_SIZE = 1024 * 1024; // 每个分片大小(byte)
const UPLOAD_PARALLEL = 5; // 同时上传的分片数
......@@ -72,30 +74,45 @@ class UploadProgressModal extends React.Component {
const { result = {} } = res;
const {
bucket,
callBack,
resourceId,
accessKeyId,
securityToken,
accessKeySecret,
callbackBody,
ossUri
ossUri,
vendorType,
callbackData,
callback
} = result;
const ossClient = new OSS({
let ossClient;
if (vendorType === 'TENCENT_COS') {
// 腾讯云 COS 客户端配置
ossClient = new COS({
SecretId: accessKeyId,
SecretKey: accessKeySecret,
SecurityToken: securityToken
});
} else {
// 阿里云 OSS 客户端配置
ossClient = new OSS({
bucket,
accessKeyId,
accessKeySecret,
region: UPLOAD_REGION,
stsToken: securityToken,
});
}
this.setState({
ossClient,
resourceId,
callBack,
callbackBody,
ossUri
ossUri,
vendorType,
bucket,
callback,
callbackData,
});
resolve({ ossClient, resourceId, callBack, callbackBody, ossUri });
resolve({ ossClient, resourceId, ossUri, vendorType, bucket, callback, callbackData });
})
})
}
......@@ -108,17 +125,48 @@ class UploadProgressModal extends React.Component {
const { id = 0 } = currentFolder;
const { name, type } = fileContent;
const resourceName = window.random_string(16) + name.slice(name.lastIndexOf('.'));
const resourceName = randomString(16) + name.slice(name.lastIndexOf('.'));
const { instId } = window.currentUserInstInfo;
// 开始上传之前初始化OssClient
this.initOssClient(id, resourceName).then((result) => {
const { ossClient, resourceId, callBack, callbackBody, ossUri } = result;
const { ossClient, resourceId, ossUri, vendorType, bucket, callback, callbackData } = result;
if (vendorType === 'TENCENT_COS') {
// 腾讯云分片上传
ossClient.sliceUploadFile({
Bucket: bucket,
Region: TX_UPLOAD_REGION,
Key: ossUri,
Body: fileContent,
SliceSize: UPLOAD_PART_SIZE,
// 回调配置
Callback: callback,
onProgress: (progressData) => {
const progress = progressData.percent;
this.onMultipartUploadProgress(progress, { uploadId: randomString(16), file: fileContent }, file);
},
onTaskReady: (taskId) => {
// 记录任务ID,用于取消上传
file.taskId = taskId;
},
})
.then(res => {
file.status = 'success';
this.setState({ fileList });
this.props.onUpload(fileContent, resourceId);
})
.catch(err => {
file.status = 'fail';
this.setState({ fileList });
});
} else {
// 阿里云分片上传
ossClient.multipartUpload(ossUri, fileContent, {
callback: {
url: callBack,
body: callbackBody,
contentType: 'application/json',
url: callbackData.url,
body: callbackData.body,
callbackSNI: true,
contentType: callbackData.contentType
},
parallel: UPLOAD_PARALLEL,
partSize: UPLOAD_PART_SIZE,
......@@ -134,6 +182,7 @@ class UploadProgressModal extends React.Component {
file.status = 'fail';
this.setState({ fileList });
});
}
});
}
......@@ -158,17 +207,47 @@ class UploadProgressModal extends React.Component {
// 断点续传
handleReUpload = (index) => {
const { fileList, ossClient, resourceId, callBack, callbackBody } = this.state;
const { fileList, ossClient, resourceId, callbackData, vendorType, bucket, callback, ossUri } = this.state;
const currentFile = fileList[index];
const { checkpoints, fileContent } = currentFile
const { checkpoints, fileContent } = currentFile;
if (vendorType === 'TENCENT_COS') {
// 腾讯云重新上传
ossClient.sliceUploadFile({
Bucket: bucket,
Region: TX_UPLOAD_REGION,
Key: ossUri,
Body: fileContent,
SliceSize: UPLOAD_PART_SIZE,
// 回调配置
Callback: callback,
onProgress: (progressData) => {
const progress = progressData.percent;
this.onMultipartUploadProgress(progress, { uploadId: randomString(16), file: fileContent }, currentFile);
},
onTaskReady: (taskId) => {
currentFile.taskId = taskId;
},
})
.then(res => {
currentFile.status = 'success';
this.setState({ fileList });
this.props.onUpload(fileContent, resourceId);
})
.catch(err => {
currentFile.status = 'fail';
this.setState({ fileList });
});
} else {
// 阿里云断点续传
Object.values(checkpoints).forEach(checkpoint => {
const { uploadId, file } = checkpoint;
ossClient.multipartUpload(uploadId, file, {
callback: {
url: callBack,
body: callbackBody,
contentType: 'application/json',
url: callbackData.url,
body: callbackData.body,
callbackSNI: true,
contentType: callbackData.contentType
},
checkpoint,
parallel: UPLOAD_PARALLEL,
......@@ -185,7 +264,8 @@ class UploadProgressModal extends React.Component {
currentFile.status = 'fail';
this.setState({ fileList });
});
})
});
}
}
// 显示/隐藏上传进度
......@@ -198,7 +278,7 @@ class UploadProgressModal extends React.Component {
// 取消上传
handleCancelAllUpload = () => {
// 判断是否有正在上传或者待上传的文件,有的话弹出二次提示框
const { fileList, ossClient } = this.state;
const { fileList, ossClient, vendorType } = this.state;
const uploadingFileList = fileList.filter(file => file.status === 'uploading' || file.status === 'waiting');
if (uploadingFileList.length) {
Modal.confirm({
......@@ -207,15 +287,22 @@ class UploadProgressModal extends React.Component {
icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>,
onOk: () => {
uploadingFileList.forEach((uploadingFile, index) => {
if (vendorType === 'TENCENT_COS') {
// 腾讯云取消上传
if (uploadingFile.taskId) {
ossClient.cancelTask(uploadingFile.taskId);
}
} else {
// 阿里云取消上传
const { checkpoints } = uploadingFile;
Object.values(checkpoints).forEach(checkpoint => {
const { uploadId, name } = checkpoint;
ossClient.abortMultipartUpload(name, uploadId);
});
}
fileList.splice(index, 1);
})
this.setState({ fileList });
});
this.setState({ fileList: [] });
this.props.onCancel();
}
})
......@@ -227,12 +314,21 @@ class UploadProgressModal extends React.Component {
// 取消单个文件上传
handleCancelUpload = (currentFile, index) => {
const { fileList, ossClient } = this.state;
const { fileList, ossClient, vendorType } = this.state;
if (vendorType === 'TENCENT_COS') {
// 腾讯云取消上传
if (currentFile.taskId) {
ossClient.cancelTask(currentFile.taskId);
}
} else {
// 阿里云取消上传
const { checkpoints } = currentFile;
Object.values(checkpoints).forEach(checkpoint => {
const { uploadId, name } = checkpoint;
ossClient.abortMultipartUpload(name, uploadId);
});
}
fileList.splice(index, 1);
this.setState({ fileList });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment