結合element-ui 的el-upload元件支援分片上傳

spademan發表於2018-09-14

el-upload-piecess

github地址

結合elemenet-ui 支援分片上傳

暫時不支援安裝的方式, 主要是提供思路, 可以複製程式碼去使用(程式碼邏輯還可以繼續優化)

程式碼核心在 utils.uploadByPieces 函式

readFileMD5 讀取檔案的md5
  const readFileMD5 = (files) => {
    // 讀取每個檔案的md5
    files.map((file, index) => {
      let fileRederInstance = new FileReader()
      fileRederInstance.readAsBinaryString(file)
      fileRederInstance.addEventListener('load', e => {
        let fileBolb = e.target.result
        let fileMD5 = md5(fileBolb)
        if (!fileList.some((arr) => arr.md5 === fileMD5)) {
          fileList.push({md5: fileMD5, name: file.name, file})
          AllFileSize = AllFileSize + file.size
        }
        if (index === files.length - 1) readChunkMD5(fileList)
      }, false)
    })
  }
複製程式碼
readChunkMD5 將讀取到的檔案進行分片處理
  // 針對每個檔案進行chunk處理
  const readChunkMD5 = (fileList) => {
    fileList.map((currentFile, fileIndex) => {
      const chunkSize = pieceSize * 1024 * 1024 // 5MB一片
      const chunkCount = Math.ceil(currentFile.file.size / chunkSize) // 總片數
      AllChunk = AllChunk + chunkCount // 計算全域性chunk數
      // let fileSize = currentFile.file.size // 檔案大小
      // 針對單個檔案進行chunk上傳
      for (var i = 0; i < chunkCount; i++) {
        const { chunk } = getChunkInfo(currentFile.file, i, chunkSize)
        let chunkFR = new FileReader()
        chunkFR.readAsBinaryString(chunk)
        chunkFR.addEventListener('load', e => {
          let chunkBolb = e.target.result
          let chunkMD5 = md5(chunkBolb)
          this.readingFile = false
          uploadChunk(currentFile, {chunkMD5, chunk, currentChunk: i, chunkCount}, fileIndex)
        }, false)
      }
    })
  }
複製程式碼
uploadChunk 上傳分片,並且更新上傳進度,並且在分片上傳完畢之後,進行整個檔案的上傳
  const uploadChunk = (currentFile, chunkInfo, fileIndex) => {
    let fetchForm = new FormData()
    fetchForm.append('file_name', currentFile.name)
    fetchForm.append('md5', currentFile.fileMD5)
    fetchForm.append('data', chunkInfo.chunk)
    fetchForm.append('chunks', chunkInfo.chunkCount)
    fetchForm.append('chunk_index', chunkInfo.currentChunk)
    fetchForm.append('chunk_md5', chunkInfo.chunkMD5)
    fetch({
      type: 'post',
      url: chunkUrl,
      data: fetchForm
    }).then(res => {
      progressFun()
      // currentAllChunk++
      if (chunkInfo.currentChunk < chunkInfo.chunkCount - 1) {
        successAllCount++
      } else {
        // 當總數大於等於分片個數的時候
        if (chunkInfo.currentChunk >= chunkInfo.chunkCount - 1) {
          uploadFile(currentFile, fileIndex)
        }
      }
    }).catch((e) => {
      error && error(e)
    })
  }
複製程式碼
uploadFile 整個檔案(某個已經分片已經全部上傳完的檔案)的上傳
  // 對分片已經處理完畢的檔案進行上傳
  const uploadFile = (currentFile) => {
    let makeFileForm = new FormData()
    makeFileForm.append('md5', currentFile.fileMD5)
    makeFileForm.append('file_name', currentFile.name)
    fetch({ // 合併檔案
      type: 'post',
      url: fileUrl,
      data: makeFileForm
    }).then(res => {
      progressFun()
      res.file_name = currentFile.name
      success && success(res)
      successAllCount++
    }).catch(e => {
      error && error(e)
    })
  }
複製程式碼

注意

這裡的上傳是並行的,如果要序列需要改造程式碼

相關文章