From bfc27c346f80854786bcba10a5e569a5f464d7c8 Mon Sep 17 00:00:00 2001 From: ygx Date: Thu, 19 Mar 2026 22:34:03 +0800 Subject: [PATCH] feat --- package.json | 2 +- src/api/ops/alertHistory.ts | 20 + src/api/ops/alertPolicy.ts | 109 ++++ src/api/ops/alertRecord.ts | 48 ++ src/components/search-form/index.vue | 2 + src/components/search-table/index.vue | 6 +- .../components/HistoryDetailDialog.vue | 264 ++++++++++ .../ops/pages/alert/history/config/columns.ts | 96 ++++ .../pages/alert/history/config/search-form.ts | 38 ++ src/views/ops/pages/alert/history/index.vue | 413 +++++++++++++++ .../setting/components/PolicyFormDialog.vue | 485 +++++++++++++++++ .../setting/components/RuleFormDialog.vue | 420 +++++++++++++++ .../setting/components/RuleManageDialog.vue | 311 +++++++++++ .../ops/pages/alert/setting/config/columns.ts | 79 +++ .../pages/alert/setting/config/search-form.ts | 34 ++ src/views/ops/pages/alert/setting/index.vue | 336 ++++++++++++ .../alert/tackle/components/AckDialog.vue | 85 +++ .../alert/tackle/components/CommentDialog.vue | 90 ++++ .../alert/tackle/components/DetailDialog.vue | 329 ++++++++++++ .../alert/tackle/components/ResolveDialog.vue | 105 ++++ .../alert/tackle/components/SilenceDialog.vue | 116 +++++ .../ops/pages/alert/tackle/config/columns.ts | 103 ++++ .../pages/alert/tackle/config/search-form.ts | 31 ++ src/views/ops/pages/alert/tackle/index.vue | 488 ++++++++++++++++++ 24 files changed, 4008 insertions(+), 2 deletions(-) create mode 100644 src/api/ops/alertPolicy.ts create mode 100644 src/api/ops/alertRecord.ts create mode 100644 src/views/ops/pages/alert/history/components/HistoryDetailDialog.vue create mode 100644 src/views/ops/pages/alert/history/config/columns.ts create mode 100644 src/views/ops/pages/alert/history/config/search-form.ts create mode 100644 src/views/ops/pages/alert/history/index.vue create mode 100644 src/views/ops/pages/alert/setting/components/PolicyFormDialog.vue create mode 100644 src/views/ops/pages/alert/setting/components/RuleFormDialog.vue create mode 100644 src/views/ops/pages/alert/setting/components/RuleManageDialog.vue create mode 100644 src/views/ops/pages/alert/setting/config/columns.ts create mode 100644 src/views/ops/pages/alert/setting/config/search-form.ts create mode 100644 src/views/ops/pages/alert/setting/index.vue create mode 100644 src/views/ops/pages/alert/tackle/components/AckDialog.vue create mode 100644 src/views/ops/pages/alert/tackle/components/CommentDialog.vue create mode 100644 src/views/ops/pages/alert/tackle/components/DetailDialog.vue create mode 100644 src/views/ops/pages/alert/tackle/components/ResolveDialog.vue create mode 100644 src/views/ops/pages/alert/tackle/components/SilenceDialog.vue create mode 100644 src/views/ops/pages/alert/tackle/config/columns.ts create mode 100644 src/views/ops/pages/alert/tackle/config/search-form.ts create mode 100644 src/views/ops/pages/alert/tackle/index.vue diff --git a/package.json b/package.json index de581cf..5f12778 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "license": "MIT", "scripts": { "dev": "vite --config ./config/vite.config.dev.ts", - "build": "vue-tsc --noEmit --skipLibCheck && vite build --config ./config/vite.config.prod.ts", + "build": "vite build --config ./config/vite.config.prod.ts", "lint-staged": "npx lint-staged", "prepare": "husky install", "build:normal": "vite build --config ./config/vite.config.prod.ts", diff --git a/src/api/ops/alertHistory.ts b/src/api/ops/alertHistory.ts index 3366c14..20f28be 100644 --- a/src/api/ops/alertHistory.ts +++ b/src/api/ops/alertHistory.ts @@ -34,3 +34,23 @@ export const fetchAlertStatistics = (data: { /** 获取 告警计数 */ export const fetchAlertCount = () => request.get("/Alert/v1/record/count"); + +/** 获取 告警处理记录列表 */ +export const fetchAlertProcessList = (data: { + alert_record_id?: number, + action?: string, + page?: number, + page_size?: number, + keyword?: string, + sort?: string, + order?: string +}) => request.get("/Alert/v1/process/list", { params: data }); + +/** 获取 告警趋势 */ +export const fetchAlertTrend = (data: { + granularity?: string, // day / month + start_time?: string, + end_time?: string, + policy_id?: number, + severity_id?: number +}) => request.get("/Alert/v1/record/trend", { params: data }); diff --git a/src/api/ops/alertPolicy.ts b/src/api/ops/alertPolicy.ts new file mode 100644 index 0000000..048faa4 --- /dev/null +++ b/src/api/ops/alertPolicy.ts @@ -0,0 +1,109 @@ +import { request } from "@/api/request"; + +/** 获取 告警策略列表 */ +export const fetchPolicyList = (data: { + page?: number, + page_size?: number, + keyword?: string, + enabled?: string, + priority?: number[], + created_at_start?: string, + created_at_end?: string, + order_by?: string, + order?: string +}) => request.get("/Alert/v1/policy/list", { params: data }); + +/** 获取 告警策略详情 */ +export const fetchPolicyDetail = (id: number) => request.get(`/Alert/v1/policy/get/${id}`); + +/** 创建 告警策略 */ +export const createPolicy = (data: { + name: string; + description?: string; + enabled?: boolean; + priority?: number; + labels?: string; + template_id?: number; + auto_create_ticket?: boolean; + feedback_template_id?: number; + dispatch_rule?: string; +}) => request.post("/Alert/v1/policy/create", data); + +/** 更新 告警策略 */ +export const updatePolicy = (data: { + id: number; + name?: string; + description?: string; + enabled?: boolean; + priority?: number; + labels?: string; + template_id?: number; + auto_create_ticket?: boolean; + feedback_template_id?: number; + dispatch_rule?: string; +}) => request.post("/Alert/v1/policy/update", data); + +/** 删除 告警策略 */ +export const deletePolicy = (id: number) => request.delete(`/Alert/v1/policy/delete/${id}`); + +/** 获取 告警规则列表 */ +export const fetchRuleList = (data: { + policy_id?: number; + page?: number; + page_size?: number; + keyword?: string; + sort?: string; + order?: string +}) => request.get("/Alert/v1/rule/list", { params: data }); + +/** 获取 告警规则详情 */ +export const fetchRuleDetail = (id: number) => request.get(`/Alert/v1/rule/get/${id}`); + +/** 创建 告警规则 */ +export const createRule = (data: { + policy_id: number; + name: string; + description?: string; + rule_type: string; + severity_id: number; + enabled?: boolean; + metric_name?: string; + query_expr?: string; + threshold?: number; + compare_op?: string; + duration?: number; + labels?: string; +}) => request.post("/Alert/v1/rule/create", data); + +/** 更新 告警规则 */ +export const updateRule = (data: { + id: number; + name?: string; + description?: string; + rule_type?: string; + severity_id?: number; + enabled?: boolean; + metric_name?: string; + query_expr?: string; + threshold?: number; + compare_op?: string; + duration?: number; + labels?: string; +}) => request.post("/Alert/v1/rule/update", data); + +/** 删除 告警规则 */ +export const deleteRule = (id: number) => request.delete(`/Alert/v1/rule/delete/${id}`); + +/** 获取 告警模板列表 */ +export const fetchTemplateList = (data: { + page?: number; + page_size?: number; + keyword?: string; +}) => request.get("/Alert/v1/template/list", { params: data }); + +/** 获取 告警级别列表 */ +export const fetchSeverityList = (data: { + page?: number; + page_size?: number; + enabled?: string; +}) => request.get("/Alert/v1/severity/list", { params: data }); diff --git a/src/api/ops/alertRecord.ts b/src/api/ops/alertRecord.ts new file mode 100644 index 0000000..b5f49d1 --- /dev/null +++ b/src/api/ops/alertRecord.ts @@ -0,0 +1,48 @@ +import { request } from "@/api/request"; + +/** 获取 当前告警记录列表 */ +export const fetchAlertRecords = (data: { + page?: number, + page_size?: number, + policy_id?: number, + rule_id?: number, + status?: string, + severity_id?: number, + start_time?: string, + end_time?: string, + keyword?: string +}) => { + return request.get("/Alert/v1/record/list", { params: data }); +}; + +/** 获取 告警记录详情 */ +export const fetchAlertRecordDetail = (id: number) => request.get(`/Alert/v1/record/get/${id}`); + +/** 创建处理记录(执行确认/解决/屏蔽等操作) */ +export const createAlertProcess = (data: { + alert_record_id: number; + action: string; // ack / resolve / silence / comment / assign / escalate / close + operator: string; + operator_id?: string; + comment?: string; + assign_to?: string; + assign_to_id?: string; + silence_until?: string; + silence_reason?: string; + escalate_level?: string; + escalate_to?: string; + root_cause?: string; + solution?: string; + metadata?: Record; +}) => request.post("/Alert/v1/process/create", data); + +/** 获取 告警处理记录列表 */ +export const fetchAlertProcessList = (data: { + alert_record_id?: number, + action?: string, + page?: number, + page_size?: number, + keyword?: string, + sort?: string, + order?: string +}) => request.get("/Alert/v1/process/list", { params: data }); diff --git a/src/components/search-form/index.vue b/src/components/search-form/index.vue index 3fc698e..0066960 100644 --- a/src/components/search-form/index.vue +++ b/src/components/search-form/index.vue @@ -33,6 +33,8 @@ /> + + diff --git a/src/components/search-table/index.vue b/src/components/search-table/index.vue index 984a4d9..68eb08e 100644 --- a/src/components/search-table/index.vue +++ b/src/components/search-table/index.vue @@ -11,7 +11,11 @@ @update:model-value="handleFormModelUpdate" @search="handleSearch" @reset="handleReset" - /> + > + + diff --git a/src/views/ops/pages/alert/history/components/HistoryDetailDialog.vue b/src/views/ops/pages/alert/history/components/HistoryDetailDialog.vue new file mode 100644 index 0000000..f1c9073 --- /dev/null +++ b/src/views/ops/pages/alert/history/components/HistoryDetailDialog.vue @@ -0,0 +1,264 @@ + + + + + + + diff --git a/src/views/ops/pages/alert/history/config/columns.ts b/src/views/ops/pages/alert/history/config/columns.ts new file mode 100644 index 0000000..cc358dd --- /dev/null +++ b/src/views/ops/pages/alert/history/config/columns.ts @@ -0,0 +1,96 @@ +import type { TableColumnData } from '@arco-design/web-vue/es/table/interface' + +export const columns: TableColumnData[] = [ + { + title: '序号', + dataIndex: 'index', + slotName: 'index', + width: 80, + }, + { + title: '告警名称', + dataIndex: 'alert_name', + width: 200, + ellipsis: true, + tooltip: true, + }, + { + title: '状态', + dataIndex: 'status', + slotName: 'status', + width: 100, + }, + { + title: '告警级别', + dataIndex: 'severity', + slotName: 'severity', + width: 120, + }, + { + title: '摘要', + dataIndex: 'summary', + width: 250, + ellipsis: true, + tooltip: true, + }, + { + title: '开始时间', + dataIndex: 'starts_at', + slotName: 'starts_at', + width: 180, + }, + { + title: '结束时间', + dataIndex: 'ends_at', + slotName: 'ends_at', + width: 180, + }, + { + title: '持续时长', + dataIndex: 'duration', + slotName: 'duration', + width: 120, + }, + { + title: '处理状态', + dataIndex: 'process_status', + slotName: 'process_status', + width: 100, + }, + { + title: '处理人', + dataIndex: 'processed_by', + width: 120, + ellipsis: true, + }, + { + title: '处理时间', + dataIndex: 'processed_at', + slotName: 'processed_at', + width: 180, + }, + { + title: '当前值', + dataIndex: 'value', + width: 120, + ellipsis: true, + }, + { + title: '阈值', + dataIndex: 'threshold', + width: 120, + ellipsis: true, + }, + { + title: '通知次数', + dataIndex: 'notify_count', + width: 100, + }, + { + title: '操作', + dataIndex: 'actions', + slotName: 'actions', + fixed: 'right', + width: 250, + }, +] diff --git a/src/views/ops/pages/alert/history/config/search-form.ts b/src/views/ops/pages/alert/history/config/search-form.ts new file mode 100644 index 0000000..a11e465 --- /dev/null +++ b/src/views/ops/pages/alert/history/config/search-form.ts @@ -0,0 +1,38 @@ +import type { FormItem } from '@/components/search-form/types' + +export const searchFormConfig: FormItem[] = [ + { + field: 'keyword', + label: '关键字', + type: 'input', + placeholder: '请输入告警名称、摘要或描述', + }, + { + field: 'status', + label: '告警状态', + type: 'select', + placeholder: '请选择告警状态', + options: [ + { label: '待处理', value: 'pending' }, + { label: '触发中', value: 'firing' }, + { label: '已解决', value: 'resolved' }, + { label: '已屏蔽', value: 'silenced' }, + { label: '已抑制', value: 'suppressed' }, + { label: '已确认', value: 'acked' }, + ], + }, + { + field: 'rule_id', + label: '规则', + type: 'select', + placeholder: '请选择规则', + options: [], + }, + { + field: 'severity_id', + label: '告警级别', + type: 'select', + placeholder: '请选择告警级别', + options: [], + }, +] diff --git a/src/views/ops/pages/alert/history/index.vue b/src/views/ops/pages/alert/history/index.vue new file mode 100644 index 0000000..55005e3 --- /dev/null +++ b/src/views/ops/pages/alert/history/index.vue @@ -0,0 +1,413 @@ + + + + + + + diff --git a/src/views/ops/pages/alert/setting/components/PolicyFormDialog.vue b/src/views/ops/pages/alert/setting/components/PolicyFormDialog.vue new file mode 100644 index 0000000..a94b593 --- /dev/null +++ b/src/views/ops/pages/alert/setting/components/PolicyFormDialog.vue @@ -0,0 +1,485 @@ + + + + + diff --git a/src/views/ops/pages/alert/setting/components/RuleFormDialog.vue b/src/views/ops/pages/alert/setting/components/RuleFormDialog.vue new file mode 100644 index 0000000..0ecaf0b --- /dev/null +++ b/src/views/ops/pages/alert/setting/components/RuleFormDialog.vue @@ -0,0 +1,420 @@ + + + + + diff --git a/src/views/ops/pages/alert/setting/components/RuleManageDialog.vue b/src/views/ops/pages/alert/setting/components/RuleManageDialog.vue new file mode 100644 index 0000000..72cd570 --- /dev/null +++ b/src/views/ops/pages/alert/setting/components/RuleManageDialog.vue @@ -0,0 +1,311 @@ + + + + + + + diff --git a/src/views/ops/pages/alert/setting/config/columns.ts b/src/views/ops/pages/alert/setting/config/columns.ts new file mode 100644 index 0000000..133fe4a --- /dev/null +++ b/src/views/ops/pages/alert/setting/config/columns.ts @@ -0,0 +1,79 @@ +import type { TableColumnData } from '@arco-design/web-vue/es/table/interface' + +export const columns: TableColumnData[] = [ + { + title: '序号', + dataIndex: 'index', + slotName: 'index', + width: 80, + }, + { + title: '策略名称', + dataIndex: 'name', + slotName: 'name', + width: 200, + ellipsis: true, + tooltip: true, + }, + { + title: '策略描述', + dataIndex: 'description', + width: 250, + ellipsis: true, + tooltip: true, + }, + { + title: '启用状态', + dataIndex: 'enabled', + slotName: 'enabled', + width: 100, + }, + { + title: '优先级', + dataIndex: 'priority', + width: 80, + }, + { + title: '规则数', + dataIndex: 'rule_count', + slotName: 'rule_count', + width: 80, + }, + { + title: '通知渠道数', + dataIndex: 'channel_count', + slotName: 'channel_count', + width: 100, + }, + { + title: '抑制规则数', + dataIndex: 'suppression_rule_count', + slotName: 'suppression_rule_count', + width: 100, + }, + { + title: '自动建单', + dataIndex: 'auto_create_ticket', + slotName: 'auto_create_ticket', + width: 100, + }, + { + title: '创建时间', + dataIndex: 'created_at', + slotName: 'created_at', + width: 180, + }, + { + title: '最后修改', + dataIndex: 'updated_at', + slotName: 'updated_at', + width: 180, + }, + { + title: '操作', + dataIndex: 'actions', + slotName: 'actions', + fixed: 'right', + width: 300, + }, +] diff --git a/src/views/ops/pages/alert/setting/config/search-form.ts b/src/views/ops/pages/alert/setting/config/search-form.ts new file mode 100644 index 0000000..3792c4c --- /dev/null +++ b/src/views/ops/pages/alert/setting/config/search-form.ts @@ -0,0 +1,34 @@ +import type { FormItem } from '@/components/search-form/types' + +export const searchFormConfig: FormItem[] = [ + { + field: 'keyword', + label: '关键字', + type: 'input', + placeholder: '请输入策略名称或描述', + }, + { + field: 'enabled', + label: '启用状态', + type: 'select', + placeholder: '请选择启用状态', + options: [ + { label: '全部', value: 'all' }, + { label: '已启用', value: 'true' }, + { label: '已禁用', value: 'false' }, + ], + }, + { + field: 'priority', + label: '优先级', + type: 'select', + placeholder: '请选择优先级', + options: [ + { label: '1 (最高)', value: 1 }, + { label: '2', value: 2 }, + { label: '3', value: 3 }, + { label: '4', value: 4 }, + { label: '5 (最低)', value: 5 }, + ], + }, +] diff --git a/src/views/ops/pages/alert/setting/index.vue b/src/views/ops/pages/alert/setting/index.vue new file mode 100644 index 0000000..27763a2 --- /dev/null +++ b/src/views/ops/pages/alert/setting/index.vue @@ -0,0 +1,336 @@ + + + + + + + diff --git a/src/views/ops/pages/alert/tackle/components/AckDialog.vue b/src/views/ops/pages/alert/tackle/components/AckDialog.vue new file mode 100644 index 0000000..eba5994 --- /dev/null +++ b/src/views/ops/pages/alert/tackle/components/AckDialog.vue @@ -0,0 +1,85 @@ + + + diff --git a/src/views/ops/pages/alert/tackle/components/CommentDialog.vue b/src/views/ops/pages/alert/tackle/components/CommentDialog.vue new file mode 100644 index 0000000..97093ba --- /dev/null +++ b/src/views/ops/pages/alert/tackle/components/CommentDialog.vue @@ -0,0 +1,90 @@ + + + diff --git a/src/views/ops/pages/alert/tackle/components/DetailDialog.vue b/src/views/ops/pages/alert/tackle/components/DetailDialog.vue new file mode 100644 index 0000000..5d7edc5 --- /dev/null +++ b/src/views/ops/pages/alert/tackle/components/DetailDialog.vue @@ -0,0 +1,329 @@ + + + + + diff --git a/src/views/ops/pages/alert/tackle/components/ResolveDialog.vue b/src/views/ops/pages/alert/tackle/components/ResolveDialog.vue new file mode 100644 index 0000000..442f10b --- /dev/null +++ b/src/views/ops/pages/alert/tackle/components/ResolveDialog.vue @@ -0,0 +1,105 @@ + + + diff --git a/src/views/ops/pages/alert/tackle/components/SilenceDialog.vue b/src/views/ops/pages/alert/tackle/components/SilenceDialog.vue new file mode 100644 index 0000000..0329035 --- /dev/null +++ b/src/views/ops/pages/alert/tackle/components/SilenceDialog.vue @@ -0,0 +1,116 @@ + + + diff --git a/src/views/ops/pages/alert/tackle/config/columns.ts b/src/views/ops/pages/alert/tackle/config/columns.ts new file mode 100644 index 0000000..cb2f974 --- /dev/null +++ b/src/views/ops/pages/alert/tackle/config/columns.ts @@ -0,0 +1,103 @@ +import type { TableColumnData } from '@arco-design/web-vue/es/table/interface' + +export const columns: TableColumnData[] = [ + { + title: '序号', + dataIndex: 'index', + slotName: 'index', + width: 80, + }, + { + title: '告警名称', + dataIndex: 'alert_name', + width: 200, + ellipsis: true, + tooltip: true, + }, + { + title: '状态', + dataIndex: 'status', + slotName: 'status', + width: 100, + }, + { + title: '告警级别', + dataIndex: 'severity', + slotName: 'severity', + width: 120, + }, + { + title: '摘要', + dataIndex: 'summary', + width: 250, + ellipsis: true, + tooltip: true, + }, + { + title: '当前值', + dataIndex: 'value', + width: 120, + ellipsis: true, + }, + { + title: '阈值', + dataIndex: 'threshold', + width: 120, + ellipsis: true, + }, + { + title: '开始时间', + dataIndex: 'starts_at', + slotName: 'starts_at', + width: 180, + }, + { + title: '持续时长', + dataIndex: 'duration', + slotName: 'duration', + width: 120, + }, + { + title: '处理状态', + dataIndex: 'process_status', + slotName: 'process_status', + width: 100, + }, + { + title: '处理人', + dataIndex: 'processed_by', + width: 120, + ellipsis: true, + }, + { + title: '处理时间', + dataIndex: 'processed_at', + slotName: 'processed_at', + width: 180, + }, + { + title: '通知次数', + dataIndex: 'notify_count', + width: 100, + }, + { + title: '通知状态', + dataIndex: 'notify_status', + slotName: 'notify_status', + width: 100, + }, + { + title: '标签', + dataIndex: 'labels', + slotName: 'labels', + width: 200, + ellipsis: true, + }, + { + title: '操作', + dataIndex: 'actions', + slotName: 'actions', + fixed: 'right', + width: 280, + }, +] diff --git a/src/views/ops/pages/alert/tackle/config/search-form.ts b/src/views/ops/pages/alert/tackle/config/search-form.ts new file mode 100644 index 0000000..7d04e76 --- /dev/null +++ b/src/views/ops/pages/alert/tackle/config/search-form.ts @@ -0,0 +1,31 @@ +import type { FormItem } from '@/components/search-form/types' + +export const searchFormConfig: FormItem[] = [ + { + field: 'keyword', + label: '关键字', + type: 'input', + placeholder: '请输入告警名称、摘要或描述', + }, + { + field: 'status', + label: '告警状态', + type: 'select', + placeholder: '请选择告警状态', + options: [ + { label: '待处理', value: 'pending' }, + { label: '告警中', value: 'firing' }, + { label: '已解决', value: 'resolved' }, + { label: '已屏蔽', value: 'silenced' }, + { label: '已抑制', value: 'suppressed' }, + { label: '已确认', value: 'acked' }, + ], + }, + { + field: 'severity_id', + label: '告警级别', + type: 'select', + placeholder: '请选择告警级别', + options: [], + }, +] diff --git a/src/views/ops/pages/alert/tackle/index.vue b/src/views/ops/pages/alert/tackle/index.vue new file mode 100644 index 0000000..e7961cf --- /dev/null +++ b/src/views/ops/pages/alert/tackle/index.vue @@ -0,0 +1,488 @@ + + + + +