<template>
  <div>
    <el-upload
      ref="upload"
      :accept="accept"
      :action="action"
      :data="data"
      :auto-upload="auto"
      :drag="drag"
      :file-list="tmpFileList"
      :headers="headers"
      :limit="max"
      :list-type="listType"
      :multiple="max > 1"
      :on-change="handleChange"
      :on-exceed="maxChange"
      :on-progress="progress"
      :on-remove="remove"
      :on-error="onError"
      :on-success="success"
      :show-file-list="showList"
      style="width: 100%"
    >
      <div v-if="drag">
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          将文件/图片拖到此处，或<em>点击上传</em>
        </div>
      </div>
      <div v-else class="flex flex-justify-start">
        <el-button
          v-if="showBtn"
          :loading="loading"
          icon="el-icon-upload"
          plain
          size="mini"
          type="primary"
          >{{ btn }}
        </el-button>
      </div>
      <slot></slot>
    </el-upload>
  </div>
</template>

<script>
import { Base64 } from 'js-base64'
import { getToken } from '../utils/auth.js'
import website from '@/config/website'
import api from '@/api'

export default {
  name: 'uploadFile', // 文件上传
  props: {
    showBtn: {
      type: Boolean,
      default: true
    },
    drag: {
      type: Boolean,
      default: false
    },
    showList: {
      type: Boolean,
      default: false
    },
    data: Object,
    auto: {
      type: Boolean,
      default: false
    },
    accept: {
      type: String,
      default: ''
    },
    max: {
      type: Number,
      default: 1
    },
    listType: {
      type: String,
      default: 'text'
    },
    btnText: {
      type: String,
      default: '点击上传'
    },
    action: {
      type: String,
      default: api.uploadPath
    },
    files: {
      type: Array,
      default() {
        return null
      }
    }
  },
  watch: {
    btnText: {
      handler(val) {
        this.btn = val
      },
      immediate: true
    }
  },
  data() {
    return {
      loading: false,
      btn: '点击上传',
      tmpFileList: [],
      fileList: [],
      headers: {
        Authorization: `Basic ${Base64.encode(
          `${website.clientId}:${website.clientSecret}`
        )}`,
        'Blade-Auth': 'bearer ' + getToken()
      }
    }
  },
  mounted() {
    this.setFiles(this.files, 'originalFileName')
  },
  methods: {
    setFiles(fileList, name) {
      // 文件回填 (参数：文件列表，文件名的字段name)
      if (!fileList || fileList.length === 0) return
      const files = []
      fileList.forEach((item, index) => {
        files.push({
          name: item[name] || '文件' + index + 1,
          response: {
            code: 200,
            success: true,
            data: [item]
          },
          status: 'success'
        })
      })
      this.fileList = files
    },
    progress(event, file, fileList) {
      if (file.status === 'ready') {
        this.loading = true
        this.btn = '正在上传'
      } else if (file.status === 'success') {
        this.loading = false
        this.btn = '点击上传'
      }

      this.$emit('progress')
    },
    handleChange(file, fileList) {
      this.tmpFileList = fileList
      this.$emit('before', this.tmpFileList)
    },
    maxChange() {
      if (this.max === 1) {
        // 只有一张图的时候超出进行覆盖
        this.fileList = []
      } else {
        this.$message.warning(`最多只能上传${this.max}个文件`)
      }
    },
    beforeUpload(file) {
      this.loading = true
      console.log(file)
      this.$emit('before', file)
    },
    success() {
      this.loading = false
      this.btn = '点击上传'
      const finishList = this.tmpFileList.filter(
        sub => sub.status === 'success'
      )
      if (finishList.length === this.tmpFileList.length) {
        this.$emit('success', {
          fileList: this.tmpFileList
        })
        setTimeout(() => {
          this.$refs.upload.clearFiles()
          this.tmpFileList = []
          this.speed = ''
        }, 2000)
      }
    },
    remove(file, fileList) {
      const ids = fileList.map(e => e.response.data[0].id)
      this.$emit('remove', {
        file,
        fileList,
        ids
      })
    },
    submit() {
      this.$refs.upload.submit()
    },
    onError(res, file, fileList) {
      const error = JSON.parse(res.message)
      this.$confirm(error.msg, {
        confirmButtonText: '确定',
        type: 'warning'
      }).then(() => {
        this.$emit('error')
      })
    }
  }
}
</script>
<style lang="scss" scoped>
.custom-upload {
  :deep(.el-upload-list__item-name) {
    white-space: pre-wrap;
    width: 100%;
  }
}
</style>
