vue中使用webuplaoder

549 阅读1分钟

首先安装插件

npm install webuploader --save

npm install jquery@1.12.4

index.vue

<template>
  <div>
    <!-- 视频分片上传
    npm install webuploader --save
    npm install jquery@1.12.4 -S -->
    <video-upload :files="videoList"
                     :libCode="libCode"
                     ref="videoUpload"
                     @videoUploadStart="videoUploadStart"
                     @videoUploadEnd="videoUploadEnd"
                     @videoUploadDel="videoUploadDel" ></video-upload>
  </div>
</template>

<script>
import videoUpload from './videoUpload' // 视频分片
export default {
  name: 'navMenu',
  components: {
    videoUpload
  },
  data () {
    return {
      libCode: ''
    }
  },
  methods: {
    videoUploadStart () { // 视频文件上传开始
      console.log('视频文件上传开始')
    },
    videoUploadEnd (data) { // 视频文件上传成功
      console.log('视频上传成功', data)
    },
    videoUploadDel () {
      console.log('删除了视频')
    }
  }
}
</script>

<style scoped>
</style>

videoUpload.vue

<template>
  <!--视频上传-->
  <div class='localUpload'>
      <div class="dialog_content">
        <div class="middle_operation">
            <!-- <span v-show="activeResType !== 'test'"> -->
                <webuploader :libCode="libCode"
                              ref="uploader"
                              :cancel-file = "cancelFile"
                              :stop-file="stopFile"
                              :continue-file="continueFile"
                              @file-add="fileAddFun"
                              @percentage="percentageFun"
                              @cancel-edit="cancelFun"
                              @upload-end="uploadEndFun"
                              @upload-config="uploadConfig">
                </webuploader>
            <!-- </span> -->
        </div>
        <div class="el-upload__tip">支持H264编码的mp4</div>
        <div class="bottom_content">
            <el-table
                v-for="(value, key, index) in tableDataObj"
                :key="index"
                :data="value"
                :ref="'multipleTable' + key"
                style="width: 100%"
                :show-header="false">
                <!-- 标题 -->
                <el-table-column>
                  <template slot-scope="scope">
                      <el-popover trigger="hover" placement="top">
                          {{ scope.row.name }}
                          <div class="resName" slot="reference">
                            {{ scope.row.name }}
                          </div>
                      </el-popover>
                  </template>
                </el-table-column>
                <!-- 进度 -->
                <el-table-column
                  width="100">
                  <template slot-scope="scope">
                    <span>{{ scope.row.percentage }}</span>
                  </template>
                </el-table-column>
                <!-- 操作-->
                <el-table-column
                  width="100">
                  <template slot-scope="scope" v-if="scope.row.success">
                    <span class="opertaions btnD" @click="openDeleteRes(scope.row, scope.$index)">重新上传</span>
                  </template>
                </el-table-column>
            </el-table>
        </div>
      </div>
  </div>
</template>
<script>
// import { Get } from '@common'
import webuploader from './webuploader.vue'
export default {
  name: 'localUpload',
  components: {
    webuploader
  },
  props: {
    files: {
      type: Array,
      default: null
    },
    libCode: {
      type: String,
      default: ''
    }
  },
  watch: {
    files (nv) {
      if (this.$route.params.data) { // 编辑
        this.tableDataObj['FILE_1'] = []
        this.tableDataObj['FILE_1'].push({
          name: nv[0].name,
          percentage: '100%',
          fileRecordId: nv[0].fileRecordId,
          success: true
        })
        this.$refs.uploader.fileList.push(nv[0].url)
        this.$refs.uploader.videoUrl = nv[0].url
        this.$forceUpdate()
      }
    }
  },
  data () {
    return {
      basePath: '',
      resType: [
        {
          title: '音视频',
          tag: 'media'
        }
      ],
      cancelFile: null, // 取消上传的文件
      stopFile: null, // 暂停上传的文件
      continueFile: null, // 继续上传的文件
      urls: {
        delRes: '/app/coursepacket/courseware/delResourceWareList' // 删除资源
      },
      tabPosition: 'top',
      tableDataObj: {}, // 资源列表对象
      fileRecordId: '',
      cfId: ''
    }
  },
  computed: {},
  created () {
  },
  mounted () {
  },
  beforeDestroy () {
  },
  methods: {
    dealData (file) {
      this.tableDataObj = {} // 清空列表
      this.tableDataObj[file.resType + file.id] = []
      this.tableDataObj[file.resType + file.id].push({
        name: file.name,
        percentage: file.percentage ? file.percentage + '%' : '等待上传',
        ext: file.ext,
        resId: file.id,
        file: file
      })
      this.$emit('videoUploadStart')
    },
    fileAddFun (file) {
      this.dealData(file)
      this.$forceUpdate()
    },
    percentageFun (file) {
      this.dealData(file)
      this.$forceUpdate()
      // this.isEmptyFun()
    },
    uploadEndFun (file, resp) {
      // console.log(file, resp)
      let data = resp.data
      this.tableDataObj[file.resType + file.id] = []
      if (resp && resp.status === 0) {
        // 上传成功
        this.tableDataObj[file.resType + file.id].push({
          name: file.name,
          percentage: file.percentage ? file.percentage + '%' : '等待上传',
          ext: file.ext,
          resId: file.id,
          id: data.ID,
          coursePackageId: this.id,
          success: true,
          fileRecordId: data.fileRecordId
        })
        this.$message.success('上传成功!')
        this.$refs.uploader.videoUrl = data.url
        data.cfId = this.cfId
        this.$emit('videoUploadEnd', { file, data })
      } else {
        // 上传失败
        delete this.tableDataObj[file.resType + file.id]
        this.$message.error(resp.message)
      }
      this.$forceUpdate()
      // this.isEmptyFun()
    },
    uploadConfig (cfId) {
      this.cfId = cfId
    },
    cancelFun () {},
    // 暂停文件上传
    stopUpload (item) {
      this.stopFile = item.file
    },
    // 继续文件上传
    continueUpload (item) {
      this.continueFile = item.file
    },
    // 取消文件上传
    cancelUpload (item) {
      // this.$confirm('确认取消文件上传操作?', '取消文件上传', {
      //   confirmButtonText: '确定',
      //   cancelButtonText: '取消',
      //   type: 'warning',
      // })
      //   .then(() => {
      this.cancelFile = item.file
      let key = item.file.resType + item.file.id
      delete this.tableDataObj[key]
      this.$message.success('已取消文件上传')
      // })
      // .catch(() => {})
    },
    openDeleteRes (item) { // 删除上传完成文件
      this.tableDataObj = {}
      this.$refs.uploader.fileList = []
      this.$refs.uploader.videoUrl = ''
      this.$emit('videoUploadDel')
      const params = {
        files: item.fileRecordId
      }
      this.$api.newList.deleteFile(params).then(res => {
        const data = res.data
        if (data.status === 0) {
          console.log('删除成功!')
        } else {
          console.log('删除失败!' + data.message)
        }
      })
    }
  }
}
</script>
<style>
.localUpload .el-dialog__footer{
  text-align: center;
}
</style>
<style scoped>
.el-upload__tip {
  font-size: 12px;
  color: #606266;
  margin-top: 7px;
}
.btnD {
  cursor: pointer;
}
</style>

webuploader.vue

<template>
  <div id="webuploader">
    <!-- <p @click="cancelEdit" id="filePicker" class="filePicker">本地上传</p> -->
    <div @click="cancelEdit" id="filePicker" class="filePicker">
      <i class="el-icon-upload iconUpload"></i>
      <p class="textUpload">点击上传</p>
    </div>
    <video v-if="videoUrl" :src="videoUrl" controls="controls" controlslist="nodownload" class="videoPlay"></video>
</div>
</template>
<script>
import WebUploader from 'webuploader'
// import { Get } from '@common'
export default {
  props: {
    libCode: {
      type: String,
      default: ''
    },
    // 要取消上传的文件
    cancelFile: {
      default: null
    },
    // 要暂停上传的文件
    stopFile: {
      default: null
    },
    // 要继续上传的文件
    continueFile: {
      default: null
    }
  },
  data () {
    return {
      fileList: [],
      basePath: '',
      subjectID: '',
      subjectName: '',
      uploader: null,
      curResType: '', // 当前上传文件的类型
      accept: {
        media: {
          exteensions: 'mp4',
          mimeTypes: '.mp4'
        }
      },
      ext: {
        media: [
          'MP4'
        ]
      },
      cfDeviceName: '',
      cfRelurl: '',
      cfId: '',
      videoUrl: ''
    }
  },
  watch: {
    // 取消文件上传
    cancelFile (file) {
      if (file) {
        this.uploader.cancelFile(file)
      }
    },
    // 暂停文件上传
    stopFile (file) {
      if (file) {
        this.uploader.stop(file)
      }
    },
    // 继续文件上传
    continueFile (file) {
      if (file) {
        this.uploader.upload(file.id)
      }
    }
  },
  created () {},
  mounted () {
    this.initUploader()
  },
  methods: {
    // 创建WebUploader实例
    initUploader () {
      let that = this
      this.uploader = WebUploader.create({
        auto: false, // 选完文件后,是否自动上传
        swf: 'https://cdn.bootcss.com/webuploader/0.1.1/Uploader.swf', // swf文件路径
        pick: {
          id: '#filePicker', // 选择文件的按钮
          multiple: false // 是否多文件上传 默认false
        },
        accept: {
          exteensions: 'mp4',
          mimeTypes: '.mp4'
        }, // 允许选择文件格式。
        threads: 1,
        resize: false, // 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
        fileNumLimit: 100, // 限制上传个数
        // formData: that.formData, // 上传所需参数
        // method: 'POST',
        chunked: true, // 分片上传
        chunkSize: 1 * 1024 * 1024, // 分片大小
        duplicate: true // 是否重复上传
      })
      // 文件加入队列前,判断文件类型
      this.uploader.on('beforeFileQueued', file => {
        // console.log(file)
        if (this.fileList.length === 1) {
          this.$message.warning('资源数已达上限,不能继续上传')
          return false
        }
        if (file.size === 0) {
          this.$message({
            message: '仅支持上传大于0KB的文件!',
            type: 'warning'
          })
          return false
        }
        // if (
        //   this.ext[this.resType].indexOf(file.ext.toLocaleUpperCase()) === -1
        // ) {
        //   this.$message.error('不支持的文件格式!')
        //   return false
        // }
      })
      // 文件参数设置,开始上传
      this.uploader.on('fileQueued', file => {
        const params = {
          type: '视频',
          libCode: this.libCode
        }
        this.$api.newList.getFileConfig(params).then(res => {
          const data = res.data
          if (data.status === 0) {
            this.cfId = data.data.cfId
            this.$emit('upload-config', this.cfId)
            this.cfDeviceName = data.data.cfDeviceName
            this.cfRelurl = data.data.cfRelurl
            // 文件上传参数
            let formData = {
              deviceName: this.cfDeviceName,
              remoteFile: this.cfRelurl,
              remoteFileName: file.name,
              chunked: true,
              guid: file.source.uid
            }
            this.$emit('file-add', file)
            this.uploader.options.formData = formData
            this.uploader.options.server = window.PROJECT_CONFIG.BASE_URL + '/dynamicFile/uploadFile.do'
            this.fileList = [] // 清空列表
            this.fileList.push(file)
            this.uploader.upload(file)
            // this.uploadFile(file)
            // this.fileList.forEach(file => { // 开始上传
            //   this.uploader.upload(file)
            // })
          } else {
            console.log(data.message)
          }
        })
      })
      // 分片发送前参数设置,解决多个文件同时分片上传时参数错乱的问题
      this.uploader.on('uploadBeforeSend', (obj, data) => {
        // this.uploader.options.server = obj.file.resType
        data.guid = obj.file.guid
        data.ext = obj.file.ext
      })
      //  文件上传进度
      this.uploader.on('uploadProgress', function (file, percentage) {
        file.percentage = Math.round(percentage * 100)
        that.$emit('percentage', file)
      })
      //  上传成功
      this.uploader.on('uploadSuccess', function (file, resp) {
        that.$emit('upload-end', file, resp)
      })
      // 上传失败
      this.uploader.on('uploadError', function (file, resp) {
        that.$message.error('上传资源失败,请稍后再试', file, resp)
      })
      // 上传完成,不管成功或失败
      this.uploader.on('uploadComplete', function (file) {
        console.log(file)
      })
    },
    // 点击确定 开始上传
    startUpload () {
      this.fileList.forEach(file => {
        this.uploader.upload(file)
      })
    },
    // 取消重命名
    cancelEdit () {
      this.$emit('cancel-edit')
    }
  }
}
</script>
<style>
/* .webuploader-element-invisible {
  opacity: 0;
} */
.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 {
  width: 100%;
  height: 100%;
  position: relative;
  display: inline-block;
  cursor: pointer;
  color: #fff;
  text-align: center;
  border-radius: 3px;
  overflow: hidden;
}
/* .webuploader-pick-hover {
  background: #00a2d4;
} */

.webuploader-pick-disable {
  opacity: 0.6;
  pointer-events:none;
}
.opertaions{
  color: #d0252e;
}
</style>
<style scoped>
#webuploader {
  position: relative;
}
.add {
  padding-left: 15px;
}
.filePicker{
  background-color: #fff;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  box-sizing: border-box;
  width: 360px;
  height: 180px;
  text-align: center;
  position: relative;
  overflow: hidden;
}
.iconUpload {
  font-size: 70px;
  display: block;
  margin: 40px auto 10px;
  color: #C0C4CC;
}
.textUpload {
  font-size: 16px;
  text-align: center;
  display: block;
  color: #666;
}
.videoPlay {
  width: 360px;
  height: 150px;
  position: absolute;
  top: 0;
  left: 0;
}
</style>