当前位置:网站首页>Implementation of large file fragment uploading based on webuploader

Implementation of large file fragment uploading based on webuploader

2022-06-22 05:37:00 Best_ Kaka

Preface

 How to use vue-simple-uploader Realize the upload of fragments 、 Breakpoint retransmission and second retransmission ;
 This study is based on WebUploader Implement these functions 

Use

1. Introduce in the project webuploader

 matters needing attention 
1、 The plug-in is based on jquery,
2、 I won't support it npm Import ( adopt  import './webuploader';  Way to introduce webuploader, Will be submitted to the ''caller', 'callee', and 'arguments' properties may not be accessed on strict mode ...' The fault of ,)

We are in the project index.html To statically import resources
stay Official website Upload and download
Uploader.swf and webuploader.min.js, Put it in static static Under the document

 Insert picture description here

 matters needing attention 
 In case of error report :Uncaught SyntaxError: Unexpected token ‘<‘,
 yes vue Static resource import error :https://blog.csdn.net/weixin_43909743/article/details/118804322
  1. Encapsulate the upload component upload.vue
    Packaged components upload.vue as follows , The interface can be expanded according to the specific business .
<template>
   <div class="upload">
   </div>
</template>

<script>
 import {
     getToken } from "@/utils/auth"; // headers What must be passed inside token
   export default {
    
       name: 'vue-upload',
       props: {
    
           accept: {
    
               type: Object,
               default: null,
           },
           //  Upload address 
           url: {
    
               type: String,
               default: '',
           },
           //  Maximum number of Uploads   The default is 100
           fileNumLimit: {
    
               type: Number,
               default: 100,
           },
           //  Size limit   Default 2M
           fileSingleSizeLimit: {
    
               type: Number,
               default: 2048000,
           },
           //  Parameters passed to the back end when uploading , It's usually token,key etc. 
           formData: {
    
               type: Object,
               default: null
           },
           //  Generate formData The key, Here's just an example , Discuss with the back end about the specific form 
           keyGenerator: {
    
               type: Function,
               default(file) {
    
                   const currentTime = new Date().getTime();
                   const key = `${
      currentTime}.${
      file.name}`;
                   return key;
               },
           },
           multiple: {
    
               type: Boolean,
               default: false,
           },
           //  Upload button ID
           uploadButton: {
    
               type: String,
               default: '',
           },
       },
       data() {
    
           return {
    
               uploader: null
           };
       },
       mounted() {
    
           this.initWebUpload();
       },
       methods: {
    
           initWebUpload() {
    
               this.uploader = WebUploader.create({
    
                   auto: true, //  After selecting the file , Whether to upload automatically 
                   // swf: '/static/lib/webuploader/Uploader.swf', // swf File path   It's not necessary 
                   server: this.url,  //  File receiving server 
                   pick: {
    
                       id: this.uploadButton,     //  Select the file button 
                       multiple: this.multiple,   //  Upload multiple files or not   Default false
                       label: '',
                   },
                   accept: this.getAccept(this.accept),  //  Allow selection of file format .
                   threads: 3,
                   fileNumLimit: this.fileNumLimit, //  Limit the number of Uploads 
                   //fileSingleSizeLimit: this.fileSingleSizeLimit, //  Limit the size of a single uploaded image 
                   formData: this.formData,  //  Upload the required parameters 
                   chunked: true,          // Patch uploading 
                   chunkSize: 2048000,    // Slice size 
                   duplicate: true,  //  Repeat upload 
                   headers: {
     Authorization: "Bearer " + getToken() },
               });
               //  When a file is added to the queue , Add to page preview 
               this.uploader.on('fileQueued', (file) => {
    
                   this.$emit('fileChange', file);
               });
               this.uploader.on('uploadStart', (file) => {
    
                   //  You can be ready here formData The data of 
                   //this.uploader.options.formData.key = this.keyGenerator(file);
               });
               //  Create a progress bar to display in real time during file upload .
               this.uploader.on('uploadProgress', (file, percentage) => {
    
                   this.$emit('progress', file, percentage);
               });
               this.uploader.on('uploadSuccess', (file, response) => {
    
                   this.$emit('success', file, response);
               });
               this.uploader.on('uploadError', (file, reason) => {
    
                   console.error(reason);
                   this.$emit('uploadError', file, reason);
               });
               this.uploader.on('error', (type) => {
    
                   let errorMessage = '';
                   if (type === 'F_EXCEED_SIZE') {
    
                       errorMessage = ` The file size cannot exceed ${
      this.fileSingleSizeLimit / (1024 * 1000)}M`;
                   } else if (type === 'Q_EXCEED_NUM_LIMIT') {
    
                       errorMessage = ' The maximum number of file uploads has been reached ';
                   } else {
    
                       errorMessage = ` Upload error ! Please check and upload again ! Error code ${
      type}`;
                   }
                   console.error(errorMessage);
                   this.$emit('error', errorMessage);
               });
               this.uploader.on('uploadComplete', (file, response) => {
    
                   this.$emit('complete', file, response);
               });
           },
           upload(file) {
    
               this.uploader.upload(file);
           },
           stop(file) {
    
               this.uploader.stop(file);
           },
           //  Cancel and interrupt file upload 
           cancelFile(file) {
    
               this.uploader.cancelFile(file);
           },
           //  Remove files from the queue 
           removeFile(file, bool) {
    
               this.uploader.removeFile(file, bool);
           },
           getAccept(accept) {
    
               switch (accept) {
    
                   case 'text':
                       return {
    
                           title: 'Texts',
                           exteensions: 'doc,docx,xls,xlsx,ppt,pptx,pdf,txt',
                           mimeTypes: '.doc,docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt'
                       };
                       break;
                   case 'video':
                       return {
    
                           title: 'Videos',
                           exteensions: 'mp4',
                           mimeTypes: '.mp4'
                       };
                       break;
                   case 'image':
                       return {
    
                           title: 'Images',
                           exteensions: 'gif,jpg,jpeg,bmp,png',
                           mimeTypes: '.gif,.jpg,.jpeg,.bmp,.png'
                       };
                       break;
                   default: return accept
               }
           },
       },
   };
</script>

<style lang="scss">
   .webuploader-container {
    
       position: relative;
   }
   .webuploader-element-invisible {
    
       position: absolute !important;
       clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
       clip: rect(1px,1px,1px,1px);
   }
   .webuploader-pick {
    
       position: relative;
       display: inline-block;
       cursor: pointer;
       background: #00b7ee;
       padding: 10px 15px;
       color: #fff;
       text-align: center;
       border-radius: 3px;
       overflow: hidden;
   }
   .webuploader-pick-hover {
    
       background: #00a2d4;
   }
   .webuploader-pick-disable {
    
       opacity: 0.6;
       pointer-events:none;
   }
</style>
  1. Use components
	<el-form-item v-show="form.struct == 'single'&&form.courseType == 2" label=" Video file ">
      <div class="page">
          <div id="filePicker"> Select File </div>
          <div class="file-panel">
              <div class="file-list">
                  <ul class="file-item" :class="`file-${file.id}`" v-for="file in fileList1" v-show="!form.videoUrl">
                      <li class="file-type" :icon="fileCategory(file.ext)"></li>
                      <li class="file-name">{
    {
    file.name}}</li>
                      <li class="file-size">{
    {
    fileSize(file.size)}}</li>
                      <li class="file-status"> Uploading ...</li>
                      <li class="progress"></li>
                      <li @click="remove1(file)"> close </li>
                  </ul>
                  <div class="no-file" v-if="!fileList1.length&&!form.videoUrl"><i class="iconfont icon-empty-file"></i>  No files to upload </div>
                  <div class="no-file" v-if="form.videoUrl">
                    <i class="iconfont icon-empty-file"></i> {
    {
    form.videoUrl}}
                    <button @click="form.videoUrl=''"> Delete </button>
                  </div>
              </div>
          </div>

          <vue-upload
                  :url="url1"
                  ref="uploader"
                  uploadButton="#filePicker"
                  @fileChange="fileChange"
                  @progress="onProgress"
                  @success="onSuccess"
          ></vue-upload>
      </div>
    </el-form-item>

data data

fileList1: [],
url1:process.env.VUE_APP_BASE_API + "/file?type=1",
computed: {
     uploader() {
         return this.$refs.uploader;
     }
 },

methods:

fileChange(file) {
    
    if(this.fileList1.length){
    return this.$message.warning(' Only one file can be uploaded at a time ')}
           if (!file.size) return;
           this.form.videoUrl=''
           this.fileList1.push(file);
           console.log(file);
   },
   onProgress(file, percent) {
    
       $(`.file-${
      file.id} .progress`).css('width', percent * 99 + '%');
       $(`.file-${
      file.id} .file-status`).html((percent * 99).toFixed(2) + '%');
   },
   onSuccess (file, response) {
    
       console.log(' Upload successful ', response);
       this.fileList1=[]
       $(`.file-${
      file.id} .file-status`).html( '100%');
       this.form.videoUrl = response.data.url
   },
    resume(file) {
    
       this.uploader.upload(file);
    },
    stop(file) {
    
        this.uploader.stop(file);
    },
    remove1(file) {
    
        //  Cancel and interrupt file upload 
        this.uploader.cancelFile(file);
        //  Remove files from the queue 
        this.uploader.removeFile(file, true);
        //  stay ui Remove on 
        let index = this.fileList1.findIndex(ele => ele.id === file.id);
        this.fileList1.splice(index, 1);
    },
    fileSize(size) {
    
        return WebUploader.Base.formatSize(size);
    },
    fileCategory(ext) {
    
        let type = '';
        const typeMap = {
    
            image: ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp'],
            video: ['mp4', 'm3u8', 'rmvb', 'avi', 'swf', '3gp', 'mkv', 'flv'],
            text: ['doc', 'txt', 'docx', 'pages', 'epub', 'pdf', 'numbers', 'csv', 'xls', 'xlsx', 'keynote', 'ppt', 'pptx']
        };
        Object.keys(typeMap).forEach((_type) => {
    
            const extensions = typeMap[_type];
            if (extensions.indexOf(ext) > -1) {
    
                type = _type
            }
        });
        return type
    }, 

css

<style lang="scss">
    $h-row: 50px; .file-panel {
    
        width: 100%;
        margin-top: 10px;
        box-shadow: 0 2px 12px 1px rgba(0, 0, 0, 0.1); > h2 {
    
            height: 40px;
            line-height: 40px;
            padding: 0 10px;
            border-radius: 4px 4px 0 0;
            border-bottom: 1px solid #ccc;
            background-color: #fff;
        }
        .file-list {
    
            position: relative;
            height: 100px;
            overflow-y: auto;
            background-color: rgb(250, 250, 250);
        }
        .file-item {
    
            position: relative;
            height: $h-row;
            line-height: $h-row;
            padding: 0 10px;
            border-bottom: 1px solid #ccc;
            background-color: #fff;
            z-index: 1; > li {
    
                display: inline-block;
            }
        }
        .file-type {
    
            width: 24px;
            height: 24px;
            vertical-align: -5px;
        }
        .file-name {
    
            width: 40%;
            margin-left: 10px;
        }
        .file-size {
    
            width: 20%;
        }
        .file-status {
    
            width: 20%;
        }
        .file-operate {
    
            width: 10%; > a {
    
                padding: 10px 5px;
                cursor: pointer;
                color: #666; &:hover {
    
                    color: #ff4081;
                }
            }
        }
        .file-type[icon=text] {
    
            // background: url(../../assets/images/icon/text-icon.png);
        }
        .file-type[icon=video] {
    
            // background: url(../../assets/images/icon/video-icon.png);
        }
        .file-type[icon=image] {
    
            // background: url(../../assets/images/icon/image-icon.png);
        }
        .progress {
    
            position: absolute;
            top: 0;
            left: 0;
            height: $h-row - 1;
            width: 0;
            background-color: #E2EDFE;
            z-index: -1;
        }
        .no-file {
    
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            font-size: 16px;
        }
    }
</style>
  1. Result chart
     Insert picture description here

  2. Reference resources :

 Back end reference :https://glory.blog.csdn.net/article/details/114284285
 Reference link :https://www.jb51.net/article/136113.htm
原网站

版权声明
本文为[Best_ Kaka]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/173/202206220523579374.html