<template>
  <div style="padding-right: 5px">
    <el-row style="padding: 5px">
      <el-button size="small" type="primary" icon="el-icon-upload" round @click="onClickUpload">上传</el-button>
      <el-button size="small" type="primary" icon="el-icon-folder-add" round @click="onCreateFolder">新建文件夹</el-button>
      <el-input
        v-model="inputData"
        placeholder="搜索我的文件"
        size="small"
        style="width: 30%; padding-left: 5px"
        clearable
        @keyup.enter.native="onSearchFile"
      >
        <el-button slot="append" icon="el-icon-search" @click="onSearchFile" />
      </el-input>
      <el-divider />
      <el-breadcrumb separator-class="el-icon-arrow-right">
        <el-breadcrumb-item
          v-for="(item, index) in pathList"
          :key="index"
          style="padding: 1px"
          :replace="true"
          :to="{ path: item.path }"
        >
          {{ item.name }}
        </el-breadcrumb-item>
      </el-breadcrumb>
      <el-divider />
      <el-table
        :data="dataList"
        :show-header="true"
        style="width: 100%"
        @selection-change="handleTableSectionChange"
      >
        <el-table-column
          align="center"
          type="selection"
        />
        <el-table-column
          prop="filename"
          label="文件名"
        >
          <template slot-scope="scope">
            <a
              style="text-decoration-line: none"
              href="javascript:void(0)"
              @click="onClickFilename(scope.row)"
            >
              <span>{{ scope.row.filename }}</span>
            </a>
          </template>
        </el-table-column>
        <el-table-column
          prop="size"
          label="大小"
        />
        <el-table-column
          prop="fileTypeStr"
          label="类型"
        />
        <el-table-column
          prop="updateTime"
          label="修改时间"
        />
      </el-table>
      <div style="margin-top: 20px">
        <el-button v-if="selectedTable.length !== 0" @click="addToAlbum">添加 {{ selectedTable.length }} 到相册</el-button>
      </div>
      <el-pagination
        background
        :small="screenWidth <= 768"
        layout="prev, pager, next"
        :page-size="pageSize"
        :current-page="currentPage"
        :total="totalSize"
        @current-change="handleCurrentChange"
        @prev-click="handleCurrentChange"
        @next-click="handleCurrentChange"
      />
    </el-row>

    <el-dialog
      :visible.sync="showPreviewDialog"
      :before-close="handlePreviewClose"
      width="100%"
      center
    >
      <el-card v-if="fileDetail !== null" class="box-card" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
        <div slot="header" class="clearfix">
          <span>{{ fileDetail.filename }}</span>
        </div>
        <div class="text item">
          <el-col v-if="fileType === 1001" :md="12">
            <div class="imgs">
              <el-image
                lazy
                fit="cover"
                class="coverImg"
                :src="fileDetail.url"
              />
            </div>
          </el-col>
          <el-col v-else-if="fileType === 1002" :md="12">
            <video
              :src="fileDetail.url"
              controls
              autoplay
              class="video"
              width="100%"
            />
          </el-col>
          <el-col v-else-if="fileType === 1003" :md="12">
            <audio
              :src="fileDetail.url"
              controls
              autoplay
              class="audio"
            />
          </el-col>
          <el-col v-else-if="fileType === 1004" :md="12">
            文档
          </el-col>
          <el-col v-else-if="fileType === 1005" :md="12">
            文件
          </el-col>
        </div>
      </el-card>
    </el-dialog>
    <el-dialog
      :visible.sync="showCreateFolderDialog"
      width="30%"
      center
    >
      <div>
        <el-form ref="createFolderForm" :model="createFolderForm">
          <el-form-item label="当前文件夹" label-width="120px" prop="title">
            <el-input
              v-model="createFolderForm.path"
              style="margin-left: 5px"
              readonly
            />
          </el-form-item>
          <el-form-item label="新文件夹名" label-width="120px" prop="title">
            <el-input
              v-model="createFolderForm.folderName"
              style="margin-left: 5px"
              clearable
            />
          </el-form-item>
          <el-button
            type="primary"
            plain
            size="small"
            icon="el-icon-plus"
            style="margin-left: 10px"
            @click="createFolder"
          >
            创建文件夹
          </el-button>
        </el-form>
      </div>
    </el-dialog>
    <el-dialog
      :visible.sync="showUploadDialog"
      :before-close="handleUploadClose"
      :close-on-click-modal="false"
      width="50%"
      center
    >
      <div>
        <uploader
          v-if="options !== null"
          class="uploader-example"
          :options="options"
          :auto-start="true"
          @file-added="onFileAdded"
          @file-success="onFileSuccess"
          @file-progress="onFileProgress"
          @file-error="onFileError"
        >
          <uploader-unsupport />
          <uploader-drop>
            <p>拖动文件到此处或</p>
            <uploader-btn :attrs="attrs">选择文件</uploader-btn>
          </uploader-drop>
          <uploader-list />
        </uploader>
      </div>
    </el-dialog>
    <el-dialog
      :visible.sync="showAddToAlbumUploadDialog"
      width="50%"
      center
    >
      <el-table
        :data="albumKeyValues"
        :show-header="true"
        style="width: 100%"
      >
        <el-table-column
          prop="value"
          label="相册 ID"
        />
        <el-table-column
          prop="label"
          label="相册名"
        />
        <el-table-column label="操作">
          <template slot-scope="scope">
            <el-button
              size="mini"
              @click="onAddToAlbum(scope.row)"
            >选择</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>
  </div>
</template>

<script>
import { addToAlbum, getAlbumKeyValues, getDiskChannelInfo, getDiskFile, getFileDetail } from '@/api/disk'
import { hashFile } from '@/utils/functions'

export default {
  name: 'DiskFile',
  data() {
    return {
      // 屏幕宽度, 为了控制分页条的大小
      screenWidth: document.body.clientWidth,
      currentPage: 1,
      pageSize: 10,
      totalSize: 0,
      dataList: [],
      // 对话框被选中的文件
      selectedTable: [],
      inputData: '',
      showPreviewDialog: false,
      fileDetail: null,
      fileType: 0,
      videoProp: null,
      pathList: [],
      queryForm: {
        pn: 1,
        path: '/',
        fileType: null
      },
      // ****************************************************************************************************************
      showCreateFolderDialog: false,
      createFolderForm: {
        path: '/',
        folderName: null
      },
      // ****************************************************************************************************************
      showAddToAlbumUploadDialog: false,
      albumKeyValues: [],
      // ****************************************************************************************************************
      showUploadDialog: false,
      options: {
        target: '',
        // 分块大小 10MB
        chunkSize: 1024 * 1024 * 10,
        // 失败自动重传次数
        maxChunkRetries: 3,
        fileParameterName: 'file',
        testChunks: true
      },
      attrs: {
        accept: '*'
      }
    }
  },
  created() {
    const pn = this.$route.query.pn
    if (pn !== undefined) {
      this.queryForm.pn = pn
    }

    const path = this.$route.query.path
    if (path !== undefined) {
      this.queryForm.path = path
    }
    document.title = '所有文件'
    this.getData()
  },
  methods: {
    // ****************************************************************************************************************
    onFileAdded(file) {
      if (file.file.size > 1024 * 1024 * 1024 * 20) {
        file.cancel()
        this.$notify({
          title: '提示',
          message: '文件应小于 20GB',
          type: 'warning',
          duration: 3000
        })
        return
      }
      this.setTitle(file.file.name)
      this.processVideo(file.file)

      file.pause()
      hashFile(file.file).then(result => {
        this.startUpload(result.sha256sum, file)
      })
    },
    startUpload(sha256sum, file) {
      file.uniqueIdentifier = sha256sum
      file.resume()
    },
    onFileProgress(rootFile, file, chunk) {
    },
    onFileSuccess(rootFile, file, response, chunk) {
      const res = JSON.parse(response)
      if (res.code === 0) {
        const resData = res.data
        this.form.videoFileId = resData.uploadId
        this.$notify({
          title: '提示',
          message: '视频已上传',
          type: 'warning',
          duration: 3000
        })
      } else {
        this.$notify({
          title: '提示',
          message: '视频文件上传失败',
          type: 'warning',
          duration: 3000
        })
      }
    },
    onFileError(rootFile, file, response, chunk) {
      this.$notify({
        title: '提示',
        message: '视频文件上传错误',
        type: 'warning',
        duration: 3000
      })
    },
    handleUploadClose() {
      this.showUploadDialog = false
    },
    onClickUpload() {
      this.showUploadDialog = true
      getDiskChannelInfo().then(resp => {
        if (resp.code === 0) {
          const respData = resp.data
          this.form.channelCode = respData.channelCode
          this.options = {
            target: respData.ossUrl,
            // 分块大小 10MB
            chunkSize: 1024 * 1024 * 10,
            // 失败自动重传次数
            maxChunkRetries: 3,
            fileParameterName: 'file',
            testChunks: true,
            // 服务器分片校验函数, 秒传及断点续传基础
            checkChunkUploadedByResponse: function(chunk, message) {
              const objMessage = JSON.parse(message)
              const respData = objMessage.data
              if (respData.skipUpload) {
                return true
              }
              return (respData.uploaded || []).indexOf(chunk.offset + 1) >= 0
            },
            query: (file, chunk) => {
              return {
                channelCode: respData.channelCode,
                multiparts: ''
              }
            },
            headers: {
              Authorization: 'Bearer ' + respData.token
            },
            withCredentials: false
          }

          this.showUploadDialog = true
        } else {
          this.$notify({
            title: '提示',
            message: '获取 OSS 服务器地址失败, 暂时无法上传视频文件',
            type: 'error',
            duration: 3000
          })
        }
      }).catch(error => {
        this.$notify({
          title: '获取 OSS 服务器地址失败, 暂时无法上传视频文件',
          message: error.message,
          type: 'warning',
          duration: 3000
        })
      })
    },
    // ****************************************************************************************************************
    handlePreviewClose() {
      this.showPreviewDialog = false
      this.fileDetail = null
      this.fileType = 0
    },
    onClickFilename(row) {
      this.fileType = row.fileType
      if (this.fileType === 1000) {
        const filename = row.filename
        const url = this.pathList[this.pathList.length - 1].path
        const arr = url.split('?')
        let path = ''
        if (arr.length === 1) {
          path = '/' + filename
        } else {
          path = arr[1].split('=')[1] + '/' + filename
        }
        this.$router.push({
          path: '/disk',
          query: {
            path: path
          }
        })
        this.$router.go(0)
      } else {
        getFileDetail(row.fileId).then(resp => {
          if (resp.code === 0) {
            this.showPreviewDialog = true
            this.fileDetail = resp.data
            if (this.fileType === 1002) {
              this.videoProp = {
                videoUrl: this.fileDetail.url
              }
            }
          }
        })
      }
    },
    // ****************************************************************************************************************
    onCreateFolder() {
      this.showCreateFolderDialog = true
    },
    createFolder() {
      console.log(this.createFolderForm)
      this.showCreateFolderDialog = false
    },
    // ****************************************************************************************************************
    handleCurrentChange(pageNumber) {
      this.currentPage = pageNumber
      this.queryForm.pn = this.currentPage
      this.getData()
      // 回到顶部
      scrollTo(0, 0)
    },
    getData() {
      getDiskFile(this.queryForm).then(resp => {
        if (resp.code === 0) {
          const respData = resp.data
          const namePathList = respData.namePathList
          const pageList = respData.pageList

          this.dataList = pageList.list
          this.totalSize = pageList.totalSize
          if (namePathList.length === 0) {
            this.pathList.push({ path: '/disk', name: '全部文件' })
          } else {
            for (const namePath of namePathList) {
              this.pathList.push({ path: '/disk?path=' + namePath.path, name: namePath.filename })
            }
          }
        }
      })
    },
    // 处理表格被选中
    handleTableSectionChange(val) {
      this.selectedTable = val
    },
    addToAlbum() {
      this.$message.info('addToAlbum')
      getAlbumKeyValues().then(resp => {
        if (resp.code === 0) {
          this.albumKeyValues = resp.data
          this.showAddToAlbumUploadDialog = true
        }
      })
    },
    onAddToAlbum(row) {
      const albumId = row.value
      const fileIds = []
      for (const item of this.selectedTable) {
        fileIds.push(item.fileId)
      }
      const jsonData = {}
      jsonData.albumId = albumId
      jsonData.fileIds = fileIds
      addToAlbum(jsonData).then(resp => {
        this.$message.info(resp.msg)
      }).finally(() => {
        this.showAddToAlbumUploadDialog = false
        this.selectedTable = []
      })
    },
    onSearchFile() {
      this.$message.info('search file')
    }
  }
}
</script>

<style>
/*处于手机屏幕时*/
@media screen and (max-width: 768px){
  .coverImg {
    height: 120px !important;
  }
}

.coverImg {
  width: 100%;
  height: 320px;
  display: block;
}
</style>
