<template>
  <section class="ai-import">
    <a v-if="$slots.default" class="custom-clicker" @click="dialog = true">
      <slot/>
    </a>
    <el-button v-else size="small" @click="dialog=true" icon="iconfont iconImport">导入</el-button>
    <ai-dialog
      :title="dialogTitle"
      :visible.sync="dialog"
      :destroy-on-close="true"
      width="800px"
      customFooter
      :close-on-click-modal="false"
      @closed="onClose">
      <el-form size="small" ref="importForm" label-width="0" class="import-form" :model="fileForm"
               :rules="fileRules">
        <el-form-item class="ai-import__tips">
          <h2>导入说明：</h2>
          <p class="ai-import__content">
            1、您正在进行【{{ name }}】批量导入操作，请先
            <span @click="downloadFile" title="下载导入模板" class="ai-link" v-text="'【点击下载导入模板】'"/>
            并规范填写；</p>
          <p class="ai-import__content">2、填写完成后，上传您编辑完成的模板文件：</p>
          <div class="ai-import__text">
            <template v-if="$slots.tips">
              <div>请注意：</div>
              <slot name="tips"/>
            </template>
            <el-row type="flex" v-else-if="!!dict">
              <div v-text="'请注意：'"/>
              <span v-text="dict.getLabel('importTips',type)"/>
            </el-row>
          </div>
        </el-form-item>
        <el-form-item prop="file" style="width: 100%">
          <ai-uploader isImport :instance="instance" v-model="fileForm.file" fileType="file" :limit="1"
                       acceptType=".xls,.xlsx" @change="onChange" :clearable="false">
            <template #trigger>
              <el-button icon="iconfont iconfangda">选择文件</el-button>
            </template>
            <template #tips>最多上传1个文件,单个文件最大10MB，仅支持Excel格式</template>
          </ai-uploader>
        </el-form-item>
      </el-form>
      <div slot="footer" style="text-align: center;">
        <el-button @click="dialog=false">取消</el-button>
        <el-button type="primary" @click="onClick">立即导入</el-button>
      </div>
    </ai-dialog>
    <div class="ai-import__loading" v-if="isHasLoadingSlot && isLoading">
      <slot name="loading"/>
    </div>
  </section>
</template>

<script>
export default {
  name: 'AiImport',
  props: {
    title: String,
    name: {
      type: String,
      required: true
    },
    instance: {
      type: Function
    },
    importUrl: {
      type: String,
    },
    importParams: {
      type: Object
    },
    suffixName: {
      type: String,
      default: 'xls'
    },
    tplParams: Object,
    url: {
      type: String,
    },
    timeout: {
      type: Number,
      default: 10 * 60 * 1000
    },
    customError: {
      type: Boolean,
      default: false
    },
    type: String,
    dict: Object
  },
  computed: {
    isHasLoadingSlot() {
      return this.$slots.loading
    },
    actions() {
      return {
        url: this.importUrl || `/app/${this.type}/import`,//导入接口
        tpl: this.url || `/app/${this.type}/downloadTemplate`,//下载模板接口
      }
    },
    dialogTitle() {
      return this.title || `${this.name}数据导入`
    }
  },
  data() {
    return {
      dialog: false,
      fileForm: {
        file: []
      },
      loading: null,
      isLoading: false,
      fileRules: {
        file: [{required: true, message: '请上传相关文件', trigger: 'change'}]
      }
    }
  },
  methods: {
    onChange(e) {
      if (e.length) {
        this.$refs.importForm.clearValidate()
      } else {
        this.$refs.importForm.validate()
      }
    },
    onClick() {
      this.$refs.importForm.validate(v => {
        if (v) {
          const data = new FormData()
          data.append('file', this.fileForm.file[0].raw)
          if (!this.isHasLoadingSlot) {
            this.loading = this.$loading({
              lock: true,
              text: '导入中',
              background: 'rgba(0, 0, 0, 0.5)'
            })
          } else {
            this.isLoading = true
          }
          this.instance.post(this.actions.url, data, {
            params: this.importParams,
            timeout: this.timeout
          }).then(res => {
            if (!this.isHasLoadingSlot) {
              this.loading?.close()
            } else {
              this.isLoading = false
            }
            if (res?.data?.importStatus == 1) {
              this.dialog = false
              const h = this.$createElement
              this.$emit('onSuccess', res)
              this.$emit('success', res)
              if (this.customError) {
                this.$emit('error')
              } else this.$confirm('导入失败数据具体原因请', {
                type: 'success',
                title: '数据导入完成',
                closeOnClickModal: false,
                customClass: 'message-wrapper',
                showConfirmButton: false,
                cancelButtonText: '关闭',
                message: h('div', {
                  class: 'importResult'
                }, [
                  h('span', null, '成功新增'),
                  h('a', {
                    style: 'color: #2EA222;'
                  }, `${res.data.addCount}`),
                  h('span', null, '条数据，更新'),
                  h('a', {
                    style: 'color: #26f;'
                  }, `${res.data.updateCount}`),
                  h('span', null, '条数据，导入失败'),
                  h('a', {
                    style: 'color: #f46;'
                  }, `${res.data.failCount}`),
                  h('span', null, '条数据。'),
                  h('div', {class: 'gap'}),
                  h('div', {style: `display:${res.data.errorFileURL ? 'block' : 'none'}`}, [
                    h('span', null, '点此'),
                    h('a', {
                      class: 'tips-link',
                      attrs: {
                        href: res.data.errorFileURL
                      }
                    }, '下载异常数据')
                  ])
                ])
              })
            } else if (res?.data?.importStatus == 0) {
              this.$message.error(res?.data?.errorMsg)
            }
          }).catch(() => {
            if (!this.isHasLoadingSlot) {
              this.loading?.close()
            } else {
              this.isLoading = false
            }
          })
        }
      })
    },
    onClose() {
      this.loading?.close()
      this.fileForm.file = []
    },
    downloadFile() {
      this.instance.post(this.actions.tpl, null, {
        responseType: 'blob',
        params: this.tplParams
      }).then((res) => {
        const link = document.createElement('a')
        let blob = new Blob([res], {type: 'application/vnd.ms-excel'})
        link.style.display = 'none'
        link.href = URL.createObjectURL(blob)
        link.setAttribute('download', this.name + '模板.' + this.suffixName)
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
      })
    },
    hide() {
      this.dialog = false
    }
  },
  created() {
    this.dict?.load("importTips")
  }
}
</script>
<style lang="scss" scoped>
.ai-import {
  .empty-input {
    opacity: 0;
    position: absolute;
    z-index: -1;
    visibility: hidden;
  }


  .custom-clicker {
    display: flex;
    align-items: center;
  }

  .ai-import__loading {
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.6);
  }

  :deep( .el-message-box ){
    width: 720px !important;
  }

  .ai-import__content {
    line-height: 22px;
  }

  .ai-import__tips {
    line-height: 1;

    :deep(.el-form-item__content ){
      line-height: 1;
    }

    h2 {
      margin-top: 4px;
      color: #333333;
      font-size: 16px;
      font-weight: 700;
    }

    p {
      margin-top: 8px;
      color: #424242;
      font-size: 14px;
    }

    .ai-link {
      cursor: pointer;
      color: $primaryColor;
    }

    .ai-import__text {
      font-size: 12px;
      margin-top: 8px;
      line-height: 16px;
      color: #999999;
    }
  }
}
</style>
<style lang="scss">
.message-wrapper {
  width: 560px !important;

  .importResult {
    color: #222222;
    font-size: 16px;
    line-height: 24px;
    font-weight: bold;

    .gap {
      width: 100%;
      height: 8px;
    }

    .tips-link {
      color: $primaryColor;
      text-decoration: unset;
    }
  }
}
</style>
