<template>
  <a-spin :spinning="spinning">
    <a-upload-dragger
      :before-upload="beforeUpload"
      :customRequest="customUpload"
      :file-list="fileList"
      :multiple="multiple"
      accept="image/gif,image/jpeg,image/jpg,image/png,image/svg"
      listType="picture"
      name="file"
      @change="handleChange"
    >
      <p class="ant-upload-drag-icon">
        <a-icon type="inbox" />
      </p>
      <p class="ant-upload-text">
        点击或拖拽文件到此处
      </p>
      <p class="ant-upload-hint">
        支持单次或批量上传。最多可上传{{ max }}张图片
      </p>
    </a-upload-dragger>
  </a-spin>
</template>

<script>
import moment from 'moment'
import { getStsAssumeRole } from '@/api/storage'

const OSS = require('ali-oss')
const md5 = require('md5')

export default {
  name: 'DraggerUpload',
  props: {
    multiple: {
      type: Boolean,
      default: true
    },
    defaults: {
      type: Array,
      default: function () {
        return []
      }
    },
    max: {
      type: Number,
      default: 9
    }
  },
  data () {
    return {
      store: '',
      fileList: [],
      spinning: false
    }
  },
  created () {
    this.initStsOSS()
  },
  deactivated () {
    this.fileList = []
  },
  watch: {
    defaults (val) {
      if (val.length > 0) {
        for (let i = 0; i < val.length; i++) {
          this.fileList.push({
            uid: i,
            name: val[i].name,
            status: 'done',
            path: val[i].path,
            thumbUrl: val[i].thumb,
            url: val[i].url
          })
        }
      }
    }
  },
  methods: {
    initStsOSS () {
      getStsAssumeRole().then(res => {
        this.store = new OSS(res)
      })
    },
    computeFileMd5 (file, callback) {
      const fileReader = new FileReader()
      fileReader.readAsArrayBuffer(file)

      fileReader.onload = function (e) {
        callback(md5(new Uint8Array(e.target.result)))
      }
      fileReader.onerror = function () {
        console.warn('FileReader error.')
      }
    },
    customUpload ({ onSuccess, onError, onProgress, file }) {
      this.spinning = true
      this.computeFileMd5(file, res => {
        const fileName = 'front' + moment().format('/YYYY/MM/DD/') + res + '.' + file.type.replace('image/', '')
        this.store.multipartUpload(fileName, file, {
          progress: (e) => {
            onProgress({
              percent: Math.round(e * 100)
            })
          },
          partSize: 100 * 1024
        }).then(res => {
          let fileUrl = ''
          const result = res.res.requestUrls
          if (result[0].indexOf('?') !== -1) {
            fileUrl = result[0].slice(0, result[0].indexOf('?'))
          } else {
            fileUrl = result[0]
          }
          this.$message.success('图片上传成功')
          onSuccess({
            url: fileUrl
          })
        }).catch(err => {
          // 重新获取一次OSS-STS
          this.initStsOSS()

          this.$message.error('图片上传失败')
          onError(err)
        }).finally(() => {
          this.spinning = false
        })
      })
    },
    beforeUpload (file) {
      if (file.size > 2 * 1024 * 1024) {
        this.$message.error('图片超过1M，请压缩后上传')
        return false
      }
      this.fileList = [...this.fileList, file]
      return true
    },
    handleChange (info) {
      let fileList = [...info.fileList]
      fileList = fileList.slice(-this.max)
      if (info.file.status === 'done') {
        fileList = fileList.map(file => {
          if (file.response) {
            file.url = file.response.url
          }
          return file
        })
      }
      this.fileList = fileList
    },
    getUploadedList () {
      return this.fileList.map(res => {
        return res.url
      })
    },
    clearFileList () {
      this.fileList = []
    }
  }
}
</script>

<style scoped>

</style>
