Ver Fonte

feat: 日志页面

wanggaokun há 1 ano atrás
pai
commit
0bf78fb701

+ 176 - 0
src/api/interface/monitor/logininfor.ts

@@ -0,0 +1,176 @@
+import { PageQuery, BaseEntity } from '@/api/interface/index'
+export interface LogininforVO extends BaseEntity {
+  /**
+   * 访问ID
+   */
+  infoId: string | number
+
+  /**
+   * 用户账号
+   */
+  userName: string
+
+  /**
+   * 客户端
+   */
+  clientKey: string
+
+  /**
+   * 设备类型
+   */
+  deviceType: string
+
+  /**
+   * 登录IP地址
+   */
+  ipaddr: string
+
+  /**
+   * 登录地点
+   */
+  loginLocation: string
+
+  /**
+   * 浏览器类型
+   */
+  browser: string
+
+  /**
+   * 操作系统
+   */
+  os: string
+
+  /**
+   * 登录状态(1成功 0失败)
+   */
+  status: string
+
+  /**
+   * 提示消息
+   */
+  msg: string
+
+  /**
+   * 访问时间
+   */
+  loginTime: string
+}
+
+export interface LogininforForm {
+  /**
+   * 访问ID
+   */
+  infoId?: string | number
+
+  /**
+   * 用户账号
+   */
+  userName?: string
+
+  /**
+   * 客户端
+   */
+  clientKey?: string
+
+  /**
+   * 设备类型
+   */
+  deviceType?: string
+
+  /**
+   * 登录IP地址
+   */
+  ipaddr?: string
+
+  /**
+   * 登录地点
+   */
+  loginLocation?: string
+
+  /**
+   * 浏览器类型
+   */
+  browser?: string
+
+  /**
+   * 操作系统
+   */
+  os?: string
+
+  /**
+   * 登录状态(1成功 0失败)
+   */
+  status?: string
+
+  /**
+   * 提示消息
+   */
+  msg?: string
+
+  /**
+   * 访问时间
+   */
+  loginTime?: string
+}
+
+export interface LogininforQuery extends PageQuery {
+  /**
+   * 访问ID
+   */
+  infoId?: string | number
+
+  /**
+   * 用户账号
+   */
+  userName?: string
+
+  /**
+   * 客户端
+   */
+  clientKey?: string
+
+  /**
+   * 设备类型
+   */
+  deviceType?: string
+
+  /**
+   * 登录IP地址
+   */
+  ipaddr?: string
+
+  /**
+   * 登录地点
+   */
+  loginLocation?: string
+
+  /**
+   * 浏览器类型
+   */
+  browser?: string
+
+  /**
+   * 操作系统
+   */
+  os?: string
+
+  /**
+   * 登录状态(1成功 0失败)
+   */
+  status?: string
+
+  /**
+   * 提示消息
+   */
+  msg?: string
+
+  /**
+   * 访问时间
+   */
+  loginTime?: string
+
+  /**
+   * 日期范围参数
+   */
+  params?: any
+}

+ 266 - 0
src/api/interface/monitor/operlog.ts

@@ -0,0 +1,266 @@
+import { PageQuery, BaseEntity } from '@/api/interface/index'
+export interface OperLogVO extends BaseEntity {
+  /**
+   * 日志主键
+   */
+  operId: string | number
+
+  /**
+   * 模块标题
+   */
+  title: string
+
+  /**
+   * 业务类型(0其它 1新增 2修改 3删除)
+   */
+  businessType: number
+
+  /**
+   * 方法名称
+   */
+  method: string
+
+  /**
+   * 请求方式
+   */
+  requestMethod: string
+
+  /**
+   * 操作类别(0其它 1后台用户 2手机端用户)
+   */
+  operatorType: number
+
+  /**
+   * 操作人员
+   */
+  operName: string
+
+  /**
+   * 部门名称
+   */
+  deptName: string
+
+  /**
+   * 请求URL
+   */
+  operUrl: string
+
+  /**
+   * 主机地址
+   */
+  operIp: string
+
+  /**
+   * 操作地点
+   */
+  operLocation: string
+
+  /**
+   * 请求参数
+   */
+  operParam: string
+
+  /**
+   * 返回参数
+   */
+  jsonResult: string
+
+  /**
+   * 操作状态(1正常 0异常)
+   */
+  status: number
+
+  /**
+   * 错误消息
+   */
+  errorMsg: string
+
+  /**
+   * 操作时间
+   */
+  operTime: string
+
+  /**
+   * 消耗时间
+   */
+  costTime: number
+}
+
+export interface OperLogForm {
+  /**
+   * 日志主键
+   */
+  operId?: string | number
+
+  /**
+   * 模块标题
+   */
+  title?: string
+
+  /**
+   * 业务类型(0其它 1新增 2修改 3删除)
+   */
+  businessType?: number
+
+  /**
+   * 方法名称
+   */
+  method?: string
+
+  /**
+   * 请求方式
+   */
+  requestMethod?: string
+
+  /**
+   * 操作类别(0其它 1后台用户 2手机端用户)
+   */
+  operatorType?: number
+
+  /**
+   * 操作人员
+   */
+  operName?: string
+
+  /**
+   * 部门名称
+   */
+  deptName?: string
+
+  /**
+   * 请求URL
+   */
+  operUrl?: string
+
+  /**
+   * 主机地址
+   */
+  operIp?: string
+
+  /**
+   * 操作地点
+   */
+  operLocation?: string
+
+  /**
+   * 请求参数
+   */
+  operParam?: string
+
+  /**
+   * 返回参数
+   */
+  jsonResult?: string
+
+  /**
+   * 操作状态(1正常 0异常)
+   */
+  status?: number
+
+  /**
+   * 错误消息
+   */
+  errorMsg?: string
+
+  /**
+   * 操作时间
+   */
+  operTime?: string
+
+  /**
+   * 消耗时间
+   */
+  costTime?: number
+}
+
+export interface OperLogQuery extends PageQuery {
+  /**
+   * 日志主键
+   */
+  operId?: string | number
+
+  /**
+   * 模块标题
+   */
+  title?: string
+
+  /**
+   * 业务类型(0其它 1新增 2修改 3删除)
+   */
+  businessType?: number
+
+  /**
+   * 方法名称
+   */
+  method?: string
+
+  /**
+   * 请求方式
+   */
+  requestMethod?: string
+
+  /**
+   * 操作类别(0其它 1后台用户 2手机端用户)
+   */
+  operatorType?: number
+
+  /**
+   * 操作人员
+   */
+  operName?: string
+
+  /**
+   * 部门名称
+   */
+  deptName?: string
+
+  /**
+   * 请求URL
+   */
+  operUrl?: string
+
+  /**
+   * 主机地址
+   */
+  operIp?: string
+
+  /**
+   * 操作地点
+   */
+  operLocation?: string
+
+  /**
+   * 请求参数
+   */
+  operParam?: string
+
+  /**
+   * 返回参数
+   */
+  jsonResult?: string
+
+  /**
+   * 操作状态(1正常 0异常)
+   */
+  status?: number
+
+  /**
+   * 错误消息
+   */
+  errorMsg?: string
+
+  /**
+   * 操作时间
+   */
+  operTime?: string
+
+  /**
+   * 消耗时间
+   */
+  costTime?: number
+
+  /**
+   * 日期范围参数
+   */
+  params?: any
+}

+ 10 - 46
src/api/modules/monitor/logininfor.ts

@@ -1,39 +1,12 @@
 import http from '@/api'
-
+import { LogininforVO, LogininforQuery } from '@/api/interface/monitor/logininfor'
 /**
  * @name 查询系统访问记录列表
  * @param query 参数
  * @returns 返回列表
  */
-export const listLogininforApi = (query: any) => {
-  return http.get<any>('/monitor/logininfor/list', query, { loading: true })
-}
-
-/**
- * @name 查询系统访问记录详细
- * @param infoId infoId
- * @returns returns
- */
-export const getLogininforApi = (infoId: any) => {
-  return http.get<any>(`/monitor/logininfor/${infoId}`)
-}
-
-/**
- * @name 新增系统访问记录
- * @param data data
- * @returns returns
- */
-export const addLogininforApi = (data: any) => {
-  return http.post<any>('/monitor/logininfor', data, { loading: false })
-}
-
-/**
- * @name 修改系统访问记录
- * @param data data
- * @returns returns
- */
-export const updateLogininforApi = (data: any) => {
-  return http.put<any>('/monitor/logininfor', data, { loading: false })
+export const listLogininforApi = (query: LogininforQuery) => {
+  return http.get<LogininforVO[]>('/monitor/logininfor/list', query, { loading: true })
 }
 
 /**
@@ -41,30 +14,21 @@ export const updateLogininforApi = (data: any) => {
  * @param infoId infoId
  * @returns returns
  */
-export const delLogininforApi = (infoId: any) => {
+export const delLogininforApi = (infoId: string | number | Array<string | number>) => {
   return http.delete<any>(`/monitor/logininfor/${infoId}`)
 }
 
 /**
- * @name 下载模板
- * @returns returns
- */
-export const importTemplateApi = () => {
-  return http.downloadPost('/monitor/logininfor/importTemplate', {})
-}
-
-/**
- * @name 导入数据
+ * @name 导出数据
  * @returns returns
  */
-export const importDataApi = (data: any) => {
-  return http.post('/monitor/logininfor/importData', data)
+export const exportLogininforApi = (data: any) => {
+  return http.downloadPost('/monitor/logininfor/export', data)
 }
 
 /**
- * @name 导出数据
- * @returns returns
+ * @name 清空日志
  */
-export const exportApi = (data: any) => {
-  return http.downloadPost('/monitor/logininfor/export', data)
+export const cleanLoginInfoApi = () => {
+  return http.delete<any>(`/monitor/logininfor/clean`)
 }

+ 12 - 39
src/api/modules/monitor/operlog.ts

@@ -1,12 +1,12 @@
 import http from '@/api'
-
+import { OperLogVO, OperLogQuery } from '@/api/interface/monitor/operlog'
 /**
  * @name 查询操作日志记录列表
  * @param query 参数
  * @returns 返回列表
  */
-export const listOperlogApi = (query: any) => {
-  return http.get<any>('/monitor/operlog/list', query, { loading: true })
+export const listOperLogApi = (query: OperLogQuery) => {
+  return http.get<OperLogVO[]>('/monitor/operlog/list', query, { loading: true })
 }
 
 /**
@@ -14,26 +14,8 @@ export const listOperlogApi = (query: any) => {
  * @param operId operId
  * @returns returns
  */
-export const getOperlogApi = (operId: any) => {
-  return http.get<any>(`/monitor/operlog/${operId}`)
-}
-
-/**
- * @name 新增操作日志记录
- * @param data data
- * @returns returns
- */
-export const addOperlogApi = (data: any) => {
-  return http.post<any>('/monitor/operlog', data, { loading: false })
-}
-
-/**
- * @name 修改操作日志记录
- * @param data data
- * @returns returns
- */
-export const updateOperlogApi = (data: any) => {
-  return http.put<any>('/monitor/operlog', data, { loading: false })
+export const getOperLogApi = (operId: string | number) => {
+  return http.get<OperLogVO>(`/monitor/operlog/${operId}`)
 }
 
 /**
@@ -41,30 +23,21 @@ export const updateOperlogApi = (data: any) => {
  * @param operId operId
  * @returns returns
  */
-export const delOperlogApi = (operId: any) => {
+export const delOperLogApi = (operId: string | number | Array<string | number>) => {
   return http.delete<any>(`/monitor/operlog/${operId}`)
 }
 
 /**
- * @name 下载模板
- * @returns returns
- */
-export const importTemplateApi = () => {
-  return http.downloadPost('/monitor/operlog/importTemplate', {})
-}
-
-/**
- * @name 导入数据
+ * @name 导出数据
  * @returns returns
  */
-export const importDataApi = (data: any) => {
-  return http.post('/monitor/operlog/importData', data)
+export const exportOperLogApi = (data: any) => {
+  return http.downloadPost('/monitor/operlog/export', data)
 }
 
 /**
- * @name 导出数据
- * @returns returns
+ * @name 清空操作日志
  */
-export const exportApi = (data: any) => {
-  return http.downloadPost('/monitor/operlog/export', data)
+export const cleanOperlogApi = () => {
+  return http.delete<any>(`/monitor/operlog/clean`)
 }

BIN
src/assets/images/avatar.gif


+ 1 - 1
src/utils/index.ts

@@ -306,7 +306,7 @@ export function filterEnum(callValue: any, enumData?: any, fieldNames?: FieldNam
 export function findItemNested(enumData: any, callValue: any, value: string, children: string) {
   return enumData.reduce((accumulator: any, current: any) => {
     if (accumulator) return accumulator
-    if (current[value] === callValue) return current
+    if (current[value] == callValue) return current
     if (current[children]) return findItemNested(current[children], callValue, value, children)
   }, null)
 }

+ 4 - 8
src/views/import-export/index.vue

@@ -116,7 +116,7 @@ const iColumns = reactive<ColumnProps<any>[]>([
     width: 120
   },
   {
-    prop: 'createBy',
+    prop: 'createByName',
     label: '操作人',
     search: {
       el: 'input'
@@ -124,12 +124,8 @@ const iColumns = reactive<ColumnProps<any>[]>([
     width: 220
   },
   {
-    prop: 'updateTime',
+    prop: 'createTime',
     label: '操作时间',
-    search: {
-      el: 'date-picker',
-      props: { type: 'datetimerange', valueFormat: 'YYYY-MM-DD HH:mm:ss' }
-    },
     width: 220
   },
   { prop: 'operation', label: '操作' }
@@ -149,12 +145,12 @@ const eColumns = reactive<ColumnProps<any>[]>([
     }
   },
   {
-    prop: 'createBy',
+    prop: 'createByName',
     label: '操作人',
     width: 220
   },
   {
-    prop: 'updateTime',
+    prop: 'createTime',
     label: '操作时间',
     width: 220
   },

+ 77 - 28
src/views/monitor/logininfor/index.vue

@@ -1,63 +1,113 @@
 <template>
   <div class="table-box">
-    <ProTable ref="proTable" :columns="columns" row-key="infoId" :request-api="listLogininforApi" :init-param="initParam"> </ProTable>
-    <ImportExcel ref="dialogRef" />
+    <ProTable ref="proTable" :columns="columns" row-key="infoId" :request-api="listLogininforApi">
+      <!-- 表格 header 按钮 -->
+      <template #tableHeader="scope">
+        <el-button type="danger" v-auth="['monitor:logininfor:remove']" icon="WarnTriangleFilled" @click="handleClean"> 清空 </el-button>
+        <el-button type="primary" v-auth="['monitor:logininfor:export']" icon="Download" plain @click="downloadFile"> 导出 </el-button>
+        <el-button
+          type="danger"
+          v-auth="['monitor:logininfor:remove']"
+          icon="Delete"
+          plain
+          :disabled="!scope.isSelected"
+          @click="batchDelete(scope.selectedListIds)"
+        >
+          批量删除
+        </el-button>
+      </template>
+    </ProTable>
   </div>
 </template>
 
-<script setup lang="tsx" name="Logininfor">
-import ImportExcel from '@/components/ImportExcel/index.vue'
+<script setup lang="tsx" name="LoginInfor">
+import { useHandleData } from '@/hooks/useHandleData'
+import { useDownload } from '@/hooks/useDownload'
+import { ElMessageBox } from 'element-plus'
 import { ProTableInstance, ColumnProps } from '@/components/ProTable/interface'
-import { listLogininforApi } from '@/api/modules/monitor/logininfor'
+import { listLogininforApi, delLogininforApi, exportLogininforApi, cleanLoginInfoApi } from '@/api/modules/monitor/logininfor'
 const { proxy } = getCurrentInstance() as ComponentInternalInstance
-const { sys_common_status } = toRefs<any>(proxy?.useDict('sys_common_status'))
+const { sys_common_status, sys_device_type } = toRefs<any>(proxy?.useDict('sys_common_status', 'sys_device_type'))
 
 // ProTable 实例
 const proTable = ref<ProTableInstance>()
 
-// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
-const initParam = reactive({ type: 1 })
+// 批量删除系统访问记录信息
+const batchDelete = async (ids: string[]) => {
+  await useHandleData(delLogininforApi, ids, '删除所选系统访问记录信息')
+  proTable.value?.clearSelection()
+  proTable.value?.getTableList()
+}
 
-// 批量添加系统访问记录
-const dialogRef = ref<InstanceType<typeof ImportExcel> | null>(null)
+// 导出系统访问记录列表
+const downloadFile = async () => {
+  ElMessageBox.confirm('确认导出系统访问记录数据?', '温馨提示', { type: 'warning' }).then(() =>
+    useDownload(exportLogininforApi, '系统访问记录列表', proTable.value?.searchParam)
+  )
+}
 
+/** 清空按钮操作 */
+const handleClean = async () => {
+  await useHandleData(cleanLoginInfoApi, '', '清空所有登录日志数据项')
+  proTable.value?.clearSelection()
+  proTable.value?.getTableList()
+}
 // 表格配置项
 const columns = reactive<ColumnProps<any>[]>([
-  { prop: 'infoId', label: '访问ID' },
+  { type: 'selection', fixed: 'left', width: 70 },
+  {
+    prop: 'infoId',
+    label: '访问编号',
+    width: 120
+  },
   {
     prop: 'userName',
     label: '用户账号',
     search: {
       el: 'input'
-    }
+    },
+    width: 120
   },
   {
-    prop: 'ipaddr',
-    label: '登录IP地址',
+    prop: 'clientKey',
+    label: '客户端',
+    width: 120
+  },
+  {
+    prop: 'deviceType',
+    label: '设备类型',
+    tag: true,
+    enum: sys_device_type,
     search: {
-      el: 'input'
-    }
+      el: 'select'
+    },
+    width: 120
+  },
+  {
+    prop: 'ipaddr',
+    label: '地址',
+    width: 120
   },
   {
     prop: 'loginLocation',
     label: '登录地点',
-    search: {
-      el: 'input'
-    }
+    width: 120
   },
   {
     prop: 'browser',
-    label: '浏览器类型',
+    label: '浏览器',
     search: {
       el: 'input'
-    }
+    },
+    width: 120
   },
   {
     prop: 'os',
     label: '操作系统',
     search: {
       el: 'input'
-    }
+    },
+    width: 120
   },
   {
     prop: 'status',
@@ -65,15 +115,13 @@ const columns = reactive<ColumnProps<any>[]>([
     tag: true,
     enum: sys_common_status,
     search: {
-      el: 'input'
+      el: 'tree-select'
     }
   },
   {
     prop: 'msg',
-    label: '提示消息',
-    search: {
-      el: 'input'
-    }
+    label: '描述',
+    width: 120
   },
   {
     prop: 'loginTime',
@@ -81,7 +129,8 @@ const columns = reactive<ColumnProps<any>[]>([
     search: {
       el: 'date-picker',
       props: { type: 'datetimerange', valueFormat: 'YYYY-MM-DD HH:mm:ss' }
-    }
+    },
+    width: 120
   }
 ])
 </script>

+ 253 - 82
src/views/monitor/operlog/index.vue

@@ -1,119 +1,146 @@
 <template>
   <div class="table-box">
-    <ProTable ref="proTable" :columns="columns" row-key="operId" :request-api="listOperlogApi" :init-param="initParam"> </ProTable>
+    <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="Operog">
+<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 } from '@/api/modules/monitor/operlog'
-
+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()
+}
 
-// 如果表格需要初始化请求参数,直接定义传给 ProTable (之后每次请求都会自动带上该参数,此参数更改之后也会一直带上,改变此参数会自动刷新表格数据)
-const initParam = reactive({ type: 1 })
+// 导出操作日志记录列表
+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>[]>([
-  { prop: 'operId', label: '日志主键' },
+  { type: 'selection', fixed: 'left', width: 70 },
   {
-    prop: 'title',
-    label: '模块标题',
+    prop: 'operId',
+    label: '日志编号',
     search: {
       el: 'input'
-    }
+    },
+    width: 120
   },
   {
-    prop: 'businessType',
-    label: '业务类型',
-    search: {
-      el: 'input'
-    }
-  },
-  {
-    prop: 'method',
-    label: '方法名称',
-    search: {
-      el: 'input'
-    }
-  },
-  {
-    prop: 'requestMethod',
-    label: '请求方式',
+    prop: 'title',
+    label: '系统模块',
     search: {
       el: 'input'
-    }
+    },
+    width: 120
   },
   {
-    prop: 'operatorType',
-    label: '操作类别',
+    prop: 'businessType',
+    label: '操作类型',
+    enum: sys_oper_type,
+    tag: true,
     search: {
-      el: 'input'
-    }
+      el: 'select'
+    },
+    width: 120
   },
   {
     prop: 'operName',
     label: '操作人员',
     search: {
       el: 'input'
-    }
+    },
+    width: 120
   },
   {
     prop: 'deptName',
-    label: '部门名称',
-    search: {
-      el: 'input'
-    }
+    label: '部门',
+    width: 120
   },
   {
     prop: 'operUrl',
-    label: '请求URL',
-    search: {
-      el: 'input'
-    }
-  },
-  {
-    prop: 'operIp',
-    label: '主机地址',
-    search: {
-      el: 'input'
-    }
-  },
-  {
-    prop: 'operLocation',
-    label: '操作地点',
-    search: {
-      el: 'input'
-    }
-  },
-  {
-    prop: 'operParam',
-    label: '请求参数',
-    search: {
-      el: 'input'
-    }
-  },
-  {
-    prop: 'jsonResult',
-    label: '返回参数',
-    search: {
-      el: 'input'
-    }
+    label: '操作地址',
+    width: 120
   },
   {
     prop: 'status',
     label: '操作状态',
+    tag: true,
+    enum: sys_common_status,
     search: {
-      el: 'input'
-    }
-  },
-  {
-    prop: 'errorMsg',
-    label: '错误消息',
-    search: {
-      el: 'input'
-    }
+      el: 'select'
+    },
+    width: 120
   },
   {
     prop: 'operTime',
@@ -121,14 +148,158 @@ const columns = reactive<ColumnProps<any>[]>([
     search: {
       el: 'date-picker',
       props: { type: 'datetimerange', valueFormat: 'YYYY-MM-DD HH:mm:ss' }
-    }
+    },
+    width: 120
   },
   {
     prop: 'costTime',
     label: '消耗时间',
-    search: {
-      el: 'input'
-    }
-  }
+    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>