import OSS from 'ali-oss'
import SparkMD5 from 'spark-md5' // 依赖库,对文件进行md5加密唯一标识
import VProgress from './Progress' // 一个简单的进度条组件
// localstorage缓存上传进度指针,失败后可再次上传
const pointerCache = {
get(file, name) {
const cache = localStorage.getItem(cacheKey)
if (!cache) return null
const cacheJson = JSON.parse(cache)
if (cacheJson.name !== name) return null
cacheJson.file = file
return cacheJson
},
set(pointer) {
localStorage.setItem(cacheKey, JSON.stringify(pointer))
},
remove() {
localStorage.removeItem(cacheKey)
}
}
export default {
props: {
data: {
type: Object,
default() {
return {
region: '',
accessKeyId: '',
accessKeySecret: '',
bucket: ''
}
}
},
multiple: {
type: Boolean,
default: true
}
},
data() {
return {
files: []
}
},
methods: {
async changFile() {
const files = this.$refs.input.files || []
for (let i = 0; i < files.length; i++) {
const file = files[i]
const name = await this.getName(file)
if (!this.files.some(item => item.name === name)) {
this.files.push({
file,
percent: 0,
name
})
}
}
console.log(this.files)
},
getName(file) {
return new Promise(resolve => {
const {name} = file
const suffix = name.substr(name.lastIndexOf('.'))
const spark = new SparkMD5.ArrayBuffer()
const reader = new FileReader()
reader.readAsArrayBuffer(file)
// Indicator.open() // loading 文件过大的时候读取时间非常长
reader.addEventListener('load', (e) => {
spark.append(e.target.result);
// Indicator.close()
resolve(spark.end() + suffix) // 文件md5加密,放置重复上传
})
})
},
async uploadAll() {
if (this.files.length === 0) {
// Toast('请选择文件')
return
}
for (let i = 0; i < this.files.length; i++) {
const {file, name} = this.files[i]
await this.upload(file, name, i)
}
},
async upload(file, name, index) {
const that = this
const client = new OSS(this.data) // 阿里文件上传对象
let checkpoint = pointerCache.get(file, name) // 断点续传指针
// 失败后尝试两次
for (let i = 0; i < 2; i++) {
try {
const result = await client.multipartUpload(name, file, {
checkpoint,
async progress(percentage, cpt) { // 上传进度
console.log(percentage)
that.files[index].percent = parseInt(percentage * 100, 10)
pointerCache.set(cpt)
checkpoint = cpt
},
})
pointerCache.remove()
console.log('上传成功:', result)
break // break if success
} catch (e) {
console.log('上传失败:', e)
}
}
},
},
components: {
VProgress
}
}