feat: 自动提交 - 周一 2025/09/22 15:12:38.91
This commit is contained in:
286
frontend/src/stores/useAlertStore.ts
Normal file
286
frontend/src/stores/useAlertStore.ts
Normal file
@@ -0,0 +1,286 @@
|
||||
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
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user