<template>
  <div class="file-upload-box">
    <component
      :is="!isBtn ? 'a-upload-dragger' : 'a-upload'"
      action="#"
      :id="uuid"
      class="upload-demo my-upload-file"
      :class="fileList.length > 0 && !loading ? 'success-file' : ''"
      :multiple="multiple"
      ref="uploadRef"
      :disabled="loading ? true : self_disabled"
      :custom-request="handleHttpUpload"
      :file-list="fileList"
      @preview="onPreview"
      @remove="handleRemove"
      :before-upload="beforeUpload"
      :showUploadList="showFileList"
      :maxCount="limit"
      :style="getCSSProperties"
    >
      <template v-if="isBtn">
        <a-button type="primary">
          <template #icon>
            <UploadOutlined />
          </template>
          点击上传</a-button
        >
      </template>
      <template v-else>
        <div>
          <FileDoneOutlined
            style="color: #67c23a; font-size: 40px"
            v-if="fileList.length > 0 && !loading"
          />
          <CloudUploadOutlined v-else style="font-size: 40px" />
        </div>
        <div v-if="!self_disabled">{{
          loading ? '上传中' : fileList.length > 0 ? '上传成功' : '点击或将文件拖拽到这里上传'
        }}</div>
      </template>
    </component>
    <div v-if="!isBtn" class="ant-upload__tip">
      <div v-if="props.fileType">支持扩展名：{{ props.fileType }}</div>
      <div v-if="props.multiple && props.limit">最多上传{{ props.limit }}个文件</div>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { computed, ref } from 'vue';
  import {
    CloudUploadOutlined,
    FileDoneOutlined,
    UploadOutlined,
    PlusOutlined,
    EditOutlined,
    DeleteOutlined,
    ZoomInOutlined,
  } from '@ant-design/icons-vue';
  import { notification } from 'ant-design-vue';
  import { generateUUID } from '@/utils/auth';

  const uploadRef = ref();
  import { upload } from '@/api/common';

  // 接受父组件参数
  const props = defineProps({
    zIndex: {
      default: -1,
    },
    width: {
      default: 200,
    },
    height: {
      default: 200,
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    isBtn: {
      type: Boolean,
      default: false,
    },
    showFileList: {
      type: Boolean,
      default: true,
    },
    btnTip: {
      type: String,
      default: '',
    },
    limit: {
      type: Number,
      default: undefined,
    },
    fileList: {
      type: Array,
      required: true,
      default: [],
    },
    disabled: {
      default: false,
    },
    fileSize: {
      default: 200,
    },
    orderNo: {
      default: '',
    },
    fileType: {
      default: '',
    },
    name: {
      default: '',
    },
    autoUpload: {
      default: true,
    },
  });

  // 生成组件唯一id
  const uuid = ref('id-' + generateUUID());

  const getCSSProperties = computed(() => {
    return {
      width: `${props.width}px`,
    };
  });
  // 判断是否禁用上传和删除
  const self_disabled = computed(() => {
    return props.disabled;
  });

  const emit = defineEmits(['upload']);

  const loading = ref(false);
  const handleHttpUpload = async (options) => {
    if (!props.autoUpload) {
      emit('upload', options);
      return;
    }
    loading.value = true;
    try {
      const formData = new FormData();
      formData.append('file', options.file);
      formData.append('name', props.name);
      const res = await upload(formData);
      if (props.multiple) {
        let list = JSON.parse(JSON.stringify(props.fileList));
        list.push({
          url: res.fileUrl,
          name: res.originalName,
          filePath: res.fileUrl,
          fileName: res.originalName,
        });
        emit('upload', list, props.zIndex);
      } else {
        emit('upload', res.fileUrl, res.originalName, props.zIndex);
      }
    } catch (error) {
      notification.error({
        message: '温馨提示',
        description: '上传文件失败！',
      });
      if (props.multiple) {
        emit('upload', props.fileList, props.zIndex);
      } else {
        // uploadRef.value!.clearFiles();
        emit('upload', '', '', props.zIndex);
      }
      options.onError(error as any);
    } finally {
      loading.value = false;
    }
  };

  const onPreview = (uploadFile) => {
    window.open(uploadFile?.url);
  };

  const handleRemove = (file: any) => {
    if (props.multiple) {
      emit(
        'upload',
        props.fileList.filter((f) => !(f.url === file.url)),
        props.zIndex,
      );
    } else {
      // uploadRef.value!.clearFiles();
      emit('upload', '', '', props.zIndex);
    }
  };

  /**
   * @description 文件上传之前判断
   * @param rawFile 选择的文件
   * */
  const beforeUpload = (rawFile) => {
    const imgSize = rawFile.size / 1024 / 1024 < props.fileSize;
    if (!imgSize) {
      notification.warning({
        message: '温馨提示',
        description: `上传文件大小不能超过 ${props.fileSize}M！`,
      });
      return false;
    }
    if (props.fileType) {
      let fileType = props.fileType.replace(/\s/g, '');
      fileType.split('.').join('|');
      let fileIndex = rawFile.name.lastIndexOf('.');
      let substrName = rawFile.name.substr(fileIndex);
      if (fileType.indexOf(substrName) == -1) {
        notification.warning({
          message: '温馨提示',
          description: '上传文件不符合所需的格式！',
        });
        return false;
      }
    }
    return true;
  };
</script>
<style lang="less">
  .success-file.ant-upload.ant-upload-drag {
    border-width: 3px;
    border-color: #67c23a !important;
  }
  .file-upload-box {
    .my-upload-file.ant-upload.ant-upload-drag {
      height: 160px !important;
      .ant-upload {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
      }
    }
    .ant-upload__tip {
      line-height: 18px;
      font-size: 12px;
      margin-top: 7px;
    }
  }
</style>
