美文网首页
webuploader

webuploader

作者: 若水亦城空 | 来源:发表于2021-02-06 10:26 被阅读0次
<template>
  <!--dom结构部分-->
  <div id="uploader-demo" class="uploader1">
    <!--用来存放item-->
    <div :id="ids" class="one" style="margin-right: 10px ;width:448px">
      <!--      <img :src="imgsrc" alt="" style="width:200px;height: 160px">-->
      <!--      <span style="color: red;text-align: center;width: 100%;display: inline-block;"> 格式:.zip</span>-->
      <div style="display: flex;align-items: center;justify-content: center;width:448px;height: 100px">
        <icon-svg class="icon-file" style="width: 60px;height: 60px; font-size: 160px" icon-class="iconshangchuanwenjian" />
      </div>
      <div style="text-align: center;color: #1580fd;font-size: 14px;font-weight: bold;line-height: 30px"><span>{{ title }}</span></div>
      <div style="text-align:center;color: red ;line-height: 30px">
        <span> {{ rules }}</span>
      </div>
    </div>
    <div style="padding: 0 20px;font-weight: bold;font-size: 16px">
      已上传
    </div>
    <div style="flex: 1;height: 160px;overflow-y: auto" class="two">
      <div class="upbox">
        <div v-if="childData1.length>0" style="display:flex;flex-wrap: wrap;">
          <div v-for="(item,index) in childData1" :key="index" class="file-style">
            <div class="list-file">
              <div style="flex: 1;display: flex;">
                <icon-svg style="width: 24px;height: 24px ;margin-top: 5px;margin-left: 30px" icon-class="iconyasuowenjian" />
                <TextTooltip
                  style="line-height:40px ;height: 40px; font-size: 16px ;margin-left: 32px"
                  :content="item.attachmentName"
                  class="wid170"
                  ref-name="supplierName"
                />
                <!--                <span style="line-height: 32px;font-size: 16px ;margin-left: 24px"> {{ item.name }}</span>-->
              </div>
              <icon-svg style="width: 22px;height: 22px;margin-top: 5px;margin-right: 5px" icon-class="iconshanchu" @click.native="deleteclick(item)" />
            </div>
            <el-progress v-if=" Math.ceil(mumberList[index])!==100 && mumberList[index]" style="padding-left: 22px;" :stroke-width="2" :percentage="Math.ceil(mumberList[index]) " />
          </div>
        </div>
        <!--        <div :id="'fileList'+ids" class="uploader-list" />-->
      </div>

    </div>

  </div>
</template>

<!--引入JS-->

<script>
// <!--引入CSS-->
import '../../../public/static/lib/webuploader.css'
import $ from 'jquery'
import WebUploader from 'webuploader'
import { getRegister, getCheck, getMerge, getUploadend } from '@/api/upload/index'
import { url_config, plchc_pre_url } from '@/config/index'
import TextTooltip from '@/components/textTooltip'
import { Message } from 'element-ui'
// import store from '@/store'
export default {
  name: 'VueUpload',
  components: {
    TextTooltip
  },
  props: {
    accept: {
      type: Object,
      default: null
    },
    imgsrc: {
      type: String,
      default: ''
    },
    rowjdbm: {
      type: String,
      default: ''
    },
    rowcode: {
      type: String,
      default: ''
    },
    dossierData: {
      type: Array,
      default: function() {
        return []
      }
    },
    rowlcbm: {
      type: String,
      default: ''
    },
    // 上传地址
    ids: {
      type: String,
      default: ''
    },
    // 上传最大数量 默认为100
    fileNumLimit: {
      type: Number,
      default: 10
    },
    // 大小限制 默认2M
    fileSingleSizeLimit: {
      type: Number,
      default: 2048000
    },
    // 上传时传给后端的参数,一般为token,key等
    // formData: {
    //   type: Object,
    //   default: null
    // },
    // 生成formData中文件的key,下面只是个例子,具体哪种形式和后端商议
    keyGenerator: {
      type: Function,
      default(file) {
        const currentTime = new Date().getTime()
        const key = `${currentTime}.${file.name}`
        return key
      }
    },
    multiple: {
      type: Boolean,
      default: false
    },
    // 上传按钮ID
    uploadButton: {
      type: String,
      default: ''
    },
    title: {
      type: String,
      default: ''
    },
    rules: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      childData1: [],
      //   actionUrl: `${url_config + plchc_pre_url}/file/upload`,
      uploader: null,
      webUploadloader: null,
      mumberList: []
    }
  },
  mounted() {
    setTimeout(() => {
      this.initWebUpload()
      this.initDossier()
    }, 300)
  },
  destroyed() {
    WebUploader.Uploader.unRegister(this.ids)
    // this.uploader.destroy()
  },
  methods: {
    initDossier() {
      if (this.dossierData) {
        if (this.dossierData.length > 0) {
          this.childData1 = this.dossierData.map(item => {
            return {
              attachmentHref: item.attachmentHref,
              attachmentId: item.attachmentId,
              attachmentName: item.attachmentName,
              officeType: item.officeType,
              batchNo: item.batchNo,
              uuidName: item.uuidName
            }
          })
        }
      }
    },
    deleteclick(item) {
      this.childData1.splice(this.childData1.findIndex(arr => arr.uuidName === item.uuidName), 1)
      // this.$set(this.childData1, 0)
      this.$emit('cdata', this.childData1)
    },
    initWebUpload() {
      var dataIndex = 0
      let loading
      // 监听分块上传的时间点,断点续传
      // let fileMd5;    //保存文件MD5名称
      // let uploader;   //全局对象uploader
      const _this = this
      // this.webUploadloader = WebUploader
      WebUploader.Uploader.register(
        {
          'before-send-file': 'beforeSendFile', // 文件上传之前执行
          'before-send': 'beforeSend',      // 文件块上传之前执行
          'after-send-file': 'afterSendFile', // 上传完成之后执行
          'name': _this.ids
        },
        {
          // 时间点1:所有进行上传之前调用此函数
          beforeSendFile: (file) => {
            const file_suffix = ['zip', 'rar', 'Zip', 'RAR']
            if (!file_suffix.includes(file.name.split('.').slice(-1).join())) {
              this.$message.warning({
                title: '上传失败',
                message: '需上传文件格式为:zip, rar, Zip, RAR',
                duration: 3000
              })
              return
            }
            loading = this.$loading({
              lock: true,
              text: '请求中...',
              spinner: 'el-icon-loading',
              background: 'rgba(0, 0, 0, 0.7)'
            })
            const me = this
            const task = WebUploader.Deferred()
            console.log('regist', file)

            // TODO 将以下属性设置到 this.uploader.options.formData ?
            this.fileName = file.name
            this.fileSize = file.size

            this.mimeType = ('.' + file.type)
            this.fileExt = file.ext;

            // 计算文件的唯一标识,用于断点续传和妙传
            (new WebUploader.Uploader()).md5File(file, 0,
              10 * 1024 * 1024).progress(
              function(percentage) {
                // $("#" + file.id).find("span.state").text("正在获取文件信息...");
              }).then(
              function(val) {
                // $("#" + file.id).find("span.state").text("成功获取文件信息");
                console.log('hash', val)
                me.fileHash = val
                // _this.munberobj.percentageValue = 0
                getRegister({
                  'businessKey': 'test-01',
                  'extraParamMap': {},
                  'fileExt': ('.' + file.ext),
                  'fileHash': val,
                  'fileName': file.name,
                  'fileSize': file.size
                }).then(res => {
                  console.log('register', res)
                  if (res && res.code === 200 && !res.filePath) {
                    _this.childData1.push(file)
                    dataIndex = _this.childData1.length - 1
                    console.log(_this.childData1, '取值了')
                    task.resolve()
                  } else if (res && res.code === 200 && res.filePath) {
                    // this.childData1.splice(this.childData1.findIndex(arr => arr.id === res.id), 1)
                    loading.close()
                    Message({
                      message: '已有上传卷宗',
                      type: 'error',
                      duration: 3000
                    })
                    // 文件已上传
                    // this.onSuccess({
                    //   fileName: this.fileName,
                    //   resourceId: res.fileId,
                    //   filePath: res.filePath,
                    // });
                    task.reject()
                  } else {
                    file.statusText = res && res.msg
                    task.reject()
                  }
                })
                me.uploader.options.formData.fileMd5 = val
              })

            return task.promise()
          },
          // 每一个分块发送之前执行该操作,检查当前块是否已经上传
          beforeSend: (block) => {
            const file_suffix = ['zip', 'rar', 'Zip', 'RAR']

            if (!file_suffix.includes(block.file.ext.toLowerCase())) {
              return
            }
            console.log('beforeSend')
            const task = WebUploader.Deferred()
            const fileHash = this.uploader.options.formData.fileMd5
            const fileChunk = {
              chunk: block.chunk,
              chunkSize: block.end - block.start,
              fileHash: fileHash
            }
            getCheck(fileChunk).then(res => {
              console.log('checkChunk', res)
              if (res && res.code === 200 && res.chunkId >= 0) {
                task.reject() // 分片存在,则跳过上传
              } else {
                task.resolve()
              }
            })

            this.uploader.options.formData.chunk = fileChunk.chunk
            this.uploader.options.formData.chunkSize = fileChunk.chunkSize
            this.uploader.options.formData.fileHash = fileHash

            return task.promise()
          },
          afterSendFile: (file) => {
            const file_suffix = ['zip', 'rar', 'Zip', 'RAR']

            if (!file_suffix.includes(file.ext.toLowerCase())) {
              return
            }
            // 通知合并分块
            const task = new WebUploader.Deferred()
            const fileMetaData = {
              'businessKey': 'test-01',
              'extraParamMap': {},
              'fileExt': ('.' + file.ext),
              'fileHash': this.fileHash,
              'fileId': file.id,
              'fileName': file.name,
              'fileSize': file.size,
              'mimeType': file.type
            }
            getMerge(fileMetaData).then(res => {
              console.log(res.filePath)
              const uploadfile = {
                'authorization': this.$store.state.user.token,
                'filePath': res.filePath,
                'xtCode': this.rowcode,
                'lcbm': this.rowlcbm,
                'jdbm': this.rowjdbm
              }
              getUploadend(uploadfile).then(resdata => {
                this.childData1 = this.childData1.filter(item => item.ext !== 'zip')
                if (resdata) {
                  this.childData1 = [...this.childData1, ...[resdata]]
                  this.$emit('cdata', this.childData1)
                  this.$forceUpdate()
                  // this.childData1.push(resdata)
                  // console.log(this.childData1, '取值了')
                  // /
                  // this.$set(this.childData1, 0)
                  // this.$emit('cdata', this.childData1)
                }
              })
              console.log('mergeChunks', res)
              if (res && res.code === 200 && res.filePath) {
                console.log('切片合并成功')
                task.resolve()
                // this.onSuccess({
                //   fileName: this.fileName,
                //   resourceId: res.fileId,
                //   filePath: res.filePath,
                // });
              } else {
                console.log('合并文件失败')
                task.reject()
                // this.onError({ msg: '合并文件失败' });
              }
            })
          }
        }
      )

      this.uploader = WebUploader.create({
        // 选完文件后,是否自动上传。
        auto: true,
        // swf文件路径
        swf: '<%=request.getContextPath()%>/static/lib/webuploader/Uploader.swf',
        // 文件接收服务端。
        server: url_config + '/' + plchc_pre_url + '/v1/bigfile/upload-chunk',
        // server: 'http://192.168.0.12:9201/yunpi-plchc-srv-ga/v1/bigfile/upload-chunk',
        // 选择文件的按钮。可选。
        // 内部根据当前运行是创建,可能是input元素,也可能是flash.
        pick: document.getElementById(this.ids),
        accept: this.getAccept(this.accept), // 允许选择文件格式。
        threads: 3,
        multiple: false,
        // fileNumLimit: this.fileNumLimit, // 限制上传个数
        // fileSingleSizeLimit: this.fileSingleSizeLimit, // 限制单个上传图片的大小
        chunked: true, // 分片上传
        chunkSize: 5242880, // 分片大小
        duplicate: true, // 重复上传
        formData: { // 上传分片的http请求中一同携带的数据
          appid: '1',
          fileHash: ''
          // methodname: 'breakpointRenewal',
        }
      })
      console.log('upload', this.uploader)
      // 当有文件添加进来的时候
      this.uploader.on('fileQueued', (file) => {
        console.log(file, 'fileQueued')
        const $li = $(
          '<div id="' + file.id + '" class="file-item thumbnail">' +
                      '<img>' +
                      '<div class="info">' + file.name + '</div>' +
                  '</div>'
        )
        const $img = $li.find('img')

        // $list为容器jQuery实例
        $('#fileList' + this.ids).append($li)

        // 创建缩略图
        // 如果为非图片文件,可以不用调用此方法。
        // thumbnailWidth x thumbnailHeight 为 100 x 100
        this.uploader.makeThumb(file, function(error, src) {
          if (error) {
            $img.replaceWith('<span>不能预览</span>')
            return
          }

          $img.attr('src', src)
        }, 100, 100)
      })

      this.uploader.on('uploadStart', (file) => {
        // 在这里可以准备好formData的数据
      })

      // 文件上传过程中创建进度条实时显示。
      this.uploader.on('uploadProgress', function(file, percentage) {
        if (file) {
          _this.mumberList[dataIndex] = percentage * 100
          _this.$set(_this.mumberList, dataIndex, _this.mumberList[dataIndex])
        }

        // const $li = $('#' + file.id)
        /* let $percent = $li.find('.progress span')

        // 避免重复创建
        if (!$percent.length) {
          $percent = $('<p class="progress"><span></span></p>')
            .appendTo($li)
            .find('span')
        }

        $percent.css('width', percentage * 100 + '%')*/
      })

      // 文件上传成功,给item添加成功class, 用样式标记上传成功。
      this.uploader.on('uploadSuccess', function(file) {
        loading.close()
      })

      // 文件上传失败,显示上传出错。
      this.uploader.on('uploadError', function(file) {
        loading.close()
        /* const $li = $('#' + file.id)
        let $error = $li.find('div.error')

        // 避免重复创建
        if (!$error.length) {
          $error = $('<div class="error"></div>').appendTo($li)
        }

        $error.text('上传失败')*/
      })

      // 完成上传完了,成功或者失败,先删除进度条。
      this.uploader.on('uploadComplete', function(file) {
      })

      this.uploader.on('uploadSuccess', (file, response) => {
      })

      this.uploader.on('uploadError', (file, reason) => {
      })

      this.uploader.on('error', (type) => {
        let errorMessage = ''
        if (type === 'F_EXCEED_SIZE') {
          errorMessage = `文件大小不能超过${this.fileSingleSizeLimit / (1024 * 1000)}M`
        } else if (type === 'Q_EXCEED_NUM_LIMIT') {
          errorMessage = '文件上传已达到最大上限数'
        } else {
          errorMessage = `上传出错!请检查后重新上传!错误代码${type}`
        }

        console.error(errorMessage)
        this.$emit('error', errorMessage)
      })

      this.uploader.on('uploadComplete', (file, response) => {
      })
    },

    upload(file) {
      this.uploader.upload(file)
    },
    stop(file) {
      this.uploader.stop(file)
    },
    // 取消并中断文件上传
    cancelFile(file) {
      this.uploader.cancelFile(file)
    },
    // 在队列中移除文件
    removeFile(file, bool) {
      this.uploader.removeFile(file, bool)
    },

    getAccept(accept) {
      switch (accept) {
        case 'text':
          return {
            title: 'Texts',
            exteensions: '.zip,.rar',
            mimeTypes: '.zip,.rar'
          }
          // eslint-disable-next-line no-unreachable
          break
        // case 'video':
        //   return {
        //     title: 'Videos',
        //     exteensions: 'mp4',
        //     mimeTypes: '.mp4'
        //   }
        //   // eslint-disable-next-line no-unreachable
        //   break
        // case 'image':
        //   return {
        //     title: 'Images',
        //     exteensions: 'gif,jpg,jpeg,bmp,png',
        //     mimeTypes: '.gif,.jpg,.jpeg,.bmp,.png'
        //   }
        //   // eslint-disable-next-line no-unreachable
        //   break
        default: return accept
      }
    }

  }
}
</script>

<style lang="scss"  scoped>
.uploader1{
  display: flex;
  flex-direction: row;
  .one,.two{
    /*width: 50%;*/
    /*height: 190px;*/
    /*border:1px solid #ccc;*/
    // float: left;
    box-sizing: border-box;
  }
  .upbox{

    .uploader-list{
      display: flex;
      flex-direction: row;
      overflow: auto;
      .file-item{
        // margin-right: 10px;
        padding: 4%;
      }
    }
  }
}
.list-file{
  display: flex;
  /*width: 50%;*/
  /*padding: 10px 20px;*/
  /*justify-content: space-around;*/
  /*background-color: #f8f8f8;*/
  /*background-color:#eee;*/
  /*width:calc(33.3% - 10px) ;*/
  /*margin-top: 10px;*/
  /*margin-bottom: 10px;*/
  /*margin-right: 10px;*/
  justify-content: space-between;
}
.file-style{
  width: calc(33.3%  - 10px);
  margin-right: 10px;
  margin-top: 10px;
  margin-bottom: 10px;
  /*padding: 10px;*/
  background-color: rgb(238, 238, 238);
}
// 直接把官方的css粘过来就行了
</style>

相关文章

网友评论

      本文标题:webuploader

      本文链接:https://www.haomeiwen.com/subject/mhnntltx.html