diff --git a/web/js/events.js b/web/js/events.js index d5d54f6..91c96b2 100644 --- a/web/js/events.js +++ b/web/js/events.js @@ -2,56 +2,80 @@ import { apiFetch } from "./api.js"; import { dom } from "./dom.js"; import { state } from "./state.js"; +const PAGE_SIZE = 10; + +let _page = 1; +let _hasMore = false; +let _loading = false; + function formatTime(value) { - if (!value) { - return "--"; - } - return value; + return value || "--"; } -export function renderEvents() { - dom.eventList.innerHTML = ""; - - if (!state.events.length) { - dom.eventList.innerHTML = '
暂无事件
'; - return; - } - - state.events.forEach((item) => { - const row = document.createElement("div"); - row.className = "event-card"; - row.innerHTML = `
${(item.level || "info").toUpperCase()}${formatTime(item.created_at)}${item.event_type}
${item.message}
`; - dom.eventList.appendChild(row); - }); +function makeCard(item) { + const row = document.createElement("div"); + row.className = "event-card"; + row.innerHTML = `
${(item.level || "info").toUpperCase()}${formatTime(item.created_at)}${item.event_type}
${item.message}
`; + return row; } -function matchesCurrentFilter(item) { - if (state.selectedUnitId && item.unit_id !== state.selectedUnitId) { - return false; - } - return true; -} +async function loadMore() { + if (_loading || !_hasMore) return; + _loading = true; -export function prependEvent(item) { - if (!matchesCurrentFilter(item)) { - return; - } + const params = new URLSearchParams({ page: String(_page), page_size: String(PAGE_SIZE) }); + if (state.selectedUnitId) params.set("unit_id", state.selectedUnitId); - state.events = [item, ...state.events.filter((existing) => existing.id !== item.id)].slice(0, 20); - renderEvents(); + try { + const response = await apiFetch(`/api/event?${params.toString()}`); + const items = response.data || []; + items.forEach((item) => dom.eventList.appendChild(makeCard(item))); + _hasMore = items.length === PAGE_SIZE; + _page += 1; + } finally { + _loading = false; + } } export async function loadEvents() { - const params = new URLSearchParams({ - page: "1", - page_size: "20", - }); + _page = 1; + _hasMore = false; + _loading = false; + dom.eventList.innerHTML = ""; - if (state.selectedUnitId) { - params.set("unit_id", state.selectedUnitId); + const params = new URLSearchParams({ page: "1", page_size: String(PAGE_SIZE) }); + if (state.selectedUnitId) params.set("unit_id", state.selectedUnitId); + + _loading = true; + try { + const response = await apiFetch(`/api/event?${params.toString()}`); + const items = response.data || []; + + if (!items.length) { + dom.eventList.innerHTML = '
暂无事件
'; + return; + } + + items.forEach((item) => dom.eventList.appendChild(makeCard(item))); + _hasMore = items.length === PAGE_SIZE; + _page = 2; + } finally { + _loading = false; } - - const response = await apiFetch(`/api/event?${params.toString()}`); - state.events = response.data || []; - renderEvents(); } + +export function prependEvent(item) { + if (state.selectedUnitId && item.unit_id !== state.selectedUnitId) return; + + const placeholder = dom.eventList.querySelector(".list-item"); + if (placeholder) placeholder.remove(); + + dom.eventList.insertBefore(makeCard(item), dom.eventList.firstChild); +} + +dom.eventList.addEventListener("scroll", () => { + const el = dom.eventList; + if (el.scrollTop + el.clientHeight >= el.scrollHeight - 40) { + loadMore(); + } +});