瀏覽代碼

Vue3 重构:操作日志的详情

YunaiV 2 年之前
父節點
當前提交
e669dffddc

+ 1 - 51
src/utils/formatTime.ts

@@ -12,57 +12,7 @@ import dayjs from 'dayjs'
  * @returns 返回拼接后的时间字符串
  */
 export function formatDate(date: Date, format: string): string {
-  const we = date.getDay() // 星期
-  const z = getWeek(date) // 周
-  const qut = Math.floor((date.getMonth() + 3) / 3).toString() // 季度
-  const opt: { [key: string]: string } = {
-    'Y+': date.getFullYear().toString(), // 年
-    'm+': (date.getMonth() + 1).toString(), // 月(月份从0开始,要+1)
-    'd+': date.getDate().toString(), // 日
-    'H+': date.getHours().toString(), // 时
-    'M+': date.getMinutes().toString(), // 分
-    'S+': date.getSeconds().toString(), // 秒
-    'q+': qut // 季度
-  }
-  // 中文数字 (星期)
-  const week: { [key: string]: string } = {
-    '0': '日',
-    '1': '一',
-    '2': '二',
-    '3': '三',
-    '4': '四',
-    '5': '五',
-    '6': '六'
-  }
-  // 中文数字(季度)
-  const quarter: { [key: string]: string } = {
-    '1': '一',
-    '2': '二',
-    '3': '三',
-    '4': '四'
-  }
-  if (/(W+)/.test(format))
-    format = format.replace(
-      RegExp.$1,
-      RegExp.$1.length > 1 ? (RegExp.$1.length > 2 ? '星期' + week[we] : '周' + week[we]) : week[we]
-    )
-  if (/(Q+)/.test(format))
-    format = format.replace(
-      RegExp.$1,
-      RegExp.$1.length == 4 ? '第' + quarter[qut] + '季度' : quarter[qut]
-    )
-  if (/(Z+)/.test(format))
-    format = format.replace(RegExp.$1, RegExp.$1.length == 3 ? '第' + z + '周' : z + '')
-  for (const k in opt) {
-    const r = new RegExp('(' + k + ')').exec(format)
-    // 若输入的长度不为1,则前面补零
-    if (r)
-      format = format.replace(
-        r[1],
-        RegExp.$1.length == 1 ? opt[k] : opt[k].padStart(RegExp.$1.length, '0')
-      )
-  }
-  return format
+  return dayjs(date).format(format)
 }
 
 /**

+ 3 - 3
src/views/system/mail/log/index.vue

@@ -29,8 +29,8 @@
     </Table>
   </content-wrap>
 
-  <!-- 表单弹窗:添加/修改 -->
-  <mail-log-detail ref="modalRef" @success="getList" />
+  <!-- 表单弹窗:详情 -->
+  <mail-log-detail ref="modalRef" />
 </template>
 <script setup lang="ts" name="MailLog">
 import { allSchemas } from './log.data'
@@ -46,7 +46,7 @@ const { tableObject, tableMethods } = useTable({
 // 获得表格的各种操作
 const { getList, setSearchParams } = tableMethods
 
-/** 添加/修改操作 */
+/** 详情操作 */
 const modalRef = ref()
 const openModal = (id: number) => {
   modalRef.value.openModal(id)

+ 80 - 0
src/views/system/operatelog/detail.vue

@@ -0,0 +1,80 @@
+<template>
+  <Dialog title="详情" v-model="modelVisible" :scroll="true" :max-height="500" width="800">
+    <el-descriptions border :column="1">
+      <el-descriptions-item label="日志主键" min-width="120">
+        {{ detailData.id }}
+      </el-descriptions-item>
+      <el-descriptions-item label="链路追踪">
+        {{ detailData.traceId }}
+      </el-descriptions-item>
+      <el-descriptions-item label="操作人编号">
+        {{ detailData.userId }}
+      </el-descriptions-item>
+      <el-descriptions-item label="操作人名字">
+        {{ detailData.userNickname }}
+      </el-descriptions-item>
+      <el-descriptions-item label="操作人 IP">
+        {{ detailData.userIp }}
+      </el-descriptions-item>
+      <el-descriptions-item label="操作人 UA">
+        {{ detailData.userAgent }}
+      </el-descriptions-item>
+      <el-descriptions-item label="操作模块">
+        {{ detailData.module }}
+      </el-descriptions-item>
+      <el-descriptions-item label="操作名">
+        {{ detailData.name }}
+      </el-descriptions-item>
+      <el-descriptions-item label="操作内容" v-if="detailData.content">
+        {{ detailData.content }}
+      </el-descriptions-item>
+      <el-descriptions-item label="操作拓展参数" v-if="detailData.exts">
+        {{ detailData.exts }}
+      </el-descriptions-item>
+      <el-descriptions-item label="请求 URL">
+        {{ detailData.requestMethod }} {{ detailData.requestUrl }}
+      </el-descriptions-item>
+      <el-descriptions-item label="Java 方法名">
+        {{ detailData.javaMethod }}
+      </el-descriptions-item>
+      <el-descriptions-item label="Java 方法参数">
+        {{ detailData.javaMethodArgs }}
+      </el-descriptions-item>
+      <el-descriptions-item label="操作时间">
+        {{ formatDate(detailData.startTime, 'YYYY-MM-DD HH:mm:ss') }}
+      </el-descriptions-item>
+      <el-descriptions-item label="执行时长">{{ detailData.duration }} ms</el-descriptions-item>
+      <el-descriptions-item label="操作结果">
+        <div v-if="detailData.resultCode === 0">正常</div>
+        <div v-else>失败({{ detailData.resultCode }})</div>
+      </el-descriptions-item>
+      <el-descriptions-item label="操作结果" v-if="detailData.resultCode === 0">
+        {{ detailData.resultData }}
+      </el-descriptions-item>
+      <el-descriptions-item label="失败提示" v-if="detailData.resultCode > 0">
+        {{ detailData.resultMsg }}
+      </el-descriptions-item>
+    </el-descriptions>
+  </Dialog>
+</template>
+<script setup lang="ts">
+import { formatDate } from '@/utils/formatTime'
+import * as OperateLogApi from '@/api/system/operatelog'
+
+const modelVisible = ref(false) // 弹窗的是否展示
+const detailLoading = ref(false) // 表单的加载中
+const detailData = ref() // 详情数据
+
+/** 打开弹窗 */
+const openModal = async (data: OperateLogApi.OperateLogVO) => {
+  modelVisible.value = true
+  // 设置数据
+  detailLoading.value = true
+  try {
+    detailData.value = data
+  } finally {
+    detailLoading.value = false
+  }
+}
+defineExpose({ openModal }) // 提供 openModal 方法,用于打开弹窗
+</script>

+ 11 - 8
src/views/system/operatelog/index.vue

@@ -21,7 +21,7 @@
       <el-form-item label="类型" prop="type">
         <el-select v-model="queryParams.type" placeholder="操作类型" clearable>
           <el-option
-            v-for="dict in getDictOptions(DICT_TYPE.INFRA_CONFIG_TYPE)"
+            v-for="dict in getDictOptions(DICT_TYPE.SYSTEM_OPERATE_TYPE)"
             :key="parseInt(dict.value)"
             :label="dict.label"
             :value="parseInt(dict.value)"
@@ -94,7 +94,7 @@
           <el-button
             link
             type="primary"
-            @click="openModal('update', scope.row.id)"
+            @click="openModal(scope.row)"
             v-hasPermi="['infra:config:query']"
           >
             详情
@@ -110,13 +110,16 @@
       @pagination="getList"
     />
   </content-wrap>
+
+  <!-- 表单弹窗:详情 -->
+  <operate-log-detail ref="modalRef" />
 </template>
 <script setup lang="ts" name="OperateLog">
 import { DICT_TYPE, getDictOptions } from '@/utils/dict'
 import { dateFormatter } from '@/utils/formatTime'
 import download from '@/utils/download'
 import * as OperateLogApi from '@/api/system/operatelog'
-// import ConfigForm from './form.vue'
+import OperateLogDetail from './detail.vue'
 const message = useMessage() // 消息弹窗
 
 const loading = ref(true) // 列表的加载中
@@ -158,11 +161,11 @@ const resetQuery = () => {
   handleQuery()
 }
 
-/** 添加/修改操作 */
-// const modalRef = ref()
-// const openModal = (type: string, id?: number) => {
-//   modalRef.value.openModal(type, id)
-// }
+/** 详情操作 */
+const modalRef = ref()
+const openModal = (data: OperateLogApi.OperateLogVO) => {
+  modalRef.value.openModal(data)
+}
 
 /** 导出按钮操作 */
 const handleExport = async () => {

+ 0 - 106
src/views/system/operatelog/operatelog.data.ts

@@ -1,106 +0,0 @@
-import type { VxeCrudSchema } from '@/hooks/web/useVxeCrudSchemas'
-
-const { t } = useI18n() // 国际化
-
-const crudSchemas = reactive<VxeCrudSchema>({
-  primaryKey: 'id',
-  primaryType: 'id',
-  primaryTitle: '日志编号',
-  action: true,
-  actionWidth: '80px',
-  columns: [
-    {
-      title: '操作模块',
-      field: 'module',
-      isSearch: true
-    },
-    {
-      title: '操作名',
-      field: 'name'
-    },
-    {
-      title: '操作类型',
-      field: 'type',
-      dictType: DICT_TYPE.SYSTEM_OPERATE_TYPE,
-      dictClass: 'number',
-      isSearch: true
-    },
-    {
-      title: '请求方法名',
-      field: 'requestMethod',
-      isTable: false
-    },
-    {
-      title: '请求地址',
-      field: 'requestUrl',
-      isTable: false
-    },
-    {
-      title: '操作人员',
-      field: 'userNickname',
-      isSearch: true
-    },
-    {
-      title: '操作明细',
-      field: 'content',
-      isTable: false
-    },
-    {
-      title: '用户 IP',
-      field: 'userIp',
-      isTable: false
-    },
-    {
-      title: 'userAgent',
-      field: 'userAgent'
-    },
-    {
-      title: '操作结果',
-      field: 'resultCode',
-      table: {
-        slots: {
-          default: 'resultCode'
-        }
-      }
-    },
-    {
-      title: '操作结果',
-      field: 'success',
-      isTable: false,
-      isDetail: false,
-      search: {
-        show: true,
-        itemRender: {
-          name: '$select',
-          props: { placeholder: t('common.selectText') },
-          options: [
-            { label: '成功', value: 'true' },
-            { label: '失败', value: 'false' }
-          ]
-        }
-      }
-    },
-    {
-      title: '操作日期',
-      field: 'startTime',
-      formatter: 'formatDate',
-      isForm: false,
-      search: {
-        show: true,
-        itemRender: {
-          name: 'XDataTimePicker'
-        }
-      }
-    },
-    {
-      title: '执行时长',
-      field: 'duration',
-      table: {
-        slots: {
-          default: 'duration'
-        }
-      }
-    }
-  ]
-})
-export const { allSchemas } = useVxeCrudSchemas(crudSchemas)