feat: 展示真实运维审计日志
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { Refresh } from '@element-plus/icons-vue'
|
||||
import StatusPill from '../components/StatusPill.vue'
|
||||
import { usePlatformStore } from '../stores/platform'
|
||||
import type { AuditLogEntry } from '../types/devops'
|
||||
import type { IntegrationConfigState } from '../types/devops'
|
||||
|
||||
const platform = usePlatformStore()
|
||||
@@ -43,6 +45,26 @@ function formatCheckedAt(value: string): string {
|
||||
minute: '2-digit',
|
||||
}).format(date)
|
||||
}
|
||||
|
||||
function auditActor(record: AuditLogEntry): string {
|
||||
return record.actorName || record.actorId || '-'
|
||||
}
|
||||
|
||||
function auditResource(record: AuditLogEntry): string {
|
||||
return record.resourceId
|
||||
? `${record.resourceType} / ${record.resourceId}`
|
||||
: record.resourceType
|
||||
}
|
||||
|
||||
function auditDigest(record: AuditLogEntry): string {
|
||||
const payload = record.after ?? record.parameterDigest ?? record.before
|
||||
|
||||
if (!payload) {
|
||||
return '-'
|
||||
}
|
||||
|
||||
return JSON.stringify(payload)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -158,6 +180,45 @@ function formatCheckedAt(value: string): string {
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section class="panel">
|
||||
<div class="panel-header">
|
||||
<h2>最近运维审计</h2>
|
||||
<ElButton :icon="Refresh" size="small" @click="platform.loadAuditLogs()">
|
||||
刷新
|
||||
</ElButton>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ElTable :data="platform.auditLogs" border>
|
||||
<ElTableColumn label="时间" min-width="150">
|
||||
<template #default="{ row }">
|
||||
{{ formatCheckedAt(row.createdAt) }}
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn prop="action" label="动作" min-width="220" />
|
||||
<ElTableColumn label="资源" min-width="220">
|
||||
<template #default="{ row }">
|
||||
<span class="mono">{{ auditResource(row) }}</span>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="操作者" min-width="130">
|
||||
<template #default="{ row }">
|
||||
{{ auditActor(row) }}
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="脱敏摘要" min-width="280">
|
||||
<template #default="{ row }">
|
||||
<span class="audit-digest">{{ auditDigest(row) }}</span>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
</ElTable>
|
||||
<ElEmpty
|
||||
v-if="platform.auditLogs.length === 0"
|
||||
description="暂无审计记录"
|
||||
:image-size="72"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<div class="panel-header">
|
||||
<h2>前端环境变量</h2>
|
||||
@@ -279,6 +340,17 @@ function formatCheckedAt(value: string): string {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.audit-digest {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
color: #4b5565;
|
||||
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', monospace;
|
||||
font-size: 12px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 1080px) {
|
||||
.variable-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
|
||||
Reference in New Issue
Block a user