fix: 优化历史详情日志查看

This commit is contained in:
2026-05-18 16:54:44 +08:00
parent f7233da3b8
commit 47a296e414
3 changed files with 126 additions and 4 deletions
+71 -3
View File
@@ -63,8 +63,20 @@
</div>
<div>
<div class="section-label">处理日志</div>
<n-log :log="detail.logs.join('\n') || '暂无日志'" language="text" trim class="log-panel" />
<div class="section-label log-section-header">
<span>处理日志</span>
<n-button size="small" tertiary circle title="复制日志" :disabled="!detailLogText" @click="copyDetailLogs">
<template #icon><n-icon><CopyOutline /></n-icon></template>
</n-button>
</div>
<div class="colored-log-panel" role="log" aria-label="处理日志">
<pre class="colored-log-content"><span
v-for="(line, index) in detailLogLines"
:key="index"
class="colored-log-line"
:class="`log-level-${line.level}`"
>{{ line.text }}</span></pre>
</div>
</div>
</n-space>
</n-modal>
@@ -74,12 +86,14 @@
<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
import { useDialog, useMessage } from 'naive-ui';
import { FileTrayOutline, RefreshOutline, TrashOutline } from '@vicons/ionicons5';
import { CopyOutline, FileTrayOutline, RefreshOutline, TrashOutline } from '@vicons/ionicons5';
import { apiGet, apiPost } from '../api/client';
import type { CacheSize, HistoryDetail, HistoryRecord } from '../types';
import { resetPageHeader, setPageHeader } from '../composables/pageHeader';
type LogLevel = 'default' | 'info' | 'success' | 'warning' | 'error';
const message = useMessage();
const dialog = useDialog();
const records = ref<HistoryRecord[]>([]);
@@ -93,6 +107,14 @@ let recordSizeToken = 0;
const totalSizeText = computed(() => `总占用: ${cacheSize.value?.size_formatted || '计算中...'}`);
const hasRecords = computed(() => records.value.length > 0);
const detailLogText = computed(() => detail.value?.logs?.join('\n') || '');
const detailLogLines = computed(() => {
const lines = detailLogText.value ? detailLogText.value.split(/\r?\n/) : ['暂无日志'];
return lines.map(line => ({
text: line,
level: resolveLogLevel(line)
}));
});
onMounted(() => {
setPageHeader({
@@ -164,6 +186,52 @@ async function loadRecordSize(recordId: string) {
}
}
async function copyDetailLogs() {
if (!detailLogText.value) {
message.warning('暂无可复制日志');
return;
}
try {
await writeClipboardText(detailLogText.value);
message.success('日志已复制');
} catch {
message.error('复制日志失败');
}
}
async function writeClipboardText(text: string) {
if (navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(text);
return;
}
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.setAttribute('readonly', 'true');
textarea.style.position = 'fixed';
textarea.style.top = '-1000px';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
try {
if (!document.execCommand('copy')) {
throw new Error('copy failed');
}
} finally {
document.body.removeChild(textarea);
}
}
function resolveLogLevel(line: string): LogLevel {
if (/\b(ERROR|FAILED|FAILURE)\b|错误|失败/i.test(line)) return 'error';
if (/\b(WARN|WARNING)\b|警告/i.test(line)) return 'warning';
if (/\b(SUCCESS|SUCCEEDED|COMPLETED)\b|成功|完成/i.test(line)) return 'success';
if (/\bINFO\b|信息/i.test(line)) return 'info';
return 'default';
}
function confirmDelete(recordId: string) {
dialog.warning({
title: '删除历史记录',
+48 -1
View File
@@ -1002,7 +1002,54 @@ select {
color: var(--td-error-color);
}
.log-panel,
.log-section-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.colored-log-panel {
height: 360px;
overflow: scroll;
padding: 12px;
color: #d7dde7;
background: #111820;
border-radius: var(--td-radius-default);
}
.colored-log-content {
display: block;
min-width: max-content;
margin: 0;
font-family: var(--td-font-family-mono);
font-size: 13px;
line-height: 1.7;
white-space: pre;
}
.colored-log-line {
display: block;
color: #d7dde7;
white-space: pre;
}
.colored-log-line.log-level-info {
color: #62a8ff;
}
.colored-log-line.log-level-success {
color: #38d996;
}
.colored-log-line.log-level-warning {
color: #f6c453;
}
.colored-log-line.log-level-error {
color: #ff6b7a;
}
.script-log {
min-height: 320px;
padding: 12px;