fix
This commit is contained in:
@@ -6,9 +6,11 @@ VITE_APP_WORKSPACE=ops
|
|||||||
# 应用标题
|
# 应用标题
|
||||||
VITE_APP_TITLE=标准管理系统
|
VITE_APP_TITLE=标准管理系统
|
||||||
VITE_APP_DESCRIPTION="default standard template"
|
VITE_APP_DESCRIPTION="default standard template"
|
||||||
|
VITE_USE_MOCK=false
|
||||||
|
|
||||||
# API 基础URL
|
# API 基础URL
|
||||||
VITE_API_BASE_URL=https://ops-api.apinb.com
|
# VITE_API_BASE_URL=https://ops-api.apinb.com
|
||||||
|
VITE_API_BASE_URL=http://127.0.0.1
|
||||||
|
|
||||||
# Logs 本地调试地址(仅 logs 模块使用)
|
# Logs 本地调试地址(仅 logs 模块使用)
|
||||||
VITE_LOGS_API_BASE_URL=http://127.0.0.1:12440
|
VITE_LOGS_API_BASE_URL=http://127.0.0.1:12440
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ VITE_APP_WORKSPACE=ops
|
|||||||
|
|
||||||
VITE_APP_TITLE=标准管理系统
|
VITE_APP_TITLE=标准管理系统
|
||||||
VITE_APP_DESCRIPTION="default standard template"
|
VITE_APP_DESCRIPTION="default standard template"
|
||||||
|
VITE_USE_MOCK=false
|
||||||
|
|
||||||
# API 基础URL
|
# API 基础URL
|
||||||
VITE_API_BASE_URL=https://ops-api.apinb.com
|
VITE_API_BASE_URL=https://ops-api.apinb.com
|
||||||
|
|||||||
17
src/api/ops/alertEvent.ts
Normal file
17
src/api/ops/alertEvent.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { request } from '@/api/request'
|
||||||
|
|
||||||
|
export const fetchAlertEvents = (data: {
|
||||||
|
page?: number
|
||||||
|
page_size?: number
|
||||||
|
alert_record_id?: number
|
||||||
|
event_type?: string
|
||||||
|
source?: string
|
||||||
|
severity?: string
|
||||||
|
start_time?: string
|
||||||
|
end_time?: string
|
||||||
|
keyword?: string
|
||||||
|
sort?: string
|
||||||
|
order?: string
|
||||||
|
}) => request.get('/Alert/v1/event/list', { params: data })
|
||||||
|
|
||||||
|
export const fetchAlertEventDetail = (id: number) => request.get(`/Alert/v1/event/get/${id}`)
|
||||||
@@ -5,7 +5,6 @@ import { createApp } from 'vue'
|
|||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import directive from './directive'
|
import directive from './directive'
|
||||||
import i18n from './locale'
|
import i18n from './locale'
|
||||||
import './mock'
|
|
||||||
import router from './router'
|
import router from './router'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
// Styles are imported via arco-plugin. See config/plugin/arcoStyleImport.ts in the directory for details
|
// Styles are imported via arco-plugin. See config/plugin/arcoStyleImport.ts in the directory for details
|
||||||
@@ -14,6 +13,10 @@ import store from './store'
|
|||||||
import '@/api/interceptor'
|
import '@/api/interceptor'
|
||||||
import '@/assets/style/global.less'
|
import '@/assets/style/global.less'
|
||||||
|
|
||||||
|
if (import.meta.env.VITE_USE_MOCK === 'true') {
|
||||||
|
import('./mock')
|
||||||
|
}
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|
||||||
app.use(ArcoVue, {})
|
app.use(ArcoVue, {})
|
||||||
|
|||||||
@@ -174,6 +174,20 @@
|
|||||||
</a-table>
|
</a-table>
|
||||||
<a-empty v-if="!processLoading && processRecords.length === 0" description="暂无处理记录" />
|
<a-empty v-if="!processLoading && processRecords.length === 0" description="暂无处理记录" />
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mt-4">
|
||||||
|
<div class="section-title">事件流水</div>
|
||||||
|
<a-table :data="eventRecords" :columns="eventColumns" :pagination="false" :loading="eventLoading" size="medium">
|
||||||
|
<template #event_type="{ record }">
|
||||||
|
<a-tag :color="getEventTypeColor(record.event_type)">
|
||||||
|
{{ getEventTypeText(record.event_type) }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
<template #occurred_at="{ record }">
|
||||||
|
{{ formatDateTime(record.occurred_at) }}
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
<a-empty v-if="!eventLoading && eventRecords.length === 0" description="暂无事件流水" />
|
||||||
|
</div>
|
||||||
</a-card>
|
</a-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -206,6 +220,7 @@ import { useRoute, useRouter } from 'vue-router'
|
|||||||
import { Message } from '@arco-design/web-vue'
|
import { Message } from '@arco-design/web-vue'
|
||||||
import { IconLeft, IconCheck, IconCheckCircle, IconMute, IconDown, IconUp } from '@arco-design/web-vue/es/icon'
|
import { IconLeft, IconCheck, IconCheckCircle, IconMute, IconDown, IconUp } from '@arco-design/web-vue/es/icon'
|
||||||
import { fetchAlertRecordDetail, fetchAlertProcessList } from '@/api/ops/alertRecord'
|
import { fetchAlertRecordDetail, fetchAlertProcessList } from '@/api/ops/alertRecord'
|
||||||
|
import { fetchAlertEvents } from '@/api/ops/alertEvent'
|
||||||
import AckDialog from '../tackle/components/AckDialog.vue'
|
import AckDialog from '../tackle/components/AckDialog.vue'
|
||||||
import ResolveDialog from '../tackle/components/ResolveDialog.vue'
|
import ResolveDialog from '../tackle/components/ResolveDialog.vue'
|
||||||
import SilenceDialog from '../tackle/components/SilenceDialog.vue'
|
import SilenceDialog from '../tackle/components/SilenceDialog.vue'
|
||||||
@@ -215,8 +230,10 @@ const router = useRouter()
|
|||||||
|
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const processLoading = ref(false)
|
const processLoading = ref(false)
|
||||||
|
const eventLoading = ref(false)
|
||||||
const record = ref<any>(null)
|
const record = ref<any>(null)
|
||||||
const processRecords = ref<any[]>([])
|
const processRecords = ref<any[]>([])
|
||||||
|
const eventRecords = ref<any[]>([])
|
||||||
const showRawData = ref(false)
|
const showRawData = ref(false)
|
||||||
|
|
||||||
// 对话框状态
|
// 对话框状态
|
||||||
@@ -277,6 +294,13 @@ const processColumns = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
// 加载详情
|
// 加载详情
|
||||||
|
const eventColumns = [
|
||||||
|
{ title: '时间', dataIndex: 'occurred_at', slotName: 'occurred_at', width: 180 },
|
||||||
|
{ title: '事件', dataIndex: 'event_type', slotName: 'event_type', width: 140 },
|
||||||
|
{ title: '来源', dataIndex: 'source', width: 120 },
|
||||||
|
{ title: '说明', dataIndex: 'message', ellipsis: true, tooltip: true },
|
||||||
|
]
|
||||||
|
|
||||||
const loadDetail = async () => {
|
const loadDetail = async () => {
|
||||||
if (!alertId.value) {
|
if (!alertId.value) {
|
||||||
Message.error('告警ID无效')
|
Message.error('告警ID无效')
|
||||||
@@ -315,6 +339,26 @@ const loadProcessRecords = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 返回
|
// 返回
|
||||||
|
const loadAlertEvents = async () => {
|
||||||
|
if (!alertId.value) return
|
||||||
|
|
||||||
|
eventLoading.value = true
|
||||||
|
try {
|
||||||
|
const result = await fetchAlertEvents({
|
||||||
|
alert_record_id: alertId.value,
|
||||||
|
page: 1,
|
||||||
|
page_size: 100,
|
||||||
|
sort: 'occurred_at',
|
||||||
|
order: 'desc',
|
||||||
|
})
|
||||||
|
eventRecords.value = result.details?.data || result.data || []
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载事件流水失败:', error)
|
||||||
|
} finally {
|
||||||
|
eventLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleGoBack = () => {
|
const handleGoBack = () => {
|
||||||
router.back()
|
router.back()
|
||||||
}
|
}
|
||||||
@@ -343,6 +387,7 @@ const handleSilence = () => {
|
|||||||
const handleActionSuccess = () => {
|
const handleActionSuccess = () => {
|
||||||
loadDetail()
|
loadDetail()
|
||||||
loadProcessRecords()
|
loadProcessRecords()
|
||||||
|
loadAlertEvents()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 切换原始数据显示
|
// 切换原始数据显示
|
||||||
@@ -454,9 +499,42 @@ const getActionText = (action: string) => {
|
|||||||
return textMap[action] || action
|
return textMap[action] || action
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getEventTypeColor = (eventType: string) => {
|
||||||
|
const colorMap: Record<string, string> = {
|
||||||
|
received: 'arcoblue',
|
||||||
|
notified: 'green',
|
||||||
|
ticket_created: 'purple',
|
||||||
|
ticket_create_failed: 'red',
|
||||||
|
policy_load_failed: 'red',
|
||||||
|
policy_disabled: 'gray',
|
||||||
|
suppressed: 'orange',
|
||||||
|
ack: 'gold',
|
||||||
|
resolve: 'green',
|
||||||
|
silence: 'gray',
|
||||||
|
}
|
||||||
|
return colorMap[eventType] || 'blue'
|
||||||
|
}
|
||||||
|
|
||||||
|
const getEventTypeText = (eventType: string) => {
|
||||||
|
const textMap: Record<string, string> = {
|
||||||
|
received: '接收告警',
|
||||||
|
notified: '通知发送',
|
||||||
|
ticket_created: '自动建单',
|
||||||
|
ticket_create_failed: '建单失败',
|
||||||
|
policy_load_failed: '策略加载失败',
|
||||||
|
policy_disabled: '策略停用',
|
||||||
|
suppressed: '告警抑制',
|
||||||
|
ack: '确认',
|
||||||
|
resolve: '解决',
|
||||||
|
silence: '屏蔽',
|
||||||
|
}
|
||||||
|
return textMap[eventType] || eventType
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadDetail()
|
loadDetail()
|
||||||
loadProcessRecords()
|
loadProcessRecords()
|
||||||
|
loadAlertEvents()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user