import { qs, escapeHtml, STATUS_LABELS, classLabel, formatDate, enabledChannelNames } from "../modules/dom.js"; import { apiFetch } from "../modules/api.js"; import { showToast, setServiceStatus } from "../modules/ui.js"; import { renderTrend } from "../modules/charts.js"; import { store } from "../modules/store.js"; import { loadDashboard } from "./dashboard.js"; let eventFilter = ""; export async function loadEvents() { try { const query = eventFilter ? `?status=${eventFilter}` : ""; const result = await apiFetch(`/api/events${query}`); store.eventData = result.events || []; renderEventTable(store.eventData); updateEventSummary(result.summary); renderTrend(store.eventData); setServiceStatus(true); } catch (error) { setServiceStatus(false); showToast(`无法读取告警事件:${error.message}`, "error"); } } function updateEventSummary(summary) { qs("#allEventsCount").textContent = String(summary.total); qs("#pendingEventsCount").textContent = String(summary.pending); qs("#ackEventsCount").textContent = String(summary.acknowledged); qs("#resolvedEventsCount").textContent = String(summary.resolved); qs("#pendingNavCount").textContent = String(summary.pending); qs("#notificationDot").hidden = summary.pending === 0; } function renderEventTable(events) { qs("#eventTableMeta").textContent = `${events.length} 条记录`; if (!events.length) { qs("#eventTableBody").innerHTML = '当前筛选条件下暂无告警事件'; return; } qs("#eventTableBody").innerHTML = events.map((event) => { const classes = (event.classes || []) .map((name) => `${classLabel(name)}`) .join(" "); const channels = enabledChannelNames(event.notification_channels).join(" + ") || "未发送"; const statusLabel = STATUS_LABELS[event.status] || escapeHtml(event.status); return `${escapeHtml(event.id)}${formatDate(event.created_at)}${classes}${Math.round(event.max_confidence * 100)}%${channels}${statusLabel}
${event.status === "pending" ? `` : ""}${event.status !== "resolved" ? `` : ""}
`; }).join(""); } export async function updateEventStatus(eventId, status) { try { await apiFetch(`/api/events/${encodeURIComponent(eventId)}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ status }), }); showToast(`事件 ${eventId} 已更新为${STATUS_LABELS[status]}`, "success"); await Promise.all([loadEvents(), loadDashboard()]); } catch (error) { showToast(`事件更新失败:${error.message}`, "error"); } } export function initEvents() { qs("#refreshEventsButton").addEventListener("click", loadEvents); qs("#eventTableBody").addEventListener("click", (event) => { const button = event.target.closest("[data-event-id]"); if (button) updateEventStatus(button.dataset.eventId, button.dataset.eventStatus); }); document.querySelectorAll("[data-event-filter]").forEach((button) => { button.addEventListener("click", () => { eventFilter = button.dataset.eventFilter; document.querySelectorAll("[data-event-filter]").forEach((item) => item.classList.toggle("is-active", item === button)); loadEvents(); }); }); }