<!--
 * @Description: 单个图片[.jpg,.png]文件上传组件
 * @Author: Rockery
 * @Date: 2021-12-27 11:19:47
 * @LastEditors: Rockery
 * @LastEditTime: 2022-01-21 14:55:59
 * @FilePath: \party_construct_web\src\components\RocImgFileUpload\index.vue
 * @Copyright: Copyright (c) 2016~2021 Rockery(1113269755@qq.com)
-->

<template>
  <div class="rocimgfileupload">
    <div class="rocimgfileupload-attachment" v-loading="removeLoading">
      <el-upload
        ref="rocImgFileUploadRef"
        :limit="1"
        accept=".jpg, .png"
        :auto-upload="true"
        :show-file-list="true"
        :action="actionUrl"
        :headers="headers"
        :before-upload="handleRocImgFileUploadBeforeUpload"
        :on-success="handleRocImgFileUploadOnsuccess"
        :on-change="handleRocImgFileUploadOnchange"
        :on-remove="handleRocImgFileUploadOnRemove"
        :on-exceed="handleRocImgFileUploadOnExceed"
        class="rocimgfileupload-attachment-fileupload"
      >
        <div class="rocimgfileupload-attachment-fileupload-content">
          <i class="el-icon-plus" />
          上传文件，格式：JPG、PNG
        </div>
      </el-upload>
      <div v-if="isUploadSuccess" v-viewer class="fl rocimgfileupload-attachment-addr">
        <img :src="successResp.successUrl" :alt="successResp.url" @error="imgViewerOnerror" />
      </div>
      <el-button
        v-if="isSelect && !isUploadSuccess"
        type="primary"
        size="small"
        @click="submitRocImgFileUploadClick"
      >上传文件</el-button>
      <el-button
        v-if="isSelect"
        type="info"
        size="small"
        @click="removeRocImgFileUploadClick"
      >移除文件</el-button>
    </div>
  </div>
</template>

<script>
import { getToken } from '@/utils/auth';
import Viewer from 'v-viewer';
import 'viewerjs/dist/viewer.css';
import Vue from 'vue';
Vue.use(Viewer, {
  defaultOptions: {
    zIndex: 9999
  }
});

export default {
  name: 'Rocimgfileupload',
  props: {
    // 值
    value: {
      type: String,
      default: ''
    },
    // 文件上传地址
    uploadUrl: {
      type: String,
      default: `${process.env.VUE_APP_FILE_UPLOAD_API}`
    },
    // 请求头对象
    uploadHeaders: {
      type: Object,
      default: () => {
        return {
          Authorization: 'Bearer ' + getToken()
        };
      }
    },
    // 上传文件标题
    uploadFileTitle: {
      type: String,
      default: ''
    },
  },
  data() {
    return {
      // 是否选择文件
      isSelect: false,
      // 是否上传文件成功
      isUploadSuccess: false,
      // 文件上传成功数据对象
      successUrl: '',
      // 文件上传成功数据对象
      successResp: {},
      removeLoading: false,
      setTimeoutTimer: null
    };
  },
  computed: {
    // 文件上传地址
    actionUrl() {
      return this.uploadUrl;
    },
    // 请求头对象
    headers() {
      return this.uploadHeaders;
    },
    // 上传文件标题
    fileTitle() {
      if (this.uploadFileTitle) {
        return `文件【${this.uploadFileTitle}】`;
      }

      return '文件';
    },
  },
  destroyed() {
    this.setTimeoutTimer && clearTimeout(this.setTimeoutTimer);
  },
  methods: {
    /**
     * 文件上传预处理
     */
    handleRocImgFileUploadBeforeUpload(file) {
      if(!['image/png', 'image/jpeg'].includes(file.type || '')){
        this.$refs.rocImgFileUploadRef.clearFiles();
        this.msgError(`${this.fileTitle}格式错误，请上传类型格式为jpg或png的图片文件！`);
        return;
      }
    },
    /**
     * 文件上传成功处理
     */
    handleRocImgFileUploadOnsuccess(response, file, fileList) {
      // 校验封面图片是否上传成功
      if (response.code !== 200) {
        this.$refs.rocImgFileUploadRef?.clearFiles?.();
        this.isSelect = false;
        this.isUploadSuccess = false;
        this.msgError(`上传${this.fileTitle}失败，请重新选择图片文件上传！`);
        return;
      }

      let successUrl = `${window.origin}${process.env.VUE_APP_FILE_VIEW_API}${response?.data?.url}`;

      // 绑定封面图片数据
      this.successUrl = successUrl;

      // 文件上传成功数据对象
      this.successResp = {
        ...response?.data,
        successUrl: successUrl
      };

      this.$emit('input', response?.data?.url);
      this.isUploadSuccess = true;
      this.$alert(`${this.fileTitle}上传成功！`, '上传结果', { dangerouslyUseHTMLString: true });
    },
    /**
     * 文件状态改变
     */
    handleRocImgFileUploadOnchange(file, fileList) {
      if (file.status === 'ready') {
        if(!['image/png', 'image/jpeg'].includes((file.raw || {}).type || '')){
          this.$refs.rocImgFileUploadRef.clearFiles();
          this.isSelect = false;
          this.msgError(`${this.fileTitle}格式错误，请上传类型格式为jpg或png的图片文件！`);
          return;
        }
        this.isSelect = true;
        this.isUploadSuccess = false;
        this.$emit('input', 'ROCIMGUPLOADSELECT');
      } else if (file.status === 'success') {
        this.isUploadSuccess = true;
      } else {
        this.isUploadSuccess = false;
        this.isSelect = false;
        this.$emit('input', 'ROCIMGUPLOADSELECT');
      }
    },
    /**
     * 文件列表移除文件时的钩子
     */
    handleRocImgFileUploadOnRemove(file, fileList) {
      this.removeLoading = true;
      this.setTimeoutTimer = setTimeout(() => {
        this.successResp = {};
        this.successUrl = '';
        this.isUploadSuccess = false;
        this.isSelect = false;
        this.$emit('input', '');
        this.setTimeoutTimer && clearTimeout(this.setTimeoutTimer);
        this.removeLoading = false;
      }, 900);
    },
    /**
     * 文件超出个数限制时的钩子
     */
    handleRocImgFileUploadOnExceed(files, fileList) {
      this.msgWarning(`只允许上传单个${this.fileTitle}`);
    },
    /**
     * 提交上传相关材料文件
     */
    submitRocImgFileUploadClick() {
      if (!this.isSelect) { return; }
      this.$confirm(`确定上传${this.fileTitle}操作吗？`, '提示', {
        confirmButtonText: '确定 ',
        cancelButtonText: '取消 ',
        type: 'info'
      }).then(() => {
        this.$refs.rocImgFileUploadRef?.submit?.();
      }).catch(() => {
        this.msgInfo('您已取消上传操作！');
      });
    },
    /**
     * 移除选择相关材料文件
     */
    removeRocImgFileUploadClick() {
      this.removeLoading = true;
      this.$refs.rocImgFileUploadRef.clearFiles();
      this.setTimeoutTimer = setTimeout(() => {
        this.isSelect = false;
        this.isUploadSuccess = false;
        this.successResp = {};
        this.successUrl = '';
        this.$emit('input', '');
        this.setTimeoutTimer && clearTimeout(this.setTimeoutTimer);
        this.removeLoading = false;
      }, 1000);
    }
  }
}
</script>

<style lang="scss">
.rocimgfileupload {
  .rocimgfileupload-attachment {
    &-fileupload {
      .el-upload {
        width: 100%;
        border: 1px dashed #d9d9d9;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;

        &:hover {
          border-color: #409eff;
        }
      }

      .el-upload-list.el-upload-list--text {
        .el-upload-list__item:first-child {
          margin-top: 0;
        }
      }

      &-content {
        width: 100%;
        height: 32px;
        font-size: 14px;
        font-weight: 400;
        color: #8c939d;
        text-align: center;
      }
    }

    &-addr {
      width: 100%;
      padding: 5px 0;

      img {
        max-width: 100px;
        max-height: 100px;
      }
    }
  }
}
</style>