zoukankan      html  css  js  c++  java
  • 实现前端断点续传功能

    实现原理将文件切割成几份,一份份的上传,上传完毕,再通过接口告知后端将所有片段合并

    // 模板

    <el-form-item label="请选择文件:" v-if="!processPercentage">
            <div class="upload-button-box">
              <input
                type="file"
                name="file" 
                ref="input"
                accept=".tar.gz"
                @change="onChange"
                class="upload-button"
              />
              <el-button size="small" type="primary">上传文件</el-button>
              <span v-if="form.file" style="margin-left: 15px">{{ this.form.file.name }}</span>
              <div class="tips">支持扩展名:.tar.gz</div>
            </div>
          </el-form-item>
    

    // 引入依赖

    import md5Hex from 'md5-hex'
    

    // 定义数据

    data () {
        return {
          form: {
            file: undefined
          },
          rules: {
          },
          processPercentage: 0,
          // 文件块大小 200M
          eachSize: 1024 * 1024 * 20,
          loading: {
            upload: false
          },
          fileLength: 0,
          isBool: false,
          isError: false
        }
      },
    

    // 实现方法

    // 关闭弹框的方法
    onClose (type = 'dismiss') {
          if(type === 'dismiss') {
            this.isBool = false;
          }
          this.$emit('closeDialog', {
            name: this.dialoagName,
            type
          });
        },
    

      

    onChange (e) {
          this.form.file = Array.from(e.target.files)[0];
        },
        // 开始上传
        async onImport() {
          try {
            this.isError = false;
            this.loading.upload = true;
            // 将名字转成编码
            this.form.file.uid =  md5Hex(this.form.file.name);
            // 定义当前上传的索引
            this.form.file.chunk = 0;
            // 分片大小要求100M以下的分片大小设置为5M,以上的设置为20M
            if(this.form.size > 1024 * 1024 * 100) {
              this.eachSize = 1024 * 1024 * 20
            } else {
              this.eachSize = 1024 * 1024 * 5
            }
            this.fileLength = Math.ceil(this.form.file.size / this.eachSize);
     
            // 检测文件是否存在
            const { data } = await PackageImportService.getPackageImportUpload(this.form.file.uid);
            this.isBool = true;
            this.onUpload(this.form, data);
     
          } catch (error) {
            console.log(error)
          }
        },
        // 合并分片
        async packageImportMerge() {
          try {
            // 合并分片
            this.processPercentage = 100;
            await PackageImportService.packageImportMerge(
              this.form.file.uid,
              this.fileLength,
              this.form.file.name,
              this.$route.params.appId,
              this.$route.params.planId
            );
            this.$message.success(`程序包[${this.form.file.name}]导入成功`);
            this.onClose('confirm')
          } finally {
            this.loading.upload = false;
          }
        },
        async onUpload({file}, chunk) {
          try {
            if(!this.isBool) return;
            // 当前字节
            const blobFrom = file.chunk * this.eachSize;
            // 获取文件块的终止字节
            const blobTo = (file.chunk + 1) * this.eachSize > file.size ? file.size : (file.chunk + 1) * this.eachSize;
            if (chunk) file.chunk = chunk;
     
            // 进度条数值
            this.processPercentage = Number((blobTo / file.size * 100).toFixed(1));
            // 合并分片
            if (file.chunk === this.fileLength) {
              this.packageImportMerge()
              return;
            }
            // 检查断点续传的分片存在与否
            const { data } = await PackageImportService.checkPackageImport(file.uid, file.chunk);
            // 片段存在跳过本次上传
            if (data) {
              file.chunk++;
              this.onUpload({file: file});
              return;
            }
            // 将分片数据上传
            let formData = new FormData();
            formData.set('file', file.slice(blobFrom, blobTo));
            await PackageImportService.packageImport(file.uid, file.chunk, formData);
            file.chunk++;
            this.onUpload({file: file});
     
          } catch (error) {
            this.loading.upload = false;
            this.isError = true;
          }
        }
    

      

  • 相关阅读:
    D. The Fair Nut and the Best Path 树形dp (终于会了)
    (二)网络流之最大流
    网络流(知识点) 一 终究还是躲不掉
    dp 优化 F2. Pictures with Kittens (hard version)
    da shu mo ban
    AtCoder Regular Contest 090 F
    Codeforces 918D MADMAX 图上dp 组合游戏
    Codeforces 918C The Monster
    AtCoder Regular Contest 090 C D E F
    poj 3623 Best Cow Line, Gold 后缀数组 + 贪心
  • 原文地址:https://www.cnblogs.com/fczbk/p/12395025.html
Copyright © 2011-2022 走看看