HTML内容
<!-- 点击上传 -->
<el-dialog
v-model="showUpload"
v-if="showUpload"
width="40%"
title="上传文件"
@close="closeFiles"
>
<div id="customForm">
<div
class="file-content"
style="height: 80px"
>
<div class="file-handle">
<el-upload
ref="uploadFile"
action="#"
:auto-upload="false"
:file-list="fileList"
:on-change="fileChange"
:on-success="uploadSuccess"
:on-error="uploadError"
:http-request="putinMirror"
>
<div class="file-text">
<el-button type="primary" v-auto-blur>点击上传</el-button>
</div>
</el-upload>
</div>
</div>
<el-form
:model="downloadData"
label-width="80px"
:rules="rules"
label-position="left"
ref="ruleFormRef"
>
<el-form-item label="版本号:" prop="version" style="width: 80%">
<el-input v-model="downloadData.version" placeholder="请输入" />
</el-form-item>
</el-form>
<div class="button-wrap">
<el-button @click="closeFiles">取消</el-button>
<el-button type="primary" @click="okBtn">确定</el-button>
</div>
</div>
</el-dialog>
js方法
使用spark-md5计算文件的md5
npm 下载 spark-md5,引入
<script lang="ts">
import { ElLoading, ElMessage, FormInstance } from "element-plus";
import { defineComponent , ref } from "vue";
import SparkMD5 from "spark-md5";
export default defineComponent({
data() {
let rules = {
version: [
{
required: true,
message: "请输入版本号",
trigger: "blur",
},
],
};
let chunkSize = 10 * 1024 * 1024; //定义分片的大小 暂定为10M
let file: any = {};
let md5: any = "";
let downloadData: any = {};
return {
rules,
downloadData,
fileList: [], //上传的文件列表
file,
currentFile: "",
showUpload: false,
percentage: ref(0),
opType: "",
chunkSize,
md5,
mapId: "",
};
},
})
methods: {
uploadSuccess(res) {
if (res.data.code === 0) {
ElMessage({
type: "success",
message: "上传成功",
});
} else {
ElMessage({
type: "error",
message: "上传失败",
});
}
this.initMapList();
},
okBtn() {
(this.$refs.ruleFormRef as FormInstance).validate(async (valid) => {
if (valid) {
//编辑
if (this.opType == "editVersion") {
let params = {
id: this.downloadData.id,
version: this.downloadData.version,
};
let res = await updateMap(params);
if (res.data == true) {
ElMessage({
type: "success",
message: res.msg,
});
this.initMapList();
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
} else if (this.opType == "uploadFile") {
//新增
if (this.fileList.length == 0) {
ElMessage({
type: "error",
message: "请选择上传文件!",
});
return;
}
// 1.拿到文件,计算出文件md5。(需要拿到file作为文件md5方法入参)-----fileList/this.file
// 2.调用save接口,返回mapid
// 3.拿到mapid之后,this.$refs.uploadFile.submit()
// const fileType = this.file.name.split(".")[0];
let params = {
version: this.downloadData.version,
md5: this.md5,
name: this.file.name,
packageName: this.file.name,
};
let res = await saveMap(params);
if (res.code == 0) {
this.mapId = res.data;
this.initMapList();
this.fileList = [];
this.$refs.uploadFile.submit();
}
}
this.showUpload = false;
}
});
},
async putinMirror(file) {
let that = this;
const blob = file.file;
const fileSize = blob.size; // 文件大小
let fileName = blob.name; // 文件名
that.currentFile = file;
//计算当前选择文件需要的分片数量
const chunkCount: Number = Math.ceil(fileSize / that.chunkSize);
console.log(
"文件大小:",
fileSize / 1024 / 1024 + "Mb",
"分片数:",
chunkCount
);
//获取文件md5
let res;
// let fileMd5 = await that.getFileMd5(file, that.chunkSize);
// 循环上传
for (let i: any = 0; i < chunkCount; i++) {
//分片开始位置
let start = i * that.chunkSize;
//分片结束位置
let end = Math.min(fileSize, start + that.chunkSize);
let chunk: any = blob.slice(
start,
Math.min(fileSize, start + that.chunkSize)
);
let _chunkFile = fileName.slice(start, end);
console.log("chunk========", chunk);
console.log("that.md5=====+++++++++===", that.md5);
//mapId name md5 size chunks chunk file
let formdata = new FormData();
formdata.append("md5", that.md5);
formdata.append("name", that.file.name);
formdata.append("chunks", chunkCount);
formdata.append("chunk", i);
formdata.append("size", fileSize);
formdata.append("file", that.file.raw);
formdata.append("id", that.mapId);
/**
* 上传文件方法
* @param formdata 上传文件的参数
*/
res = await uploadMap(formdata);
//一个分片上传完成后再调用接口上传下一片
// if(res.code == 0){
// // that.progress = ((i+1)/chunkCount).toFixed(1) * 100;//控制进度条
// setTimeout(function() {
// if((i+1) == chunkCount){
// ElMessage({
// message: '上传成功',
// type: 'success'
// });
// that.showUpload = true;
// that.closeFiles();
// }
// }, 1000);
// }else {
// ElMessage({
// message: '上传失败',
// type: 'error'
// });
// }
}
this.initMapList();
setTimeout(() => {
this.uploadSuccess(res);
}, 2000);
},
//实现单个文件上传
async fileChange(File, fileList) {
if (fileList.length > 1) {
fileList.splice(0, 1);
}
this.file = File; //获取用户选择的文件
let loadingInstance = ElLoading.service({
text: "文件检验中...",
fullscreen: false,
target: "#customForm",
});
this.md5 = await this.getFileMd5(File, this.chunkSize);
if (this.md5) {
loadingInstance.close();
}
},
/**
* 获取文件MD5
* @param file
* @returns {Promise<unknown>}
*/
getFileMd5(file, chunkSize) {
return new Promise((resolve, reject) => {
let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
let chunks = Math.ceil(file.size / chunkSize);
let currentChunk = 0;
let spark = new SparkMD5.ArrayBuffer(); //追加数组缓冲区。
let fileReader = new FileReader(); //读取文件
fileReader.onload = function (e) {
spark.append(e.target.result);
currentChunk++;
if (currentChunk < chunks) {
loadNext();
} else {
let md5 = spark.end(); //完成md5的计算,返回十六进制结果。
resolve(md5);
}
};
fileReader.onerror = function (e) {
reject(e);
};
function loadNext() {
let start = currentChunk * chunkSize;
let end = start + chunkSize;
end > file.size && (end = file.size);
fileReader.readAsArrayBuffer(blobSlice.call(file.raw, start, end));
}
loadNext();
});
},
}
</script>