Commit ba4e2f23 by renmanyi

feat:腾讯云分片上传

parent 4324d0e7
import React from 'react'; import React from 'react';
import { Modal } from 'antd'; import { Modal } from 'antd';
import OSS from 'ali-oss'; import OSS from 'ali-oss';
import COS from 'cos-js-sdk-v5';
import Service from '@/common/js/service'; 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 { DEFAULT_SIZE_UNIT, FileTypeIcon, FileVerifyMap } from "@/common/constants/academic/lessonEnum";
import { getFileTypeByName } from '../components/FolderManage'; import { getFileTypeByName } from '../components/FolderManage';
...@@ -10,6 +11,7 @@ import User from '@/common/js/user'; ...@@ -10,6 +11,7 @@ import User from '@/common/js/user';
import './UploadProgressModal.less'; import './UploadProgressModal.less';
const UPLOAD_REGION = 'oss-cn-hangzhou'; const UPLOAD_REGION = 'oss-cn-hangzhou';
const TX_UPLOAD_REGION = 'ap-guangzhou';
const UPLOAD_PART_SIZE = 1024 * 1024; // 每个分片大小(byte) const UPLOAD_PART_SIZE = 1024 * 1024; // 每个分片大小(byte)
const UPLOAD_PARALLEL = 5; // 同时上传的分片数 const UPLOAD_PARALLEL = 5; // 同时上传的分片数
...@@ -72,30 +74,45 @@ class UploadProgressModal extends React.Component { ...@@ -72,30 +74,45 @@ class UploadProgressModal extends React.Component {
const { result = {} } = res; const { result = {} } = res;
const { const {
bucket, bucket,
callBack,
resourceId, resourceId,
accessKeyId, accessKeyId,
securityToken, securityToken,
accessKeySecret, accessKeySecret,
callbackBody, ossUri,
ossUri vendorType,
callbackData,
callback
} = result; } = 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, bucket,
accessKeyId, accessKeyId,
accessKeySecret, accessKeySecret,
region: UPLOAD_REGION, region: UPLOAD_REGION,
stsToken: securityToken, stsToken: securityToken,
}); });
}
this.setState({ this.setState({
ossClient, ossClient,
resourceId, resourceId,
callBack, ossUri,
callbackBody, vendorType,
ossUri 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 { ...@@ -108,17 +125,48 @@ class UploadProgressModal extends React.Component {
const { id = 0 } = currentFolder; const { id = 0 } = currentFolder;
const { name, type } = fileContent; 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 // 开始上传之前初始化OssClient
this.initOssClient(id, resourceName).then((result) => { 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, { ossClient.multipartUpload(ossUri, fileContent, {
callback: { callback: {
url: callBack, url: callbackData.url,
body: callbackBody, body: callbackData.body,
contentType: 'application/json', callbackSNI: true,
contentType: callbackData.contentType
}, },
parallel: UPLOAD_PARALLEL, parallel: UPLOAD_PARALLEL,
partSize: UPLOAD_PART_SIZE, partSize: UPLOAD_PART_SIZE,
...@@ -134,6 +182,7 @@ class UploadProgressModal extends React.Component { ...@@ -134,6 +182,7 @@ class UploadProgressModal extends React.Component {
file.status = 'fail'; file.status = 'fail';
this.setState({ fileList }); this.setState({ fileList });
}); });
}
}); });
} }
...@@ -158,17 +207,47 @@ class UploadProgressModal extends React.Component { ...@@ -158,17 +207,47 @@ class UploadProgressModal extends React.Component {
// 断点续传 // 断点续传
handleReUpload = (index) => { 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 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 => { Object.values(checkpoints).forEach(checkpoint => {
const { uploadId, file } = checkpoint; const { uploadId, file } = checkpoint;
ossClient.multipartUpload(uploadId, file, { ossClient.multipartUpload(uploadId, file, {
callback: { callback: {
url: callBack, url: callbackData.url,
body: callbackBody, body: callbackData.body,
contentType: 'application/json', callbackSNI: true,
contentType: callbackData.contentType
}, },
checkpoint, checkpoint,
parallel: UPLOAD_PARALLEL, parallel: UPLOAD_PARALLEL,
...@@ -185,7 +264,8 @@ class UploadProgressModal extends React.Component { ...@@ -185,7 +264,8 @@ class UploadProgressModal extends React.Component {
currentFile.status = 'fail'; currentFile.status = 'fail';
this.setState({ fileList }); this.setState({ fileList });
}); });
}) });
}
} }
// 显示/隐藏上传进度 // 显示/隐藏上传进度
...@@ -198,7 +278,7 @@ class UploadProgressModal extends React.Component { ...@@ -198,7 +278,7 @@ class UploadProgressModal extends React.Component {
// 取消上传 // 取消上传
handleCancelAllUpload = () => { handleCancelAllUpload = () => {
// 判断是否有正在上传或者待上传的文件,有的话弹出二次提示框 // 判断是否有正在上传或者待上传的文件,有的话弹出二次提示框
const { fileList, ossClient } = this.state; const { fileList, ossClient, vendorType } = this.state;
const uploadingFileList = fileList.filter(file => file.status === 'uploading' || file.status === 'waiting'); const uploadingFileList = fileList.filter(file => file.status === 'uploading' || file.status === 'waiting');
if (uploadingFileList.length) { if (uploadingFileList.length) {
Modal.confirm({ Modal.confirm({
...@@ -207,15 +287,22 @@ class UploadProgressModal extends React.Component { ...@@ -207,15 +287,22 @@ class UploadProgressModal extends React.Component {
icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>, icon: <span className="icon iconfont default-confirm-icon">&#xe6f4;</span>,
onOk: () => { onOk: () => {
uploadingFileList.forEach((uploadingFile, index) => { uploadingFileList.forEach((uploadingFile, index) => {
if (vendorType === 'TENCENT_COS') {
// 腾讯云取消上传
if (uploadingFile.taskId) {
ossClient.cancelTask(uploadingFile.taskId);
}
} else {
// 阿里云取消上传
const { checkpoints } = uploadingFile; const { checkpoints } = uploadingFile;
Object.values(checkpoints).forEach(checkpoint => { Object.values(checkpoints).forEach(checkpoint => {
const { uploadId, name } = checkpoint; const { uploadId, name } = checkpoint;
ossClient.abortMultipartUpload(name, uploadId); ossClient.abortMultipartUpload(name, uploadId);
}); });
}
fileList.splice(index, 1); fileList.splice(index, 1);
}) });
this.setState({ fileList: [] });
this.setState({ fileList });
this.props.onCancel(); this.props.onCancel();
} }
}) })
...@@ -227,12 +314,21 @@ class UploadProgressModal extends React.Component { ...@@ -227,12 +314,21 @@ class UploadProgressModal extends React.Component {
// 取消单个文件上传 // 取消单个文件上传
handleCancelUpload = (currentFile, index) => { 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; const { checkpoints } = currentFile;
Object.values(checkpoints).forEach(checkpoint => { Object.values(checkpoints).forEach(checkpoint => {
const { uploadId, name } = checkpoint; const { uploadId, name } = checkpoint;
ossClient.abortMultipartUpload(name, uploadId); ossClient.abortMultipartUpload(name, uploadId);
}); });
}
fileList.splice(index, 1); fileList.splice(index, 1);
this.setState({ fileList }); 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