// Filename: frontend/js/pages/logs/index.js import { apiFetchJson } from '../../services/api.js'; import LogList from './logList.js'; // [最终版] 创建一个共享的数据仓库,用于缓存 Groups 和 Keys const dataStore = { groups: new Map(), keys: new Map(), }; class LogsPage { constructor() { this.state = { logs: [], pagination: { page: 1, pages: 1, total: 0, page_size: 20 }, isLoading: true, filters: { page: 1, page_size: 20 } }; this.elements = { tableBody: document.getElementById('logs-table-body'), }; this.initialized = !!this.elements.tableBody; if (this.initialized) { this.logList = new LogList(this.elements.tableBody, dataStore); } } async init() { if (!this.initialized) return; this.initEventListeners(); // 页面初始化:先加载群组,再加载日志 await this.loadGroupsOnce(); await this.loadAndRenderLogs(); } initEventListeners() { /* 分页和筛选的事件监听器 */ } async loadGroupsOnce() { if (dataStore.groups.size > 0) return; // 防止重复加载 try { const { success, data } = await apiFetchJson("/admin/keygroups"); if (success && Array.isArray(data)) { data.forEach(group => dataStore.groups.set(group.id, group)); } } catch (error) { console.error("Failed to load key groups:", error); } } async loadAndRenderLogs() { this.state.isLoading = true; this.logList.renderLoading(); try { const query = new URLSearchParams(this.state.filters); const { success, data } = await apiFetchJson(`/admin/logs?${query.toString()}`); if (success && typeof data === 'object') { const { items, total, page, page_size } = data; this.state.logs = items; this.state.pagination = { page, page_size, total, pages: Math.ceil(total / page_size) }; // [核心] 在渲染前,按需批量加载本页日志所需的、尚未缓存的Key信息 await this.enrichLogsWithKeyNames(items); // 调用 render,此时 dataStore 中已包含所有需要的数据 this.logList.render(this.state.logs, this.state.pagination); } else { this.logList.render([], this.state.pagination); } } catch (error) { console.error("Failed to load logs:", error); this.logList.render([], this.state.pagination); } finally { this.state.isLoading = false; } } async enrichLogsWithKeyNames(logs) { const missingKeyIds = [...new Set( logs.filter(log => log.KeyID && !dataStore.keys.has(log.KeyID)).map(log => log.KeyID) )]; if (missingKeyIds.length === 0) return; try { const idsQuery = missingKeyIds.join(','); const { success, data } = await apiFetchJson(`/admin/apikeys?ids=${idsQuery}`); if (success && Array.isArray(data)) { data.forEach(key => dataStore.keys.set(key.ID, key)); } } catch (error) { console.error(`Failed to fetch key details:`, error); } } } export default function() { const page = new LogsPage(); page.init(); }