vue项目中大文件断点续传

1、安装 MD5

npm i spark-md5

2.看看代码 把接口对上直接复制代码使用

<template>
  <div class="breakpoint">
    <el-upload
      class="uploadFile"
      ref="upload"
      :action="api + uploadVideoUrlnew"
      :data="mySkyFileParam"
      :http-request="uploadFile"
      :on-error="handlefileerror"
      :before-upload="beforeAvatarUpload"
      :on-success="handleupfileOK"
      :on-change="changeFile"
      :headers="Headers"
      :on-progress="handleAvatarprogress"
      :show-file-list="false"
      multiple
      accept
    >
      <i v-if="percentage==0" style="font-size:30px;" class="el-icon-plus avatar-uploader-icon"></i>
      <i v-else  style="font-size:30px;" class="el-icon-video-camera-solid"></i>
      <el-progress :percentage="percentage"></el-progress>
    </el-upload>
  </div>
</template>
<script>
import { is_show, is_show_RET } from "@/utils/is_show";//提示语
import SparkMD5 from "spark-md5"; //引入MD5
import {
  postChunk,//分片上传接口
  mergeFile,//合并分片接口 
  getIdentifier,//检测是否传过
} from "@/api/resume";
import { getToken,getuserName } from "@/utils/auth";
export default {
  name:'breakpoint',
  components: {},

  data() {
    return {
      percentage:0,
      api: window.g.BASE_API,
      uploadVideoUrlnew: "/basic/uploader/chunk",
      upFlag: false,
      Headers: {
          access_token:getToken()
        },
      mySkyFileParam: {
        uuid: "",
        parentId: "",
        subjectId: "",
        yearperiodId: "",
      },
      sendDatas:{
        videoName:'',
        fileSize:'',
        data:'',
      }
    };
  },
  watch: {},
  created() {},
  methods: {
    uploadFile(param) {
      const file = param.file;
      this.handlePrepareUpload(file);
    },
    // 计算MD5
    handlePrepareUpload(file) {
      const fileReader = new FileReader();
      const dataFile = file;
      const _this = this;
      const spark = new SparkMD5(); // 创建md5对象(基于SparkMD5)
      if (dataFile.size > 1024 * 1024 * 50) {
        const data1 = dataFile.slice(0, 1024 * 1024 * 50); // 将文件进行分块 file.slice(start,length)
        fileReader.readAsBinaryString(data1); // 将文件读取为二进制码
      } else {
        fileReader.readAsBinaryString(dataFile);
      }
      // 文件读取完毕之后的处理
      fileReader.onload = function (e) {
        spark.appendBinary(e.target.result);
        const md5 = spark.end();
        // 检验上传
        _this.detection(file, md5);
      };
    },
    // 切割上传
    async upload(file, num, md5) {
        // console.log(file,'切割上传=====', num)
        // 计算总片数
        let bytesPerPiece = 8 * 1024 * 1024; // 每个文件切片大小定为8MB
        const totalPieces = Math.ceil(file.size / bytesPerPiece); // 总片数
        // console.log(totalPieces,'总片数');
        this.percentage = Number(((num / totalPieces) * 100).toFixed(0));
        // console.log(this.percentage)
        // console.log('总数' + totalPieces)
        if (num === totalPieces) {
          return;
        }
        // 切割上传
        const nextSize = Math.min((num + 1) * bytesPerPiece, file.size); // 61764222
        const fileData = file.slice(num * bytesPerPiece, nextSize);
        // let currentChunkSize = nextSize-(num * bytesPerPiece)
        const formData = new FormData();
        if (num === totalPieces - 1) {
          // 最后一次文件大小
          bytesPerPiece = file.size - num * 50 * 1024 * 1024;
        }
        const fileName = file.name;
        const size = file.size;
        const lastModified = file.size;
        this.sendDatas.videoName=fileName
        this.sendDatas.fileSize=size

        formData.append('chunkNumber',num );//当前文件块(片)
        formData.append('totalChunks',totalPieces );//文件分片的总片数
        formData.append("identifier", md5);//MD5加密后的文
        formData.append('chunkSize',bytesPerPiece );//每片文件的大小件片标识
        formData.append("filename", fileName);//文件名
        formData.append("totalSize",lastModified );//文件的总大小
        formData.append("upfile", fileData);//文件的内容
        formData.append("currentChunkSize",size );//文件的大小
        formData.append("relativePath",fileName );//文件保存的相对路径
        this.sendDatas.data=''
        postChunk(formData).then((res) => {
          if (res.code === 200) {
            // console.log(num, totalPieces - 1);

            if (num === totalPieces - 1) {
              // console.log('上传完成')
              let add={
                name:fileName,
                relativePath:fileName,
                size:lastModified,
                uniqueIdentifier:md5,
                refProjectId:'1',//随便传的
              }
              mergeFile(add).then((res) => {
                if (res.code === 200) {
                    this.percentage = 100;
                    this.sendDatas.data=res.data
                    is_show(res, "上传成功");
                }
                 this.sendData()
              });
            } else {
              this.sendData()
              this.upload(file, ++num, md5);
            }
          }
        });



    },
    //合并后返回值
    sendData(){
       if (this.percentage==100) {
         // 在这处理成功的数据
         console.log(this.sendDatas);
         
       }
    },
    // 检测
    async detection(file, md5) {
      const identifier = md5;
      // console.log(file.size);
      getIdentifier(identifier,file.name).then((res) => {
        if (res.code === 200) {
          this.upFlag = true;
          if (res.data.index==undefined || res.data.index=='' || res.data.index==null) {
            res.data={
              index:0
            }
          }
          this.upload(file, res.data.index, md5);
        }
      });
    },
    handlefileerror(res) {
      this.$message({
        message: '上传失败!',
        type: 'error'
      })
    },
     beforeAvatarUpload(file) {
      let index = file.name.lastIndexOf(".");
      let extension = file.name.substr(index + 1);
      const extensionList = ['mp4','MP4','mov','MOV']
      const isLt2G = file.size / 1024 / 1024 < 1 * 1024 // 算出文件大小
      if (!isLt2G) {
        // 限制文件大小为1G
        this.$message.error('视频文件不可超出1G')
        return isLt2G
      }
      if (
         extensionList.indexOf(extension) < 0
      ) {
        // 限制文件类型
        this.$message({
          message: '请上传正确文件格式',
          type: 'error',
          center: true
        });
        return false
      }
    },
    handleupfileOK(res, upfileList) {
       this.$message({
        message: '上传成功',
        type: 'success'
      })

    },
    changeFile(res, fileList) {
      // console.log(res, fileList);
    },
    handleAvatarprogress(){

    },
  },
  mounted() {},
  destroyed() {},
};
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped >
</style>

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学而时习之不亦说乎。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值