feat: improve polling recovery and session cleanup

This commit is contained in:
2026-04-27 20:33:12 +08:00
parent ca2c559555
commit 89ba4163fc
22 changed files with 442 additions and 75 deletions
+50 -5
View File
@@ -1,10 +1,12 @@
<script setup lang="ts">
import { computed, onMounted, reactive, ref } from "vue";
import { computed, onBeforeUnmount, onMounted, reactive, ref } from "vue";
import apiClient, { getApiErrorMessage } from "@/api/client";
import { useViewport } from "@/composables/useViewport";
import type { SystemLog } from "@/types";
import { logLevelLabelMap } from "@/types";
const AUTO_REFRESH_INTERVAL_MS = 15000;
const loading = ref(false);
const logs = ref<SystemLog[]>([]);
const loadError = ref("");
@@ -26,7 +28,13 @@ const totalWarnings = computed(() => logs.value.filter((item) => item.level ===
const totalErrors = computed(() => logs.value.filter((item) => item.level === 3).length);
const newestLogTime = computed(() => (logs.value[0] ? formatDate(logs.value[0].createdAt) : "-"));
let autoRefreshTimer: number | null = null;
async function loadLogs() {
if (loading.value) {
return;
}
loading.value = true;
loadError.value = "";
@@ -48,6 +56,34 @@ async function loadLogs() {
}
}
async function autoRefreshLogs() {
if (document.visibilityState !== "visible") {
return;
}
await loadLogs();
}
function startAutoRefresh() {
stopAutoRefresh();
autoRefreshTimer = window.setInterval(() => {
void autoRefreshLogs();
}, AUTO_REFRESH_INTERVAL_MS);
}
function stopAutoRefresh() {
if (autoRefreshTimer !== null) {
window.clearInterval(autoRefreshTimer);
autoRefreshTimer = null;
}
}
function handleVisibilityChange() {
if (document.visibilityState === "visible") {
void autoRefreshLogs();
}
}
function levelTagType(level: number) {
if (level === 3) {
return "danger";
@@ -64,7 +100,16 @@ function formatDate(value?: string) {
return value ? new Date(value).toLocaleString() : "-";
}
onMounted(loadLogs);
onMounted(async () => {
await loadLogs();
startAutoRefresh();
document.addEventListener("visibilitychange", handleVisibilityChange);
});
onBeforeUnmount(() => {
stopAutoRefresh();
document.removeEventListener("visibilitychange", handleVisibilityChange);
});
</script>
<template>
@@ -74,7 +119,7 @@ onMounted(loadLogs);
<div class="page-kicker">排障中心</div>
<h1 class="page-title">系统日志</h1>
<p class="page-subtitle">
面向排障的原始事件流这里保留最近发生的关键日志可以按直播间任务和级别快速缩范围
面向排障的原始事件流这里保留最近发生的关键日志可以按直播间任务和级别快速缩范围
</p>
</div>
@@ -103,7 +148,7 @@ onMounted(loadLogs);
</div>
<div class="stat-card">
<div class="stat-card__label">最新事件</div>
<div class="stat-card__value" style="font-size: 18px; letter-spacing: -0.03em;">{{ newestLogTime }}</div>
<div class="stat-card__value" style="font-size: 18px;">{{ newestLogTime }}</div>
<div class="stat-card__hint">默认按时间倒序优先展示最近发生的事件</div>
</div>
</div>
@@ -146,7 +191,7 @@ onMounted(loadLogs);
<div class="toolbar-row">
<div>
<h3 class="section-title">日志列表</h3>
<p class="section-subtitle">桌面端保留高密度表格移动端成事件卡片便于单手排查</p>
<p class="section-subtitle">页面会自动刷新移动端成事件卡片桌面端保留高密度表格</p>
</div>
</div>