大文件上传(串行(不全))

 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>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值