关于程序包大文件上传处理,前端实现断点续传文件

// dom代码
<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
    }
  },

  

// 实现方法

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;
      }
    }

  

 

猜你喜欢

转载自www.cnblogs.com/soonK/p/13395666.html