<template>
  <ElUpload
    class="x-upload-file"
    :class="{'x-upload-file__disabled': disabled}"
    ref="upload"
    v-bind="$attrs"
    v-on="$listeners"
    :action="action"
    :file-list="fileList"
    :multiple="multiple"
    :list-type="listType"
    :limit="limit"
    :auto-upload="autoUpload"
    :on-exceed="handleExceed"
    :on-success="handleSuccess"
    :before-upload="handleBeforeUpload"
  >
    <i class="el-icon-plus"/>
    <div slot="file" slot-scope="{ file }">
      <img
        class="el-upload-list__item-thumbnail"
        :src="getPreviewImgSrc(file)"
        alt=""
      />
      <span class="el-upload-list__item-actions">
          <span
            class="el-upload-list__item-preview"
            @click="handlePreviewFile(file)"
          >
            <i class="el-icon-zoom-in"></i>
          </span>
          <span
            class="el-upload-list__item-delete"
            @click="handleRemoveFile(file)"
          >
            <i class="el-icon-delete"></i>
          </span>
      </span>
    </div>
    <ElImageViewer
      :z-index='zIndex'
      :url-list="previewSrcList"
      :initialIndex="initialIndex"
      v-if="showViewer"
      :on-close="triggerViewer"/>
  </ElUpload>
</template>
<script>
import { Upload as ElUpload} from 'element-ui';
import { getFileUrlById } from '../../../lib/api/sysDownloadApi';
import ElImageViewer from 'element-ui/packages/image/src/image-viewer';
import 'element-ui/lib/theme-chalk/image.css';
const imgFormat = ['png', 'gif', 'jpg', 'jpeg', 'bmp'];
const getExtension = (str) => {
  return str?.substring(str?.toLowerCase().lastIndexOf('.') + 1);
};
export default {
  name: 'XUploadFile',
  /**
   * 属性参数
   * @member props
   * @property {Array} [uploadType] 限制上传文件的类型
   */
  props: {
    value: {
      type: [String, Number],
      default: ''
    },
    disabled: {
      default: false,
      type: Boolean
    },
    size: {
      type: Number,
      default: 10
    },
    limit: {
      default: 3,
      type: Number
    },
    action: {
      type: String,
      default: '/api/core/uploadFileMinIO.do'
    },
    autoUpload: {
      type: Boolean,
      default: true
    },
    uploadType: {
      type: Array,
      default: () => []
    },
    listType: {
      type: String,
      default: 'picture-card'
    },
    multiple: {
      type: Boolean,
      default: true
    },
    zIndex: {
      default: 9999,
      type: Number
    }
  },
  watch: {
    value(newNum) {
      this.fileIds = newNum;
      this.getFiles();
    }
  },
  data () {
    return {
      previewSrcList: [],
      fileList: [],
      fileIds: this.value,
      showViewer: false,
      initialIndex: 0
    };
  },
  mounted () {
    this.getFiles();
  },
  methods: {
    handleExceed() {
      this.$notify.error(`最多只能上传${this.limit}个附件!`);
    },
    handleBeforeUpload (file) {
      const uploadType = this.uploadType;
      let ret = true;
      if (file.size / 1024 / 1024 > this.size) {
        this.$notify.error(`上传的附件大小不能超过 ${this.size}MB!`);
        ret = false;
      } else if (uploadType.length) {
        let isExist = false;
        for (const item of uploadType) {
          if (file.name?.split('.')[file.name?.split('.').length - 1].toLowerCase() === item) {
            isExist = true;
          }
        }
        if (isExist) {
          ret = true;
        } else {
          this.$notify.error(`上传的附件只能是 ${uploadType.join('、')}格式`);
          ret = false;
        }
      }
      return ret;
    },
    handleSuccess (data, file) {
      const id = data.data.id;
      const fileIdsArr = this.fileIds?.toString().split(',');

      if (!data.success && !id) {
        return false;
      }

      if (fileIdsArr && fileIdsArr.includes(id.toString())) {
        const $upload = this.$refs.upload;
        $upload.uploadFiles.splice($upload.uploadFiles.length - 1, 1);
        this.$notify.error('不能上传重复的附件');
        return false;
      }

      // 更新id, 用于删除
      file.id = id;

      this.fileIds = this.fileIds ? this.fileIds + ',' + id : id;
      this.$emit('input', this.fileIds);

      this.$emit('success', data);
    },
    handleRemoveFile (file) {
      const $upload = this.$refs.upload;
      const uploadFiles = $upload.uploadFiles;

      $upload.uploadFiles = uploadFiles.filter(item => item.url !== file.url);

      if (file.id) {
        this.fileIds = this.fileIds?.toString().split(',')
          .filter(id => Number(id) !== Number(file.id))
          .join(',');
        this.$emit('input', this.fileIds);
      }
    },
    handlePreviewFile (file) {
      const fileName = file.name || file.url || '';

      if (['docx', 'ppt', 'xlsx', 'xls'].includes(getExtension(file.url)?.toLowerCase())) {
        const openDocSrc = 'https://view.officeapps.live.com/op/view.aspx?src=';
        window.open(openDocSrc + (file.filePath || file.response.data.filePath));
      } else if (imgFormat.includes(getExtension(fileName)?.toLowerCase())) {
        const uploadFiles = this.$refs.upload.uploadFiles || [];
        const filesUrl = uploadFiles.filter(item => {
          const itemFileName = item.name || item.url || '';
          return imgFormat.includes(getExtension(itemFileName)?.toLowerCase());
        }).map(item => item.url);

        const currentIndex = filesUrl.findIndex(url => url === file.url) || 0;

        this.previewSrcList = filesUrl;
        this.initialIndex = currentIndex;
        this.triggerViewer();
      } else {
        window.open(file.url);
      }
    },
    getPreviewImgSrc (file) {
      const path = '//oss.newpearl.com/newpearl/img';
      const fileName = file.name || file.url || '';
      let ret = '';
      if (fileName.toLowerCase().indexOf('.pdf') > -1) {
        ret = path + '/file-img/PDF.png';
      } else if (fileName.toLowerCase().indexOf('.ppt') > -1) {
        ret = path + '/file-img/PPT.png';
      } else if (fileName.toLowerCase().indexOf('.xlsx') > -1 || fileName.indexOf('.xls') > -1) {
        ret = path + '/file-img/EXCEL.png';
      } else if (fileName.toLowerCase().indexOf('.docx') > -1) {
        ret = path + '/file-img/WORD.png';
      } else if (imgFormat.includes(getExtension(fileName)?.toLowerCase())) {
        ret = file.url;
      } else {
        ret = path + '/2021-11-02/b445afc62e59482e95f5ea40da3229f9.png';
      }
      return ret;
    },
    triggerViewer () {
      this.showViewer = !this.showViewer;
    },
    getFiles () {
      if (!this.fileIds) {
        return false;
      }

      getFileUrlById({ ids: this.fileIds }).then((response) => {
        const res = response.data;
        if (res.success) {
          this.fileList = res.data.map(item => {
            return {
              ...item,
              filePath: item.filePath,
              url: item.url || item.filePath
            };
          });
        } else {
          this.$notify.error('查询附件失败:' + res.msg);
        }
      });
    }
  },
  components: {
    ElUpload,
    ElImageViewer
  }
};
</script>
