vue自定义文件分片上传,自定义上传进度

思路请看下一篇文件上传

GlobalUploader全局的组件


<style scoped lang="scss">
  /* 设置滚动条的样式 */
  .scrollbar-div::-webkit-scrollbar {
    width: 5px;
    background-color: #e8e8e8;
  }
  /* 滚动槽 */
  .scrollbar-div::-webkit-scrollbar-track {
    -webkit-box-shadow:inset006pxrgba(0,0,0,0.3);
    border-radius:10px;
  }
  /* 滚动条滑块 */
  .scrollbar-div::-webkit-scrollbar-thumb {
    border-radius:10px;
    background:rgba(92,53,110,0.6);
    -webkit-box-shadow:inset006pxrgba(0,0,0,0.5);
  }
  .show-file-list-uploader{
    width: 520px;
    z-index: 99;
    min-height: 326px;
    border-top: 6px solid rgba(205,179,217,0.93);border-radius: 20px 20px 0px 0px;
    -webkit-box-shadow: 0 4px 6px rgba(96,102,110,0.16);
    -moz-box-shadow: 0 4px 6px rgba(96,102,110,0.16);
    box-shadow: 0 4px 6px rgba(96,102,110,0.16);
    display: flex;
    flex-direction: column;

    .progress-title{
      font-size: 16px;font-weight: bold;color: #5C356E;
      margin: 14px 0;
      display: flex;
      flex-direction: row;
      justify-content: center;
      justify-items: center;
      cursor: pointer;
      .hide-button{
        margin-top: -2px;margin-left: 12px;
        width: 11px;
        height: 11px;
      }
    }
  }
  .tip-file-list{
    margin: 0;padding: 0;font-size: 12px;color: #999999
  }
  /*上传进度条*/
  .hide-file-uploader{
    cursor: pointer;

    .all-file-progress{
      position: relative;
      width: 68px;
      height: 68px;

      .el-progress-box{
        width: 68px;
        height: 68px;
      }
      .percentage-img-background{
        width: 68px;
        height: 68px;
        position: absolute;
        top: 0;
        left: 0;
      }
      .circle-txt{
        position: absolute;
        display: flex;
        flex-direction: column;
        top: 17px;
        left: 10px;
        color: #FFFFFF;
        font-size: 12px;
        text-align: center;
        /*border: 1px solid red;*/

        .ch-txt{
          font-size: 12px;
        }
      }
    }
  }
</style>
<template>
    <div>
      <div class="hide-file-uploader " v-show="panelShow == false"  >
        <div >
          <!--  @click.stop="changePanel(true)"-->
          <div class="all-file-progress"  ref="alarmMain" @mousedown="moveDrag" @click="openClick(true)">
            <img class="percentage-img-background" src="../../assets/images/ic_schedule@2x.png" />
            <el-progress type="circle" :width="68" :percentage="percentage" :color="colors"
                         class="el-progress-box" :stroke-width="4" :show-text="false">
            </el-progress>
            <div class="circle-txt" >
              <span class="ch-txt">上传进度</span>
              <span>{{uploadSuccessSize}}/{{totalSize}}</span>
            </div>
          </div>
        </div>
      </div>

      <div class="show-file-list-uploader common-white-box " id="my_upload_panel_custom__"  v-show="panelShow == true" style="max-height: 390px">
        <div class="progress-title">
          <span>上传进度</span>
          <span @click.stop="changePanel(false)"><img class="hide-button" src="../../assets/images/ic_schedule_receive@2x.png"/></span>
        </div>

        <!--未上传完的-->
        <div style="overflow-y: scroll;max-height: 360px" class="scrollbar-div">
          <div v-for="(fileObj,index) in partUploadFileList" style="margin-bottom: 10px;" >
            <my-custom-uploader :part-file="fileObj.file"
                                :params="fileObj.params"
                                :inputAccept="fileObj.inputAccept"
                                :inputReg="fileObj.inputReg"
                                :stateProgress="fileObj.isUpload"
                                @onUploadSuccess="val=>{onUploadSuccess(fileObj,val,index)}"
                                @deleteFileIcon="val=>{deleteFileState(val);fileObj.isDelete = true;}"
            ></my-custom-uploader>
            <p class="tip-file-list" v-show="!fileObj.isDelete">来源:{{fileObj.comeFrom.origin}}-{{fileObj.comeFrom.originName}}-{{fileObj.comeFrom.position}}</p>
          </div>
          <!--新上传的-->
          <div v-for="(fileObj,index) in currentNotUploadFiles" style="margin-bottom: 10px;">
            <my-custom-uploader :file-obj="fileObj.obj.file"
                                :params="fileObj.obj.params"
                                :stateProgress="fileObj.isUpload"
                                @onUploadSuccess="val=>{onUploadSuccess(fileObj,val,index)}"
                                @saveFilePresent="val=>{}"
                                @deleteFileIcon="val=>{deleteFileState(val);fileObj.isDelete = true;}"
            ></my-custom-uploader>
            <p class="tip-file-list" v-show="!fileObj.isDelete">来源:{{fileObj.obj.comeFrom.origin}}-{{fileObj.obj.comeFrom.originName}}-{{fileObj.obj.comeFrom.position}}</p>
          </div>
          <input ref="reSelectInput" hidden/>
        </div>
      </div>
    </div>
</template>

<script>
  //import indexDB from '@/server/indexDB'//没用到
  import {mapState,mapMutations} from 'vuex'
  import Bus from '@/server/bus';
  import MyCustomUploader from'./CustomUploader'
  import commonApi from '@/api/commonApi';//我整合项目的api接口
  import {ACCEPT_CONFIG} from "@/config/config";//静态数据
    export default {
        name: "GlobalUploader",
      components:{
        MyCustomUploader,
      },
      data(){
          return{
            // panelShow: false,   //选择文件后,展示上传panel
            colors:[
              {color: '#5C356E', percentage: 100},//进度条颜色
            ],
            percentage:0,// 上传进度 0-100
            globalDB:null,
            currentNotUploadFiles:[],
            totalSize:0,
            uploadSuccessSize:0,
            notUploadingFile:[],
            partUploadFileList:[],

            positionX:0,
            positionY:0,
          }
      },
      computed:{
        ...mapState('uploadFile',{//新添加的未上传的文件
          selectFileList:'selectFileList'
        }),
        ...mapState('uploadFile',{//新添加的未上传的文件
          currentUploadedFile:'currentUploadedFile'
        }),
        selectNewFile(){
          return this.selectFileList||[]
        },
        ...mapState('uploadFile',{//显示与隐藏
          panelShowAndHide:'panelShowAndHide'
        }),

        panelShow(){
          return this.panelShowAndHide||false;
        },
      },
      mounted(){

          let that = this;
          // that.OpenDB();//打开数据库
          this.getNotUploadingFileList();//获取未上传完的文件的参数
        /**
         * 开始上传
         */
        Bus.$on('startUpload', param => {
          // this.panelShow = true;//显示上传面板d
          this.panelShowAndHideMutations(true)
          if(this.selectNewFile.length>0){
            // this.currentNotUploadFiles = this.selectNewFile;
            this.totalSize += this.selectNewFile.length;
            // console.log('选中文件上传前',this.selectNewFile)
            for (let i=0;i<this.selectNewFile.length;i++){
              this.currentNotUploadFiles.push({obj:this.selectNewFile[i],isUpload:false,isDelete:false});
            }
            setTimeout(function () {
              console.log('新文件文件上传')
            },100);

          }
        });

        //点击空白处隐藏
        document.addEventListener('mouseup',(e) =>{
          var _con = document.getElementById('my_upload_panel_custom__');
          if(_con) {
            // console.log('对象',e.target);
            if(!_con.contains(e.target)) {
              // this.visible = false;
              this.panelShowAndHideMutations(false)
            }
          }
        })



      },
      watch:{
        uploadSuccessSize(n,o){
          if(n && n != o){
            if(n > 0 && this.totalSize>0){
              this.percentage = 100 * (Math.floor(n / this.totalSize));
              // console.log('进度条',this.percentage ,'this.totalSize = ',this.totalSize,'=>',Math.floor(n / this.totalSize))
              return;
            }
          }
        },

      },
      methods:{
          changePanel(flag){
            this.panelShowAndHideMutations(flag);
          },
        //1、删除文件
        //2、移除文件上传状态
        deleteFileState(flag){
            // if (flag == 'delete') {
            //   this.uploadSuccessSize --;
            // }
            // if (flag == 'remove') {
            //
            // }
            // this.totalSize --;
        },

        //上传成功后
        onUploadSuccess(file,response,index){
          this.uploadSuccessSize ++;
          console.log('global 该文件上传成功this.uploadSuccessSize++,',this.uploadSuccessSize);
         file.isUpload = true;
         Bus.$emit('onUploadSuccess',true)

        },

        // 拖动事件
        moveDrag (e) {
          console.log(e, 'eeee')
          let odiv = e.target // 获取目标元素
          this.$refs.alarmMain.setAttribute('data-flag', false) // 动态为元素添加属性用于判断是否为拖动状态
          const firstTime = new Date().getTime()

          var disx = e.pageX - this.$refs.alarmMain.offsetLeft;
          var disy = e.pageY - this.$refs.alarmMain.offsetTop;
          document.onmousemove = (e) => { // 鼠标按下并移动的事件

            this.$refs.alarmMain.style.left = e.pageX - disx + 'px';
            this.$refs.alarmMain.style.top = e.pageY - disy + 'px';
          }
          document.onmouseup = (e) => {
            document.onmousemove = null
            document.onmouseup = null
            // onmouseup 时的时间,并计算差值
            const lastTime = new Date().getTime()
            if ((lastTime - firstTime) < 200) {
              this.$refs.alarmMain.setAttribute('data-flag', true)
            }
          }
        },
        //点击事件
        openClick (flag) {
          //  验证是否为点击事件,是则继续执行click事件,否则不执行
          let isClick = this.$refs.alarmMain.getAttribute('data-flag')
          if (isClick !== 'true') {
            return false
          } else {
            // this.$refs.alarmTable.open()
            this.panelShowAndHideMutations(flag);
          }
        },

        /**
         * 获取上次未上传完的文件MD5,
         */
        getNotUploadingFileList(){
          let that = this;
          that.$axios.get(commonApi.getUploadingFile()).then((res)=>{
            console.log('未上传完的MD5',res.data);
            if(res.data.IsSuccess){
              if(res.data.ResultValue && res.data.ResultValue.length > 0){
                // console.log('你有未上传的文件,请重新选择')
                const h = this.$createElement;
                  that.$notify({
                    title: '提示',
                    message: h('i',{ style: 'color: #ff6f74'},'您有未上传完的文件数据!'),
                    type: 'warning',
                    duration: 0
                  });
                for (let i=0;i<res.data.ResultValue.length;i++) {
                  let inputType = ACCEPT_CONFIG.getFileRegByFileClassification(res.data.ResultValue[i].FileClassification);//获取文件类型和正则
                  that.partUploadFileList.push({
                    file:{
                      filename:res.data.ResultValue[i].FileName,
                      md5:res.data.ResultValue[i].FileMD5,
                      UploadedMaxChunkNum:res.data.ResultValue[i].UploadedMaxChunkNum
                    },
                    params:{
                      SourceId : res.data.ResultValue[i].SourceId,
                      DataSource : res.data.ResultValue[i].DataSource,
                      FileClassification : res.data.ResultValue[i].FileClassification,
                      LocalPath  : null,
                      CurrentUserId : '',
                      CurrentRoleCode  : '',
                    },
                    comeFrom:{
                      origin:that.$tools.hashValueInArray(res.data.ResultValue[i].DataSource,'key',ACCEPT_CONFIG.DataSourceList,'name'),
                      originName:res.data.ResultValue[i].Remark,
                      position:that.$tools.hashValueInArray(res.data.ResultValue[i].FileClassification,'key',ACCEPT_CONFIG.FileClassificationList,'name'),
                    },
                    inputAccept:inputType.accept,//重新选择文件的时候,文件类型
                    inputReg:inputType.reg,
                    isUpload:false,
                    isDelete:false,
                  })
                }
                this.totalSize += this.partUploadFileList.length;

              }
            }
          })
        },
//其他组件传过来的文件list,给selectFileList赋值前,先清空
        ...mapMutations('uploadFile',{
          selectFileListMutations:'selectFileListMutations'
        }),

//上传列表(要上传的文件)
        ...mapMutations('uploadFile',{
          currentUploadedFileMutations:'currentUploadedFileMutations'
        }),

        ...mapMutations('uploadFile',{//新添加的未上传的文件
          panelShowAndHideMutations:'panelShowAndHideMutations'
        }),
      }
    }
</script>


 

CustomUploader文件上传和上传进度

<style scoped>
  .uploader-img-icon{
    width: 22px;
    height: 28px;
  }
  .uploader-file-name{
    display: inline-block;width: 100px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: left;
  }
</style>
<template>
    <div @click.stop="function() {

          }">
      <!--未上传完的文件,需要重新选择文件上传-->
      <div v-if="fileObject == null">
        <div v-show="(!fileIsDelete)">
          <p style="margin: 0;display: flex;justify-content: space-between;" >
            <span>{{partUpload.filename}}</span>&nbsp;&nbsp;&nbsp;
            <span :style="{color:fileState == 'error'?'#ff6f74':''}" >{{state[(isPart?'interrupt':fileState)].bgc}}</span><!--错误状态-->
            <i class="el-icon-folder-add" @click.stop="reSelectedFile()" v-show="addFileBtn"></i><!--添加文件-->

            <span  style="float: right">
              <span v-show="isReUpload">
                 <i  v-show="reUploadPercentage!=100 && pauseState == 0" class="el-icon-video-pause" @click.stop="pauseUpload"></i><!--暂停-->
                 <i  v-show="reUploadPercentage!=100 && pauseState == 1" class="el-icon-video-play" @click.stop="goOnUpload"></i><!--继续-->
              </span>
            &nbsp;&nbsp; &nbsp;
              <span :style="{display:uploadStateProgress?'none':''}">
                  <el-popconfirm
                    confirmButtonText='删除'
                    cancelButtonText='取消'
                    icon="el-icon-info"
                    iconColor="red"
                    title="确定删除吗?"
                    @onConfirm="deleteFile(true)"
                  >
                   <i class="el-icon-delete-solid" slot="reference"></i>
                 </el-popconfirm>
              </span>
              <span @click.stop="removeUploadBar" v-show="uploadStateProgress == true" style="cursor: pointer">移除</span>

             &nbsp;&nbsp;&nbsp; &nbsp;
          </span>
            <!--<i class="el-icon-delete-solid" @click.stop="deleteFile(false)"></i>-->
          </p>
          <el-progress :percentage="10" :color="errColors" v-show="!isReUpload"></el-progress>
          <el-progress :percentage="reUploadPercentage" :color="errColors" v-show="isReUpload"></el-progress>
        </div>
      </div>
      <input ref="reSelectInput" hidden type="file" @change="reSelectFileByUser" :accept="accepts"/>

      <!--新选的文件-->
      <div v-if="fileObject">
        <div v-show="!fileIsDelete||!hideUploadBar">
          <p style="margin: 0;display: flex;justify-content: space-between">
         <span>
            <img class="uploader-img-icon" :src="getIconByFileSuffix(fileObject)"/>&nbsp;
           <span class="uploader-file-name"  :title="fileObject.name">{{fileObject.name}}</span>&nbsp;&nbsp;&nbsp;&nbsp;
            <span :state="state[fileState].bgc" :style="{color:fileState == 'error'?'#ff6f74':''}">{{state[fileState].bgc}}</span>
         </span>
            <span >
            <i  v-show="uploadPercentage!=100&&pauseState==0" class="el-icon-video-pause" @click.stop="pauseUpload"></i><!--暂停-->
            <i  v-show="uploadPercentage!=100&&pauseState==1" class="el-icon-video-play" @click.stop="goOnUpload"></i><!--继续-->
            &nbsp;&nbsp; &nbsp;
              <span :style="{display:uploadStateProgress?'none':''}">
                 <el-popconfirm
                   confirmButtonText='删除'
                   cancelButtonText='取消'
                   icon="el-icon-info"
                   iconColor="red"
                   title="确定删除吗?"
                   @onConfirm="deleteFile(true)"
                 >
                   <i class="el-icon-delete-solid" slot="reference" ></i>
                 </el-popconfirm>
              </span>

              <span @click.stop="removeUploadBar" v-show="uploadStateProgress == true" style="cursor: pointer">移除</span>
             &nbsp;&nbsp;&nbsp; &nbsp;
          </span>
          </p>
          <el-progress :percentage="uploadPercentage" :color="colors"></el-progress>
        </div>

      </div>

    </div>
</template>

<script>
    import SparkMD5 from "spark-md5";//加密插件
    import {ACCEPT_CONFIG} from '@/config/config';//我设置的一些静态数据
    import Bus from '@/server/bus';//组件对话

    import commonApi from '@/api/commonApi';//这是我分装好的api
    export default {
        name: "CustomUploader",
      props:[
        "fileObj",//新上传的文件
        "params",
        "stateProgress",
        "partFile",//未上传完的文件
        "inputAccept",//重新选择文件的类型
        "inputReg",
      ],

      data(){
          return{
            hideUploadBar:false,//移除文件上传状态
            fileIsDelete:false,
            uploadingFile:{},
            isPart:false,
            addFileBtn:true,
            partUpload:{
              filename:'',
              md5:'',
              UploadedMaxChunkNum:0
            },
            partOldName:'',
            colors:[
              {color: '#5C356E', percentage: 100},
            ],
            errColors:[
              {color: '#ff6f74', percentage: 100},
            ],
            paramsForm:{},//自定义上传参数
            thisMD5:'',
            pauseState:0,
            thisFile:null,//要上传的这个文件
            fileSize:0,
            uploadPercentage:0,
            reUploadPercentage:0,
            isReUpload:false,//选择了文件要重新上传
            fileState:'',
            maxReUpload:0,
            state:{
              md5:{
                key:'md5',
                bgc:'MD5计算'
              },
              success:{
                key:'success',
                bgc:'完成'
              },
              error:{
                key:'error',
                bgc:'错误'
              },
              pause:{
                key:'pause',
                bgc:'暂停'
              },
              cancel:{
                key:'cancel',
                bgc:'取消'
              },
              interrupt:{
                key:'interrupt',
                bgc:'请重新选择文件'
              },
              start:{
                key:'start',
                bgc:'开始'
              },
              exist:{
                key:'exist',
                bgc:'该文件已经存在'
              },
              uploading:{
                key:'uploading',
                bgc:'正在上传'
              }
            },

            xhr:null,//取消当前的axios请求,就是暂停
            accepts:ACCEPT_CONFIG.accept,
            acceptsReg:'',

            CancelToken:null,
            source:null,
          }
      },
      computed:{
          //上传完成
          uploadStateProgress(){
            return this.stateProgress||false;
          },
          /**
           * @param 对象
           * 1、用户选中的文件和参数
           * 2、未上传完的文件参数
           * */
        //
        fileObject(){
          if (this.stateProgress == true){
            this.uploadPercentage = 100;
            this.fileState = 'success';
          } else {
            if (this.fileObj){
              if (this.fileObj instanceof File){
                this.startUploadFile(this.fileObj,this.params);
              }else {
                this.uploadPercentage = 100;
                this.fileState = 'err';
              }
            }
            if (this.partFile){
              this.isPart = true;
              this.isUpload = false;
              this.partUpload = this.partFile;
              if (this.partOldName!=''){

              } else {
                this.partOldName = this.partUpload.filename+'';//缓存旧文件的名字
              }

              this.paramsForm = this.params;
              this.accepts = this.inputAccept||ACCEPT_CONFIG.accept;
              this.acceptsReg = this.inputReg||'';
            }
          }

          return this.fileObj||null;
        },

      },
      mounted(){
        this.CancelToken = this.$axios.CancelToken;
        this.source = this.CancelToken.source();//取消xhr
      },
      methods:{
          removeUploadBar(){
            this.hideUploadBar = true;
            this.fileIsDelete = true;
            this.$emit('deleteFileIcon','remove');//隐藏文件的来源
          },

        /**
         * 文件第一次重头开始上传
         * @param file 一个文件
         * @param param 新加的上传参数,必填
         */
        startUploadFile(file,param){
          if(param){
            this.paramsForm = param;
          }
          if (file instanceof  File) {
            this.thisFile = file;
            this.fileChunkAndCheck(file,true);
          }else{
            console.log('不是文件类型')
          }

        },
        /**
         * @method 计算文件的md5
         * @param file File类型
         * @param isNew  true是先添加的,false是已经上传了部分的文件
         * */
        fileChunkAndCheck(file,isNew){
          this.fileSize = file.size;
          if (this.fileSize && this.fileSize == 0) {
            return;
          }
          let that = this;
          let fileReader = new FileReader();
          let blobSlice = File.prototype.slice ||File.prototype.mozSlice ||File.prototype.webkitSlice;
          let currentChunk = 0;
          const chunkSize = 1 * 1024 * 1024;
          let chunks = Math.ceil(file.size / chunkSize);

          if (isNaN(chunks)) {
            return;
          }
          let spark = new SparkMD5.ArrayBuffer();

          let oneFileChunks= [];//一个文件的所有分片

          loadNext();
          that.fileState ='md5'
          fileReader.onload = (e)=>{
            spark.append(e.target.result);
            // console.log("一个分片对象", e);
            if ((currentChunk+1) < chunks) {
              currentChunk++;
              loadNext();
            } else {
              let md5 = spark.end();
              // console.log("最后一个分片", e, oneFileChunks);
              this.thisMD5 = md5;
              if (isNew){

              } else {//未上传完的重新上传,对比MD5
                // console.log('续传')
                if (that.partUpload.md5 != md5) {
                  that.partUpload.filename = that.partOldName;//文件不匹配的时候,还是显示旧文件的名字
                  that.$message.error('该文件与之前上传的文件不匹配。文件被修改了或者不是之前的文件');
                  return ;
                }
                this.errColors[0].color = '#5C356E';//改变颜色
                this.isReUpload = true;
                that.addFileBtn = false;//隐藏选择文件按钮
              }
              that.completMD5Success(oneFileChunks,md5,isNew);
            }
          }

          fileReader.onerror = function () {
           console.log(`文件${file.name}读取出错,请检查该文件`)
           that.fileState = 'error';
          };

          function loadNext() { //分片
            let start = currentChunk * chunkSize;
            let end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;

            let pieceFile = blobSlice.call(file, start,end);//一个分片
            pieceFile.name = file.name;
            let tmpObj = {
              fileObj: pieceFile,
              currentSize: end - start,
              currentNum: currentChunk,
            };

            oneFileChunks.push(tmpObj);//保存分片

            fileReader.readAsArrayBuffer(pieceFile);
          }
        },

        /**
         * @method completMD5Success 上传分片数组,文件上传前检验,分片数组上传,判断是否取消上传(断点)
         * @param fileChunksList 分片数组
         * @param md5 文件的md5
         * @param isNew
         * */
        async completMD5Success(fileChunksList,md5,isNew){
          let that = this;
          let totalChunk=fileChunksList.length||0;

          // console.log('计算结束后,MD5值是否在',md5);
          this.$emit('saveFilePresent',md5);
          let one = await this.checkFileChunk(fileChunksList[0].currentNum,fileChunksList[0].fileObj,totalChunk,md5)//校验第一个分片
          if (one.ResultCode) {

            if(one.ResultCode == 1||one.ResultCode == 5){
              that.fileState = 'exist';
              return;
            }else if (one.ResultCode == 2){//已经存在
              that.fileState ='success';
              // this.reUploadPercentage = 100;
              // this.uploadPercentage = 100;
              return;
            }else {//3,只上传了一部分,4,重新上传,6,上传
              // console.log('开始分片上传,分片开始Num',one.ResultValue,'从one.ResultValue-1片开始上传,0开始')
              for (let i = one.ResultValue-1;i<fileChunksList.length;){
                if (this.pauseState!=0){//中断请求
                  return ;
                }
                let res =  await this.uploaderFileChunk(fileChunksList[i].currentNum,fileChunksList[i].fileObj,totalChunk,md5);
                // console.log('等待返回的结果',res);
                if (res.ResultCode) {
                  let result = res.ResultCode;
                  if (result == 1) {//文件上传成功
                    // console.log('文件上传成功',res);
                    that.fileState ='success';
                    if (isNew){
                      this.uploadPercentage = 100;
                    } else {
                      this.reUploadPercentage = 100;
                    }
                    that.$emit('onUploadSuccess',{res,md5});
                    return;
                  } else if (result == 2) {//当前片上传成功

                    if (!isNew){
                      that.reUploadPercentage = Math.floor((i+1)/totalChunk*100);//进度条++
                    } else {
                      that.uploadPercentage = Math.floor((i+1)/totalChunk*100);//进度条++
                    }

                    that.fileState ='uploading';
                    i++;//下一片
                  } else if (result == 3) {//从指定文件片数开始重新上传
                    // console.log('继续下一篇',res)
                    if (that.maxReUpload == 3){//从指定片数重传3次后,失败
                      that.fileState ='error';
                      return;
                    }
                    if (i == res.ResultValue) {
                      that.maxReUpload ++;
                    }
                    i = res.ResultValue;
                  } else if (result == 4) {//
                    i = res.ResultValue;
                    if (that.maxReUpload == 3){
                      that.fileState ='error';
                      return;
                    }
                   that.maxReUpload ++;
                  } else if (result == 5) {//文件已经存在,这是秒传
                    that.fileState ='success';
                    if (isNew){
                      this.uploadPercentage = 100;
                    } else {
                      this.reUploadPercentage = 100;
                    }
                    return;
                  } else if (result ==  999) {//服务器内部错误
                    that.fileState ='error';
                    return;
                  }

                }else {
                  console.log('中断分片')
                  return;
                }
              }
            }
          }
          return;

        },


        /**
         * @method 一个分片上传的方法
         * @param currentChunk 当前的分片的序号index,前台文件分割从0开始数
         * @param chunk 分片对象
         * @param totalChunk 总分片数
         * @param md5
         * */
        uploaderFileChunk(currentChunk,chunk,totalChunk,md5) {

          let that = this;
          var param = new FormData(); //创建表单
          param.append("upfile", chunk);
          param.append("identifier", md5); //md5值
          param.append("chunkNumber", currentChunk+1); //当前的分片的序号,后台从1开始接收
          param.append("totalChunks", totalChunk);
          param.append("filename", chunk.name);
          param.append("totalSize",this.fileSize);

          param.append("SourceId", this.paramsForm.SourceId);
          param.append("DataSource", parseInt(this.paramsForm.DataSource));
          param.append("FileClassification", parseInt(this.paramsForm.FileClassification));
          param.append("LocalPath", null);
          param.append("CurrentUserId", this.paramsForm.CurrentUserId);
          param.append("CurrentRoleCode", this.paramsForm.CurrentRoleCode);
          return new Promise((resolve, reject) => {
            that.xhr = that.$axios.post(commonApi.uploadFileByChunk(), param).then(res => {
              resolve(res.data)
            }).catch(err=>{
              reject(err)
            })
          })
        },

        /**
         * @method  checkFileChunk 文件上传前,检查是否上传过
         * @param currentChunk 默认传0
         * @param chunk 分片对象
         * @param totalChunk 总分片数
         * @param md5
         * @return 返回一个对象,包含从1、第几片开始,2、是否已经上传,3、状态
         * */
        checkFileChunk(currentChunk,chunk,totalChunk,md5){
          let that = this;
          return new Promise((resolve, reject) => {
            // 'http://101.132.66.135:8029/Upload/ChunkUpload'
            that.$axios.get(commonApi.checkFileMD5(),{ params:{
                "chunkNumber": (currentChunk+1),
                "totalChunks": totalChunk,
                "filename": chunk.filename,
                "identifier": md5,
                "totalSize":this.fileSize,
                "SourceId":this.paramsForm.SourceId,
                "DataSource":this.paramsForm.DataSource,
                "FileClassification":this.paramsForm.FileClassification,
                "LocalPath":null,
                "CurrentUserId":this.paramsForm.CurrentUserId,
                "CurrentRoleCode":this.paramsForm.CurrentRoleCode,
              }}).then(res => {
              // console.log('校验一个文件返回的结果', res.data);
              resolve(res.data)
            }).catch(err=>{
              reject(err)
            })

          })
        },
       pauseUpload() { //取消上传
          console.log('取消上传',this.xhr)
         this.pauseState =1;//中断请求
          this.source.cancel('Operation canceled by the user.');
        },
        goOnUpload(){//继续上传
          this.pauseState = 0;//继续上传请求
          if (this.thisFile instanceof  File){
            this.fileChunkAndCheck(this.thisFile,true);
          } else {
            console.log('续传文件丢失')
          }
        },
        deleteFile(flag){
          let option={
            "FileMD5": this.thisMD5,
            "SourceId":this.paramsForm.SourceId,
            "DataSource": parseInt(this.paramsForm.DataSource),
            "FileClassification": parseInt(this.paramsForm.FileClassification)
          };
          if (flag) {

          }else {
            option.FileMD5 =this.partUpload.md5;
          }

          let that=this;
          this.$axios.post(commonApi.deleteUploadingFile(),option).then(res=>{
            if (res.data.IsSuccess) {
              that.fileIsDelete = true;
              that.$emit('deleteFileIcon','delete');//隐藏文件的来源
              that.$message.success(res.data.ResultValue);
            }
          }).catch(err=>{

          })
        },

        /**
         * 重新选择文件
         */
        reSelectedFile(){
          this.$refs.reSelectInput.dispatchEvent(new MouseEvent('click'))
        },
        reSelectFileByUser(){
          let files = this.$refs.reSelectInput.files;//this.$refs.scheduleFileInput.files
          if (files && files.length>0){

            if (this.acceptsReg.test(files[0].name)) {
              this.partUpload.filename = files[0].name;
              this.isPart = false;
              this.fileState='start';
              this.reUploadPercentage = 0;//进度条设置值为0

              this.fileChunkAndCheck(files[0],false);
            }else {
              this.$message.error('文件类型必须是'+this.accepts);
              return;
            }
          }
        },

        /**
         * @method 获取文件图标
         * @param fileObj 一个文件对象
         * @return {*} 返回图片的地址
         */
        getIconByFileSuffix(fileObj){
          let fileName = fileObj?fileObj.name:'';
          if (!fileName||fileName == ''){
            return '';
          }
          let suffix = fileName.substring(fileName.lastIndexOf('.'));
          if(ACCEPT_CONFIG.videoFile.test(suffix)){
            return require('../../assets/images/ic_move@2x.png');
          }else if(ACCEPT_CONFIG.imageFile.test(suffix)){
            return this.$tools.preViewPicture(fileObj);
          }else if(ACCEPT_CONFIG.pptFile.test(suffix)){
            console.log('ppt',suffix)
            return require('../../assets/images/ic_ppt@2x.png');
          }else if(ACCEPT_CONFIG.wordFile.test(suffix)){
            console.log('word',suffix)
            return require('../../assets/images/ic_word@2x.png');
          }else if(ACCEPT_CONFIG.pdfFile.test(suffix)){
            console.log('pdf',suffix)
            return require('../../assets/images/ic_pdf@2x.png');
          }
          return require('@/assets/images/ic_file@2x.png');
        },


      }
    }
</script>


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值