<template>
  <div class="table-box">
    <ProTable ref="proTable" :columns="columns" row-key="operId" :request-api="listOperLogApi">
      <!-- 表格 header 按钮 -->
      <template #tableHeader="scope">
        <el-button type="danger" v-auth="['monitor:operlog:remove']" icon="WarnTriangleFilled" @click="handleClean"> 清空 </el-button>
        <el-button type="primary" v-auth="['monitor:operlog:export']" icon="Download" plain @click="downloadFile"> 导出 </el-button>
        <el-button
          type="danger"
          v-auth="['monitor:operlog:remove']"
          icon="Delete"
          plain
          :disabled="!scope.isSelected"
          @click="batchDelete(scope.selectedListIds)"
        >
          批量删除
        </el-button>
      </template>

      <template #costTime="scope">
        <span>{{ scope.row.costTime }}毫秒</span>
      </template>
      <!-- 表格操作 -->
      <template #operation="scope">
        <el-button type="primary" link icon="View" v-auth="['monitor:operlog:query']" @click="openDialog(3, '操作日志记录查看', scope.row)">
          查看
        </el-button>
      </template>
    </ProTable>
    <FormDialog ref="formDialogRef" :items-options="itemsOptions" :model="model" />
  </div>
</template>

<script setup lang="tsx" name="OperLog">
import { useHandleData } from '@/hooks/useHandleData'
import { useDownload } from '@/hooks/useDownload'
import { ElMessageBox } from 'element-plus'
import FormDialog from '@/components/FormDialog/index.vue'
import { ProTableInstance, ColumnProps } from '@/components/ProTable/interface'
import { listOperLogApi, delOperLogApi, exportOperLogApi, getOperLogApi, cleanOperlogApi } from '@/api/modules/monitor/operlog'
const { proxy } = getCurrentInstance() as ComponentInternalInstance
const { sys_oper_type, sys_common_status } = toRefs<any>(proxy?.useDict('sys_oper_type', 'sys_common_status'))
// ProTable 实例
const proTable = ref<ProTableInstance>()
// 表单model
const model = ref({})

// 批量删除操作日志记录信息
const batchDelete = async (ids: string[]) => {
  await useHandleData(delOperLogApi, ids, '删除所选操作日志记录信息')
  proTable.value?.clearSelection()
  proTable.value?.getTableList()
}

// 导出操作日志记录列表
const downloadFile = async () => {
  ElMessageBox.confirm('确认导出操作日志记录数据?', '温馨提示', { type: 'warning' }).then(() =>
    useDownload(exportOperLogApi, '操作日志记录列表', proTable.value?.searchParam)
  )
}

/** 清空按钮操作 */
const handleClean = async () => {
  await useHandleData(cleanOperlogApi, '', '清空所有操作日志数据项')
  proTable.value?.clearSelection()
  proTable.value?.getTableList()
}

const formDialogRef = ref<InstanceType<typeof FormDialog> | null>(null)
// 打开弹框的功能
const openDialog = async (type: number, title: string, row?: any) => {
  let res = { data: {} }
  if (row?.operId) {
    res = await getOperLogApi(row?.operId || null)
  }
  model.value = type == 1 ? {} : res.data
  // 重置表单
  setItemsOptions()
  const params = {
    title,
    width: 580,
    isEdit: type !== 3,
    getTableList: proTable.value?.getTableList
  }
  formDialogRef.value?.openDialog(params)
}

// 表格配置项
const columns = reactive<ColumnProps<any>[]>([
  { type: 'selection', fixed: 'left', width: 70 },
  {
    prop: 'operId',
    label: '日志编号',
    search: {
      el: 'input'
    },
    width: 120
  },
  {
    prop: 'title',
    label: '系统模块',
    search: {
      el: 'input'
    },
    width: 120
  },
  {
    prop: 'businessType',
    label: '操作类型',
    enum: sys_oper_type,
    tag: true,
    search: {
      el: 'select'
    },
    width: 120
  },
  {
    prop: 'operName',
    label: '操作人员',
    search: {
      el: 'input'
    },
    width: 120
  },
  {
    prop: 'deptName',
    label: '部门',
    width: 120
  },
  {
    prop: 'operUrl',
    label: '操作地址',
    width: 120
  },
  {
    prop: 'status',
    label: '操作状态',
    tag: true,
    enum: sys_common_status,
    search: {
      el: 'select'
    },
    width: 120
  },
  {
    prop: 'operTime',
    label: '操作时间',
    search: {
      el: 'date-picker',
      props: { type: 'datetimerange', valueFormat: 'YYYY-MM-DD HH:mm:ss' }
    },
    width: 120
  },
  {
    prop: 'costTime',
    label: '消耗时间',
    width: 120
  },
  { prop: 'operation', label: '操作', width: 230, fixed: 'right' }
])
// 表单配置项
let itemsOptions = ref<ProForm.ItemsOptions[]>([])
const setItemsOptions = () => {
  itemsOptions.value = [
    {
      label: '日志主键',
      prop: 'operId',
      rules: [{ required: true, message: '日志主键不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入日志主键'
      }
    },
    {
      label: '模块标题',
      prop: 'title',
      rules: [{ required: true, message: '模块标题不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入模块标题'
      }
    },
    {
      label: '业务类型',
      prop: 'businessType',
      rules: [{ required: true, message: '业务类型不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入业务类型'
      }
    },
    {
      label: '方法名称',
      prop: 'method',
      rules: [{ required: true, message: '方法名称不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入方法名称'
      }
    },
    {
      label: '请求方式',
      prop: 'requestMethod',
      rules: [{ required: true, message: '请求方式不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入请求方式'
      }
    },
    {
      label: '操作类别',
      prop: 'operatorType',
      rules: [{ required: true, message: '操作类别不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入操作类别'
      }
    },
    {
      label: '操作人员',
      prop: 'operName',
      rules: [{ required: true, message: '操作人员不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入操作人员'
      }
    },
    {
      label: '部门名称',
      prop: 'deptName',
      rules: [{ required: true, message: '部门名称不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入部门名称'
      }
    },
    {
      label: '请求URL',
      prop: 'operUrl',
      rules: [{ required: true, message: '请求URL不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入请求URL'
      }
    },
    {
      label: '主机地址',
      prop: 'operIp',
      rules: [{ required: true, message: '主机地址不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入主机地址'
      }
    },
    {
      label: '操作地点',
      prop: 'operLocation',
      rules: [{ required: true, message: '操作地点不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入操作地点'
      }
    },
    {
      label: '请求参数',
      prop: 'operParam',
      rules: [{ required: true, message: '请求参数不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入请求参数'
      }
    },
    {
      label: '返回参数',
      prop: 'jsonResult',
      rules: [{ required: true, message: '返回参数不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入返回参数'
      }
    },
    {
      label: '操作状态',
      prop: 'status',
      rules: [{ required: true, message: '操作状态不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入操作状态'
      }
    },
    {
      label: '错误消息',
      prop: 'errorMsg',
      rules: [{ required: true, message: '错误消息不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入错误消息'
      }
    },
    {
      label: '操作时间',
      prop: 'operTime',
      rules: [{ required: true, message: '操作时间不能为空', trigger: 'change' }],
      compOptions: {
        elTagName: 'date-picker',
        type: 'date',
        placeholder: '请选择操作时间'
      }
    },
    {
      label: '消耗时间',
      prop: 'costTime',
      rules: [{ required: true, message: '消耗时间不能为空', trigger: 'blur' }],
      compOptions: {
        placeholder: '请输入消耗时间'
      }
    }
  ]
}
</script>
