<template>
  <p-card>
    <div slot='extra'>
      <a-upload v-if='type !=="view"' :customRequest='receiveFile'>
        <p-button :loading='updateLoading' type='primary'>上传</p-button>
      </a-upload>
      <p-button v-if='type !=="add"' class='ml-10' type='primary' @click='batchDownload'>打包下载</p-button>
    </div>
    <div>
      <div v-for='(item,index) in localList' class='upload-box' @click='viewImg(index)'>
        <img :alt='item.originFileName' :src='item.fileUrl' class='upload-box-img' />
        <div v-if='type !=="view"' class='upload-box-del' @click.stop='delFile(item)'>
          <p-icon :iconStyle='{color:"#ffffff"}' type='delete' />
        </div>
      </div>
      <a-empty v-if='localList.length === 0 && type ==="view"' />
      <a-upload v-if='type !=="view"' :customRequest='receiveFile' accept='image/gif,image/jpeg,image/jpg,image/png'>
        <div class='upload-box plus'>
          <p-icon :type="updateLoading ? 'loading' : 'plus'" />
          <div class='ant-upload-text'>请上传图片</div>
        </div>
      </a-upload>
    </div>
  </p-card>
</template>

<script>
import { batchDownloadFile, delFile, downloadFile, getFileList, uploadFile } from '../api'

const reg = /\.(png|jpg|gif|jpeg|webp)$/
export default {
  props: {
    type: '',
    editData: {
      type: Object,
      default: () => ({})
    },
    bizType: {
      type: [Number, String],
      default: '1'
    }
  },
  data() {
    return {
      activeKey: '1', // 面板切换
      updateLoading: false, // 上传状态
      localList: [], // 本地文件列表
      fileSelectedRowKeys: []
    }
  },
  filters: {
    fileSizeFilter(bytes) {
      if (!bytes) return '0 B'
      const k = 1024
      const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return (bytes / k ** i).toPrecision(3) + ' ' + sizes[i]
    }
  },
  computed: {
    enterpriseId() {
      return this.$store.state.user.info.enterpriseId
    },
    imgDataSource() { // 图片型列表
      return this.localList.filter(_ => reg.test(_.fileName))
    },
    fileDataSource() { // 文件型列表
      return this.localList.filter(_ => !reg.test(_.fileName))
    }
  },
  created() {
    if (this.editData.id) {
      this.getFiles()
    }
  },
  methods: {
    // 获取文件
    receiveFile(event) {
      // 新增证件时,附件加入到本地缓存
      if (this.type === 'add') return this.cacheFile(event)
      // 非新增证件时候，附件直接上传
      this.updateLoading = true
      const bizId = this.editData.id
      const enterpriseId = this.enterpriseId
      const formData = new FormData()
      formData.append('files', event.file)
      formData.append('bizId', bizId)
      formData.append('bizType', this.bizType)
      formData.append('enterpriseid', enterpriseId)
      uploadFile(formData).then(res => {
        if (res.success) {
          this.$message.success(res.message)
          this.getFiles()
        } else {
          this.$message.error(res.message)
        }
      }).catch(err => {
        this.$message.error(err.toString())
      }).finally(() => this.updateLoading = false)
    },
    // 本地缓存文件
    async cacheFile(event) {
      try {
        const { file: { name: fileName, size: fileSize, uid: id } } = event
        const isImg = reg.test(fileName)
        let fileUrl = ''
        if (isImg) {
          fileUrl = await this.readFile(event.file)
        }
        const fileExt = /\.[^\.]+$/.exec(fileName)
        this.localList.push({ id, fileExt, fileUrl, fileSize, fileName, originFileName: fileName, fileClassify: '', isLocal: true, event })
      } catch (e) {
        this.$message.error(e.toString())
      }
    },
    // 本地未上传文件读取
    readFile(file) {
      return new Promise((resolve, reject) => {
        const fs = new FileReader()
        fs.readAsDataURL(file)
        fs.onload = () => resolve(fs.result)
        fs.onerror = e => reject(e)
      })
    },
    // 上传本地缓存文件
    uploadAllFile(bizId) {
      if (this.localList.length === 0) return Promise.resolve()
      const enterpriseId = this.enterpriseId
      const formData = new FormData()
      this.localList.forEach(_ => formData.append('files', _.event.file))
      formData.append('bizId', bizId)
      formData.append('bizType', this.bizType)
      formData.append('enterpriseid', enterpriseId)
      return uploadFile(formData)
    },
    // 获取远程文件列表
    getFiles() {
      this.updateLoading = true
      const bizId = this.editData.id
      const enterpriseid = this.enterpriseId
      getFileList({ bizId, bizType: this.bizType, enterpriseid }).then((res) => {
        this.localList = res.data.map(item => ({ ...item.file, ...item }))
      }).finally(() => this.updateLoading = false)
    },
    // 文件下载
    async downloadSimple(record) {
      const { fileUrl, originFileName } = record
      const file = await downloadFile(fileUrl)
      const blob = new Blob([file])
      const downloadElement = document.createElement('a')
      const href = window.URL.createObjectURL(blob)
      downloadElement.href = href
      downloadElement.download = originFileName
      document.body.appendChild(downloadElement)
      downloadElement.click()
      document.body.removeChild(downloadElement)
      window.URL.revokeObjectURL(href)
    },
    // 打包下载
    batchDownload() {
      let selectedFiles = this.localList // 待下载文件集合
      const fileDownIds = selectedFiles.map(file => file.id)
      batchDownloadFile(fileDownIds.join(',')).then(stream => {
        const blob = new Blob([stream])
        const downloadElement = document.createElement('a')
        const href = window.URL.createObjectURL(blob)
        downloadElement.href = href
        downloadElement.download = '证件文件.zip'
        document.body.appendChild(downloadElement)
        downloadElement.click()
        document.body.removeChild(downloadElement)
        window.URL.revokeObjectURL(href)
      })
    },
    // 图片预览
    viewImg(initialViewIndex = 0) {
      this.$viewerApi({
        options: { initialViewIndex },
        images: this.localList.map(_ => _.fileUrl)
      })
    },
    // 删除文件&图片
    delFile(file) {
      const { id } = file
      if (this.type === 'add') return this.localList = this.localList.filter(_ => _.id !== id)
      const self = this
      this.$confirm({
        title: `确定是否要删除${file.originFileName}?`,
        content: '',
        onOk() {
          return new Promise((resolve, reject) => {
            delFile(id).then(res => {
              if (res.success) {
                self.$message.success(res.message)
                self.getFiles()
                resolve()
              } else {
                self.$message.error(res.message)
                reject()
              }
            })
          })
        }
      })
    }
  }
}
</script>

<style lang='less' scoped>
.upload-box {
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: 100px;
  height: 100px;
  margin-right: 8px;
  margin-bottom: 8px;
  text-align: center;
  vertical-align: top;
  border: 1px dashed #d9d9d9;
  border-radius: 2px;
  float: left;
  overflow: hidden;
  position: relative;

  .upload-box-del {
    position: absolute;
    top: 0;
    right: 0;
    cursor: pointer;
    transition: all 200ms;
    background: #ff4d4f;
  }

  .upload-box-img {
    width: 100%;
    height: 100%;
  }

  &.plus {
    cursor: pointer;
  }
}
</style>