/** * 预警管理页面组件 */ import { api } from '../core/api.js'; import { formatDate, formatRelativeTime } from '../core/utils.js'; import { confirm, alert } from '../components/modal.js'; import store from '../core/store.js'; export default class Alerts { constructor(container, route) { this.container = container; this.route = route; this.filters = { level: '', status: '', type: '', page: 1, per_page: 10 }; this.init(); } async init() { try { this.render(); await this.loadData(); this.bindEvents(); } catch (error) { console.error('Alerts page init error:', error); this.showError(error); } } render() { this.container.innerHTML = `
0
严重预警
0
警告预警
0
信息预警
0
总预警数
监控控制
监控状态: 检查中...
预警规则
规则名称 类型 级别 阈值 状态 操作
预警历史
时间 级别 规则 消息 状态 操作
`; // 渲染规则模态框 this.renderRuleModal(); } renderRuleModal() { const modalHTML = ` `; document.body.insertAdjacentHTML('beforeend', modalHTML); } async loadData() { try { // 并行加载数据 const [alertsRes, rulesRes, statistics, monitorStatus] = await Promise.all([ api.alerts.list(this.filters), api.rules.list(), api.alerts.statistics(), api.monitor.status() ]); // 更新统计数据 this.updateStatistics(statistics); // 更新监控状态 this.updateMonitorStatus(monitorStatus); // 更新规则列表 this.updateRulesList(rulesRes); // 更新预警列表 this.updateAlertsList(alertsRes); } catch (error) { console.error('Load alerts data error:', error); this.showError(error); } } updateStatistics(statistics) { document.getElementById('critical-alerts').textContent = statistics.critical || 0; document.getElementById('warning-alerts').textContent = statistics.warning || 0; document.getElementById('info-alerts').textContent = statistics.info || 0; document.getElementById('total-alerts').textContent = statistics.total || 0; } updateMonitorStatus(status) { const statusEl = document.getElementById('monitor-status'); const textEl = document.getElementById('monitor-text'); if (status.status === 'running') { statusEl.className = 'status-indicator online'; textEl.textContent = '监控运行中'; } else { statusEl.className = 'status-indicator offline'; textEl.textContent = '监控已停止'; } } updateRulesList(rules) { const tbody = document.getElementById('rules-table'); if (!tbody) return; if (!rules || rules.length === 0) { tbody.innerHTML = ` 暂无预警规则 `; return; } tbody.innerHTML = rules.map(rule => ` ${rule.name} ${rule.alert_type} ${rule.level} ${rule.threshold} ${rule.enabled ? '启用' : '禁用'}
`).join(''); } updateAlertsList(response) { const tbody = document.getElementById('alerts-table'); if (!tbody) return; const alerts = response.alerts || []; if (alerts.length === 0) { tbody.innerHTML = ` 暂无预警记录 `; return; } tbody.innerHTML = alerts.map(alert => ` ${formatDate(alert.created_at, 'MM-DD HH:mm')} ${alert.level} ${alert.rule_name} ${alert.message} ${alert.is_active ? '活跃' : '已解决'} ${alert.is_active ? ` ` : '-'} `).join(''); // 更新分页 this.updatePagination(response); } updatePagination(response) { const pagination = document.getElementById('pagination'); if (!pagination) return; const { page = 1, total_pages = 1 } = response; if (total_pages <= 1) { pagination.innerHTML = ''; return; } let html = ''; // 上一页 if (page > 1) { html += `
  • 上一页
  • `; } // 页码 for (let i = Math.max(1, page - 2); i <= Math.min(total_pages, page + 2); i++) { html += `
  • ${i}
  • `; } // 下一页 if (page < total_pages) { html += `
  • 下一页
  • `; } pagination.innerHTML = html; } getLevelColor(level) { const colors = { 'critical': 'danger', 'error': 'danger', 'warning': 'warning', 'info': 'info' }; return colors[level] || 'secondary'; } bindEvents() { // 监控控制 document.getElementById('start-monitor')?.addEventListener('click', () => { this.startMonitor(); }); document.getElementById('stop-monitor')?.addEventListener('click', () => { this.stopMonitor(); }); document.getElementById('check-alerts')?.addEventListener('click', () => { this.checkAlerts(); }); // 规则表单 document.getElementById('save-rule')?.addEventListener('click', () => { this.saveRule(); }); // 筛选器 document.getElementById('filter-level')?.addEventListener('change', (e) => { this.filters.level = e.target.value; this.filters.page = 1; this.loadAlerts(); }); document.getElementById('filter-status')?.addEventListener('change', (e) => { this.filters.status = e.target.value === 'active' ? 'active' : e.target.value === 'resolved' ? 'resolved' : ''; this.filters.page = 1; this.loadAlerts(); }); document.getElementById('filter-search')?.addEventListener('input', this.debounce((e) => { this.filters.search = e.target.value; this.filters.page = 1; this.loadAlerts(); }, 300) ); document.getElementById('reset-filters')?.addEventListener('click', () => { this.resetFilters(); }); // 分页 document.getElementById('pagination')?.addEventListener('click', (e) => { if (e.target.classList.contains('page-link')) { e.preventDefault(); const page = parseInt(e.target.dataset.page); if (page) { this.filters.page = page; this.loadAlerts(); } } }); } debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } async startMonitor() { try { await api.monitor.start(); await this.loadData(); store.dispatch('showToast', { type: 'success', message: '监控已启动' }); } catch (error) { console.error('Start monitor error:', error); store.dispatch('showToast', { type: 'error', message: '启动监控失败' }); } } async stopMonitor() { try { await api.monitor.stop(); await this.loadData(); store.dispatch('showToast', { type: 'success', message: '监控已停止' }); } catch (error) { console.error('Stop monitor error:', error); store.dispatch('showToast', { type: 'error', message: '停止监控失败' }); } } async checkAlerts() { try { const result = await api.monitor.checkAlerts(); await this.loadData(); store.dispatch('showToast', { type: 'success', message: `检查完成,发现 ${result.alerts_count || 0} 个新预警` }); } catch (error) { console.error('Check alerts error:', error); store.dispatch('showToast', { type: 'error', message: '检查预警失败' }); } } async saveRule() { const form = document.getElementById('rule-form'); const formData = new FormData(form); const data = { name: formData.get('name'), alert_type: formData.get('alert_type'), level: formData.get('level'), threshold: parseFloat(formData.get('threshold')), description: formData.get('description'), condition: formData.get('condition'), check_interval: parseInt(formData.get('check_interval')), cooldown: parseInt(formData.get('cooldown')), enabled: formData.has('enabled') }; try { await api.rules.create(data); await this.loadData(); // 关闭模态框 const modal = bootstrap.Modal.getInstance(document.getElementById('ruleModal')); modal.hide(); // 重置表单 form.reset(); store.dispatch('showToast', { type: 'success', message: '规则创建成功' }); } catch (error) { console.error('Save rule error:', error); store.dispatch('showToast', { type: 'error', message: '创建规则失败' }); } } async editRule(name) { // TODO: 实现编辑规则功能 store.dispatch('showToast', { type: 'info', message: '编辑功能开发中' }); } async deleteRule(name) { const confirmed = await confirm({ title: '删除规则', message: `确定要删除规则 "${name}" 吗?` }); if (!confirmed) return; try { await api.rules.delete(name); await this.loadData(); store.dispatch('showToast', { type: 'success', message: '规则已删除' }); } catch (error) { console.error('Delete rule error:', error); store.dispatch('showToast', { type: 'error', message: '删除规则失败' }); } } async resolveAlert(alertId) { try { await api.alerts.resolve(alertId, { resolved_by: 'admin', resolution: '手动解决' }); await this.loadAlerts(); store.dispatch('showToast', { type: 'success', message: '预警已解决' }); } catch (error) { console.error('Resolve alert error:', error); store.dispatch('showToast', { type: 'error', message: '解决预警失败' }); } } resetFilters() { this.filters = { level: '', status: '', search: '', page: 1, per_page: 10 }; // 重置筛选器UI document.getElementById('filter-level').value = ''; document.getElementById('filter-status').value = ''; document.getElementById('filter-search').value = ''; // 重新加载数据 this.loadAlerts(); } async loadAlerts() { try { const response = await api.alerts.list(this.filters); this.updateAlertsList(response); } catch (error) { console.error('Load alerts error:', error); } } showError(error) { this.container.innerHTML = ` `; } } // 暴露到全局供内联事件使用 window.alertsPage = null;