<template>
  <div class="custom-upload">
    <el-dialog
      title="图片裁剪"
      :visible.sync="showCropper"
      top="6vh"
      width="50%"
      height="700"
      class="cropper-dialog"
      center
      append-to-body
    >
      <vue-cropper
        v-if="showCropper"
        id="corpper"
        ref="cropper"
        :class="{'corpper-warp':showCropper}"
        v-bind="cropper"
        :style="{height:`${height}px`}"
      />
      <div v-if="showCropper" class="cropper-button">
        <el-button class="cancel-btn" size="small" @click.native="showCropper=false">取消</el-button>
        <el-button size="small" type="primary" :loading="loading" @click="uploadCover">完成</el-button>
      </div>
    </el-dialog>
    <input
      :id="id"
      type="file"
      style="display: none"
      name="single"
      accept="image/*"
      @change="onChange($event)"
    />

    <div class="avatar-uploader" @click="handleOpenFile()">
      <div class="el-upload el-upload--text">
        <img v-if="img" :src="img" class="avatar" />
        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
      </div>
    </div>

    <div v-if="tips" class="tips clear-margin-top">{{ tips }}</div>
  </div>
</template>

<script>
// 上传文件组件
import { VueCropper } from 'vue-cropper'

// 定义的接口根据自己项目更换

import { isImageFile, isMaxFileSize, readFile } from '@/utils/upload' // 见下文
import { Message } from 'element-ui'

export default {
  components: {
    VueCropper
  },
  props: {
    // 最大上传文件的大小
    maxFileSize: {
      type: Number,
      default: 1024 // （MB)
    },
    uploadUrl: {
      type: String
    },
    img: {
      type: String
    },
    // 提示内容
    tips: {
      type: String
    },
    // 图片裁剪比列
    fixedNumber: {
      type: Array,
      default: function () {
        return []
      }
    },
    // 图片文件分辨率的宽度
    width: {
      type: Number,
      default: 8640
    },
    // 图片文件分辨率的高度
    height: {
      type: Number,
      default: 1920
    }
  },
  data () {
    return {
      id: 'cropper-input-' + new Date(),
      loading: false,
      showCropper: false,
      imgName: '',
      cropper: {
        img: '',
        info: true,
        size: 1024 * 4,
        outputType: 'jpg',
        canScale: true,
        autoCrop: true,
        full: true,
        // 只有自动截图开启 宽度高度才生效
        autoCropWidth: this.width,
        autoCropHeight: this.height,
        fixedBox: false,
        // 开启宽度和高度比例
        fixed: true,
        fixedNumber: this.fixedNumber,
        original: false,
        canMoveBox: true,
        canMove: true
      }
    }
  },
  methods: {
    // 打开文件
    handleOpenFile () {
      const input = document.getElementById(this.id)
      // 解决同一个文件不能监听的问题
      input.addEventListener(
        'click',
        function () {
          this.value = ''
        },
        false
      )
      // 点击input
      input.click()
    },

    // 裁剪input 监听
    async onChange (e) {
      const file = e.target.files[0]

      if (!file) {
        return Message.error('选择图片失败')
      }
      // 验证文件类型
      if (!isImageFile(file)) {
        return
      }
      try {
        // 读取文件
        const src = await readFile(file)
        this.imgName = file.name
        this.showCropper = true
        this.cropper.img = src
      } catch (error) {
        console.log(error)
      }
    },

    // 封面上传功能
    uploadCover () {
      this.$refs.cropper.getCropBlob(async imgRes => {
        try {
          // 文件大小限制
          if (!isMaxFileSize(imgRes, this.maxFileSize)) {
            return
          }
          this.loading = true
          let formData = new FormData()
          formData.append('file', imgRes)
          formData.append('filename', this.imgName)

          const res = await this.$http.post(
            this.uploadUrl,
            formData,
            {'Content-Type': 'multipart/form-data'})

          this.$emit('subUploadSucceed', res.data)
          Message.success('上传成功')
          this.loading = false
          this.showCropper = false
        } catch (error) {
          this.loading = false
          this.showCropper = false
          Message.error(error.data.message)
        }
      })
    }
  }
}
</script>

<style lang="less"  >
#corpper {
  width: 90%;
  margin: 0 auto;
  background-image: none;
  background: #fff;
  z-index: 1002;
  height: 512px;
}
.cropper-dialog {
  height: 800px;
  text-align: center;
  .el-dialog__header {
    padding-top: 15px;
  }
  .el-dialog--center .el-dialog__body {
    padding-top: 0;
    padding-bottom: 15px;
  }
  .el-dialog {
    text-align: center;
  }
}
.cropper-button {
  z-index: 1003;
  text-align: center;
  margin-top: 20px;
  .el-button {
    font-size: 16px;
    cursor: pointer;
    text-align: center;
  }
  .cancel-btn {
    color: #373737;
  }
  .el-button:last-child {
    margin-left: 100px;
  }
}
.cropper-modal {
  background-color: rgba(0, 0, 0, 0.5) !important;
}
.custom-upload {
  .tips {
    margin-top: 10px;
    color: red;
    font-size: 12px;
  }
  .clear-margin-top {
    margin-top: 0;
  }
}
</style>

<style>
.avatar-uploader{
  width: 180px;
  max-height: 180px;
}
.avatar-uploader .el-upload {
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}
.avatar {
  width: 178px;
  /* height: 178px; */
  display: block;
}
</style>
