<template>
  <div class="batch-add-box">
    <h2>导入信息选择：</h2>
    <div class="header">
      <div class="header-body header-body-left">
        <div class="sel-item">
          <div class="sel-label">角色：</div>
          <el-select size="mini" v-model="baseForm.role" placeholder="请选择">
            <el-option
              v-for="item in baseData.role"
              placeholder="请选择用户角色！"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            >
            </el-option>
          </el-select>
        </div>
        <div class="sel-item">
          <div class="sel-label">组织机构：</div>
          <el-cascader
            v-model="baseForm.org"
            :options="baseData.org"
            placeholder="请选择组织机构！"
            size="mini"
            :props="{
              checkStrictly: true,
              expandTrigger: 'hover',
              label: 'name',
              value: 'id',
            }"
          ></el-cascader>
        </div>
        <div class="sel-item">
          <div class="sel-label">所属老师：</div>
          <el-select
            v-model="baseForm.manageTeacher"
            size="mini"
            multiple
            filterable
            reserve-keyword
            placeholder="请选择管辖老师，可为空！"
          >
            <el-option
              v-for="v in baseData.teacher"
              :key="v.id"
              :label="v.name"
              :value="v.id"
            />
          </el-select>
        </div>
        <div class="sel-item">
          <el-button
            round
            type="text"
            @click="downloadModelFile"
            style="padding: 0"
            >下载模板</el-button
          >
          <div
            class="gy-label middle"
            style="
              height: 32px;
              white-space: nowrap;
              color: #ed0000;
              line-height: 32px;
            "
          >
            （下载模板后按要求录入内容）
          </div>
        </div>
      </div>
      <div class="header-body header-body-right">
        <el-button
          type="primary"
          @click="toLoadUserExcel"
          v-if="!successImportList.length && !isLoadAfter"
          >导入</el-button
        >
        <el-button
          type="primary"
          @click="uploadUserList"
          v-if="successImportList.length && !isLoadAfter"
          >{{ errImportList.length ? "过滤错误并上传" : "上传" }} ({{
            successImportList.length
          }})</el-button
        >
        <el-button type="danger" @click="clear">清理</el-button>
      </div>
    </div>
    <div class="content">
      <div v-if="errImportList.length === 0">
        <el-empty description="请先导入用户"
          ><template slot="description">
            {{
              (successImportList.length &&
                errImportList.length <= 0 &&
                "暂无错误用户") ||
              "请先导入用户信息"
            }}
          </template></el-empty
        >
      </div>
      <ul class="error-info-list" v-else>
        <li class="error-item header">
          <div class="column">用户名</div>
          <div class="column">行号</div>
          <div class="column">姓名</div>
          <div class="column">错误信息</div>
        </li>
        <div style="overflow-y: auto; max-height: 50vh">
          <li
            v-for="(item, ind) in errImportList"
            :key="ind"
            class="error-item"
          >
            <div class="column">{{ item.username || "未填写" }}</div>
            <div class="column">{{ item.ind }}</div>
            <div class="column">{{ item.name || "【 未填写 】" }}</div>
            <ul class="column">
              {{
                item.errMsg
              }}
              <!-- <li v-for="(err, ind) in item.error" :key="ind">
                {{ err }}
              </li> -->
            </ul>
          </li>
        </div>
      </ul>
    </div>
  </div>
</template>

<script>
import * as XLSX from 'xlsx'
import { getDistFile } from '@/utils'
import { findAllOrgApi } from '@/api/system/org'
import { findAllRoleApi } from '@/api/system/role'
import {
  createUserApi,
  deleteUsersApi,
  findAllUserApi,
  findAllTeacherApi,
  updateUserApi,
  batchCreateUserApi,
  resetPasswordApi
} from '@/api/system/user'
export default {
  data () {
    return {
      baseForm: {
        org: null,
        role: null,
        manageTeacher: null
      },
      baseData: {
        org: null,
        role: null,
        teacher: null
      },
      importUserList: [],
      errImportList: [],
      successImportList: [],
      isLoadAfter: false
    }
  },
  activated () {
    this.findAllRole()
    this.findAllOrg()
    this.findAllTeacher()
  },
  methods: {
    /**
     * 生成excel模板数据-并自动下载
     */
    downloadModelFile () {
      const dataSheets = [
        {
          sheetName: '添加用户',
          data: [
            [
              '用户名(登录ID)',
              '姓名',
              '性别',
              '出生年月',
              '身份证号',
              '职位',
              '电话',
              '邮箱'
            ],
            [
              'wcc123',
              '王促成-示例（上传前请删除）',
              '男',
              '1998.9.10',
              '610100199809012043',
              '学员',
              '17688786352',
              '17688786352@163.com'
            ]
          ]
        }
      ]
      const sheets = []
      dataSheets.forEach((sheetItem) => {
        const colWidths = []
        const data = sheetItem.data
        data.forEach((row, index) => {
          // 遍历列
          row.forEach((col, ind) => {
            if (colWidths[ind] == null) colWidths[ind] = []
            colWidths[ind].push(this.getCellWidth(col))
          })
        })
        const ws = XLSX.utils.aoa_to_sheet(data)
        ws['!cols'] = []
        colWidths.forEach((widths, index) => {
          ws['!cols'].push({ wch: Math.max(...widths) })
        })
        sheets.push({
          name: sheetItem.sheetName,
          ws
        })
      })

      // const ws = XLSX.utils.json_to_sheet(data)

      const wb = XLSX.utils.book_new()
      sheets.forEach((wsItem) => {
        XLSX.utils.book_append_sheet(wb, wsItem.ws, wsItem.name)
      })
      XLSX.writeFile(
        wb,
        `用户导入模板${new Date().format('yyyy-MM-dd hh-mm-ss')}.xlsx`
      )
    },
    /**
     * 获取文字长度-自适应excel列宽度
     */
    getCellWidth (value) {
      // 判断是否为null或undefined
      if (value == null) {
        return 10
      } else if (/.*[\u4e00-\u9fa5]+.*$/.test(value)) {
        // 中文的长度
        const chineseLength = value.match(/[\u4e00-\u9fa5]/g).length
        // 其他不是中文的长度
        const otherLength = value.length - chineseLength
        return chineseLength * 2.1 + otherLength * 1.1
      } else {
        return value.toString().length * 1.1
        /* 另一种方案
        value = value.toString()
        return value.replace(/[\u0391-\uFFE5]/g, 'aa').length
        */
      }
    },
    /**
     * 获取角色
     */
    async findAllRole () {
      const { data } = await findAllRoleApi()
      const { tree } = data.toTree()
      this.baseData.role = tree
    },
    /**
     * 获取组织机构
     */
    async findAllOrg () {
      const { data } = await findAllOrgApi()
      const { tree } = data.toTree()
      this.baseData.org = tree
    },
    /**
     * 查询所有老师
     */
    async findAllTeacher () {
      const { data } = await findAllTeacherApi()
      this.baseData.teacher = data
    },
    /**
     * 加载excel
     */
    async toLoadUserExcel () {
      if (
        !this.baseForm.org ||
        this.baseForm.org.length < 1 ||
        !this.baseForm.role
      ) {
        this.$message.error('请先选择用户角色、组织机构、所属老师信息后再选择')
        return
      }
      const [file] = await getDistFile({ accepts: ['xlsx'] })
      if (!/^.+\.xlsx$/.test(file.name)) {
        this.$message.error(new Error('不是Excel表格文件'))
      }
      const reader = new FileReader()
      reader.onload = (event) => {
        const data = event.target.result
        const workbook = XLSX.read(data, {
          type: 'binary'
        })
        const sheetData = XLSX.utils.sheet_to_json(
          workbook.Sheets[workbook.SheetNames[0]]
        )
        const awaitResultRes = sheetData
        const checkRes = {}
        const errorRes = []
        const successRes = []
        const resultRes = []
        awaitResultRes.forEach((item) => {
          resultRes.push({
            username: item['用户名(登录ID)'],
            name: item['姓名'],
            sex: item['性别'],
            birthday: item['出生年月'],
            idcard: item['身份证号'],
            identity: item['职位'],
            phone: item['电话'],
            email: item['邮箱']
          })
        })
        resultRes.forEach((item, i) => {
          // let newData = {'username':"",
          //           'name',
          //           'sex',
          //           'birthday',
          //           'idcard',
          //           'identity',
          //           'phone',
          //           'email'}

          item.ind = i + 2
          if (!item.name || !item.sex || !item.username) {
            item.errMsg = ['缺少用户信息必填项！']
            errorRes.push(item)
          }
          if (item.username && checkRes[item.username]) {
            if (item.errMsg) {
              item.errMsg.push('用户ID重复')
            } else {
              item.errMsg = ['用户ID重复']
            }
          } else {
            checkRes[item.username] = item
          }
          if (!item.errMsg) {
            item.sex === '男' ? (item.sex = 1) : (item.sex = 0)
            item.roleId = this.baseForm.role
            item.orgId = this.baseForm.org[0]
            item.orgIds = this.baseForm.org.join(',')
            item.manageTeacher = this.baseForm.manageTeacher
            item.birthday && (item.birthday = new Date(item.birthday))
            successRes.push(item)
          }
        })
        this.errImportList = errorRes
        this.importUserList = resultRes
        this.successImportList = successRes
        if (!errorRes.length) {
          this.uploadUserList()
        }
      }
      reader.readAsBinaryString(file)
    },
    async uploadUserList () {
      if (
        !this.baseForm.org ||
        this.baseForm.org.length < 1 ||
        !this.baseForm.role
      ) {
        this.$message.error('请先选择用户角色、组织机构、所属老师信息后再提交')
      }
      const err = this.errImportList.length
      const suc = this.successImportList.length
      const message = [
        `文件中共包含 ${err + suc} 位用户,`,
        err ? `，其中 ${err} 位填写不符合规范,` : '',
        `本次将导入 ${suc} 位用户，确认导入吗？`
      ]
      this.$confirm(message.join(''), '提示', { type: 'warn' })
        .then(async (_) => {
          const { data } = await batchCreateUserApi(this.successImportList)

          this.$message.warning(
            `本次成功上传${data.sucList.length}个用户,失败${data.errList.length}个！`
          )
          this.errImportList = data.errList.map((item) => ({
            ...item,
            errMsg: item.errMsg
          }))
          this.isLoadAfter = true
          // this.$router.push('/login')
        })
        .catch((_) => {
          console.log(_)
          // this.register_form = { roleId: 3, photoResource: '', sex: 1 }
        })
    },
    clear () {
      this.errImportList = []
      this.importUserList = []
      this.successImportList = []
      this.isLoadAfter = false
      this.baseForm = {
        org: null,
        role: null,
        manageTeacher: null
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.batch-add-box {
  .header {
    height: 40px;
    border-bottom: 1px solid rgba(204, 204, 204, 0.315);
    height: fit-content;
    display: flex;
    justify-content: space-between;
  }
  .header-body {
    display: flex;
    padding: 10px 0;
    .sel-item {
      padding-right: 15px;
      display: flex;
      align-items: center;
    }
    .sel-label {
      font-size: 14px;
      font-weight: bold;
    }
  }
}
.error-info-list {
  margin-top: 10px;
  display: flex;
  border: 2px solid $--color-primary;
  border-radius: 4px;

  &,
  ul {
    padding: 0;
    list-style: none;
    flex-direction: column;
  }

  .error-item {
    display: flex;
    border-top: 1px solid #eee;

    &.header {
      color: #fff;
      border-top: none;
      background: $--color-primary;

      .column {
        border: none;
      }
    }

    .column {
      padding: 5px;
      border-right: 1px solid #eee;
      flex-grow: 1;
      flex-basis: 0;
      line-height: normal;
      display: flex;
      align-items: center;
      justify-content: center;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;

      &:nth-child(1),
      &:nth-child(2) {
        width: 60px;
        flex-basis: 60px;
        flex-grow: 0;
      }

      // &:nth-child(4)
      // {
      //   width: 100px;
      //   flex-basis: 100px;
      //   flex-grow: 0;
      // }
      &:last-child {
        border-right: none;
      }
    }
  }
}
</style>
