一、获取key
getKeyHanlder(obj, file, val) {
// this.uploadDisabled = true;
if (this.timer) {
this.clearTimeoutHandle();
}
breakpointGetKey(obj).then((res) => {
if (res.code == "200") {
this.uploadUrl = res.data.uploadUrl;
this.checkUrl = res.data.checkUrl;
this.uploadKey = res.data.key;
this.randomName = res.data.fileName;
var formData = new FormData(); // 当前为空
formData.append("file", file.raw);
formData.append("key", this.uploadKey);
formData.append("regionId", this.upid);
this.changeFile(file, this.uploadUrl,res.data);
} else {
// this.uploadDisabled = false;
}
});
},
二、创建切片
const chunkSize = 5 * 1024 * 1024; // 每个块的大小为 5MB
const fileSize = file.size; // 文件大小
const chunks = Math.ceil(fileSize / chunkSize); // 总块数
// 切片个数
this.slicesNum = chunks;
// 创建切片
let partList = [],
partsize = chunkSize || file.size / this.slicesNum;
for (let i = 1; i <= this.slicesNum; i++) {
const start = (i - 1) * partsize;
const end = Math.min(start + partsize, fileSize);
let item = {
// chunk: file.slice(cur, Math.min(file.size, cur + partsize)),
chunk: file.slice(start, end),
filename: `${hash}_${i}.${suffix}`,
chunkNumber: `${i - 1}`,
// file: file.slice(cur, Math.min(file.size, cur + partsize)),
file: file.slice(start, end),
};
// cur += partsize;
partList.push(item);
}
this.requestData = {
fileMd5: hash,
name: this.randomName,
size: file.size,
totalChunks: this.slicesNum,
chunkSize: partsize,
fileName: file.name,
uploadKey: reqKeyData.key, // 后台需要的key
};
let obj = {
total: 0,
abort: false,
btn: false,
partList: partList,
uploadErr: false, //是否上传失败
status: 1, //上传状态
};
let fileObj = { ...this.requestData, ...obj };
//文件列表
this.openlistnum.push(fileObj);
this.isUploading = true;
this.sendRequest(fileObj);
三、请求集合
async sendRequest(element) {
element.uploadSuc = false;
// 根据100个切片创造100个请求集合
let requestList = [];
try {
element.partList.forEach((item, index) => {
// 每一个函数都发送一个切片请求
let fn = async (chunkNumber) => {
let formData = new FormData(),
shardFile = new SparkMD5.ArrayBuffer(),
shardFileBuffer = await fileParse(item.chunk, "buffer"),
shardFileHash;
shardFile.append(shardFileBuffer);
shardFileHash = shardFile.end();
formData.append(
"chunk",
element.reqNextChunkNumber ? element.reqNextChunkNumber : item.chunkNumber
);
formData.append("file", item.file);
formData.append("chunks", element.totalChunks);
formData.append("md5", element.fileMd5);
formData.append("name", element.name);
formData.append("size", element.chunkSize);
formData.append("key", element.uploadKey);
return breakpointUpLoadFile(this.uploadUrl, formData).then(
(res) => {
const { code, data } = res;
if (code == 206) {
// element.total += parseInt(100 / element.totalChunks);
//进度
element.total = parseInt(
(res.data.chunkNumber / element.totalChunks) * 100
);
// 传完的切片我们把它移除掉
if(data.chunkNumber){
element.partList.shift();
element.reqNextChunkNumber = res.data.chunkNumber
}
return data.chunkNumber;
} else if (code == 200) {
this.$message.success("上传成功");
element.uploadSuc = true;
element.total = 100;
element.status = 0;
element.uploadErr = false;
this.$parent.gettableList();
this.$parent.getPage(2, this.upid, this.USER_id);
this.closeUploadInfo();
} else {
throw Error(`We've found the target element.`);
}
}
);
};
requestList.push(fn);
});
} catch (err) {}
let i = 0;
let send = async (params) => {
if (params.abort) return;
if (i >= requestList.length && !params.uploadSuc) {
this.$message.warning("上传失败,请重新上传");
params.total = 0;
params.status = 0;
params.uploadErr = true;
this.closeUploadInfo();
return;
}
if (params.uploadSuc) {
params.status = 0;
params.total = 100;
params.uploadErr = false;
return;
}
await requestList[i]().then((res) => {
});
i++;
send(params);
};
send(element);
},
四、暂停,续传
handleBtn(params) {
if (params.btn) {
params.abort = false;
params.btn = false;
this.sendRequest(params);
return;
}
params.btn = true;
params.abort = true;
},
欢迎访问微信小程序“WEB前端宝典”,高频面试题,面试必备。