<template>
  <div class="attendanceCenterDep">
    <h1>考勤统计表</h1>
    <div class="depSearch">
      <div class="depSearchFlex">
        <div class="searBox">
          <span class="span">月份：</span>
          <el-date-picker v-model="fromParams.month" type="month" placeholder="请选择月份" />
        </div>
        <div class="searBox" v-if="porps.deptsName == '公司'">
          <span class="span">部门：</span>
          <DeptTree
            v-model="fromParams['deptId']"
            placeholder="请选择部门"
            :disabled="porps.deptsName !== '公司'"
            check-strictly
          />
        </div>
        <div class="searBox">
          <span class="span">人员：</span>
          <el-input v-model="fromParams.userName" placeholder="请输入人员名称" />
        </div>
        <div class="searBtns">
          <el-button @click="querysClick" type="primary" style="background: #3485ff">
            <img src="@/assets/imgs/OA/search.png" class="mr-8px" alt="" />
            查询</el-button
          >
          <ExportToExcel
            v-if="porps.deptsName == '公司'"
            :data="excelDataSource"
            :file-name="`${moment(fromParams.month).format('YYYY年MM月')}考勤统计.xlsx`"
            :colsWidth="colsWidth"
            :title="`${moment(fromParams.month).format('YYYY年MM月')}-考勤数据表`"
          />
          <el-button
            v-if="porps.deptsName == '公司'"
            type="warning"
            plain
            @click="handleImport"
            v-hasPermi="['adm:attendance-sheet:import']"
          >
            <Icon icon="ep:upload" /> 导入
          </el-button>
          <!-- <el-button v-if="porps.deptsName == '公司'" plain @click="dialogVisible = true">
            免考勤人员设置
          </el-button> -->
          <el-button type="success" style="background-color: #05ce9e" v-if="false">
            <img src="@/assets/imgs/OA/kq/kqqrIcon.png" class="mr-8px" alt="" />
            考勤确认</el-button
          >
        </div>
      </div>

      <!-- 免考勤人员设置 -->
      <el-dialog v-model="dialogVisible" title="免考勤人员设置" width="500" align-center>
        <UserOrgTree v-model="notAttendanceList" :multiple="true" placeholder="请选择免考勤人员" />
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="dialogVisible = false">关闭</el-button>
            <el-button type="primary" @click="noAttendanceSet"> 确定 </el-button>
          </div>
        </template>
      </el-dialog>

      <el-popover :width="50">
        <template #reference>
          <div class="depStateBox">
            <p>?</p>
          </div>
        </template>
        <template #default>
          <div class="depStateContent">
            <ul class="">
              <li class="flex" v-for="(l, i) in depStateContentList" :key="i">
                <div v-if="i == 0" class="flex">
                  <img src="@/assets/imgs/OA/kq/gouzi.png" alt="" />：
                  <p>{{ l.name }}</p>
                </div>
                <div v-else class="flex">
                  <h4>{{ l.deps }}：</h4>
                  <p>{{ l.name }}</p>
                </div>
              </li>
            </ul>
          </div>
        </template>
      </el-popover>
    </div>
    <div class="depTable">
      <el-table
        v-loading="tableLoading"
        :data="
          tableData.slice(
            (pagesList.pageNo - 1) * pagesList.pageSize,
            pagesList.pageSize * pagesList.pageNo
          )
        "
        style="width: 100%; height: 100%"
        stripe
      >
        <!-- <el-table-column type="index" width="50" /> -->
        <el-table-column prop="deptName" label="部门" />
        <el-table-column prop="nickName" label="姓名" width="80" />
        <el-table-column
          v-for="(item, index) in tableHeadList"
          :key="index"
          :label="item.dayOfWeek"
          width="30"
          :label-class-name="item.isworkday == 1 ? '' : 'workday'"
        >
          <el-table-column
            :label-class-name="item.isworkday == 1 ? '' : 'workday'"
            :label="item.day"
            width="30"
          >
            <template #default="scope">
              <div class="iconsFlex" v-if="item.isworkday == 1">
                <div class="sw" @click="swStateClick(scope.row, item, 1)">
                  <div v-if="sco(scope.row, item, 1) == '1'">
                    <img src="@/assets/imgs/OA/kq/gouzi.png" alt="" />
                  </div>
                  <div v-else class="spans">
                    {{ attendanceTypeObj[sco(scope.row, item, 1)] ?? '' }}
                  </div>
                </div>
                <div class="xw" @click="swStateClick(scope.row, item, 2)">
                  <div v-if="sco(scope.row, item, 2) == '1'">
                    <img src="@/assets/imgs/OA/kq/gouzi.png" alt="" />
                  </div>
                  <div v-else class="spans">
                    {{ attendanceTypeObj[sco(scope.row, item, 2)] ?? '' }}
                  </div>
                </div>
              </div>
            </template>
          </el-table-column>
        </el-table-column>
        <el-table-column
          v-for="(item, index) in columList"
          :prop="item.prop"
          width="40"
          label-class-name="labelModeRl"
          :key="index"
        >
          <template #header>
            <span>{{ item.text }}</span>
            <span class="m-t-8px font-size-14px c-#989FA8">{{ item.unit }}</span>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="depPages">
      <el-pagination
        :current-page="pagesList.pageNo"
        :page-size="pagesList.pageSize"
        background
        layout="total, prev, pager, next, jumper"
        :total="pagesList.total"
        @current-change="handleCurrentChange"
      />
    </div>

    <DepsUpdataDetail ref="depsDetailRef" @updataInit="updataInit" />
  </div>
  <!-- 用户导入对话框 -->
  <AttendanceSheetImportForm ref="importFormRef" @success="init" />
</template>
<script setup lang="ts">
defineOptions({ name: 'AttendanceDep' })
import * as DeptApi from '@/api/system/dept'
import DepsUpdataDetail from './components/depsUpdataDetail.vue'
import { handleTree } from '@/utils/tree'
import * as MineApi from '@/api/oa/attendanceCenter'
import { arrFlatten, depSort, isArrayDelOrNickname, allDeptsArr, dayOfWeekCall } from './attendAuth'
import moment from 'moment'
import { depsState } from './depsState'
import ExportToExcel from '@/components/ExportToExcel/index.vue'
import { getUserInfo } from '@/utils/tool'
import AttendanceSheetImportForm from './components/attendanceSheetImportForm.vue'
import DeptTree from '@/views/OaSystem/components/DeptTree/index.vue'
import UserOrgTree from '@/views/OaSystem/components/UserOrgTree/index.vue'

const userInfo = getUserInfo()

const porps = defineProps(['deptsName'])

const pagesList: any = ref({
  pageNo: 1,
  pageSize: 12,
  total: 0
})
const fromParams: any = ref({
  deptId: userInfo.deptId ?? '',
  month: '',
  userName: ''
})

if (porps.deptsName == '公司') {
  fromParams.value.deptId = '4e99393c-c0ea-4146-a7fb-56fb8019c477'
}
const deptSort: any = ref([])
const deptList = ref<Tree[]>([]) // 树形结构
const tableData = ref([])
const initTreeDeps = async () => {
  DeptApi.getSimpleDeptList().then((res) => {
    deptList.value = handleTree(res)
    deptSort.value = arrFlatten(res, 'children')
  })
}
const depStateContentList = ref()
depStateContentList.value = depsState
const handleCurrentChange = async (page) => {
  pagesList.value.pageNo = page
  let toMoseMonths: any = []
  toMoseMonths[0] = moment().startOf('months').format('YYYY-MM-DD') + ' 00:00:00'
  toMoseMonths[1] = moment().endOf('months').format('YYYY-MM-DD') + ' 23:59:59'
  // initInsMouth(toMoseMonths)
}
const querysClick = async () => {
  // initInsMouth()
  pagesList.value.pageNo = 1
  let month = fromParams.value.month
  let toMoseMonths: any = []
  toMoseMonths[0] = moment(month).startOf('months').format('YYYY-MM-DD') + ' 00:00:00'
  toMoseMonths[1] = moment(month).endOf('months').format('YYYY-MM-DD') + ' 23:59:59'
  initInsMouth(toMoseMonths)
}

const tableLoading = ref(true)
const updataInit = (date) => {
  initInsMouth(date)
}

const initInsMouth = async (date: any) => {
  tableLoading.value = true
  let params = {
    attendanceDate: date, //	考勤时间
    attendanceStatus: '', //	考勤状态,示例值(2)
    attendanceType: '', //	考勤类型(1:上午;2:下午),示例值(1)
    otherMinute: '', //	其他考勤状态分钟(除了出勤)
    nickname: fromParams.value.userName, //用户昵称
    deptId: fromParams.value.deptId //部门ID
  }
  let urlApi = initWorkDay(date).then((restall) => {
    if (porps.deptsName == '公司') {
      MineApi.getWorkdaySheetList(params).then((res) => {
        let namesArr: any = isArrayDelOrNickname(JSON.parse(JSON.stringify(res)))
        let resArr: any = res
        resArr.forEach((item: any) => {
          if (item.attendanceTime) {
            item.date = moment(item.attendanceTime).format('YYYY-MM-DD')
          } else {
            item.date = moment(item.attendanceDate).format('YYYY-MM-DD')
          }
        })
        let arr = allDeptsArr(restall, resArr, namesArr)
        let sbArr = depSort(deptSort.value, arr)

        // 导出数据
        excelDataSource.value = getExcelTable(sbArr)

        tableData.value = sbArr
        pagesList.value.total = arr.length
        tableLoading.value = false
      })
    } else {
      MineApi.getWorkdaySheetDeptList(params).then((res) => {
        let namesArr: any = isArrayDelOrNickname(JSON.parse(JSON.stringify(res)))
        let resArr: any = res
        resArr.forEach((item: any) => {
          if (item.attendanceTime) {
            item.date = moment(item.attendanceTime).format('YYYY-MM-DD')
          } else {
            item.date = moment(item.attendanceDate).format('YYYY-MM-DD')
          }
        })
        let arr = allDeptsArr(restall, resArr, namesArr)
        let sbArr = depSort(deptSort.value, arr)

        // 导出数据
        excelDataSource.value = getExcelTable(sbArr)

        tableData.value = sbArr
        pagesList.value.total = arr.length
        tableLoading.value = false
      })
    }
  })
}
const sco = (row, item, index) => {
  let kq = ''
  if (index == 1) {
    row.attendArray.forEach((k) => {
      if (k.date == item.date) {
        kq = k.swAttendanceStatus ?? ''
      }
    })
  } else {
    row.attendArray.forEach((k) => {
      if (k.date == item.date) {
        kq = k.xwAttendanceStatus ?? ''
      }
    })
  }
  return kq
}
const tableHeadList: any = ref([])
const initWorkDay = async (date: any) => {
  let params = {
    dateDay: date, //		日期（数组）
    dayOfWeek: '', //			星期几
    holidayRemark: '', //			节假备注,示例值(国庆节)
    isworkday: '', //		是否工作日
    year: '', //		年份
    month: '', //		月份
    week: '' //		周
  }
  const res = await MineApi.getWorkdayList(params)
  let arr = res
  arr.forEach((item: any) => {
    item.date = moment(item.dateDay).format('YYYY-MM-DD')
    item.prop = item.dayOfWeek
    item.dayOfWeek = dayOfWeekCall(item.dayOfWeek)
    item.day = moment(item.dateDay).format('DD')
  })
  tableHeadList.value = arr
  return await arr
}
const depsDetailRef = ref()
const swStateClick = (row, item, index) => {
  //更改考勤
  if (porps.deptsName == '公司') {
    depsDetailRef.value.initShow(row, item, index, fromParams.value.month)
    return
  }
}
// 考勤对应的字典
const attendanceTypeObj = {
  '1': '', // 出勤
  '2': '迟', // '迟到'
  '3': '早', // '早退'
  '4': '旷', // '旷工'
  '5': '差', // '出差'
  '11': '事', // '事假'
  '12': '病', // '病假'
  '13': '婚', // '婚假'
  '14': '产', // '产假'
  '15': '陪', // '陪产假'
  '19': '丧', // '丧假'
  '16': '伤', // '工伤'
  '17': '年', // '年假'
  '18': '调', // '调休'
  '20': '假' // '其他'
}
// 考勤统计
const columList = [
  { text: '旷 工', prop: 'kg', unit: '天' },
  { text: '迟 到', prop: 'cd', unit: '次' },
  { text: '早 退', prop: 'zt', unit: '次' },
  { text: '出 差', prop: 'cc', unit: '天' },
  { text: '事 假', prop: 'sj', unit: '天' },
  { text: '调 休', prop: 'tx', unit: '天' },
  { text: '病 假', prop: 'bj', unit: '天' },
  { text: '年 假', prop: 'nj', unit: '天' },
  { text: '产 假', prop: 'cj', unit: '天' },
  { text: '其 他', prop: 'qt', unit: '天' }
]

// 考勤表格
const excelDataSource = ref<any>()
// 合并的单元格
// const mergeRanges = [
// { s: { r: 0, c: 0 }, e: { r: 1, c: 0 } }, // 合并第一行的前两列
// { s: { r: 0, c: 1 }, e: { r: 1, c: 1 } } // 合并第二行的前两列
// ]
// 列宽设置
const colsWidth = ref([{ wch: 30 }, { wch: 10 }, { wch: 8 }])
// 获取导出的数据表格
const getExcelTable = (attendanceData) => {
  const tableHead = [['部门', '姓名', '时间', ...tableHeadList.value.map((item) => item.day)]]
  // 日期单元格列宽设置
  colsWidth.value = [...colsWidth.value, ...tableHeadList.value.map(() => ({ wch: 3 }))]
  const tableBody: any = []
  for (let index = 0; index < attendanceData.length; index++) {
    const item = attendanceData[index]
    const data1 = item.attendArray.map((arr, i) => {
      // 判断是不是工作日
      const isworkday = tableHeadList.value[i].isworkday
      if (!isworkday) return ''
      // 判断有没有数据
      if (!arr.swAttendanceStatus) return ''
      return attendanceTypeObj[arr.swAttendanceStatus] ?? ''
    })
    const data2 = item.attendArray.map((arr, i) => {
      const isworkday = tableHeadList.value[i].isworkday
      if (!isworkday) return ''
      if (!arr.swAttendanceStatus) return ''
      return attendanceTypeObj[arr.xwAttendanceStatus] ?? ''
    })
    tableBody.push(
      [item.deptName, item.nickName, '上午', ...data1],
      [item.deptName, item.nickName, '下午', ...data2]
    )
  }

  return [...tableHead, ...tableBody]
}

/** 考勤导入 */
const importFormRef = ref()
const handleImport = () => {
  importFormRef.value.open()
}

/** 初始化 */
const init = () => {
  let toMonth = moment().format('YYYY-MM')
  fromParams.value.month = toMonth
  // 加载部门树
  initTreeDeps()
  let toMoseMonths: any = []
  toMoseMonths[0] = moment().startOf('months').format('YYYY-MM-DD') + ' 00:00:00'
  toMoseMonths[1] = moment().endOf('months').format('YYYY-MM-DD') + ' 23:59:59'
  initInsMouth(toMoseMonths)
}

onMounted(() => {
  init()
})

/** 免考勤人员设置 */
const dialogVisible = ref(false)
const notAttendanceList = ref([])
const noAttendanceSet = () => {
  dialogVisible.value = false
  // console.log('notAttendanceList', notAttendanceList.value)
}
</script>
<style lang="scss" scoped>
.attendanceCenterDep {
  position: relative;
  width: 100%;
  height: calc(100% - 15px);
  padding: 15px 30px;
  margin-top: 15px;
  background: #fff;
  border-radius: 10px;

  h1 {
    margin-bottom: 20px;
    font-size: 20px;
    font-weight: 600;
    color: #121518;
  }

  .depSearch {
    display: flex;
    width: 100%;
    margin-bottom: 20px;
    align-items: center;
    justify-content: space-between;

    .depSearchFlex {
      display: flex;
      align-items: center;

      .searBox {
        display: flex;
        align-items: center;
        margin-right: 25px;

        .span {
          font-size: 16px;
          white-space: nowrap;
        }
      }
    }

    .depStateBox {
      display: flex;
      width: 30px;
      height: 30px;
      cursor: pointer;
      border: 2px solid #e1e4ea;
      border-radius: 50%;
      align-items: center;
      justify-content: center;

      p {
        font-size: 16px;
        font-weight: 600;
        color: #e1e4ea;
      }
    }
  }

  .depTable {
    width: 100%;
    height: calc(100% - 140px);
  }

  .depPages {
    position: absolute;
    right: 30px;
    bottom: 10px;
  }
}

:deep(.depTable) {
  .el-table {
    .workDayClass {
      color: pink;
    }

    .is-group {
      height: 80px;

      tr {
        background-color: #e5f0fb;

        th {
          font-weight: 500;
          color: #233755;
          background-color: #e5f0fb;
          border-color: #fff;
        }
      }
    }

    .cell {
      width: 100%;
      height: 100%;
      padding: 0 !important;
      font-size: 16px !important;
      text-align: center;
    }

    .el-table__cell {
      // padding: 0;
    }

    .el-table__body-wrapper {
      tr {
        td {
          border: 0;
        }
      }

      .el-table__row--striped {
        td {
          background-color: #f7f7f7;
        }
      }
    }

    .iconsFlex {
      display: flex;
      width: 100%;
      height: 100%;
      align-items: center;
      flex-wrap: wrap;

      .spans {
        display: flex;
        width: 100%;
        height: 24px;
        padding: 0;
        margin: 0;
        font-size: 14px !important;
        font-weight: 800;
        color: #f23c3c;
        cursor: pointer;
        user-select: none;
        justify-content: center;
        align-items: center;
      }

      .sw {
        display: flex;
        width: 100%;
        height: 50%;
        user-select: none;
        align-items: center;
        justify-content: center;
      }

      .sw:hover {
        .spans {
          color: #989fa8;
        }
      }

      .xw:hover {
        .spans {
          color: #989fa8;
        }
      }

      .xw {
        display: flex;
        width: 100%;
        height: 50%;
        user-select: none;
        align-items: center;
        justify-content: center;
      }
    }
  }

  .labelModeRl {
    writing-mode: vertical-rl;
  }
}

:deep(.workday) {
  color: #989fa8 !important;
}
</style>
