<template>
  <div class="oss-upload">
    <input v-show="false" id="file" ref="ossFileInput" type="file" multiple @change="onFileChange">
    <!-- 文件上传进度 -->
    <el-dialog title="上传进度" :visible.sync="visible" width="700px">
      <el-alert v-if="alterVisiable" title="上传记录将在关闭浏览器后清除" type="warning" @close="onAlertClose" />
      <div class="oss-upload__progress">
        <el-table :data="fileList" style="width: 100%" :height="tableHeight">
          <el-table-column label="文件名" prop="fileName" align="center" />
          <el-table-column label="大小" width="120" align="center">
            <template slot-scope="{ row }">
              <span>{{ row.size | fileSize }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="progress" label="进度" width="180" align="center">
            <template slot-scope="{ row }">
              <el-progress :percentage="row.percentage" :show-text="false" :status="breakStatus(row.status)" />
            </template>
          </el-table-column>
          <el-table-column prop="status" label="状态" width="100" align="center">
            <template slot-scope="{ row }">
              <span v-if="row.status === 0">上传失败</span>
              <span v-else-if="row.status === 1">上传成功</span>
              <span v-else>上传中</span>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { v4 as uuidv4 } from 'uuid'
import { upload } from './upload'
export default {
  name: 'OssUpload',
  filters: {
    fileSize(size) {
      size = Math.round(size / 1024)
      if (size < 1024) return size + 'KB'
      size = Math.round(size / 1024)
      if (size < 1024) return size + 'MB'
      return Math.round(size / 1024) + 'GB'
    }
  },
  props: {
    onProgress: {
      type: Function,
      default: null
    },
    onSuccess: {
      type: Function,
      default: null
    },
    onFaild: {
      type: Function,
      default: null
    }
  },
  data() {
    return {
      alterVisiable: false,
      visible: false,
      fileList: []
    }
  },
  computed: {
    count() {
      return this.fileList.length
    },
    tableHeight() {
      return this.count > 7 ? '400' : 'auto'
    }
  },
  created() {
    const flag = localStorage.getItem('alert-confirm')
    this.alterVisiable = !flag
  },
  methods: {
    open() {
      this.visible = true
    },
    close() {
      this.visible = false
    },
    breakStatus(status) {
      if (status === 0) return 'exception'
      if (status === 1) return 'success'
      return undefined
    },
    chooseFile() {
      this.$nextTick(() => {
        this.$refs.ossFileInput.click()
      })
    },
    onFileChange(e) {
      const fileList = Array.from(e.target.files).map((file) => this.generageRowfile(file))
      this.fileList = [...this.fileList, ...fileList]
      this.visible = true
      upload(this.fileList, {
        success: this.success,
        faild: this.faild,
        progress: this.progress
      })
    },
    generageRowfile(file) {
      return {
        uuid: uuidv4(),
        fileName: file.name,
        size: file.size,
        type: file.type,
        file: file,
        percentage: 0,
        status: -1, // 0 上次失败 1 上传成功 2 上传中 -1 待上传
        response: null,
        url: '',
        checkpoint: null
      }
    },
    // 上传成功
    success(file, response, resultUrl) {
      file.response = response
      file.status = 1
      file.url = resultUrl
      this.onSuccess && this.onSuccess(file, this.fileList)
    },
    // 上传进度
    progress(file, response) {
      const { p, cpt, res } = response
      file.percentage = p * 100
      file.checkpoint = cpt
      file.response = res
      file.status = 2
      this.onProgress && this.onProgress(file, this.fileList)
    },
    // 上传失败
    faild(file, response) {
      file.response = response
      file.status = 0
      this.onFaild && this.onFaild(file, this.fileList)
    },
    // 警告框关闭
    onAlertClose() {
      localStorage.setItem('alert-confirm', true)
    }
  }
}
</script>
<style scoped lang="scss">
.oss-upload__progress {
  border: 1px solid #eee;
  border-bottom: 0;
}

.el-alert {
  margin-bottom: 12px;
}
</style>
