<!--
 * @since: 2025-02-07
 * LoginLog.vue
-->
<template>
  <div class="login-log">
    <el-card class="mb-3 proCard">
      <el-space>
        <el-form ref="searchFormRef" :inline="true" :model="requestParams.queryParam" class="form-inline">
          <el-form-item prop="queryType">
            <el-select v-model="requestParams.queryParam.queryType" placeholder="选择类型" class="type-select">
              <el-option v-for="item in queryTypeSelect" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
            <el-input
              v-model="requestParams.queryParam.queryTypeContent"
              clearable
              placeholder="请输入搜索关键字"
              @keyup.enter="queryLoginLogPage"
              :disabled="requestParams.queryParam.queryType === ''"
            />
          </el-form-item>
          <el-form-item label="终端类型" prop="device">
            <el-select v-model="requestParams.queryParam.device" placeholder="请选择终端类型" clearable>
              <el-option :label="item.label" :value="item.value" v-for="item in deviceList" :key="item.value" />
            </el-select>
          </el-form-item>
          <el-form-item label="登录时间" prop="date">
            <el-date-picker
              v-model="requestParams.queryParam.date"
              type="daterange"
              placeholder="请选择登录时间"
              range-separator="～"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
              :disabled-date="disabledDate"
              clearable
              format="YYYY/MM/DD"
              value-format="YYYY/MM/DD"
            />
          </el-form-item>
          <el-form-item label="请选择组织：" label-position="left" prop="deptId">
            <el-tree-select
              type="daterange"
              range-separator="To"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
              v-model="requestParams.queryParam.deptId"
              :data="departmentList"
              :render-after-expand="false"
              :default-expand-all="true"
              check-strictly
              placeholder="请选择组织"
              class="protocal-select"
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" :icon="Search" @click="queryLoginLogPage">查询</el-button>
            <el-button :icon="Refresh" @click="hanleResetForm(searchFormRef)">重置</el-button>
          </el-form-item>
        </el-form>
      </el-space>
    </el-card>

    <el-card>
      <template #header>
        <el-button type="primary" @click="handleExport()">导出数据</el-button>
      </template>
      <el-table height="calc(100vh - 500px)" :data="loginLogList" v-loading="loading">
        <el-table-column type="index" label="序号" width="100" />
        <el-table-column label="登录账号" prop="userName" />
        <el-table-column label="姓名" prop="realName" />
        <el-table-column label="组织" prop="deptName" />
        <el-table-column label="客户端" prop="device">
          <template #default="{ row }">
            <el-icon :size="24" color="#409eff" v-if="row.device === ClientTypeEnum.PC"><Platform /></el-icon>
            <el-icon :size="24" color="#409eff" v-else><Iphone /></el-icon>
          </template>
        </el-table-column>
        <el-table-column label="操作类型" prop="type">
          <template #default="{ row }">
            <el-tag :type="row.type === OperationTypeEnum.LOGIN ? 'success' : 'danger'" round>
              {{ row.type === OperationTypeEnum.LOGIN ? '登录' : '登出' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作结果" prop="loginStatus">
          <template #default="{ row }">
            <el-icon :size="24" color="#67C23A" v-if="row.loginStatus === LoginStatusEnum.SUCCESS"
              ><SuccessFilled
            /></el-icon>
            <el-icon :size="24" color="#F56C6C" v-else><CircleCloseFilled /></el-icon>
          </template>
        </el-table-column>
        <el-table-column label="登录IP" prop="loginIp" />
        <el-table-column label="操作时间" prop="createdAt" />
      </el-table>

      <section class="mt-4 flex justify-end">
        <!-- 分页组件，显示总条目数、每页显示条目数选择器、上一页、页码、下一页 -->
        <el-pagination
          background
          layout="total, sizes, prev, pager, next"
          :page-sizes="[10, 30, 50]"
          :total="total"
          v-model:page-size="requestParams.pageSize"
          v-model:current-page="requestParams.pageNumber"
          @change="queryLoginLogPage"
        />
      </section>
    </el-card>
  </div>
</template>

<script setup lang="ts">
  import { ref, onMounted } from 'vue';
  import { Search, Refresh, SuccessFilled, CircleCloseFilled, Platform, Iphone } from '@element-plus/icons-vue';
  import { getAllDepartments } from '@/api/auth/dept';
  import type { FormInstance } from 'element-plus';
  import {
    OptionsProps,
    deviceList,
    queryTypeSelect,
    LoginStatusEnum,
    OperationTypeEnum,
    ClientTypeEnum,
  } from '@/types/log/constants';
  import useSceneInfos from '@/hooks/useSceneInfos';
  import useLoginLogQuery from '../hooks/useLoginLogQuery';
  import { ElMessage, ElMessageBox } from 'element-plus';
  import { exportLoginLog } from '@/api/system/log';
  import { downloadByData } from '@/utils/file/download';

  const sceneInfos = useSceneInfos();
  const { calculateTreeData } = sceneInfos;
  const { requestParams, total, loginLogList, queryLoginLogPage, loading, resetRequestParams } = useLoginLogQuery();

  const departmentList = ref<OptionsProps[]>([]);

  onMounted(async () => {
    queryLoginLogPage();
    getAllDepartments().then((res) => {
      departmentList.value = calculateTreeData(res, { level: 3, valueKey: 'id', labelKey: 'deptName' }, 1);
    });
  });

  /* 导出数据 */
  const handleExport = () => {
    ElMessageBox.confirm('确定导出所查询数据？', '导出', {
      confirmButtonText: '确定',
      showCancelButton: true,
      type: 'warning',
    })
      .then(() => {
        exportLoginLog(requestParams.queryParam).then(async (responnse) => {
          if (!responnse) {
            throw new Error('下载文件失败');
          }
          downloadByData(responnse, '登录日志.xlsx');
          ElMessage.success('下载文件成功');
        });
      })
      .catch(() => {
        ElMessage({
          type: 'info',
          message: '取消导出',
        });
      });
  };

  /* 重置 */
  const searchFormRef = ref<FormInstance>();
  const hanleResetForm = (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    resetRequestParams();
    formEl.resetFields();
    queryLoginLogPage();
  };

  /* 设置今天之后的时间不可选 */
  const disabledDate = (time) => {
    return time.getTime() > Date.now();
  };
</script>

<style scoped lang="scss">
  .form-inline .el-input {
    --el-input-width: 160px;
  }

  .form-inline .el-select {
    --el-select-width: 160px;
  }
</style>
