主要是写了一个大体的思路,需微调整
import Compressor from 'compressorjs'
import {satrtUpload,satrtBinaryUpload,remuseUpload, remuseBinaryUpload} from serviceData
const blobToBase64 = (blob, type = 'BASE64')=>{
return new Promise((resolve,reject)=>{
try{
const render = new FileReader()
if(type === 'BASE64'){
render.readAsDataURL(Blob)
}else{
render.readAsArrayBuffer(blob)
}
render.onload = (e) =>{
if(type = 'BASE64'){
resolve(e.target.result)
}else{
const binaryArr = new Int8Array(render.result)
resolve(binaryArr)
}
}
} catch(e){
reject(e)
}
})
}
const compress = (file) => {
return new Promise((resolve, reject) => {
if (!file) {
return reject(new Error('文件上传失败,请重试'))
}
let quality = 0.6
const fileSize = Number(file.size) || 0
if (fileSize >= 10485760) {
quality = 0.1
} else if (fileSize < 3145728 && fileSize >= 1048576) {
quality = 0.3
} else if (fileSize < 1048576 && fileSize >= 524288) {
quality = 0.8
} else {
quality = 1
}
new Compressor(file, {
quality,
success: async (result) =>{
const base64 = await blobToBase64(result)
const binary = await blobToBase64(result, 'BINARY')
let base64Str = base64
if(base64 && base64.length > 20){
if(base64.indexOf(',') > -1){
base64Str = base64.split(',')[1]
}
resolve({base64,base64Str, binary})
}else{
reject(new Error('图片流为空'))
}
},
error: (err)=>{
reject(err)
}
})
})
}
let base64Data = ''
let binaryData = []
let fileType = ''
let fileSize = ''
const fileChange = async (e) =>{
const file = e.target.files[0]
const {base64,binary} = await compress(file)
base64Data = base64
binaryData = binary
fileType = file.type.split('/')[1]
fileSize = file.size
beforeUpload('BINARY')
}
let uploadCount = ''
let uploadId = ''
let uploadSize = ''
let remainIds = []
let uploaded = []
let retryTimes = 0
let allIds = []
const beforeUpload = async(fileDataType = 'BASE64') =>{
let data = {}
if(fileDataType === 'BASE64'){
data = await satrtUpload({fileSize: base64Data.length})
}else{
data = await satrtBinaryUpload({fileSize,fileType})
}
if(data.type === 1){
this.$emit('afterUpload',1)
}else if(data.type === 2){
uploadCount = data.count
uploadId = data.id
uploadSize = data.size
uploadCount = data.count
const temp = []
for(let i = 0; i <uploadCount; i++){
temp.push(i)
}
allIds = temp
initResume([])
}
}
let initResume = async (uploaded) =>{
remainIds = await allIds.filter(item =>{
uploaded.indexOf(item) < 0
})
resumeUpload()
}
const resumeUpload = async () =>{
if(retryTimes >= 10){
return toast('上传重试达到10次,已取消上传')
}
for(let i = 0; i < remainIds.length; i++){
const no = remainIds[i]
let remuseData = ''
if(fileDataType === 'BASE64'){
remuseData = base64Data.slice(uploadSize * no, uploadSize * (no + 1))
await remuseUpload({no,remuseData})
uploaded.push(no)
}else{
remuseData = binaryData.slice(uploadSize * no, uploadSize * (no + 1))
let form = new FormData()
form.append('no',no)
form.append('uploadId',uploadId)
form.append('remuseData',remuseData)
await remuseBinaryUpload({no,remuseData})
uploaded.push(no)
}
}
let data = {}
if(fileDataType === 'BASE64'){
data = await endUpoad({})
}else{
data = await endBinaryUpoad({uploadId})
}
if(data.remainCount > 0){
retryTimes++
uploaded = data.uploaded
await initResume(uploaded)
}else{
this.$emit('afterUpload',2,uploadId)
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人