实现列表查询活跃告警和历史告警

This commit is contained in:
2025-11-10 13:41:26 +08:00
parent b94aa6137c
commit 37f515d4a8
13 changed files with 1792 additions and 70 deletions

View File

@@ -23,6 +23,339 @@ const docTemplate = `{
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/api/v1/alarm/threshold/active-alarms": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "根据过滤条件和分页参数查询活跃告警列表",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"告警管理"
],
"summary": "批量查询活跃告警",
"parameters": [
{
"type": "string",
"description": "告警触发时间范围 - 结束时间",
"name": "end_time",
"in": "query"
},
{
"type": "boolean",
"description": "按是否被忽略过滤",
"name": "is_ignored",
"in": "query"
},
{
"enum": [
"Debug",
"Info",
"Warn",
"Error",
"DPanic",
"Panic",
"Fatal"
],
"type": "string",
"x-enum-varnames": [
"DebugLevel",
"InfoLevel",
"WarnLevel",
"ErrorLevel",
"DPanicLevel",
"PanicLevel",
"FatalLevel"
],
"description": "按告警严重性等级过滤",
"name": "level",
"in": "query"
},
{
"type": "string",
"description": "排序字段,例如 \"trigger_time DESC\"",
"name": "order_by",
"in": "query"
},
{
"type": "integer",
"name": "page",
"in": "query"
},
{
"type": "integer",
"name": "page_size",
"in": "query"
},
{
"type": "integer",
"description": "按告警来源ID过滤",
"name": "source_id",
"in": "query"
},
{
"enum": [
"普通设备",
"区域主控",
"系统"
],
"type": "string",
"x-enum-varnames": [
"AlarmSourceTypeDevice",
"AlarmSourceTypeAreaController",
"AlarmSourceTypeSystem"
],
"description": "按告警来源类型过滤",
"name": "source_type",
"in": "query"
},
{
"type": "string",
"description": "告警触发时间范围 - 开始时间",
"name": "trigger_time",
"in": "query"
}
],
"responses": {
"200": {
"description": "成功获取活跃告警列表",
"schema": {
"allOf": [
{
"$ref": "#/definitions/controller.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/dto.ListActiveAlarmResponse"
}
}
}
]
}
}
}
}
},
"/api/v1/alarm/threshold/historical-alarms": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "根据过滤条件和分页参数查询历史告警列表",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"告警管理"
],
"summary": "批量查询历史告警",
"parameters": [
{
"enum": [
"Debug",
"Info",
"Warn",
"Error",
"DPanic",
"Panic",
"Fatal"
],
"type": "string",
"x-enum-varnames": [
"DebugLevel",
"InfoLevel",
"WarnLevel",
"ErrorLevel",
"DPanicLevel",
"PanicLevel",
"FatalLevel"
],
"description": "按告警严重性等级过滤",
"name": "level",
"in": "query"
},
{
"type": "string",
"description": "排序字段,例如 \"trigger_time DESC\"",
"name": "order_by",
"in": "query"
},
{
"type": "integer",
"name": "page",
"in": "query"
},
{
"type": "integer",
"name": "page_size",
"in": "query"
},
{
"type": "string",
"description": "告警解决时间范围 - 结束时间",
"name": "resolve_time_end",
"in": "query"
},
{
"type": "string",
"description": "告警解决时间范围 - 开始时间",
"name": "resolve_time_start",
"in": "query"
},
{
"type": "integer",
"description": "按告警来源ID过滤",
"name": "source_id",
"in": "query"
},
{
"enum": [
"普通设备",
"区域主控",
"系统"
],
"type": "string",
"x-enum-varnames": [
"AlarmSourceTypeDevice",
"AlarmSourceTypeAreaController",
"AlarmSourceTypeSystem"
],
"description": "按告警来源类型过滤",
"name": "source_type",
"in": "query"
},
{
"type": "string",
"description": "告警触发时间范围 - 结束时间",
"name": "trigger_time_end",
"in": "query"
},
{
"type": "string",
"description": "告警触发时间范围 - 开始时间",
"name": "trigger_time_start",
"in": "query"
}
],
"responses": {
"200": {
"description": "成功获取历史告警列表",
"schema": {
"allOf": [
{
"$ref": "#/definitions/controller.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/dto.ListHistoricalAlarmResponse"
}
}
}
]
}
}
}
}
},
"/api/v1/alarm/threshold/{id}/cancel-snooze": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "根据告警ID取消对一个阈值告警的忽略状态",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"告警管理"
],
"summary": "取消忽略阈值告警",
"parameters": [
{
"type": "string",
"description": "告警ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "成功取消忽略告警",
"schema": {
"$ref": "#/definitions/controller.Response"
}
}
}
}
},
"/api/v1/alarm/threshold/{id}/snooze": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "根据告警ID忽略一个活跃的阈值告警或更新其忽略时间",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"告警管理"
],
"summary": "忽略阈值告警",
"parameters": [
{
"type": "string",
"description": "告警ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "忽略告警请求体",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.SnoozeAlarmRequest"
}
}
],
"responses": {
"200": {
"description": "成功忽略告警",
"schema": {
"$ref": "#/definitions/controller.Response"
}
}
}
}
},
"/api/v1/area-controllers": {
"get": {
"security": [
@@ -4170,6 +4503,50 @@ const docTemplate = `{
"CodeServiceUnavailable"
]
},
"dto.ActiveAlarmDTO": {
"type": "object",
"properties": {
"alarm_code": {
"$ref": "#/definitions/models.AlarmCode"
},
"alarm_details": {
"type": "string"
},
"alarm_summary": {
"type": "string"
},
"created_at": {
"type": "string"
},
"id": {
"type": "integer"
},
"ignored_until": {
"type": "string"
},
"is_ignored": {
"type": "boolean"
},
"last_notified_at": {
"type": "string"
},
"level": {
"$ref": "#/definitions/models.SeverityLevel"
},
"source_id": {
"type": "integer"
},
"source_type": {
"$ref": "#/definitions/models.AlarmSourceType"
},
"trigger_time": {
"type": "string"
},
"updated_at": {
"type": "string"
}
}
},
"dto.AreaControllerResponse": {
"type": "object",
"properties": {
@@ -4589,6 +4966,58 @@ const docTemplate = `{
}
}
},
"dto.HistoricalAlarmDTO": {
"type": "object",
"properties": {
"alarm_code": {
"$ref": "#/definitions/models.AlarmCode"
},
"alarm_details": {
"type": "string"
},
"alarm_summary": {
"type": "string"
},
"id": {
"type": "integer"
},
"level": {
"$ref": "#/definitions/models.SeverityLevel"
},
"resolve_method": {
"type": "string"
},
"resolve_time": {
"type": "string"
},
"resolved_by": {
"type": "integer"
},
"source_id": {
"type": "integer"
},
"source_type": {
"$ref": "#/definitions/models.AlarmSourceType"
},
"trigger_time": {
"type": "string"
}
}
},
"dto.ListActiveAlarmResponse": {
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ActiveAlarmDTO"
}
},
"pagination": {
"$ref": "#/definitions/dto.PaginationDTO"
}
}
},
"dto.ListDeviceCommandLogResponse": {
"type": "object",
"properties": {
@@ -4617,6 +5046,20 @@ const docTemplate = `{
}
}
},
"dto.ListHistoricalAlarmResponse": {
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.HistoricalAlarmDTO"
}
},
"pagination": {
"$ref": "#/definitions/dto.PaginationDTO"
}
}
},
"dto.ListMedicationLogResponse": {
"type": "object",
"properties": {
@@ -4984,13 +5427,13 @@ const docTemplate = `{
"type": "integer"
},
"level": {
"$ref": "#/definitions/zapcore.Level"
"$ref": "#/definitions/models.SeverityLevel"
},
"message": {
"type": "string"
},
"notifier_type": {
"$ref": "#/definitions/notify.NotifierType"
"$ref": "#/definitions/models.NotifierType"
},
"status": {
"$ref": "#/definitions/models.NotificationStatus"
@@ -5882,7 +6325,7 @@ const docTemplate = `{
"description": "Type 指定要测试的通知渠道",
"allOf": [
{
"$ref": "#/definitions/notify.NotifierType"
"$ref": "#/definitions/models.NotifierType"
}
]
}
@@ -5911,6 +6354,19 @@ const docTemplate = `{
}
}
},
"dto.SnoozeAlarmRequest": {
"type": "object",
"required": [
"duration_minutes"
],
"properties": {
"duration_minutes": {
"description": "忽略时长,单位分钟",
"type": "integer",
"minimum": 1
}
}
},
"dto.SubPlanResponse": {
"type": "object",
"properties": {
@@ -6412,6 +6868,40 @@ const docTemplate = `{
}
}
},
"models.AlarmCode": {
"type": "string",
"enum": [
"温度阈值",
"湿度阈值",
"重量阈值",
"电池电量阈值",
"信号强度阈值",
"设备离线",
"区域主控离线"
],
"x-enum-varnames": [
"AlarmCodeTemperature",
"AlarmCodeHumidity",
"AlarmCodeWeight",
"AlarmCodeBatteryLevel",
"AlarmCodeSignalMetrics",
"AlarmCodeDeviceOffline",
"AlarmCodeAreaControllerOffline"
]
},
"models.AlarmSourceType": {
"type": "string",
"enum": [
"普通设备",
"区域主控",
"系统"
],
"x-enum-varnames": [
"AlarmSourceTypeDevice",
"AlarmSourceTypeAreaController",
"AlarmSourceTypeSystem"
]
},
"models.AuditStatus": {
"type": "string",
"enum": [
@@ -6522,6 +7012,21 @@ const docTemplate = `{
"NotificationStatusSkipped"
]
},
"models.NotifierType": {
"type": "string",
"enum": [
"邮件",
"企业微信",
"飞书",
"日志"
],
"x-enum-varnames": [
"NotifierTypeSMTP",
"NotifierTypeWeChat",
"NotifierTypeLark",
"NotifierTypeLog"
]
},
"models.PenStatus": {
"type": "string",
"enum": [
@@ -6805,6 +7310,27 @@ const docTemplate = `{
"SensorTypeWeight"
]
},
"models.SeverityLevel": {
"type": "string",
"enum": [
"Debug",
"Info",
"Warn",
"Error",
"DPanic",
"Panic",
"Fatal"
],
"x-enum-varnames": [
"DebugLevel",
"InfoLevel",
"WarnLevel",
"ErrorLevel",
"DPanicLevel",
"PanicLevel",
"FatalLevel"
]
},
"models.StockLogSourceType": {
"type": "string",
"enum": [
@@ -6830,10 +7356,12 @@ const docTemplate = `{
"计划分析",
"等待",
"下料",
"全量采集"
"全量采集",
"告警通知"
],
"x-enum-comments": {
"TaskPlanAnalysis": "解析Plan的Task列表并添加到待执行队列的特殊任务",
"TaskTypeAlarmNotification": "告警通知任务",
"TaskTypeFullCollection": "新增的全量采集任务",
"TaskTypeReleaseFeedWeight": "下料口释放指定重量任务",
"TaskTypeWaiting": "等待任务"
@@ -6842,13 +7370,15 @@ const docTemplate = `{
"解析Plan的Task列表并添加到待执行队列的特殊任务",
"等待任务",
"下料口释放指定重量任务",
"新增的全量采集任务"
"新增的全量采集任务",
"告警通知任务"
],
"x-enum-varnames": [
"TaskPlanAnalysis",
"TaskTypeWaiting",
"TaskTypeReleaseFeedWeight",
"TaskTypeFullCollection"
"TaskTypeFullCollection",
"TaskTypeAlarmNotification"
]
},
"models.ValueDescriptor": {
@@ -6867,21 +7397,6 @@ const docTemplate = `{
}
}
},
"notify.NotifierType": {
"type": "string",
"enum": [
"邮件",
"企业微信",
"飞书",
"日志"
],
"x-enum-varnames": [
"NotifierTypeSMTP",
"NotifierTypeWeChat",
"NotifierTypeLark",
"NotifierTypeLog"
]
},
"repository.PlanTypeFilter": {
"type": "string",
"enum": [

View File

@@ -15,6 +15,339 @@
"version": "1.0"
},
"paths": {
"/api/v1/alarm/threshold/active-alarms": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "根据过滤条件和分页参数查询活跃告警列表",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"告警管理"
],
"summary": "批量查询活跃告警",
"parameters": [
{
"type": "string",
"description": "告警触发时间范围 - 结束时间",
"name": "end_time",
"in": "query"
},
{
"type": "boolean",
"description": "按是否被忽略过滤",
"name": "is_ignored",
"in": "query"
},
{
"enum": [
"Debug",
"Info",
"Warn",
"Error",
"DPanic",
"Panic",
"Fatal"
],
"type": "string",
"x-enum-varnames": [
"DebugLevel",
"InfoLevel",
"WarnLevel",
"ErrorLevel",
"DPanicLevel",
"PanicLevel",
"FatalLevel"
],
"description": "按告警严重性等级过滤",
"name": "level",
"in": "query"
},
{
"type": "string",
"description": "排序字段,例如 \"trigger_time DESC\"",
"name": "order_by",
"in": "query"
},
{
"type": "integer",
"name": "page",
"in": "query"
},
{
"type": "integer",
"name": "page_size",
"in": "query"
},
{
"type": "integer",
"description": "按告警来源ID过滤",
"name": "source_id",
"in": "query"
},
{
"enum": [
"普通设备",
"区域主控",
"系统"
],
"type": "string",
"x-enum-varnames": [
"AlarmSourceTypeDevice",
"AlarmSourceTypeAreaController",
"AlarmSourceTypeSystem"
],
"description": "按告警来源类型过滤",
"name": "source_type",
"in": "query"
},
{
"type": "string",
"description": "告警触发时间范围 - 开始时间",
"name": "trigger_time",
"in": "query"
}
],
"responses": {
"200": {
"description": "成功获取活跃告警列表",
"schema": {
"allOf": [
{
"$ref": "#/definitions/controller.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/dto.ListActiveAlarmResponse"
}
}
}
]
}
}
}
}
},
"/api/v1/alarm/threshold/historical-alarms": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "根据过滤条件和分页参数查询历史告警列表",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"告警管理"
],
"summary": "批量查询历史告警",
"parameters": [
{
"enum": [
"Debug",
"Info",
"Warn",
"Error",
"DPanic",
"Panic",
"Fatal"
],
"type": "string",
"x-enum-varnames": [
"DebugLevel",
"InfoLevel",
"WarnLevel",
"ErrorLevel",
"DPanicLevel",
"PanicLevel",
"FatalLevel"
],
"description": "按告警严重性等级过滤",
"name": "level",
"in": "query"
},
{
"type": "string",
"description": "排序字段,例如 \"trigger_time DESC\"",
"name": "order_by",
"in": "query"
},
{
"type": "integer",
"name": "page",
"in": "query"
},
{
"type": "integer",
"name": "page_size",
"in": "query"
},
{
"type": "string",
"description": "告警解决时间范围 - 结束时间",
"name": "resolve_time_end",
"in": "query"
},
{
"type": "string",
"description": "告警解决时间范围 - 开始时间",
"name": "resolve_time_start",
"in": "query"
},
{
"type": "integer",
"description": "按告警来源ID过滤",
"name": "source_id",
"in": "query"
},
{
"enum": [
"普通设备",
"区域主控",
"系统"
],
"type": "string",
"x-enum-varnames": [
"AlarmSourceTypeDevice",
"AlarmSourceTypeAreaController",
"AlarmSourceTypeSystem"
],
"description": "按告警来源类型过滤",
"name": "source_type",
"in": "query"
},
{
"type": "string",
"description": "告警触发时间范围 - 结束时间",
"name": "trigger_time_end",
"in": "query"
},
{
"type": "string",
"description": "告警触发时间范围 - 开始时间",
"name": "trigger_time_start",
"in": "query"
}
],
"responses": {
"200": {
"description": "成功获取历史告警列表",
"schema": {
"allOf": [
{
"$ref": "#/definitions/controller.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/dto.ListHistoricalAlarmResponse"
}
}
}
]
}
}
}
}
},
"/api/v1/alarm/threshold/{id}/cancel-snooze": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "根据告警ID取消对一个阈值告警的忽略状态",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"告警管理"
],
"summary": "取消忽略阈值告警",
"parameters": [
{
"type": "string",
"description": "告警ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "成功取消忽略告警",
"schema": {
"$ref": "#/definitions/controller.Response"
}
}
}
}
},
"/api/v1/alarm/threshold/{id}/snooze": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "根据告警ID忽略一个活跃的阈值告警或更新其忽略时间",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"告警管理"
],
"summary": "忽略阈值告警",
"parameters": [
{
"type": "string",
"description": "告警ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "忽略告警请求体",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.SnoozeAlarmRequest"
}
}
],
"responses": {
"200": {
"description": "成功忽略告警",
"schema": {
"$ref": "#/definitions/controller.Response"
}
}
}
}
},
"/api/v1/area-controllers": {
"get": {
"security": [
@@ -4162,6 +4495,50 @@
"CodeServiceUnavailable"
]
},
"dto.ActiveAlarmDTO": {
"type": "object",
"properties": {
"alarm_code": {
"$ref": "#/definitions/models.AlarmCode"
},
"alarm_details": {
"type": "string"
},
"alarm_summary": {
"type": "string"
},
"created_at": {
"type": "string"
},
"id": {
"type": "integer"
},
"ignored_until": {
"type": "string"
},
"is_ignored": {
"type": "boolean"
},
"last_notified_at": {
"type": "string"
},
"level": {
"$ref": "#/definitions/models.SeverityLevel"
},
"source_id": {
"type": "integer"
},
"source_type": {
"$ref": "#/definitions/models.AlarmSourceType"
},
"trigger_time": {
"type": "string"
},
"updated_at": {
"type": "string"
}
}
},
"dto.AreaControllerResponse": {
"type": "object",
"properties": {
@@ -4581,6 +4958,58 @@
}
}
},
"dto.HistoricalAlarmDTO": {
"type": "object",
"properties": {
"alarm_code": {
"$ref": "#/definitions/models.AlarmCode"
},
"alarm_details": {
"type": "string"
},
"alarm_summary": {
"type": "string"
},
"id": {
"type": "integer"
},
"level": {
"$ref": "#/definitions/models.SeverityLevel"
},
"resolve_method": {
"type": "string"
},
"resolve_time": {
"type": "string"
},
"resolved_by": {
"type": "integer"
},
"source_id": {
"type": "integer"
},
"source_type": {
"$ref": "#/definitions/models.AlarmSourceType"
},
"trigger_time": {
"type": "string"
}
}
},
"dto.ListActiveAlarmResponse": {
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.ActiveAlarmDTO"
}
},
"pagination": {
"$ref": "#/definitions/dto.PaginationDTO"
}
}
},
"dto.ListDeviceCommandLogResponse": {
"type": "object",
"properties": {
@@ -4609,6 +5038,20 @@
}
}
},
"dto.ListHistoricalAlarmResponse": {
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.HistoricalAlarmDTO"
}
},
"pagination": {
"$ref": "#/definitions/dto.PaginationDTO"
}
}
},
"dto.ListMedicationLogResponse": {
"type": "object",
"properties": {
@@ -4976,13 +5419,13 @@
"type": "integer"
},
"level": {
"$ref": "#/definitions/zapcore.Level"
"$ref": "#/definitions/models.SeverityLevel"
},
"message": {
"type": "string"
},
"notifier_type": {
"$ref": "#/definitions/notify.NotifierType"
"$ref": "#/definitions/models.NotifierType"
},
"status": {
"$ref": "#/definitions/models.NotificationStatus"
@@ -5874,7 +6317,7 @@
"description": "Type 指定要测试的通知渠道",
"allOf": [
{
"$ref": "#/definitions/notify.NotifierType"
"$ref": "#/definitions/models.NotifierType"
}
]
}
@@ -5903,6 +6346,19 @@
}
}
},
"dto.SnoozeAlarmRequest": {
"type": "object",
"required": [
"duration_minutes"
],
"properties": {
"duration_minutes": {
"description": "忽略时长,单位分钟",
"type": "integer",
"minimum": 1
}
}
},
"dto.SubPlanResponse": {
"type": "object",
"properties": {
@@ -6404,6 +6860,40 @@
}
}
},
"models.AlarmCode": {
"type": "string",
"enum": [
"温度阈值",
"湿度阈值",
"重量阈值",
"电池电量阈值",
"信号强度阈值",
"设备离线",
"区域主控离线"
],
"x-enum-varnames": [
"AlarmCodeTemperature",
"AlarmCodeHumidity",
"AlarmCodeWeight",
"AlarmCodeBatteryLevel",
"AlarmCodeSignalMetrics",
"AlarmCodeDeviceOffline",
"AlarmCodeAreaControllerOffline"
]
},
"models.AlarmSourceType": {
"type": "string",
"enum": [
"普通设备",
"区域主控",
"系统"
],
"x-enum-varnames": [
"AlarmSourceTypeDevice",
"AlarmSourceTypeAreaController",
"AlarmSourceTypeSystem"
]
},
"models.AuditStatus": {
"type": "string",
"enum": [
@@ -6514,6 +7004,21 @@
"NotificationStatusSkipped"
]
},
"models.NotifierType": {
"type": "string",
"enum": [
"邮件",
"企业微信",
"飞书",
"日志"
],
"x-enum-varnames": [
"NotifierTypeSMTP",
"NotifierTypeWeChat",
"NotifierTypeLark",
"NotifierTypeLog"
]
},
"models.PenStatus": {
"type": "string",
"enum": [
@@ -6797,6 +7302,27 @@
"SensorTypeWeight"
]
},
"models.SeverityLevel": {
"type": "string",
"enum": [
"Debug",
"Info",
"Warn",
"Error",
"DPanic",
"Panic",
"Fatal"
],
"x-enum-varnames": [
"DebugLevel",
"InfoLevel",
"WarnLevel",
"ErrorLevel",
"DPanicLevel",
"PanicLevel",
"FatalLevel"
]
},
"models.StockLogSourceType": {
"type": "string",
"enum": [
@@ -6822,10 +7348,12 @@
"计划分析",
"等待",
"下料",
"全量采集"
"全量采集",
"告警通知"
],
"x-enum-comments": {
"TaskPlanAnalysis": "解析Plan的Task列表并添加到待执行队列的特殊任务",
"TaskTypeAlarmNotification": "告警通知任务",
"TaskTypeFullCollection": "新增的全量采集任务",
"TaskTypeReleaseFeedWeight": "下料口释放指定重量任务",
"TaskTypeWaiting": "等待任务"
@@ -6834,13 +7362,15 @@
"解析Plan的Task列表并添加到待执行队列的特殊任务",
"等待任务",
"下料口释放指定重量任务",
"新增的全量采集任务"
"新增的全量采集任务",
"告警通知任务"
],
"x-enum-varnames": [
"TaskPlanAnalysis",
"TaskTypeWaiting",
"TaskTypeReleaseFeedWeight",
"TaskTypeFullCollection"
"TaskTypeFullCollection",
"TaskTypeAlarmNotification"
]
},
"models.ValueDescriptor": {
@@ -6859,21 +7389,6 @@
}
}
},
"notify.NotifierType": {
"type": "string",
"enum": [
"邮件",
"企业微信",
"飞书",
"日志"
],
"x-enum-varnames": [
"NotifierTypeSMTP",
"NotifierTypeWeChat",
"NotifierTypeLark",
"NotifierTypeLog"
]
},
"repository.PlanTypeFilter": {
"type": "string",
"enum": [

View File

@@ -53,6 +53,35 @@ definitions:
- CodeConflict
- CodeInternalError
- CodeServiceUnavailable
dto.ActiveAlarmDTO:
properties:
alarm_code:
$ref: '#/definitions/models.AlarmCode'
alarm_details:
type: string
alarm_summary:
type: string
created_at:
type: string
id:
type: integer
ignored_until:
type: string
is_ignored:
type: boolean
last_notified_at:
type: string
level:
$ref: '#/definitions/models.SeverityLevel'
source_id:
type: integer
source_type:
$ref: '#/definitions/models.AlarmSourceType'
trigger_time:
type: string
updated_at:
type: string
type: object
dto.AreaControllerResponse:
properties:
created_at:
@@ -340,6 +369,40 @@ definitions:
remarks:
type: string
type: object
dto.HistoricalAlarmDTO:
properties:
alarm_code:
$ref: '#/definitions/models.AlarmCode'
alarm_details:
type: string
alarm_summary:
type: string
id:
type: integer
level:
$ref: '#/definitions/models.SeverityLevel'
resolve_method:
type: string
resolve_time:
type: string
resolved_by:
type: integer
source_id:
type: integer
source_type:
$ref: '#/definitions/models.AlarmSourceType'
trigger_time:
type: string
type: object
dto.ListActiveAlarmResponse:
properties:
list:
items:
$ref: '#/definitions/dto.ActiveAlarmDTO'
type: array
pagination:
$ref: '#/definitions/dto.PaginationDTO'
type: object
dto.ListDeviceCommandLogResponse:
properties:
list:
@@ -358,6 +421,15 @@ definitions:
pagination:
$ref: '#/definitions/dto.PaginationDTO'
type: object
dto.ListHistoricalAlarmResponse:
properties:
list:
items:
$ref: '#/definitions/dto.HistoricalAlarmDTO'
type: array
pagination:
$ref: '#/definitions/dto.PaginationDTO'
type: object
dto.ListMedicationLogResponse:
properties:
list:
@@ -600,11 +672,11 @@ definitions:
id:
type: integer
level:
$ref: '#/definitions/zapcore.Level'
$ref: '#/definitions/models.SeverityLevel'
message:
type: string
notifier_type:
$ref: '#/definitions/notify.NotifierType'
$ref: '#/definitions/models.NotifierType'
status:
$ref: '#/definitions/models.NotificationStatus'
title:
@@ -1199,7 +1271,7 @@ definitions:
properties:
type:
allOf:
- $ref: '#/definitions/notify.NotifierType'
- $ref: '#/definitions/models.NotifierType'
description: Type 指定要测试的通知渠道
required:
- type
@@ -1219,6 +1291,15 @@ definitions:
time:
type: string
type: object
dto.SnoozeAlarmRequest:
properties:
duration_minutes:
description: 忽略时长,单位分钟
minimum: 1
type: integer
required:
- duration_minutes
type: object
dto.SubPlanResponse:
properties:
child_plan:
@@ -1558,6 +1639,34 @@ definitions:
weight:
type: number
type: object
models.AlarmCode:
enum:
- 温度阈值
- 湿度阈值
- 重量阈值
- 电池电量阈值
- 信号强度阈值
- 设备离线
- 区域主控离线
type: string
x-enum-varnames:
- AlarmCodeTemperature
- AlarmCodeHumidity
- AlarmCodeWeight
- AlarmCodeBatteryLevel
- AlarmCodeSignalMetrics
- AlarmCodeDeviceOffline
- AlarmCodeAreaControllerOffline
models.AlarmSourceType:
enum:
- 普通设备
- 区域主控
- 系统
type: string
x-enum-varnames:
- AlarmSourceTypeDevice
- AlarmSourceTypeAreaController
- AlarmSourceTypeSystem
models.AuditStatus:
enum:
- 成功
@@ -1646,6 +1755,18 @@ definitions:
- NotificationStatusSuccess
- NotificationStatusFailed
- NotificationStatusSkipped
models.NotifierType:
enum:
- 邮件
- 企业微信
- 飞书
- 日志
type: string
x-enum-varnames:
- NotifierTypeSMTP
- NotifierTypeWeChat
- NotifierTypeLark
- NotifierTypeLog
models.PenStatus:
enum:
- 空闲
@@ -1877,6 +1998,24 @@ definitions:
- SensorTypeTemperature
- SensorTypeHumidity
- SensorTypeWeight
models.SeverityLevel:
enum:
- Debug
- Info
- Warn
- Error
- DPanic
- Panic
- Fatal
type: string
x-enum-varnames:
- DebugLevel
- InfoLevel
- WarnLevel
- ErrorLevel
- DPanicLevel
- PanicLevel
- FatalLevel
models.StockLogSourceType:
enum:
- 采购入库
@@ -1899,9 +2038,11 @@ definitions:
- 等待
- 下料
- 全量采集
- 告警通知
type: string
x-enum-comments:
TaskPlanAnalysis: 解析Plan的Task列表并添加到待执行队列的特殊任务
TaskTypeAlarmNotification: 告警通知任务
TaskTypeFullCollection: 新增的全量采集任务
TaskTypeReleaseFeedWeight: 下料口释放指定重量任务
TaskTypeWaiting: 等待任务
@@ -1910,11 +2051,13 @@ definitions:
- 等待任务
- 下料口释放指定重量任务
- 新增的全量采集任务
- 告警通知任务
x-enum-varnames:
- TaskPlanAnalysis
- TaskTypeWaiting
- TaskTypeReleaseFeedWeight
- TaskTypeFullCollection
- TaskTypeAlarmNotification
models.ValueDescriptor:
properties:
multiplier:
@@ -1926,18 +2069,6 @@ definitions:
type:
$ref: '#/definitions/models.SensorType'
type: object
notify.NotifierType:
enum:
- 邮件
- 企业微信
- 飞书
- 日志
type: string
x-enum-varnames:
- NotifierTypeSMTP
- NotifierTypeWeChat
- NotifierTypeLark
- NotifierTypeLog
repository.PlanTypeFilter:
enum:
- 所有任务
@@ -1987,6 +2118,224 @@ info:
title: 猪场管理系统 API
version: "1.0"
paths:
/api/v1/alarm/threshold/{id}/cancel-snooze:
post:
consumes:
- application/json
description: 根据告警ID取消对一个阈值告警的忽略状态
parameters:
- description: 告警ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: 成功取消忽略告警
schema:
$ref: '#/definitions/controller.Response'
security:
- BearerAuth: []
summary: 取消忽略阈值告警
tags:
- 告警管理
/api/v1/alarm/threshold/{id}/snooze:
post:
consumes:
- application/json
description: 根据告警ID忽略一个活跃的阈值告警或更新其忽略时间
parameters:
- description: 告警ID
in: path
name: id
required: true
type: string
- description: 忽略告警请求体
in: body
name: request
required: true
schema:
$ref: '#/definitions/dto.SnoozeAlarmRequest'
produces:
- application/json
responses:
"200":
description: 成功忽略告警
schema:
$ref: '#/definitions/controller.Response'
security:
- BearerAuth: []
summary: 忽略阈值告警
tags:
- 告警管理
/api/v1/alarm/threshold/active-alarms:
get:
consumes:
- application/json
description: 根据过滤条件和分页参数查询活跃告警列表
parameters:
- description: 告警触发时间范围 - 结束时间
in: query
name: end_time
type: string
- description: 按是否被忽略过滤
in: query
name: is_ignored
type: boolean
- description: 按告警严重性等级过滤
enum:
- Debug
- Info
- Warn
- Error
- DPanic
- Panic
- Fatal
in: query
name: level
type: string
x-enum-varnames:
- DebugLevel
- InfoLevel
- WarnLevel
- ErrorLevel
- DPanicLevel
- PanicLevel
- FatalLevel
- description: 排序字段,例如 "trigger_time DESC"
in: query
name: order_by
type: string
- in: query
name: page
type: integer
- in: query
name: page_size
type: integer
- description: 按告警来源ID过滤
in: query
name: source_id
type: integer
- description: 按告警来源类型过滤
enum:
- 普通设备
- 区域主控
- 系统
in: query
name: source_type
type: string
x-enum-varnames:
- AlarmSourceTypeDevice
- AlarmSourceTypeAreaController
- AlarmSourceTypeSystem
- description: 告警触发时间范围 - 开始时间
in: query
name: trigger_time
type: string
produces:
- application/json
responses:
"200":
description: 成功获取活跃告警列表
schema:
allOf:
- $ref: '#/definitions/controller.Response'
- properties:
data:
$ref: '#/definitions/dto.ListActiveAlarmResponse'
type: object
security:
- BearerAuth: []
summary: 批量查询活跃告警
tags:
- 告警管理
/api/v1/alarm/threshold/historical-alarms:
get:
consumes:
- application/json
description: 根据过滤条件和分页参数查询历史告警列表
parameters:
- description: 按告警严重性等级过滤
enum:
- Debug
- Info
- Warn
- Error
- DPanic
- Panic
- Fatal
in: query
name: level
type: string
x-enum-varnames:
- DebugLevel
- InfoLevel
- WarnLevel
- ErrorLevel
- DPanicLevel
- PanicLevel
- FatalLevel
- description: 排序字段,例如 "trigger_time DESC"
in: query
name: order_by
type: string
- in: query
name: page
type: integer
- in: query
name: page_size
type: integer
- description: 告警解决时间范围 - 结束时间
in: query
name: resolve_time_end
type: string
- description: 告警解决时间范围 - 开始时间
in: query
name: resolve_time_start
type: string
- description: 按告警来源ID过滤
in: query
name: source_id
type: integer
- description: 按告警来源类型过滤
enum:
- 普通设备
- 区域主控
- 系统
in: query
name: source_type
type: string
x-enum-varnames:
- AlarmSourceTypeDevice
- AlarmSourceTypeAreaController
- AlarmSourceTypeSystem
- description: 告警触发时间范围 - 结束时间
in: query
name: trigger_time_end
type: string
- description: 告警触发时间范围 - 开始时间
in: query
name: trigger_time_start
type: string
produces:
- application/json
responses:
"200":
description: 成功获取历史告警列表
schema:
allOf:
- $ref: '#/definitions/controller.Response'
- properties:
data:
$ref: '#/definitions/dto.ListHistoricalAlarmResponse'
type: object
security:
- BearerAuth: []
summary: 批量查询历史告警
tags:
- 告警管理
/api/v1/area-controllers:
get:
description: 获取系统中所有区域主控的列表

View File

@@ -195,6 +195,8 @@ func (a *API) setupRoutes() {
{
thresholdGroup.POST("/:id/snooze", a.alarmController.SnoozeThresholdAlarm) // 忽略阈值告警
thresholdGroup.POST("/:id/cancel-snooze", a.alarmController.CancelSnoozeThresholdAlarm) // 取消忽略阈值告警
thresholdGroup.GET("/active-alarms", a.alarmController.ListActiveAlarms) // 获取活跃告警
thresholdGroup.GET("/historical-alarms", a.alarmController.ListHistoricalAlarms) // 获取历史告警
}
}
logger.Debug("告警相关接口注册成功 (需要认证和审计)")

View File

@@ -9,6 +9,7 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
"git.huangwc.com/pig/pig-farm-controller/internal/app/service"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
"github.com/labstack/echo/v4"
"gorm.io/gorm"
@@ -107,3 +108,73 @@ func (t *ThresholdAlarmController) CancelSnoozeThresholdAlarm(ctx echo.Context)
logger.Infof("%s: 告警忽略状态已成功取消, ID: %d", actionType, alarmID)
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "告警忽略状态已成功取消", nil, actionType, "告警忽略状态已成功取消", alarmID)
}
// ListActiveAlarms godoc
// @Summary 批量查询活跃告警
// @Description 根据过滤条件和分页参数查询活跃告警列表
// @Tags 告警管理
// @Security BearerAuth
// @Accept json
// @Produce json
// @Param query query dto.ListActiveAlarmRequest true "查询参数"
// @Success 200 {object} controller.Response{data=dto.ListActiveAlarmResponse} "成功获取活跃告警列表"
// @Router /api/v1/alarm/threshold/active-alarms [get]
func (t *ThresholdAlarmController) ListActiveAlarms(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), t.ctx, "ListActiveAlarms")
const actionType = "批量查询活跃告警"
var req dto.ListActiveAlarmRequest
if err := ctx.Bind(&req); err != nil {
logger.Errorf("%s: 参数绑定失败: %v", actionType, err)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求参数: "+err.Error(), actionType, "请求参数绑定失败", nil)
}
resp, err := t.thresholdAlarmService.ListActiveAlarms(reqCtx, &req)
if err != nil {
// 捕获 ErrInvalidPagination 错误,并返回 Bad Request
if errors.Is(err, repository.ErrInvalidPagination) {
logger.Warnf("%s: 无效的分页参数: %v", actionType, err)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的分页参数: "+err.Error(), actionType, "无效分页参数", req)
}
logger.Errorf("%s: 服务层查询活跃告警失败: %v", actionType, err)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "查询活跃告警失败: "+err.Error(), actionType, "服务层查询活跃告警失败", req)
}
logger.Infof("%s: 成功, 获取到 %d 条记录, 总计 %d 条", actionType, len(resp.List), resp.Pagination.Total)
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "成功获取活跃告警列表", resp, actionType, "成功获取活跃告警列表", req)
}
// ListHistoricalAlarms godoc
// @Summary 批量查询历史告警
// @Description 根据过滤条件和分页参数查询历史告警列表
// @Tags 告警管理
// @Security BearerAuth
// @Accept json
// @Produce json
// @Param query query dto.ListHistoricalAlarmRequest true "查询参数"
// @Success 200 {object} controller.Response{data=dto.ListHistoricalAlarmResponse} "成功获取历史告警列表"
// @Router /api/v1/alarm/threshold/historical-alarms [get]
func (t *ThresholdAlarmController) ListHistoricalAlarms(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), t.ctx, "ListHistoricalAlarms")
const actionType = "批量查询历史告警"
var req dto.ListHistoricalAlarmRequest
if err := ctx.Bind(&req); err != nil {
logger.Errorf("%s: 参数绑定失败: %v", actionType, err)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求参数: "+err.Error(), actionType, "请求参数绑定失败", nil)
}
resp, err := t.thresholdAlarmService.ListHistoricalAlarms(reqCtx, &req)
if err != nil {
// 捕获 ErrInvalidPagination 错误,并返回 Bad Request
if errors.Is(err, repository.ErrInvalidPagination) {
logger.Warnf("%s: 无效的分页参数: %v", actionType, err)
return controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的分页参数: "+err.Error(), actionType, "无效分页参数", req)
}
logger.Errorf("%s: 服务层查询历史告警失败: %v", actionType, err)
return controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "查询历史告警失败: "+err.Error(), actionType, "服务层查询历史告警失败", req)
}
logger.Infof("%s: 成功, 获取到 %d 条记录, 总计 %d 条", actionType, len(resp.List), resp.Pagination.Total)
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "成功获取历史告警列表", resp, actionType, "成功获取历史告警列表", req)
}

View File

@@ -0,0 +1,65 @@
package dto
import (
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
)
// NewListActiveAlarmResponse 从模型数据创建活跃告警列表响应 DTO
func NewListActiveAlarmResponse(data []models.ActiveAlarm, total int64, page, pageSize int) *ListActiveAlarmResponse {
dtos := make([]ActiveAlarmDTO, len(data))
for i, item := range data {
dtos[i] = ActiveAlarmDTO{
ID: item.ID,
CreatedAt: item.CreatedAt,
UpdatedAt: item.UpdatedAt,
SourceType: item.SourceType,
SourceID: item.SourceID,
AlarmCode: item.AlarmCode,
AlarmSummary: item.AlarmSummary,
Level: item.Level,
AlarmDetails: item.AlarmDetails,
TriggerTime: item.TriggerTime,
IsIgnored: item.IsIgnored,
IgnoredUntil: item.IgnoredUntil,
LastNotifiedAt: item.LastNotifiedAt,
}
}
return &ListActiveAlarmResponse{
List: dtos,
Pagination: PaginationDTO{
Total: total,
Page: page,
PageSize: pageSize,
},
}
}
// NewListHistoricalAlarmResponse 从模型数据创建历史告警列表响应 DTO
func NewListHistoricalAlarmResponse(data []models.HistoricalAlarm, total int64, page, pageSize int) *ListHistoricalAlarmResponse {
dtos := make([]HistoricalAlarmDTO, len(data))
for i, item := range data {
dtos[i] = HistoricalAlarmDTO{
ID: item.ID,
SourceType: item.SourceType,
SourceID: item.SourceID,
AlarmCode: item.AlarmCode,
AlarmSummary: item.AlarmSummary,
Level: item.Level,
AlarmDetails: item.AlarmDetails,
TriggerTime: item.TriggerTime,
ResolveTime: item.ResolveTime,
ResolveMethod: item.ResolveMethod,
ResolvedBy: item.ResolvedBy,
}
}
return &ListHistoricalAlarmResponse{
List: dtos,
Pagination: PaginationDTO{
Total: total,
Page: page,
PageSize: pageSize,
},
}
}

View File

@@ -1,6 +1,83 @@
package dto
import (
"time"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
)
// SnoozeAlarmRequest 定义了忽略告警的请求体
type SnoozeAlarmRequest struct {
DurationMinutes uint `json:"duration_minutes" validate:"required,min=1"` // 忽略时长,单位分钟
}
// ListActiveAlarmRequest 定义了获取活跃告警列表的请求参数
type ListActiveAlarmRequest struct {
Page int `json:"page" query:"page"`
PageSize int `json:"page_size" query:"page_size"`
SourceType *models.AlarmSourceType `json:"source_type" query:"source_type"` // 按告警来源类型过滤
SourceID *uint `json:"source_id" query:"source_id"` // 按告警来源ID过滤
Level *models.SeverityLevel `json:"level" query:"level"` // 按告警严重性等级过滤
IsIgnored *bool `json:"is_ignored" query:"is_ignored"` // 按是否被忽略过滤
TriggerTime *time.Time `json:"trigger_time" query:"trigger_time"` // 告警触发时间范围 - 开始时间
EndTime *time.Time `json:"end_time" query:"end_time"` // 告警触发时间范围 - 结束时间
OrderBy string `json:"order_by" query:"order_by"` // 排序字段,例如 "trigger_time DESC"
}
// ActiveAlarmDTO 是用于API响应的活跃告警结构
type ActiveAlarmDTO struct {
ID uint `json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
SourceType models.AlarmSourceType `json:"source_type"`
SourceID uint `json:"source_id"`
AlarmCode models.AlarmCode `json:"alarm_code"`
AlarmSummary string `json:"alarm_summary"`
Level models.SeverityLevel `json:"level"`
AlarmDetails string `json:"alarm_details"`
TriggerTime time.Time `json:"trigger_time"`
IsIgnored bool `json:"is_ignored"`
IgnoredUntil *time.Time `json:"ignored_until"`
LastNotifiedAt *time.Time `json:"last_notified_at"`
}
// ListActiveAlarmResponse 是获取活跃告警列表的响应结构
type ListActiveAlarmResponse struct {
List []ActiveAlarmDTO `json:"list"`
Pagination PaginationDTO `json:"pagination"`
}
// ListHistoricalAlarmRequest 定义了获取历史告警列表的请求参数
type ListHistoricalAlarmRequest struct {
Page int `json:"page" query:"page"`
PageSize int `json:"page_size" query:"page_size"`
SourceType *models.AlarmSourceType `json:"source_type" query:"source_type"` // 按告警来源类型过滤
SourceID *uint `json:"source_id" query:"source_id"` // 按告警来源ID过滤
Level *models.SeverityLevel `json:"level" query:"level"` // 按告警严重性等级过滤
TriggerTimeStart *time.Time `json:"trigger_time_start" query:"trigger_time_start"` // 告警触发时间范围 - 开始时间
TriggerTimeEnd *time.Time `json:"trigger_time_end" query:"trigger_time_end"` // 告警触发时间范围 - 结束时间
ResolveTimeStart *time.Time `json:"resolve_time_start" query:"resolve_time_start"` // 告警解决时间范围 - 开始时间
ResolveTimeEnd *time.Time `json:"resolve_time_end" query:"resolve_time_end"` // 告警解决时间范围 - 结束时间
OrderBy string `json:"order_by" query:"order_by"` // 排序字段,例如 "trigger_time DESC"
}
// HistoricalAlarmDTO 是用于API响应的历史告警结构
type HistoricalAlarmDTO struct {
ID uint `json:"id"`
SourceType models.AlarmSourceType `json:"source_type"`
SourceID uint `json:"source_id"`
AlarmCode models.AlarmCode `json:"alarm_code"`
AlarmSummary string `json:"alarm_summary"`
Level models.SeverityLevel `json:"level"`
AlarmDetails string `json:"alarm_details"`
TriggerTime time.Time `json:"trigger_time"`
ResolveTime time.Time `json:"resolve_time"`
ResolveMethod string `json:"resolve_method"`
ResolvedBy *uint `json:"resolved_by"`
}
// ListHistoricalAlarmResponse 是获取历史告警列表的响应结构
type ListHistoricalAlarmResponse struct {
List []HistoricalAlarmDTO `json:"list"`
Pagination PaginationDTO `json:"pagination"`
}

10
internal/app/dto/dto.go Normal file
View File

@@ -0,0 +1,10 @@
package dto
// --- General ---
// PaginationDTO 定义了分页信息的标准结构
type PaginationDTO struct {
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}

View File

@@ -7,15 +7,6 @@ import (
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
)
// --- General ---
// PaginationDTO 定义了分页信息的标准结构
type PaginationDTO struct {
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
// --- SensorData ---
// ListSensorDataRequest 定义了获取传感器数据列表的请求参数

View File

@@ -4,8 +4,10 @@ import (
"context"
"time"
domainAlarm "git.huangwc.com/pig/pig-farm-controller/internal/domain/alarm" // 引入领域层的 AlarmService
"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
domainAlarm "git.huangwc.com/pig/pig-farm-controller/internal/domain/alarm"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
)
// ThresholdAlarmService 定义了阈值告警配置服务的接口。
@@ -15,19 +17,25 @@ type ThresholdAlarmService interface {
SnoozeThresholdAlarm(ctx context.Context, alarmID uint, durationMinutes uint) error
// CancelSnoozeThresholdAlarm 取消对一个阈值告警的忽略状态。
CancelSnoozeThresholdAlarm(ctx context.Context, alarmID uint) error
// ListActiveAlarms 批量查询活跃告警。
ListActiveAlarms(ctx context.Context, req *dto.ListActiveAlarmRequest) (*dto.ListActiveAlarmResponse, error)
// ListHistoricalAlarms 批量查询历史告警。
ListHistoricalAlarms(ctx context.Context, req *dto.ListHistoricalAlarmRequest) (*dto.ListHistoricalAlarmResponse, error)
}
// thresholdAlarmService 是 ThresholdAlarmService 接口的具体实现。
type thresholdAlarmService struct {
ctx context.Context
alarmService domainAlarm.AlarmService // 注入领域层的 AlarmService
alarmService domainAlarm.AlarmService
alarmRepo repository.AlarmRepository
}
// NewThresholdAlarmService 创建一个新的 ThresholdAlarmService 实例。
func NewThresholdAlarmService(ctx context.Context, alarmService domainAlarm.AlarmService) ThresholdAlarmService {
func NewThresholdAlarmService(ctx context.Context, alarmService domainAlarm.AlarmService, alarmRepo repository.AlarmRepository) ThresholdAlarmService {
return &thresholdAlarmService{
ctx: ctx,
alarmService: alarmService,
alarmRepo: alarmRepo,
}
}
@@ -42,3 +50,48 @@ func (s *thresholdAlarmService) CancelSnoozeThresholdAlarm(ctx context.Context,
serviceCtx := logs.AddFuncName(ctx, s.ctx, "CancelSnoozeThresholdAlarm")
return s.alarmService.CancelAlarmSnooze(serviceCtx, alarmID)
}
// ListActiveAlarms 实现了批量查询活跃告警的逻辑。
func (s *thresholdAlarmService) ListActiveAlarms(ctx context.Context, req *dto.ListActiveAlarmRequest) (*dto.ListActiveAlarmResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListActiveAlarms")
opts := repository.ActiveAlarmListOptions{
SourceType: req.SourceType,
SourceID: req.SourceID,
Level: req.Level,
IsIgnored: req.IsIgnored,
TriggerTime: req.TriggerTime,
EndTime: req.EndTime,
OrderBy: req.OrderBy,
}
alarms, total, err := s.alarmRepo.ListActiveAlarms(serviceCtx, opts, req.Page, req.PageSize)
if err != nil {
return nil, err
}
return dto.NewListActiveAlarmResponse(alarms, total, req.Page, req.PageSize), nil
}
// ListHistoricalAlarms 实现了批量查询历史告警的逻辑。
func (s *thresholdAlarmService) ListHistoricalAlarms(ctx context.Context, req *dto.ListHistoricalAlarmRequest) (*dto.ListHistoricalAlarmResponse, error) {
serviceCtx := logs.AddFuncName(ctx, s.ctx, "ListHistoricalAlarms")
opts := repository.HistoricalAlarmListOptions{
SourceType: req.SourceType,
SourceID: req.SourceID,
Level: req.Level,
TriggerTimeStart: req.TriggerTimeStart,
TriggerTimeEnd: req.TriggerTimeEnd,
ResolveTimeStart: req.ResolveTimeStart,
ResolveTimeEnd: req.ResolveTimeEnd,
OrderBy: req.OrderBy,
}
alarms, total, err := s.alarmRepo.ListHistoricalAlarms(serviceCtx, opts, req.Page, req.PageSize)
if err != nil {
return nil, err
}
return dto.NewListHistoricalAlarmResponse(alarms, total, req.Page, req.PageSize), nil
}

View File

@@ -269,6 +269,7 @@ func initAppServices(ctx context.Context, infra *Infrastructure, domainServices
thresholdAlarmService := service.NewThresholdAlarmService(
logs.AddCompName(baseCtx, "ThresholdAlarmService"),
domainServices.alarmService,
infra.repos.alarmRepo,
)
return &AppServices{

View File

@@ -23,6 +23,18 @@ type ActiveAlarmListOptions struct {
OrderBy string // 排序字段,例如 "trigger_time DESC"
}
// HistoricalAlarmListOptions 定义了查询历史告警列表时的可选参数
type HistoricalAlarmListOptions struct {
SourceType *models.AlarmSourceType // 按告警来源类型过滤
SourceID *uint // 按告警来源ID过滤
Level *models.SeverityLevel // 按告警严重性等级过滤
TriggerTimeStart *time.Time // 告警触发时间范围 - 开始时间
TriggerTimeEnd *time.Time // 告警触发时间范围 - 结束时间
ResolveTimeStart *time.Time // 告警解决时间范围 - 开始时间 (对应 models.HistoricalAlarm.ResolveTime)
ResolveTimeEnd *time.Time // 告警解决时间范围 - 结束时间 (对应 models.HistoricalAlarm.ResolveTime)
OrderBy string // 排序字段,例如 "trigger_time DESC"
}
// AlarmRepository 定义了对告警模型的数据库操作接口
type AlarmRepository interface {
// CreateActiveAlarm 创建一条新的活跃告警记录
@@ -47,6 +59,10 @@ type AlarmRepository interface {
// 返回活跃告警列表、总记录数和错误。
ListActiveAlarms(ctx context.Context, opts ActiveAlarmListOptions, page, pageSize int) ([]models.ActiveAlarm, int64, error)
// ListHistoricalAlarms 支持分页和过滤的历史告警列表查询。
// 返回历史告警列表、总记录数和错误。
ListHistoricalAlarms(ctx context.Context, opts HistoricalAlarmListOptions, page, pageSize int) ([]models.HistoricalAlarm, int64, error)
// UpdateAlarmNotificationStatus 显式更新告警的通知相关状态字段。
// lastNotifiedAt: 传入具体的发送时间。
// isIgnored: 告警新的忽略状态。
@@ -148,7 +164,7 @@ func (r *gormAlarmRepository) ListActiveAlarms(ctx context.Context, opts ActiveA
repoCtx := logs.AddFuncName(ctx, r.ctx, "ListActiveAlarms")
// --- 校验分页参数 ---
if page <= 0 || pageSize <= 0 {
return nil, 0, ErrInvalidPagination // 复用已定义的错误
return nil, 0, ErrInvalidPagination
}
var results []models.ActiveAlarm
@@ -195,6 +211,61 @@ func (r *gormAlarmRepository) ListActiveAlarms(ctx context.Context, opts ActiveA
return results, total, err
}
// ListHistoricalAlarms 实现了分页和过滤查询历史告警记录的功能
func (r *gormAlarmRepository) ListHistoricalAlarms(ctx context.Context, opts HistoricalAlarmListOptions, page, pageSize int) ([]models.HistoricalAlarm, int64, error) {
repoCtx := logs.AddFuncName(ctx, r.ctx, "ListHistoricalAlarms")
// --- 校验分页参数 ---
if page <= 0 || pageSize <= 0 {
return nil, 0, ErrInvalidPagination
}
var results []models.HistoricalAlarm
var total int64
query := r.db.WithContext(repoCtx).Model(&models.HistoricalAlarm{})
// --- 应用过滤条件 ---
if opts.SourceType != nil {
query = query.Where("source_type = ?", *opts.SourceType)
}
if opts.SourceID != nil {
query = query.Where("source_id = ?", *opts.SourceID)
}
if opts.Level != nil {
query = query.Where("level = ?", *opts.Level)
}
if opts.TriggerTimeStart != nil {
query = query.Where("trigger_time >= ?", *opts.TriggerTimeStart)
}
if opts.TriggerTimeEnd != nil {
query = query.Where("trigger_time <= ?", *opts.TriggerTimeEnd)
}
if opts.ResolveTimeStart != nil { // 修改字段名
query = query.Where("resolve_time >= ?", *opts.ResolveTimeStart) // 修改查询字段名
}
if opts.ResolveTimeEnd != nil { // 修改字段名
query = query.Where("resolve_time <= ?", *opts.ResolveTimeEnd) // 修改查询字段名
}
// --- 计算总数 ---
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
// --- 应用排序条件 ---
orderBy := "trigger_time DESC" // 默认按触发时间倒序
if opts.OrderBy != "" {
orderBy = opts.OrderBy
}
query = query.Order(orderBy)
// --- 分页 ---
offset := (page - 1) * pageSize
err := query.Limit(pageSize).Offset(offset).Find(&results).Error
return results, total, err
}
func (r *gormAlarmRepository) UpdateAlarmNotificationStatus(ctx context.Context, alarmID uint, lastNotifiedAt time.Time, isIgnored bool, ignoredUntil *time.Time) error {
repoCtx := logs.AddFuncName(ctx, r.ctx, "UpdateAlarmNotificationStatus")

View File

@@ -54,9 +54,11 @@ internal/app/controller/monitor/monitor_controller.go
internal/app/controller/plan/plan_controller.go
internal/app/controller/response.go
internal/app/controller/user/user_controller.go
internal/app/dto/alarm_converter.go
internal/app/dto/alarm_dto.go
internal/app/dto/device_converter.go
internal/app/dto/device_dto.go
internal/app/dto/dto.go
internal/app/dto/monitor_converter.go
internal/app/dto/monitor_dto.go
internal/app/dto/notification_converter.go