VideoFile.vue 9.53 KB
<template>
  <a-card :bordered="false">

    <!-- 查询区域 -->
    <!--<div class="table-page-search-wrapper">-->
    <!--<a-form layout="inline" @keyup.enter.native="searchQuery">-->
    <!--<a-row :gutter="24">-->

    <!--<a-col :md="6" :sm="12">-->
    <!--<a-form-item label="文件名">-->
    <!--&lt;!&ndash;<a-input placeholder="请输入账号查询" v-model="queryParam.username"></a-input>&ndash;&gt;-->
    <!--<j-input placeholder="输入文件名模糊查询" v-model="queryParam.username"></j-input>-->
    <!--</a-form-item>-->
    <!--</a-col>-->

    <!--</a-row>-->
    <!--</a-form>-->
    <!--</div>-->

    <!-- 操作按钮区域 -->
    <div class="table-operator" style="border-top: 5px">
      <a-button type="primary" icon="file" @click="fileUploadBtn">上传</a-button>

      <uploader :options="options" :file-status-text="statusText" :autoStart="true" ref="uploader"
                @file-added="onFileAdded" @file-progress="fileProgress" @file-error="fileError"
                @file-complete="fileComplete" @complete="complete">
        <uploader-unsupport></uploader-unsupport>
        <uploader-btn id="file-uploader-btn" ref="uploadBtn"></uploader-btn>
        <div class="uploader_box">
          <div class="top_title" v-show="panelShow">
            <span>文件列表</span>
            <span class="close" @click="uploaderListClose">×</span>
          </div>
          <uploader-list v-show="panelShow"></uploader-list>
        </div>
      </uploader>

    </div>

    <!-- table区域-begin -->
    <div>
      <a-table
        ref="table"
        rowKey="id"
        :columns="columns"
        :dataSource="dataSource"
        :pagination="ipagination"
        :loading="loading"
        :processResponse="processResponse"
        @change="handleTableChange">

        <span slot="fileSizeSlot" slot-scope="text, record">
          <span>{{ record.fileSize }}M</span>
        </span>
        <span slot="action" slot-scope="text, record">
          <a data-clipboard-action="copy" class="copyLink link" :data-clipboard-text="record.fileUrl" @click="copyLink">复制</a>
          <a-divider type="vertical" />
          <a target="_blank" v-if="record.fileUrl !== undefined && record.fileUrl!==''" :href="record.fileUrl"
             :download="record.filename">下载</a>
          <a-divider type="vertical" />
          <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
            <a>删除</a>
          </a-popconfirm>
        </span>

      </a-table>
    </div>
  </a-card>
</template>

<script>
import { putAction, postAction, getFileAccessHttpUrl } from '@/api/manage'
import { frozenBatch } from '@/api/api'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import JEllipsis from '@/components/jeecg/JEllipsis'
import Clipboard from 'clipboard';
import Vue from 'vue'
import { ACCESS_TOKEN, TENANT_ID } from '@/store/mutation-types'
import qs from 'qs'

export default {
  name: 'VideoFile',
  mixins: [JeecgListMixin],
  components: {
    JEllipsis
  },
  data() {
    return {
      clipboard: null,
      options: {
        target: window._CONFIG['domianURL'] + '/sys/uploader/chunk',
        testChunks: true,
        simultaneousUploads: 3,
        forceChunkSize: true,
        chunkSize: 30 * 1024 * 1024,
        headers: function() {
          const headers = {}
          const token = Vue.ls.get(ACCESS_TOKEN)
          if (token) {
            headers['X-Access-Token'] = token
          }
          let tenantid = Vue.ls.get(TENANT_ID)
          if (!tenantid) {
            tenantid = 0
          }
          headers['tenant-id'] = tenantid
          return headers
        },
        parseTimeRemaining: function(timeRemaining, parsedTimeRemaining) {
          return parsedTimeRemaining
            .replace(/\syears?/, '年')
            .replace(/\days?/, '天')
            .replace(/\shours?/, '小时')
            .replace(/\sminutes?/, '分钟')
            .replace(/\sseconds?/, '秒')
        }
      },
      attrs: {
        accept: 'image/*'
      },
      statusText: {
        success: '成功',
        error: '出错',
        uploading: '上传中',
        paused: '暂停中',
        waiting: '等待中'
      },
      panelShow: false,
      description: '文件上传',
      queryParam: {},
      recycleBinVisible: false,
      columns: [
        /*{
          title: '#',
          dataIndex: '',
          key:'rowIndex',
          width:60,
          align:"center",
          customRender:function (t,r,index) {
            return parseInt(index)+1;
          }
        },*/
        {
          title: '文件名',
          align: 'left',
          dataIndex: 'filename',
          sorter: true
        },
        {
          title: '大小',
          align: 'center',
          dataIndex: 'fileSize',
          scopedSlots: { customRender: 'fileSizeSlot' }
        },
        {
          title: '上传日期',
          align: 'center',
          dataIndex: 'createTime',
          sorter: true
        },
        {
          title: '操作',
          dataIndex: 'action',
          align: 'center',
          fixed: 'right',
          width: 160,
          scopedSlots: { customRender: 'action' }
        }
      ],
      url: {
        list: '/sys/file/list',
        delete: '/sys/file/delete'
      }
    }
  },
  methods: {
    // getTotalSize: function(totalSize) {
    //   const sz = totalSize / 1024 / 1204;
    //   console.log(totalSize,sz);
    //   return sz.toFixed(2) + 'M'
    // },
    copyLink() {
      this.clipboard.on('success', e => {
        console.log('文件地址已复制到剪切板');
        this.$message.success('文件地址已复制到剪切板');
        e.clearSelection()
        this.clipboard.destroy()
        this.clipboard = new Clipboard(".copyLink");
      })
      this.clipboard.on('error', e => {
        this.$message.error('复制失败');
      })

    },
    handleMenuClick(e) {
    },
    processResponse(response, cb, file, chunk) {
      console.log('processResponse', response, cb, file, chunk)
    },
    onSyncFinally({ isToLocal }) {
      // 同步到本地时刷新下数据
      if (isToLocal) {
        this.loadData()
      }
    },
    fileUploadBtn() {
      this.$refs.uploadBtn.$el.click()
    },
    onFileAdded() {
      this.panelShow = true
    },
    uploaderListClose() {
      this.$refs.uploader.uploader.files = []
      this.$refs.uploader.uploader.fileList = []
      this.panelShow = false
    },
    //文件在上传中
    fileProgress(rootFile, file, chunk) {

    },
    //上传过程中出错了
    fileError(rootFile, file, response, chunk) {
      this.$message({
        message: '上传失败,请重新上传',
        type: 'error'
      })
    },
    // 上传完成
    complete() {
      console.log('complete', arguments, this.$refs.uploader)
    },
    // 一个根文件(文件夹)成功上传完成。
    fileComplete() {
      console.log('file complete', arguments)
      const file = arguments[0].file
      let that = this
      postAction('/sys/uploader/mergeFile', qs.stringify({
        filename: file.name,
        identifier: arguments[0].uniqueIdentifier,
        totalSize: file.size,
        type: file.type
      })).then(function(response) {
        console.log(response)
        that.loadData()
      }).catch(function(error) {
        console.log(error)
        that.loadData()
      })
    }
  },
  mounted() {
    // this.$nextTick(() => {
    //   window.uploader = this.$refs.uploader.uploader
    // })
    this.clipboard = new Clipboard(".copyLink");
  },
  destroyed () {
    // 销毁Clipboard实例,避免在其它页面或组件中实例化Clipboard后造成再次监听,产生重复回调
    this.clipboard.destroy()
  }
}
</script>

<style scoped>
@import '~@assets/less/common.less'
</style>

<style>
.uploader_box {
  position: fixed;
  right: 12px;
  bottom: 12px;
  background-color: #fff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, .2);
  z-index: 999;
}

.top_title {
  height: 50px;
  padding: 0 15px;
  background-color: #fff;
  border-bottom: 1px solid #eee;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.close {
  color: #9e9e9e;
  font-size: 28px;
  cursor: pointer;
}

.uploader-list {
  width: 600px;
  max-height: 490px;
  overflow-y: auto;
  scrollbar-color: #cdcdcd #f6f6f6;
  scrollbar-width: thin;
}

.uploader-file {
  border-bottom: 1px solid #eee !important;
}

.uploader-list ul li:last-child .uploader-file {
  border-bottom: none;
}

.uploader-file-icon {
  width: 24px;
  height: 24px;
  display: inline-block;
  vertical-align: top;
  margin-top: 13px;
  margin-right: 8px;
}

.uploader-file-icon::before {
  content: "" !important;
  display: block;
  height: 100%;
}

.uploader-file-icon[icon="folder"]::before {
  content: "" !important;
  background: url("../../assets/folder.png");
  background-size: 24px 24px;
}

.uploader-file-icon[icon="image"]::before {
  content: "" !important;
  background: url("../../assets/image.png");
  background-size: 24px 24px;
}

.uploader-file-icon[icon="video"]::before {
  content: "" !important;
  background: url("../../assets/video.png");
  background-size: 24px 24px;
}

.uploader-file-icon[icon="audio"]::before {
  content: "" !important;
  background: url("../../assets/audio.png");
  background-size: 24px 24px;
}

.uploader-file-icon[icon="document"]::before {
  content: "" !important;
  background: url("../../assets/document.png");
  background-size: 24px 24px;
}

.uploader-file-actions > span {
  opacity: 0.7;
}

#file-uploader-btn {
  position: absolute;
  clip: rect(0, 0, 0, 0);
}

.uploader-file-progress {
  background-color: #f0f6ff !important;
}
</style>