-
Notifications
You must be signed in to change notification settings - Fork 0
上传组件
xinwu-yang edited this page Mar 1, 2023
·
1 revision
支持S3标准协议,支持多线程断点续传,并提供Vue组件版和JavaScript版。超过设置分片大小的文件,自动使用分片上传,每个分片不能小于5MB,且不能超过5GB,默认为5MB。
- WebWorker多线程分片上传
- 暂停上传(暂时停止上传,保留上传任务)
- 继续上传(继续上传暂停的任务)
- 取消上传(调用取消上传后,整个文件需要重新上传)
- 断点续传(bucket、object与上次上传相同的话,自动触发断点续传)
- 超时重试(3次)
- 上传进度(status:状态,percent:进度)
- 实时上传速度(speed:速度,element:单位)
yarn add @tievd/cube-chunk-uploader -S
// vue组件 ant-design
import Vue from 'vue'
import { ChunkUploader } from '@tievd/cube-chunk-uploader'
Vue.use(ChunkUploader)
// or js类
import CubeUploader from '@tievd/lib/cubeUploader'
new CubeUploader(...)
<!-- 将安装包中的./lib/cube-chunk-uploader.min.js引入项目,样式根据自己项目实现 -->
<script type="text/javascript" src="your-path/cube-chunk-uploader.min.js"></script>
<script type="text/javascript">
var uploader = new CubeChunkUploader(...);
</script>
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
config | 基本配置,host(服务地址)、port(服务端口)、protocol(http:或https:)、accessKeyId、secretAccessKey、sessionToken、region | object | |
bucket | 上传桶名 | string | |
object | 上传对象 | string | |
styleType | 组件样式 | 'default'|'card'|'draggable' | 'default' |
tip | 提示styleType='draggable'时有用 | string | |
chunkSize | 分片大小,单位Byte | number | 5 * 1024 * 1024 |
maxSize | 最大体积,单位MB | number | 5 * 1024 * 1024 |
maxWorkerCount | 最大线程数,一般为cpu逻辑核心数 | number | window.navigator.hardwareConcurrency |
showProgress | 是否展示进度条 | boolean | false |
showSpeed | 是否展示实时速度 | boolean | false |
showLoading | 是否展示loading | boolean | false |
fileChange | 文件变化的回调 | function | function(file) |
success | 上传成功的回调 | function | function() |
progress | 上传进度的回调 | function | function(data: { status, percent})状态、进度 |
speed | 上传速度的回调 | function | function(data: {speed, element})速度、单位 |
事件名称 | 说明 |
---|---|
abortUpload | 取消上传 |
pauseUpload | 暂停上传 |
continueUpload | 继续上传 |
doUpload | 进行上传 |
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
config | 基本配置,host(服务地址)、port(服务端口)、protocol(http:或https:)、accessKeyId、secretAccessKey、sessionToken、region、chunkSize、maxWorkerCount | object | |
bucket | 上传桶名 | string | |
object | 上传对象 | string | |
handleComplete | 上传成功的回调 | function | |
handleUploadProgress | 上传进度的回调 | function | |
handleSpeed | 上传速度的回调 | function |
事件名 | 说明 | 参数 |
---|---|---|
addFile | 添加文件 | function(file) |
removeFile | 移除文件 | function(index) 文件位置 |
abortUpload | 取消上传 | function() |
pauseUpload | 暂停上传 | function() |
continueUpload | 继续上传 | function() |
doUpload | 进行上传 | function() |
<template>
<div style="margin: 20px;">
<chunk-uploader
ref="chunkUploader"
:config="config"
:bucket="bucket"
:object="object"
:showSpeed="true"
:showLoading="true"
:showProgress="true"
@fileChange="handleFileChange"
@success="handleSuccess"
@progress="handleProgress"
@speed="handleSpeed"
></chunk-uploader>
<a-button @click="doUpload">开始上传</a-button>
<a-button style="margin-left: 15px" type="danger" @click="abortUpload">终止上传</a-button>
<a-button style="margin-left: 10px" @click="pauseUpload">暂停上传</a-button>
<a-button style="margin-left: 10px" type="primary" @click="continueUpload">继续上传</a-button>
</div>
</template>
<script>
import { ChunkUploader } from '@tievd/cube-chunk-uploader'
let loadingHide = null
let splitLoadingHide = null
export default {
name: 'Demo',
components: {
ChunkUploader
},
data() {
return {
fileList: [],
uploader: {},
config: {}, // 基本配置
bucket: '', // 桶名
object: '', // 上传对象
file: {}
}
},
mounted() {
this.getMinIOConfig()
},
methods: {
async getMinIOConfig() {
// S3基本配置
this.config = {
host: '25.30.9.158',
port: 9012,
protocol: 'http:',
accessKeyId: 'H020ZG975DIWCBNVZ95Q',
secretAccessKey: 'QYF1jQVtU9zpfZQF+a1LL+I1nKUJRmyy+nJKG5Zs',
sessionToken:
'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiJIMDIwWkc5NzVESVdDQk5WWjk1USIsImV4cCI6NjA0ODAwMDAwMDAwMDAwLCJwb2xpY3kiOiJjb25zb2xlQWRtaW4iLCJzZXNzaW9uUG9saWN5IjoiZXdvZ0lDQWdJbFpsY25OcGIyNGlPaUFpTWpBeE1pMHhNQzB4TnlJc0NpQWdJQ0FpVTNSaGRHVnRaVzUwSWpvZ1d3b2dJQ0FnSUNBZ0lIc0tJQ0FnSUNBZ0lDQWdJQ0FnSWtWbVptVmpkQ0k2SUNKQmJHeHZkeUlzQ2lBZ0lDQWdJQ0FnSUNBZ0lDSkJZM1JwYjI0aU9pQmJDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWljek02VUhWMFQySnFaV04wSWdvZ0lDQWdJQ0FnSUNBZ0lDQmRMQW9nSUNBZ0lDQWdJQ0FnSUNBaVVtVnpiM1Z5WTJVaU9pQmJDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWlZWEp1T21GM2N6cHpNem82T2lvaUNpQWdJQ0FnSUNBZ0lDQWdJRjBLSUNBZ0lDQWdJQ0I5Q2lBZ0lDQmRDbjA9In0.GY3tRVCrzEQSmdxcfwbRcv0MRTToRHJ_3SK2V5Ov5JK0PHE2zbAUOV17ao20AG-FPB5sK3XJBIpnxGzIb7qSlg',
region: 'zh-sc-cd'
}
},
async getBucketObject(fileName) {
this.bucket = 'test'
this.object = `${fileName}`
},
async handleFileChange(file) {
this.file = file
await this.getBucketObject(this.file.name)
},
async doUpload() {
this.$refs.chunkUploader.handleUpload()
},
handleProgress(data) {
if (data.status === 'UPLOADING') {
splitLoadingHide && splitLoadingHide()
if (loadingHide === null) {
loadingHide = this.$message.loading('正在上传。。。', 0)
}
console.log('ChunkUploader进度:', data.percent)
} else if (data.status === 'SPLITTING') {
splitLoadingHide = this.$message.loading('正在分片。。。', 0)
}
},
handleSpeed({ speed, element }) {
console.log(`speed:${speed}${element}/s`)
},
handleSuccess() {
loadingHide && loadingHide()
loadingHide = null
console.log('ChunkUploader上传成功')
},
abortUpload() {
splitLoadingHide && splitLoadingHide()
loadingHide && loadingHide()
this.$refs.chunkUploader.abortUpload()
},
pauseUpload() {
this.$refs.chunkUploader.pauseUpload()
},
continueUpload() {
this.$refs.chunkUploader.continueUpload()
}
}
}
</script>
<template>
<div style="margin: 20px;">
<a-upload name="file" :multiple="false" :fileList="this.fileList" :beforeUpload="this.handleBeforeUpload" :remove="this.handleRemove">
<a-button> <a-icon type="upload" /> 请选择文件 </a-button>
</a-upload>
<br />
<a-button type="primary" @click="handleUpload">开始上传</a-button>
<a-button style="margin-left: 10px" type="danger" @click="cubeAbortUpload">终止上传</a-button>
<a-button style="margin-left: 10px" @click="cubePauseUpload">暂停上传</a-button>
<a-button style="margin-left: 10px" type="primary" @click="cubeContinueUpload">继续上传</a-button>
</div>
</template>
<script>
import CubeChunkUploader from '@tievd/cube-chunk-uploader/lib/cubeChunkUploader'
let loadingHide = null
let splitLoadingHide = null
export default {
name: 'Demo',
components: {},
data() {
return {
fileList: [],
uploader: {}
}
},
methods: {
handleBeforeUpload(file) {
this.fileList = [file]
return false
},
async handleUpload() {
const file = this.fileList[0]
const bucket = 'test'
const object = file.name
this.uploader = new CubeChunkUploader(
{
host: '25.30.9.158',
port: 9012,
protocol: 'http:',
accessKeyId: 'H020ZG975DIWCBNVZ95Q',
secretAccessKey: 'QYF1jQVtU9zpfZQF+a1LL+I1nKUJRmyy+nJKG5Zs',
sessionToken:
'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiJIMDIwWkc5NzVESVdDQk5WWjk1USIsImV4cCI6NjA0ODAwMDAwMDAwMDAwLCJwb2xpY3kiOiJjb25zb2xlQWRtaW4iLCJzZXNzaW9uUG9saWN5IjoiZXdvZ0lDQWdJbFpsY25OcGIyNGlPaUFpTWpBeE1pMHhNQzB4TnlJc0NpQWdJQ0FpVTNSaGRHVnRaVzUwSWpvZ1d3b2dJQ0FnSUNBZ0lIc0tJQ0FnSUNBZ0lDQWdJQ0FnSWtWbVptVmpkQ0k2SUNKQmJHeHZkeUlzQ2lBZ0lDQWdJQ0FnSUNBZ0lDSkJZM1JwYjI0aU9pQmJDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWljek02VUhWMFQySnFaV04wSWdvZ0lDQWdJQ0FnSUNBZ0lDQmRMQW9nSUNBZ0lDQWdJQ0FnSUNBaVVtVnpiM1Z5WTJVaU9pQmJDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWlZWEp1T21GM2N6cHpNem82T2lvaUNpQWdJQ0FnSUNBZ0lDQWdJRjBLSUNBZ0lDQWdJQ0I5Q2lBZ0lDQmRDbjA9In0.GY3tRVCrzEQSmdxcfwbRcv0MRTToRHJ_3SK2V5Ov5JK0PHE2zbAUOV17ao20AG-FPB5sK3XJBIpnxGzIb7qSlg',
region: 'zh-sc-cd'
},
bucket,
object,
this.handleComplete,
this.handleUploadProgress,
this.handleUploadSpeed
)
this.uploader.addFile(file)
this.uploader.doUpload()
},
handleRemove(file) {
let index = this.fileList.indexOf(file)
this.fileList.splice(index, 1)
this.uploader.removeFile(index)
},
handleUploadProgress(data) {
if (loadingHide === null) {
loadingHide = this.$message.loading('正在上传...', 0)
}
console.log('CubeUploader进度:', data.percent)
if (data.status === 'UPLOADING') {
splitLoadingHide && splitLoadingHide()
if (loadingHide === null) {
loadingHide = this.$message.loading('正在上传...', 0)
}
console.log('CubeUploader进度:', data.percent)
} else if (data.status === 'SPLITTING') {
splitLoadingHide = this.$message.loading('正在分片...', 0)
}
},
handleUploadSpeed({ speed, element }) {
console.log(`cube uploader speed:${speed}${element}/s`)
},
handleComplete() {
console.log('上传成功')
loadingHide && loadingHide()
loadingHide = null
},
cubeAbortUpload() {
splitLoadingHide && splitLoadingHide()
loadingHide && loadingHide()
this.uploader.abortUpload()
},
cubePauseUpload() {
this.uploader.pauseUpload()
},
cubeContinueUpload() {
this.uploader.continueUpload()
}
}
}
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>魔方分片上传示例</title>
<style>
html {
font-size: 62.5%;
}
#form > .form-item {
margin-bottom: 20px;
}
#file-list {
margin: 10px 0;
}
.file-btn {
position: relative;
display: inline-block;
}
#file {
position: absolute;
left: 0;
top: 0;
opacity: 0;
z-index: 999;
width: 200px;
}
.select-btn {
width: 200px;
}
</style>
<script type="text/javascript" src="cube-chunk-uploader.min.js"></script>
</head>
<body>
<div id="form">
<div class="form-item">
<div class="file-btn">
<input id="file" type="file" name="file" />
<button class="select-btn">点击这里选择你要上传的文件</button>
</div>
</div>
<div id="file-list" class="form-list"></div>
<button id="submit">提交</button>
<button id="abort">终止</button>
<button id="pause">暂停</button>
<button id="continue">继续</button>
</div>
</body>
<script>
window.onload = () => {
const fileEle = document.getElementById('file')
const submitBtn = document.getElementById('submit')
const abortBtn = document.getElementById('abort')
const pauseBtn = document.getElementById('pause')
const continueBtn = document.getElementById('continue')
const fileList = document.getElementById('file-list')
let uploader = null
fileEle.onchange = (e) => {
const files = e.target.files
const keys = Object.keys(files)
keys.forEach((index) => {
fileList.innerHTML += `<div id="file-${index}" class="file-item" width="100" height="100">${files[index].name}</div>`
})
}
submitBtn.onclick = (e) => {
function handleComplete() {
console.log('上传成功')
}
function handleUploadProgress({ status, percent }) {
console.log('进度:', percent)
}
function handleUploadSpeed({ speed, element }) {
console.log(`速度:${speed}${element}/s`)
}
const file = fileEle.files[0]
const bucket = 'test'
const object = file.name
uploader = new CubeChunkUploader(
{
host: '25.30.9.158',
port: 9012,
protocol: 'http:',
accessKeyId: 'H020ZG975DIWCBNVZ95Q',
secretAccessKey: 'QYF1jQVtU9zpfZQF+a1LL+I1nKUJRmyy+nJKG5Zs',
sessionToken:
'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiJIMDIwWkc5NzVESVdDQk5WWjk1USIsImV4cCI6NjA0ODAwMDAwMDAwMDAwLCJwb2xpY3kiOiJjb25zb2xlQWRtaW4iLCJzZXNzaW9uUG9saWN5IjoiZXdvZ0lDQWdJbFpsY25OcGIyNGlPaUFpTWpBeE1pMHhNQzB4TnlJc0NpQWdJQ0FpVTNSaGRHVnRaVzUwSWpvZ1d3b2dJQ0FnSUNBZ0lIc0tJQ0FnSUNBZ0lDQWdJQ0FnSWtWbVptVmpkQ0k2SUNKQmJHeHZkeUlzQ2lBZ0lDQWdJQ0FnSUNBZ0lDSkJZM1JwYjI0aU9pQmJDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWljek02VUhWMFQySnFaV04wSWdvZ0lDQWdJQ0FnSUNBZ0lDQmRMQW9nSUNBZ0lDQWdJQ0FnSUNBaVVtVnpiM1Z5WTJVaU9pQmJDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWlZWEp1T21GM2N6cHpNem82T2lvaUNpQWdJQ0FnSUNBZ0lDQWdJRjBLSUNBZ0lDQWdJQ0I5Q2lBZ0lDQmRDbjA9In0.GY3tRVCrzEQSmdxcfwbRcv0MRTToRHJ_3SK2V5Ov5JK0PHE2zbAUOV17ao20AG-FPB5sK3XJBIpnxGzIb7qSlg',
region: 'zh-sc-cd'
},
bucket,
object,
handleComplete,
handleUploadProgress,
handleUploadSpeed
)
uploader.addFile(file)
uploader.doUpload()
}
abortBtn.onclick = (e) => {
uploader.abortUpload()
}
pauseBtn.onclick = (e) => {
uploader.pauseUpload()
}
continueBtn.onclick = (e) => {
uploader.continueUpload()
}
}
</script>
</html>