<template>
  <div class="leo-uploader" v-loading="uploaderLoading">
    <el-upload
        class="uploader-box"
        v-show="uploaderShow"
        :action="uploaderRequestUrl"
        name="file"
        :headers="uploaderHeaders"
        :data="uploaderFormData"
        :show-file-list="false"
        :before-upload="uploaderHandleBefore"
        :on-success="uploaderHandleSuccess"
        :disabled="uploaderDisabled"
        :style="`width:${width};height:${height};`"
    >
      <img v-if="uploaderImageUrl" :src="uploaderImageUrl" class="image-preview"
           :style="`width:${width};height:${height};display: block;`">
      <i v-else class="el-icon-plus uploader-icon"
         :style="`width:${width};height:${height};line-height:${height};`"></i>
    </el-upload>
    <div class="image-show" v-show="!uploaderShow">
      <img :src="uploaderImageUrl" alt="" :width="width" :height="height">
    </div>
  </div>
</template>

<script>
  import {REQUEST_URL, ACCESS_TOKEN_PREFIX} from '@/utils/config'
  import userInfo from '@/utils/userInfo'
  import network from '../utils/network'

  export default {
    name: 'LeoUploader',
    props: {
      requestRoute: {
        type: String,
        required: true,
      },
      defaultImageUrl: {
        type: String,
        default: null,
      },
      uploaderSuccessCanChange: {
        type: Boolean,
        default: true,
      },
      width: {
        type: String,
        default: '720px',
      },
      height: {
        type: String,
        default: '480px',
      }
    },
    data() {
      return {
        uploaderShow: true,
        uploaderLoading: false,
        uploaderFormData: {
          'uploadToken': '',
        },
        uploaderRequestUrl: `${REQUEST_URL}${this.requestRoute}`,
        uploaderHeaders: {
          'Device-Type': 'pc',
          'Suppress-Response-Code': '1',
          'Authorization': '',
        },
        uploaderDisabled: false,
        successImageUrl: null,
      }
    },
    computed: {
      uploaderImageUrl() {
        if (this.successImageUrl !== null) {
          return this.successImageUrl
        }
        else if (this.defaultImageUrl !== null) {
          this.uploaderShow = false
          this.uploaderDisabled = true
          this.uploaderLoading = false
          return this.defaultImageUrl
        }
      }
    },
    watch: {
      requestRoute(newVal) {
        Object.assign(this.$data, this.$options.data())
        this.uploaderRequestUrl = `${REQUEST_URL}${this.requestRoute}`
      },
    },
    methods: {
      uploaderHandleBefore() {
        this.$message({
          message: '正在上传，请稍后。请勿关闭窗口！',
          type: 'warning',
          duration: 0,
        })
        this.uploaderLoading = true
        return network.updateToken().then(accessToken => {
          this.uploaderHeaders.Authorization = ACCESS_TOKEN_PREFIX + accessToken
          return network.getData(`file/token`)
        }).then(response => {
          this.uploaderFormData.uploadToken = response
        }).catch(response => {

        })
      },
      uploaderHandleSuccess(response, file) {
        this.$message.closeAll()
        if (response.success) {
          this.$message({
            message: '上传成功',
            type: 'success'
          })
          this.successImageUrl = URL.createObjectURL(file.raw)
          if (!this.uploaderSuccessCanChange) {
            this.uploaderShow = false
            this.uploaderDisabled = true
            this.uploaderLoading = false
          }
          this.uploaderLoading = false
          this.$emit('on-success', response.data)
        } else {
          this.$message({
            message: response.data.message,
            type: 'warning'
          })
          this.uploaderLoading = false
        }
      },
    }
  }
</script>

<style scoped>
  .uploader-box {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }

  .uploader-box:hover {
    border-color: #409EFF;
  }

  .uploader-icon {
    font-size: 28px;
    color: #8c939d;
    text-align: center;
  }
</style>