Files
assist/frontend/src/stores/useAlertStore.ts

287 lines
6.9 KiB
TypeScript

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import axios from 'axios'
export interface Alert {
id: number
rule_name: string
message: string
level: 'critical' | 'error' | 'warning' | 'info'
alert_type: 'performance' | 'quality' | 'volume' | 'system' | 'business'
data?: any
created_at: string
resolved_at?: string
status: 'active' | 'resolved'
}
export interface AlertRule {
name: string
description?: string
alert_type: 'performance' | 'quality' | 'volume' | 'system' | 'business'
level: 'critical' | 'error' | 'warning' | 'info'
threshold: number
condition: string
enabled: boolean
check_interval: number
cooldown: number
}
export interface SystemHealth {
health_score: number
status: 'excellent' | 'good' | 'fair' | 'poor' | 'critical' | 'unknown'
details?: any
}
export interface MonitorStatus {
monitor_status: 'running' | 'stopped' | 'unknown'
}
export const useAlertStore = defineStore('alert', () => {
// 状态
const alerts = ref<Alert[]>([])
const rules = ref<AlertRule[]>([])
const health = ref<SystemHealth>({ health_score: 0, status: 'unknown' })
const monitorStatus = ref<MonitorStatus>({ monitor_status: 'unknown' })
const loading = ref(false)
const alertFilter = ref('all')
const alertSort = ref('time-desc')
// 计算属性
const filteredAlerts = computed(() => {
let filtered = alerts.value
// 应用过滤
if (alertFilter.value !== 'all') {
filtered = filtered.filter(alert => alert.level === alertFilter.value)
}
// 应用排序
filtered.sort((a, b) => {
switch (alertSort.value) {
case 'time-desc':
return new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
case 'time-asc':
return new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
case 'level-desc':
const levelOrder = { 'critical': 4, 'error': 3, 'warning': 2, 'info': 1 }
return (levelOrder[b.level] || 0) - (levelOrder[a.level] || 0)
case 'level-asc':
const levelOrderAsc = { 'critical': 4, 'error': 3, 'warning': 2, 'info': 1 }
return (levelOrderAsc[a.level] || 0) - (levelOrderAsc[b.level] || 0)
default:
return 0
}
})
return filtered
})
const alertStatistics = computed(() => {
const stats = alerts.value.reduce((acc, alert) => {
acc[alert.level] = (acc[alert.level] || 0) + 1
acc.total = (acc.total || 0) + 1
return acc
}, {} as Record<string, number>)
return {
critical: stats.critical || 0,
warning: stats.warning || 0,
info: stats.info || 0,
total: stats.total || 0
}
})
// 动作
const loadAlerts = async () => {
try {
loading.value = true
const response = await axios.get('/api/alerts')
alerts.value = response.data
} catch (error) {
console.error('加载预警失败:', error)
throw error
} finally {
loading.value = false
}
}
const loadRules = async () => {
try {
loading.value = true
const response = await axios.get('/api/rules')
rules.value = response.data
} catch (error) {
console.error('加载规则失败:', error)
throw error
} finally {
loading.value = false
}
}
const loadHealth = async () => {
try {
const response = await axios.get('/api/health')
health.value = response.data
} catch (error) {
console.error('加载健康状态失败:', error)
throw error
}
}
const loadMonitorStatus = async () => {
try {
const response = await axios.get('/api/monitor/status')
monitorStatus.value = response.data
} catch (error) {
console.error('加载监控状态失败:', error)
throw error
}
}
const startMonitoring = async () => {
try {
const response = await axios.post('/api/monitor/start')
if (response.data.success) {
await loadMonitorStatus()
return true
}
return false
} catch (error) {
console.error('启动监控失败:', error)
throw error
}
}
const stopMonitoring = async () => {
try {
const response = await axios.post('/api/monitor/stop')
if (response.data.success) {
await loadMonitorStatus()
return true
}
return false
} catch (error) {
console.error('停止监控失败:', error)
throw error
}
}
const checkAlerts = async () => {
try {
const response = await axios.post('/api/check-alerts')
if (response.data.success) {
await loadAlerts()
return response.data.count
}
return 0
} catch (error) {
console.error('检查预警失败:', error)
throw error
}
}
const resolveAlert = async (alertId: number) => {
try {
const response = await axios.post(`/api/alerts/${alertId}/resolve`)
if (response.data.success) {
await loadAlerts()
return true
}
return false
} catch (error) {
console.error('解决预警失败:', error)
throw error
}
}
const createRule = async (rule: Omit<AlertRule, 'name'> & { name: string }) => {
try {
const response = await axios.post('/api/rules', rule)
if (response.data.success) {
await loadRules()
return true
}
return false
} catch (error) {
console.error('创建规则失败:', error)
throw error
}
}
const updateRule = async (originalName: string, rule: AlertRule) => {
try {
const response = await axios.put(`/api/rules/${originalName}`, rule)
if (response.data.success) {
await loadRules()
return true
}
return false
} catch (error) {
console.error('更新规则失败:', error)
throw error
}
}
const deleteRule = async (ruleName: string) => {
try {
const response = await axios.delete(`/api/rules/${ruleName}`)
if (response.data.success) {
await loadRules()
return true
}
return false
} catch (error) {
console.error('删除规则失败:', error)
throw error
}
}
const setAlertFilter = (filter: string) => {
alertFilter.value = filter
}
const setAlertSort = (sort: string) => {
alertSort.value = sort
}
const loadInitialData = async () => {
await Promise.all([
loadHealth(),
loadAlerts(),
loadRules(),
loadMonitorStatus()
])
}
return {
// 状态
alerts,
rules,
health,
monitorStatus,
loading,
alertFilter,
alertSort,
// 计算属性
filteredAlerts,
alertStatistics,
// 动作
loadAlerts,
loadRules,
loadHealth,
loadMonitorStatus,
startMonitoring,
stopMonitoring,
checkAlerts,
resolveAlert,
createRule,
updateRule,
deleteRule,
setAlertFilter,
setAlertSort,
loadInitialData
}
})