<template>
  <el-dialog v-model="dialogVisible" :width="parameter.width" :top="parameter.top" :title="`${parameter.title}`" :destroy-on-close="true" draggable>
    <el-form class="drawer-multiColumn-form" label-width="100px">
      <el-form-item label="文件上传">
        <el-upload
          ref="uploadRef"
          action="#"
          class="upload"
          :drag="true"
          :auto-upload="false"
          :limit="parameter.limit"
          :multiple="parameter.multiple"
          :show-file-list="true"
          :http-request="uploadExcel"
          :before-upload="beforeExcelUpload"
          :on-exceed="handleExceed"
          :on-success="excelUploadSuccess"
          :on-error="excelUploadError"
          :accept="parameter.fileType!.join(',')"
        >
          <slot name="empty">
            <el-icon class="el-icon--upload">
              <upload-filled />
            </el-icon>
            <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
          </slot>
          <template #tip>
            <slot name="tip">
              <div class="el-upload__tip text-center">
                <el-checkbox v-model="isCover">是否更新已存在的数据</el-checkbox>
              </div>
              <div class="el-upload__tip text-center">
                请上传 .xls , .xlsx 标准格式文件，文件最大为 {{ parameter.fileSize }}M。
                <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="downloadTemp">
                  模板下载
                </el-link>
              </div>
            </slot>
          </template>
        </el-upload>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button type="primary" @click="handleSubmit">确认</el-button>
        <el-button @click="dialogVisible = false">取消</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts" name="ImportExcel">
import { ref } from 'vue'
import { useDownload } from '@/hooks/useDownload'
import { ElNotification, UploadRequestOptions, UploadRawFile, UploadInstance } from 'element-plus'

export interface ExcelParameterProps {
  title: string // 标题
  fileSize?: number // 上传文件的大小
  limit?: number // 上传文件个数
  top?: string // 离顶部距离
  width?: number // 弹框宽度
  multiple?: boolean // 是否支持多选文件
  fileType?: File.ExcelMimeType[] // 上传文件的类型
  tempApi?: (params: any) => Promise<any> // 下载模板的Api
  importApi?: (params: any) => Promise<any> // 批量导入的Api
  getTableList?: () => void // 获取表格数据的Api
}

// 是否覆盖数据
const isCover = ref(false)
// dialog状态
const dialogVisible = ref(false)
// 父组件传过来的参数
const parameter = ref<ExcelParameterProps>({
  title: '',
  limit: 1,
  width: 500,
  top: '20vh',
  multiple: false,
  fileSize: 5,
  fileType: ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
})

// 接收父组件参数
const acceptParams = (params: ExcelParameterProps) => {
  parameter.value = { ...parameter.value, ...params }
  dialogVisible.value = true
}

// Excel 导入模板下载
const downloadTemp = () => {
  if (!parameter.value.tempApi) return
  useDownload(parameter.value.tempApi, `${parameter.value.title}_template_${new Date().getTime()}`)
}
const uploadRef = ref<UploadInstance>()
const handleSubmit = () => {
  uploadRef.value!.submit()
}

// 文件上传
const uploadExcel = async (param: UploadRequestOptions) => {
  let excelFormData = new FormData()
  excelFormData.append('file', param.file)
  excelFormData.append('updateSupport', isCover.value as unknown as Blob)
  await parameter.value.importApi!(excelFormData)
  parameter.value.getTableList && parameter.value.getTableList()
  dialogVisible.value = false
}

/**
 * @description 文件上传之前判断
 * @param file 上传的文件
 * */
const beforeExcelUpload = (file: UploadRawFile) => {
  const isExcel = parameter.value.fileType!.includes(file.type as File.ExcelMimeType)
  const fileSize = file.size / 1024 / 1024 < parameter.value.fileSize!
  if (!isExcel)
    ElNotification({
      title: '温馨提示',
      message: '上传文件只能是 xls / xlsx 格式！',
      type: 'warning'
    })
  if (!fileSize)
    setTimeout(() => {
      ElNotification({
        title: '温馨提示',
        message: `上传文件大小不能超过 ${parameter.value.fileSize}MB！`,
        type: 'warning'
      })
    }, 0)
  return isExcel && fileSize
}

// 文件数超出提示
const handleExceed = () => {
  ElNotification({
    title: '温馨提示',
    message: '最多只能上传一个文件！',
    type: 'warning'
  })
}

// 上传错误提示
const excelUploadError = () => {
  ElNotification({
    title: '温馨提示',
    message: `批量添加${parameter.value.title}失败，请您重新上传！`,
    type: 'error'
  })
}

// 上传成功提示
const excelUploadSuccess = () => {
  ElNotification({
    title: '温馨提示',
    message: `批量添加${parameter.value.title}成功！`,
    type: 'success'
  })
}

defineExpose({
  acceptParams
})
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>
