<template>
<div class="hello">
<el-upload class="upload-demo" drag :on-change='change' :auto-upload='false' action multiple>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
{{total}}
<el-progress :text-inside="true" :stroke-width="26" :percentage="total"></el-progress>
<el-button @click="handelBtn">{{btn?'继续':'暂停'}}</el-button>
</div>
</template>
<script>
import SparkMD5 from 'spark-md5'
import axios from 'axios'
import qs from 'qs'
export default {
name: 'HelloWorld',
data() {
return {
img: null,
msg: 'Welcome to Your Vue.js App',
total: 0,
video: null,
btn: false,
abort:false,
partList:[],
hash:''
}
},
methods: {
async change(file) {
file = file.raw
let fileReader = new FileReader()
fileReader.readAsArrayBuffer(file)
let buffer = null
// console.log(SparkMD5);
//1. 解析为buffer数据
fileReader.onload = ev => {
buffer = ev.target.result
console.log(buffer);
// 2. 使用SparkMD5
let spark = new SparkMD5.ArrayBuffer()
spark.append(buffer)
// 3.获取hash值
let hash = spark.end()
// 4.截取文件后缀
let suffix = /\.([0-9a-zA-Z]+)$/i.exec(file.name)[1]
console.log(suffix);
// 切片
let partList = []
// 单个切片大小 (切100片)
let partSize = Math.ceil(file.size / 100)
// 纪录当前切到哪
let cur = 0
for (let i = 0; i < 100; i++) {
let item = {
chunk: file.slice(cur, cur + partSize),
filename: `${hash}_${i}.${suffix}`,
}
cur += partSize
partList.push(item)
}
this.partList = partList
this.hash = hash
this.sendRequest(this.partList, this.hash)
}
},
// 上传分片
async sendRequest() {
// 根据切片做100请求
let requestList = []
this.partList.forEach((item, index) => {
// 每一个fn就是发送一个切片请求
let fn = () => {
let formDate = new FormData()
formDate.append('chunk', item.chunk)
formDate.append('filename', item.filename)
return axios.post('每一片请求接口', formDate, {
headers: {
"content-Type": 'multipart/form-data'
}
}).then(res => {
// debugger
if (res.data.code == 0) {
this.total += 1
// 传完切片移除掉 为了实现断点续传
this.partList.splice(index, 1)
}
})
}
requestList.push(fn)
// console.log(requestList);
})
// 传递
let i = 0
let complete = async () => {
console.log('complete')
let result = await axios.post('上传全部后的接口', {
params: {
hash: this.hash
}
})
console.log(result)
result = result.data
if (result.code = 0) {
this.video = result.path
}
}
console.log(requestList.length, '----');
let send = async () => {
// 已经终端则不在上传
if(this.abort) return
if (i >= requestList.length) {
// 全部上传成功
complete()
return
}
console.log(i, '====');
await requestList[i]()
i++
send()
}
send()
},
handelBtn() {
if(this.btn) {
// 断点续传
this.btn = false
this.abort = false
this.sendRequest()
return
}
// 暂停上传
this.btn = true
this.abort = true
},
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1,
h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
大文件分片断点续传
最新推荐文章于 2023-02-08 19:41:44 发布