<!-- 上传excel -->
<template>
  <span>
    <el-button :size="size" @click="openDialog()" v-if="!hiddenButton">{{ currentButtonName }}</el-button>

    <cs-sideslip ref="CsSideslip" :title="currentButtonName" :before-close="cancel" wrapperClosable size="small">
      <div
        style="padding: 10px"
        v-loading="loading"
        element-loading-text="拼命加载中"
        element-loading-spinner="el-icon-loading"
      >
        <el-steps :active="active" finish-status="success">
          <el-step title="下载与上传"></el-step>
          <el-step title="验证数据"></el-step>
          <el-step title="导入数据"></el-step>
        </el-steps>

        <div style="text-align: center; padding: 10px 0; line-height: 4">
          <!-- 下载与上传 -->
          <span v-if="active == 0">
            <div>1、下载Excel模板，请填入对应的信息。</div>
            <div>
              <el-button type="primary" size="mini" @click="downloadTemplate">下载模板</el-button>
            </div>

            <div>
              <span class="color-danger">*&nbsp;&nbsp;</span>
              <span>2、选择填好的Excel文件</span>
            </div>
            <div>
              <div class="upload_excel_div" @click="uploadExcel">
                <i class="el-icon-files" style="font-size: 26px"></i>
                <div style="font-size: 20px">{{ fileName }}</div>
              </div>
            </div>

            <div>
              <span class="color-danger">*&nbsp;&nbsp;</span>
              <span>3、选择工作表</span>
            </div>
            <div>
              <el-select v-model="selectSheetName" placeholder="请选择工作表">
                <el-option
                  v-for="sheetName in sheetNames"
                  :label="sheetName"
                  :key="sheetName"
                  :value="sheetName"
                ></el-option>
              </el-select>
            </div>

            <div>注意：导入Excel最大可导入{{ maxCount }}条，如果数据较大，建议分批次导入。</div>
          </span>

          <!-- 导入预览 -->
          <span v-if="active == 1">
            <div v-if="errMsg">
              <div style="line-height: 30px; margin-top: 100px">
                <div style="font-size: 20px">{{ errMsg }}</div>
              </div>
            </div>

            <!-- 表格 -->
            <div v-else-if="!errMsg">
              <el-table
                v-if="tableData.length > 0"
                :data="tableData"
                stripe
                max-height="400"
                style="width: 100%"
                id="analysis_table"
              >
                <el-table-column
                  prop="行号"
                  label="行号"
                  key="行号"
                  width="60"
                  fixed="left"
                  show-overflow-tooltip
                ></el-table-column>
                <el-table-column
                  prop="验证结果"
                  label="验证结果"
                  key="验证结果"
                  width="200"
                  fixed="left"
                  show-overflow-tooltip
                >
                  <template slot-scope="scope">
                    <span v-if="scope.row['验证结果']" class="color-warning">
                      <i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
                      {{ scope.row['验证结果'] }}
                    </span>
                    <span v-else class="color-success">
                      <i class="fa fa-check" aria-hidden="true"></i>
                    </span>
                  </template>
                </el-table-column>
                <el-table-column
                  v-for="(item, key) in tableData[0]"
                  :key="key"
                  v-if="key != '行号' && key != '验证结果'"
                  :prop="key"
                  :label="key"
                  :render-header="labelHead"
                  show-overflow-tooltip
                ></el-table-column>
              </el-table>

              <div v-if="isError && tableData.length == 0">没有错误信息！</div>

              <div v-if="errorInfo.Count > 0">
                <el-checkbox v-model="isError">只看错误项</el-checkbox>
                <span style="margin-left: 5px">
                  预计导入{{ items.length }}条数据，成功{{ items.length - invalidCount }}条，失败{{ invalidCount }}条
                </span>

                <el-button
                  type="primary"
                  size="mini"
                  style="margin-left: 10px"
                  :disabled="tableData.length == 0"
                  @click="exportExcel('#analysis_table')"
                  >导出</el-button
                >
              </div>
              <div v-else>没有数据，请确认后在进行导入</div>
            </div>
          </span>

          <!-- 导入数据（导入确认） -->
          <span v-if="active == 2">
            <div style="line-height: 30px; margin-top: 100px" v-if="!invalidCount">
              <i class="el-icon-circle-check" style="font-size: 40px; color: #36d57d"></i>
              <div style="font-size: 20px">导入成功{{ tableData.length }}条数据</div>
            </div>

            <div v-else-if="invalidCount">
              <el-table
                v-if="tableData.length > 0"
                :data="tableData"
                stripe
                max-height="400"
                style="width: 100%"
                id="import_table"
              >
                <el-table-column
                  prop="行号"
                  label="行号"
                  key="行号"
                  width="60"
                  fixed="left"
                  show-overflow-tooltip
                ></el-table-column>
                <el-table-column
                  prop="验证结果"
                  label="验证结果"
                  key="验证结果"
                  width="200"
                  fixed="left"
                  show-overflow-tooltip
                >
                  <template slot-scope="scope">
                    <span v-if="scope.row['验证结果']" class="color-warning">
                      <i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
                      {{ scope.row['验证结果'] }}
                    </span>
                    <span v-else class="color-success">
                      <i class="fa fa-check" aria-hidden="true"></i>
                    </span>
                  </template>
                </el-table-column>
                <el-table-column
                  v-for="(item, key) in tableData[0]"
                  :key="key"
                  v-if="key != '行号' && key != '验证结果'"
                  :prop="key"
                  :label="key"
                  :render-header="labelHead"
                  show-overflow-tooltip
                ></el-table-column>
              </el-table>

              <div v-if="isError && tableData.length == 0">没有错误信息！</div>

              <div>
                <el-checkbox v-model="isError">只看错误项</el-checkbox>
                <span style="margin-left: 5px">导入失败{{ invalidCount }}条，请重新检查</span>
              </div>
              <el-button
                type="primary"
                size="mini"
                style="float: right"
                :disabled="tableData.length == 0"
                @click="exportExcel('#import_table')"
              >
                导出
              </el-button>
            </div>
          </span>
        </div>
      </div>

      <template slot="button">
        <span style="margin-left: 5px">
          <el-button type="primary" size="mini" @click="analysisExcel" :disabled="!selectSheetName" v-if="active == 0">
            下一步
          </el-button>

          <el-button size="mini" @click="active = 0" v-if="active == 1">上一步</el-button>
          <el-button
            type="primary"
            size="mini"
            @click="confirmImport"
            :disabled="errMsg.length > 0 || invalidCount > 0"
            v-if="errorInfo.Count > 0 && active == 1"
            :loading="loading"
          >
            确认导入
          </el-button>

          <el-button type="primary" size="mini" @click="active = 0" :loading="loading" v-if="active == 2">
            重新导入
          </el-button>
        </span>
      </template>
    </cs-sideslip>
  </span>
</template>
<script>
// 引入导出Excel表格依赖
import XLSX from 'xlsx'

import Request from '../../../../lib/utils/request'
import analysis from './components/analysis'

export default {
  name: 'CsButtonImportExcel',
  components: {},
  props: {
    tenantId: {
      type: Number,
      default: null
    },
    buttonName: {
      type: String,
      default: null
    },
    type: {
      type: String,
      default: null
    },
    size: {
      type: String,
      default: 'mini'
    },
    query: {
      type: Object,
      default: null
    },
    hiddenButton: {
      type: Boolean,
      default: false
    },
    maxCount: {
      type: Number,
      default: 1000
    }
  },
  data() {
    return {
      active: 0,
      loading: false,

      templateUrl: '',
      fileName: '',
      sheetNames: [],
      selectSheetName: '',

      invalidCount: 0,
      errMsg: '',
      errorInfo: [],
      isError: false,

      items: [],
      tableData: []
    }
  },
  //监听属性 类似于data概念
  computed: {
    currentButtonName() {
      if (this.buttonName) {
        return this.buttonName
      } else {
        return this.$t('common.import')
      }
    }
  },
  //监控data中的数据变化
  watch: {
    isError(val) {
      this.initData()
    }
  },
  //方法集合
  methods: {
    /* 表头样式 */
    labelHead(h, { column, index }) {
      let l = column.label.length + 2
      let f = 20 //每个字大小，其实是每个字的比例值，大概会比字体大小差不多大一点，
      column.minWidth = f * l //字大小乘个数即长度 ,注意不要加px像素，这里minWidth只是一个比例值，不是真正的长度
      //然后将列标题放在一个div块中，注意块的宽度一定要100%，否则表格显示不完全
      return h('div', { class: 'table-head', style: { width: '100%' } }, [column.label])
    },

    openDialog() {
      this.$refs.CsSideslip.visible = true
    },

    /**取消*/
    cancel() {
      this.$refs.CsSideslip.visible = false
      this.active = 0

      this.templateUrl = ''
      this.fileName = ''
      this.sheetNames = []
      this.selectSheetName = ''

      this.invalidCount = 0
      this.errMsg = ''
      this.errorInfo = []
      this.isError = false

      this.items = []
      this.tableData = []
    },

    /* 下载模板 */
    downloadTemplate() {
      const url = '/api/DownloadTemplate/{0}/Excel?type={1}&ver={2}'.format(
        this.tenantId,
        this.type,
        this.$moment().format('YYYYMMDD_HH_mm_ss')
      )
      const link = document.createElement('a')
      link.href = url
      link.target = '_Blank'
      link.click()
    },

    /* 上传Excel */
    uploadExcel() {
      analysis.uploadExcel(result => {
        let sheetNames = []
        for (let i = 0; i < result.sheetNames.length; i++) {
          const name = result.sheetNames[i]

          if (name.indexOf('文件说明') > -1) {
            continue
          }
          if (name.indexOf('配置信息') > -1) {
            continue
          }
          sheetNames.push(name)
        }

        if (sheetNames.length == 0) {
          this.$util.warning('Excel没有有效工作表')
          return
        }
        this.fileName = result.fileName
        this.sheetNames = sheetNames
        this.selectSheetName = sheetNames[0]
      })
    },

    /* 解析Excel */
    analysisExcel() {
      if (!this.selectSheetName) {
        this.$util.warning('请选择工作表')
        return
      }
      this.invalidCount = 0
      this.errMsg = ''

      this.loading = true
      analysis.analysisExcel(
        this.selectSheetName,
        this.maxCount,
        val => {
          console.log(val)
          this.items = val

          let params = {}
          if (this.query && typeof this.query == 'object') {
            params = Object.assign({ type: this.type }, this.query)
          } else {
            params = { type: this.type }
          }

          Request({
            url: '/api/ImportExcel/{0}/Analysis'.format(this.tenantId),
            params: params,
            data: JSON.stringify(val),
            method: 'put'
          })
            .then(res => {
              this.loading = false
              this.errorInfo = res
              this.initData()
              this.active = 1
            })
            .catch(res => {
              this.loading = false
            })
        },
        res => {
          this.loading = false
        }
      )
    },

    /* 确认导入 */
    confirmImport() {
      let params = {}
      if (this.query && typeof this.query == 'object') {
        params = Object.assign({ type: this.type }, this.query)
      } else {
        params = { type: this.type }
      }

      this.loading = true
      Request({
        url: '/api/ImportExcel/{0}/Import'.format(this.tenantId),
        params: params,
        data: JSON.stringify(this.items),
        method: 'post'
      })
        .then(res => {
          this.loading = false
          if (res.IsValid) {
            this.$emit('change', true)
            this.$util.info('导入成功')
          } else {
            this.$util.warning('导入失败')
          }
          this.errorInfo = res
          this.initData()
          this.active = 2
        })
        .catch(res => {
          this.loading = false
        })
    },

    /* 定义导出Excel表格事件 */
    exportExcel(id) {
      let table = document.querySelector(id).cloneNode(true)
      // 因为element-ui的表格的fixed属性导致多出一个table，会下载重复内容，这里删除掉
      table.removeChild(table.querySelector('.el-table__fixed'))
      let wb = XLSX.utils.table_to_book(table, { raw: true }) //mytable为表格的id名
      /* get binary string as output */
      let wbout = XLSX.write(wb, {
        bookType: 'xlsx',
        bookSST: true,
        type: 'array'
      })
      saveAs(new Blob([wbout], { type: 'application/octet-stream' }), '导出.xlsx')
      return wbout
    },

    /* 筛选 */
    filterItemFunc(item) {
      // 只看错误信息
      if (this.isError) {
        if (!item['验证结果']) {
          return false
        }
      }
      return true
    },

    /* 构造数据 */
    initData() {
      this.tableData = []
      let tableData = []
      let result = this.$util.copy(this.errorInfo)
      const itmes = this.$util.copy(this.items)
      for (let i = 0; i < itmes.length; i++) {
        const item = itmes[i]

        // 有错误
        if (!result.IsValid) {
          // 没有错误信息说明是子项有错误
          if (!result.ErrMsg) {
            this.invalidCount = result.InvalidCount
            result.Items.forEach(errItem => {
              if (errItem.RowIndex == item['行号']) {
                item['验证结果'] = errItem.ErrMsg
              }
            })
          }
          // 否则主体有错误
          else {
            this.errMsg = result.ErrMsg
          }
        }

        //如果筛选不通过跳过
        if (!this.filterItemFunc(item)) {
          continue
        }
        tableData.push(item)
      }
      this.tableData = tableData
    },

    init() {
      if (!this.type) {
        this.$util.warning('请输入导入类型')
        return
      }
    }
  },
  //生命周期 - 创建完成（可以访问当前this实例）
  created() {
    this.init()
  },
  //生命周期 - 挂载完成（可以访问DOM元素）
  mounted() {},
  beforeCreate() {}, //生命周期 - 创建之前
  beforeMount() {}, //生命周期 - 挂载之前
  beforeUpdate() {}, //生命周期 - 更新之前
  updated() {}, //生命周期 - 更新之后
  beforeDestroy() {}, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
  activated() {} //如果页面有keep-alive缓存功能，这个函数会触发
}
</script>
<style lang="scss" scoped>
.upload_excel_div {
  border-radius: 4px;
  border: 1px solid #e6ebf5;
  background-color: #ffffff;
  overflow: hidden;
  color: #303133;
  padding: 15px;
  margin: 0 20%;
  cursor: pointer;
  line-height: 30px;
  min-height: 95px;
}
</style>

<style lang="scss">
.table-head {
  font-size: 14px !important; //设置固定的字体大小
}
</style>
