<template>
  <el-upload
    ref="upload"
    :limit="1"
    :data="params"
    :headers="headers"
    :file-list="value.uuid ? [value] : []"
    :action="action"
    :accept="accept"
    :show-file-list="false"
    :before-upload="onBefore"
    :on-remove="onRemove"
    :on-success="onSuccess"
    :on-error="onError"
    :on-exceed="onExceed"
    class="word-uploader"
  >
    <template slot="trigger">
      <img v-if="value.uuid" :src="value.url" class="imageicon">
      <div v-else :class="imageIcon" class="imageicon" />
      <div v-if="value.uuid" class="file-name">{{ value.name }}</div>
      <el-button size="mini" round @click="handleClearFile">{{ value.name ? '重新选择' : '选择文件' }}</el-button>
      <div class="el-upload__tip" v-if="!value.uuid">
        <slot name="tip">{{ tip }}</slot>
      </div>
    </template>
  </el-upload>
</template>

<script>
import { getToken } from '@/utils/auth'
import { postUploadFile } from '@/api/special-business'
import './uploadFile.scss'

export default {
  name: 'UploadWord',
  props: {
    // 请求路径
    action: {
      type: String,
      default: postUploadFile
    },
    // 请求头
    headers: {
      type: Object,
      default: () => ({
        'Authorization': `bearer ${getToken()}`
      })
    },
    // 上传接口的额外参数
    params: {
      type: Object,
      default: () => ({ rootPath: '', path: '' })
    },
    // 上传文件类型 picture: 图片 word: word文档
    type: {
      type: String,
      default: 'picture'
    },
    // 上传水平照片还是垂直
    vertical: {
      type: Boolean,
      default: false
    },
    // 提示信息
    tip: {
      type: String,
      default: ''
    },
    // 允许选择的文件
    accept: {
      type: String,
      default: ''
    },
    // 双向绑定的值
    value: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      loaded: false,
      file: {}
    }
  },
  computed: {
    /**
     * 图片icon的class类名
     */
    imageIcon() {
      // 如果当前是word
      if (this.type === 'word') {
        return 'icon-word'
      }
      if (this.type === 'picture') {
        return this.vertical ? 'icon-pic-v' : 'icon-pic-h'
      }
    }
  },
  methods: {
    /**
     * 清空上传的文件
     */
    handleClearFile() {
      this.$emit('input', {})
    },

    /**
    * 上传前校验
    * @time 2021-12-06 10:02:49
    */
    onBefore(file) {
      // 当前选择的文件名
      const fileName = file.name
      // 后缀
      const ext = fileName.slice(fileName.lastIndexOf('.'))
      // 当前允许的文件类型
      const accept = this.accept.split(',')
      // 如果当前是不合法的
      if (!accept.includes(ext)) {
        this.$message.error(`上传的文件仅支持${this.accept}格式`)
        return false
      }
      const isLt2M = file.size / 1024 / 1024 <= 2
      if (!isLt2M) {
        this.$message.error('上传文件大小不能超过2MB')
        return false
      }
      // 呈现loading状态
      this.loaded = true
    },

    /**
     * 上传数量限制
     * @time 2021-12-06 10:03:10
     */
    onExceed() {
      this.$message.error('最多上传1个文件')
      // 关闭loading状态
      this.loaded = false
    },

    /**
    * 上传错误
    * @param  {Object} err 错误对象
    * @time 2021-12-15 14:14:49
    */
    onError() {
      this.$message.error('文件上传失败')
      this.$refs.upload.clearFiles()
      this.onRemove()
      // 关闭loading状态
      this.loaded = false
    },

    /**
     * 响应删除文件操作
     * @time 2021-12-09 09:52:56
     */
    onRemove() {
      this.$emit('input', {})
    },

    /**
     * 文件上传
     * @time 2021-12-06 10:02:33
     */
    onSuccess(json) {
      if (json.success) {
        this.$message.success('文件上传成功')
        const data = json.data || {}
        // 用于组件展示用
        this.$emit('input', {
          name: data.fileName,
          url: this.type === 'word' ? require('@/assets/components/upload/ico_word_active.png') : data.accessUrl,
          fileUrl: data.accessUrl,
          uuid: data.uuid
        })
      }
      // 关闭loading状态
      this.loaded = false
    }
  }
}
</script>
