/** * 内容审计日志组件 * 展示敏感词命中记录,支持分页浏览 */ import { listAuditLogs } from '../js/api.js' import { toast } from '../js/utils.js' export default { template: `

📋 内容审计日志

记录所有敏感词命中事件,包含输入/输出方向、违规内容、命中词及处理方式。

时间 方向 违规内容 命中词 处理方式
加载中...
暂无审计日志
{{ formatTime(log.createTime) }} {{ log.direction === 'INPUT' ? '输入' : '输出' }} {{ log.originalText }} {{ formatHitWords(log.hitWords) }} {{ log.actionTaken === 'BLOCK' ? '拦截' : log.actionTaken === 'MASK' ? '脱敏' : '通过' }}
第 {{ page }} / {{ Math.ceil(total / pageSize) }} 页(共 {{ total }} 条)
`, data() { return { logs: [], loading: false, page: 1, pageSize: 30, total: 0 } }, mounted() { this.loadLogs() }, methods: { async loadLogs() { this.loading = true try { const res = await listAuditLogs(this.page, this.pageSize) if (res.success) { this.logs = res.data?.records || res.data || [] this.total = res.data?.total || 0 } else { toast('加载审计日志失败: ' + (res.message || '未知错误'), 'error') } } catch (e) { toast('加载审计日志失败: ' + e.message, 'error') } this.loading = false }, formatTime(t) { return t ? new Date(t).toLocaleString('zh-CN') : '' }, formatHitWords(hw) { if (!hw) return '' if (hw.type === 'jsonb' && hw.value) { try { hw = JSON.parse(hw.value) } catch { return hw.value } } if (typeof hw === 'string') { try { hw = JSON.parse(hw) } catch { return hw } } if (hw && hw.hits && Array.isArray(hw.hits)) { return hw.hits.map(h => `${h.word || ''}(${h.category || ''})`).join('、') } if (Array.isArray(hw)) return hw.map(h => typeof h === 'string' ? h : h.word || '').join('、') return String(hw) } } }