This commit is contained in:
zxr
2026-03-21 17:19:33 +08:00
parent 87741c59ff
commit 6ac9550133

View File

@@ -2,7 +2,6 @@
<div class="container">
<Breadcrumb :items="['menu.ops.systemSettings', 'menu.ops.systemSettings.systemLogs']" />
<!-- 使用 SearchTable 公共组件 -->
<SearchTable
:form-model="formModel"
:form-items="formItems"
@@ -23,24 +22,57 @@
@refresh="handleRefresh"
@download="handleDownload"
>
<!-- 表格自定义列日志级别 -->
<template #level="{ record }">
<a-tag :color="getLevelColor(record.level)">
{{ record.level }}
</a-tag>
</template>
<!-- 表格自定义列序号 -->
<template #index="{ rowIndex }">
<template #index="{ rowIndex }">
{{ rowIndex + 1 + (pagination.current - 1) * pagination.pageSize }}
</template>
<!-- 表格自定义列操作 -->
<template #operations="{ record }">
<a-button type="text" size="small" @click="handleView(record)">
查看
</a-button>
</template>
</SearchTable>
<a-drawer
v-model:visible="detailVisible"
:width="480"
placement="right"
:title="detailRecord ? `日志详情 #${detailRecord.id}` : '日志详情'"
:footer="false"
unmount-on-close
>
<template v-if="detailRecord">
<a-descriptions :column="1" size="large" bordered>
<a-descriptions-item label="日志级别">
<a-tag :color="getLevelColor(detailRecord.level)">
{{ detailRecord.level }}
</a-tag>
</a-descriptions-item>
<a-descriptions-item label="模块">
{{ detailRecord.module }}
</a-descriptions-item>
<a-descriptions-item label="操作人">
{{ detailRecord.operator }}
</a-descriptions-item>
<a-descriptions-item label="IP 地址">
{{ detailRecord.ip }}
</a-descriptions-item>
<a-descriptions-item label="操作时间">
{{ detailRecord.createdAt }}
</a-descriptions-item>
<a-descriptions-item label="请求 ID">
{{ detailRecord.requestId }}
</a-descriptions-item>
<a-descriptions-item label="日志内容">
<div class="detail-content">{{ detailRecord.content }}</div>
</a-descriptions-item>
</a-descriptions>
</template>
</a-drawer>
</div>
</template>
@@ -50,7 +82,6 @@ import { Message } from '@arco-design/web-vue'
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface'
import type { FormItem } from '@/components/search-form/types'
// 定义表格数据类型
interface LogRecord {
id: number
level: string
@@ -59,32 +90,42 @@ interface LogRecord {
operator: string
ip: string
createdAt: string
/** 用于时间范围筛选(毫秒时间戳) */
timestamp: number
requestId: string
}
// 模拟数据生成
const generateMockData = (count: number): LogRecord[] => {
const levels = ['INFO', 'WARN', 'ERROR', 'DEBUG']
const modules = ['用户管理', '权限管理', '系统配置', '数据备份', '登录认证']
const operators = ['管理员', '张三', '李四', '系统', '定时任务']
return Array.from({ length: count }, (_, i) => ({
id: i + 1,
level: levels[i % levels.length],
module: modules[i % modules.length],
content: `日志内容描述 ${i + 1}`,
operator: operators[i % operators.length],
ip: `192.168.${Math.floor(i / 255)}.${i % 255}`,
createdAt: new Date(Date.now() - i * 3600000).toLocaleString('zh-CN'),
}))
return Array.from({ length: count }, (_, i) => {
const timestamp = Date.now() - i * 3600000
return {
id: i + 1,
level: levels[i % levels.length],
module: modules[i % modules.length],
content: `日志内容描述 ${i + 1}:系统执行例行检查与状态同步。`,
operator: operators[i % operators.length],
ip: `192.168.${Math.floor(i / 255) % 256}.${i % 256}`,
createdAt: new Date(timestamp).toLocaleString('zh-CN'),
timestamp,
requestId: `req-${10000 + i}`,
}
})
}
// 状态管理
const loading = ref(false)
const tableData = ref<LogRecord[]>([])
const allFilteredData = ref<LogRecord[]>([])
const formModel = ref({
level: '',
module: '',
operator: '',
keyword: '',
dateRange: [] as unknown[],
})
const pagination = reactive({
@@ -93,7 +134,9 @@ const pagination = reactive({
total: 0,
})
// 表单项配置
const detailVisible = ref(false)
const detailRecord = ref<LogRecord | null>(null)
const formItems = computed<FormItem[]>(() => [
{
field: 'level',
@@ -126,9 +169,21 @@ const formItems = computed<FormItem[]>(() => [
type: 'input',
placeholder: '请输入操作人',
},
{
field: 'keyword',
label: '关键词',
type: 'input',
placeholder: '搜索日志内容',
},
{
field: 'dateRange',
label: '时间范围',
type: 'dateRange',
placeholder: '选择时间范围',
span: 16,
},
])
// 表格列配置
const columns = computed<TableColumnData[]>(() => [
{
title: '序号',
@@ -177,7 +232,6 @@ const columns = computed<TableColumnData[]>(() => [
},
])
// 获取日志级别颜色
const getLevelColor = (level: string) => {
const colorMap: Record<string, string> = {
INFO: 'arcoblue',
@@ -188,38 +242,54 @@ const getLevelColor = (level: string) => {
return colorMap[level] || 'gray'
}
// 模拟异步获取数据
const fetchData = async () => {
loading.value = true
function applyFilters(source: LogRecord[]): LogRecord[] {
let data = source
const f = formModel.value
// 模拟网络延迟
await new Promise(resolve => setTimeout(resolve, 500))
let data = generateMockData(100)
// 根据搜索条件过滤
if (formModel.value.level) {
data = data.filter(item => item.level === formModel.value.level)
if (f.level) {
data = data.filter(item => item.level === f.level)
}
if (formModel.value.module) {
data = data.filter(item => item.module === formModel.value.module)
if (f.module) {
data = data.filter(item => item.module === f.module)
}
if (formModel.value.operator) {
data = data.filter(item => item.operator.includes(formModel.value.operator))
if (f.operator) {
data = data.filter(item => item.operator.includes(f.operator))
}
if (f.keyword?.trim()) {
const kw = f.keyword.trim()
data = data.filter(item => item.content.includes(kw))
}
if (f.dateRange && f.dateRange.length === 2) {
const [start, end] = f.dateRange
const startMs = new Date(start as string | Date).getTime()
const endMs = new Date(end as string | Date).getTime()
if (!Number.isNaN(startMs) && !Number.isNaN(endMs)) {
data = data.filter(item => item.timestamp >= startMs && item.timestamp <= endMs)
}
}
// 更新分页
pagination.total = data.length
return data
}
// 分页截取
function slicePage(data: LogRecord[]) {
const start = (pagination.current - 1) * pagination.pageSize
const end = start + pagination.pageSize
tableData.value = data.slice(start, end)
}
const fetchData = async () => {
loading.value = true
await new Promise(resolve => setTimeout(resolve, 400))
const base = generateMockData(100)
const filtered = applyFilters(base)
allFilteredData.value = filtered
pagination.total = filtered.length
slicePage(filtered)
loading.value = false
}
// 事件处理
const handleSearch = () => {
pagination.current = 1
fetchData()
@@ -230,6 +300,8 @@ const handleReset = () => {
level: '',
module: '',
operator: '',
keyword: '',
dateRange: [],
}
pagination.current = 1
fetchData()
@@ -237,7 +309,7 @@ const handleReset = () => {
const handlePageChange = (current: number) => {
pagination.current = current
fetchData()
slicePage(allFilteredData.value)
}
const handleRefresh = () => {
@@ -250,10 +322,10 @@ const handleDownload = () => {
}
const handleView = (record: LogRecord) => {
Message.info(`查看日志详情:${record.id}`)
detailRecord.value = record
detailVisible.value = true
}
// 初始化加载数据
fetchData()
</script>
@@ -267,4 +339,11 @@ export default {
.container {
padding: 0 20px 20px 20px;
}
.detail-content {
white-space: pre-wrap;
word-break: break-word;
line-height: 1.6;
color: var(--color-text-1);
}
</style>