增加两个批量查询接口

This commit is contained in:
2025-11-16 16:30:26 +08:00
parent bf747e22ce
commit bf1600b385
10 changed files with 1041 additions and 11 deletions

View File

@@ -146,6 +146,126 @@ const docTemplate = `{
}
},
"/api/v1/alarm/threshold/area": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "根据过滤条件和分页参数查询区域阈值告警列表",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"告警管理"
],
"summary": "批量查询区域阈值告警",
"parameters": [
{
"type": "integer",
"description": "按区域主控ID过滤",
"name": "area_controller_id",
"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": "排序字段,例如 \"id DESC\"",
"name": "order_by",
"in": "query"
},
{
"type": "integer",
"name": "page",
"in": "query"
},
{
"type": "integer",
"name": "page_size",
"in": "query"
},
{
"enum": [
"信号强度",
"电池电量",
"温度",
"湿度",
"重量"
],
"type": "string",
"x-enum-comments": {
"SensorTypeBatteryLevel": "电池电量",
"SensorTypeHumidity": "湿度",
"SensorTypeSignalMetrics": "信号强度",
"SensorTypeTemperature": "温度",
"SensorTypeWeight": "重量"
},
"x-enum-descriptions": [
"信号强度",
"电池电量",
"温度",
"湿度",
"重量"
],
"x-enum-varnames": [
"SensorTypeSignalMetrics",
"SensorTypeBatteryLevel",
"SensorTypeTemperature",
"SensorTypeHumidity",
"SensorTypeWeight"
],
"description": "按传感器类型过滤",
"name": "sensor_type",
"in": "query"
}
],
"responses": {
"200": {
"description": "成功获取区域阈值告警列表",
"schema": {
"allOf": [
{
"$ref": "#/definitions/controller.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/dto.ListAreaThresholdAlarmResponse"
}
}
}
]
}
}
}
},
"post": {
"security": [
{
@@ -307,6 +427,126 @@ const docTemplate = `{
}
},
"/api/v1/alarm/threshold/device": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "根据过滤条件和分页参数查询设备阈值告警列表",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"告警管理"
],
"summary": "批量查询设备阈值告警",
"parameters": [
{
"type": "integer",
"description": "按设备ID过滤",
"name": "device_id",
"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": "排序字段,例如 \"id DESC\"",
"name": "order_by",
"in": "query"
},
{
"type": "integer",
"name": "page",
"in": "query"
},
{
"type": "integer",
"name": "page_size",
"in": "query"
},
{
"enum": [
"信号强度",
"电池电量",
"温度",
"湿度",
"重量"
],
"type": "string",
"x-enum-comments": {
"SensorTypeBatteryLevel": "电池电量",
"SensorTypeHumidity": "湿度",
"SensorTypeSignalMetrics": "信号强度",
"SensorTypeTemperature": "温度",
"SensorTypeWeight": "重量"
},
"x-enum-descriptions": [
"信号强度",
"电池电量",
"温度",
"湿度",
"重量"
],
"x-enum-varnames": [
"SensorTypeSignalMetrics",
"SensorTypeBatteryLevel",
"SensorTypeTemperature",
"SensorTypeHumidity",
"SensorTypeWeight"
],
"description": "按传感器类型过滤",
"name": "sensor_type",
"in": "query"
}
],
"responses": {
"200": {
"description": "成功获取设备阈值告警列表",
"schema": {
"allOf": [
{
"$ref": "#/definitions/controller.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/dto.ListDeviceThresholdAlarmResponse"
}
}
}
]
}
}
}
},
"post": {
"security": [
{
@@ -5454,15 +5694,15 @@ const docTemplate = `{
"alarm_code": {
"$ref": "#/definitions/models.AlarmCode"
},
"alarm_details": {
"type": "string"
},
"alarm_summary": {
"type": "string"
},
"id": {
"type": "integer"
},
"json_details": {
"type": "string"
},
"level": {
"$ref": "#/definitions/models.SeverityLevel"
},
@@ -5500,6 +5740,20 @@ const docTemplate = `{
}
}
},
"dto.ListAreaThresholdAlarmResponse": {
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.AreaThresholdAlarmDTO"
}
},
"pagination": {
"$ref": "#/definitions/dto.PaginationDTO"
}
}
},
"dto.ListDeviceCommandLogResponse": {
"type": "object",
"properties": {
@@ -5514,6 +5768,20 @@ const docTemplate = `{
}
}
},
"dto.ListDeviceThresholdAlarmResponse": {
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.DeviceThresholdAlarmDTO"
}
},
"pagination": {
"$ref": "#/definitions/dto.PaginationDTO"
}
}
},
"dto.ListFeedUsageRecordResponse": {
"type": "object",
"properties": {

View File

@@ -138,6 +138,126 @@
}
},
"/api/v1/alarm/threshold/area": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "根据过滤条件和分页参数查询区域阈值告警列表",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"告警管理"
],
"summary": "批量查询区域阈值告警",
"parameters": [
{
"type": "integer",
"description": "按区域主控ID过滤",
"name": "area_controller_id",
"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": "排序字段,例如 \"id DESC\"",
"name": "order_by",
"in": "query"
},
{
"type": "integer",
"name": "page",
"in": "query"
},
{
"type": "integer",
"name": "page_size",
"in": "query"
},
{
"enum": [
"信号强度",
"电池电量",
"温度",
"湿度",
"重量"
],
"type": "string",
"x-enum-comments": {
"SensorTypeBatteryLevel": "电池电量",
"SensorTypeHumidity": "湿度",
"SensorTypeSignalMetrics": "信号强度",
"SensorTypeTemperature": "温度",
"SensorTypeWeight": "重量"
},
"x-enum-descriptions": [
"信号强度",
"电池电量",
"温度",
"湿度",
"重量"
],
"x-enum-varnames": [
"SensorTypeSignalMetrics",
"SensorTypeBatteryLevel",
"SensorTypeTemperature",
"SensorTypeHumidity",
"SensorTypeWeight"
],
"description": "按传感器类型过滤",
"name": "sensor_type",
"in": "query"
}
],
"responses": {
"200": {
"description": "成功获取区域阈值告警列表",
"schema": {
"allOf": [
{
"$ref": "#/definitions/controller.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/dto.ListAreaThresholdAlarmResponse"
}
}
}
]
}
}
}
},
"post": {
"security": [
{
@@ -299,6 +419,126 @@
}
},
"/api/v1/alarm/threshold/device": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "根据过滤条件和分页参数查询设备阈值告警列表",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"告警管理"
],
"summary": "批量查询设备阈值告警",
"parameters": [
{
"type": "integer",
"description": "按设备ID过滤",
"name": "device_id",
"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": "排序字段,例如 \"id DESC\"",
"name": "order_by",
"in": "query"
},
{
"type": "integer",
"name": "page",
"in": "query"
},
{
"type": "integer",
"name": "page_size",
"in": "query"
},
{
"enum": [
"信号强度",
"电池电量",
"温度",
"湿度",
"重量"
],
"type": "string",
"x-enum-comments": {
"SensorTypeBatteryLevel": "电池电量",
"SensorTypeHumidity": "湿度",
"SensorTypeSignalMetrics": "信号强度",
"SensorTypeTemperature": "温度",
"SensorTypeWeight": "重量"
},
"x-enum-descriptions": [
"信号强度",
"电池电量",
"温度",
"湿度",
"重量"
],
"x-enum-varnames": [
"SensorTypeSignalMetrics",
"SensorTypeBatteryLevel",
"SensorTypeTemperature",
"SensorTypeHumidity",
"SensorTypeWeight"
],
"description": "按传感器类型过滤",
"name": "sensor_type",
"in": "query"
}
],
"responses": {
"200": {
"description": "成功获取设备阈值告警列表",
"schema": {
"allOf": [
{
"$ref": "#/definitions/controller.Response"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/dto.ListDeviceThresholdAlarmResponse"
}
}
}
]
}
}
}
},
"post": {
"security": [
{
@@ -5446,15 +5686,15 @@
"alarm_code": {
"$ref": "#/definitions/models.AlarmCode"
},
"alarm_details": {
"type": "string"
},
"alarm_summary": {
"type": "string"
},
"id": {
"type": "integer"
},
"json_details": {
"type": "string"
},
"level": {
"$ref": "#/definitions/models.SeverityLevel"
},
@@ -5492,6 +5732,20 @@
}
}
},
"dto.ListAreaThresholdAlarmResponse": {
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.AreaThresholdAlarmDTO"
}
},
"pagination": {
"$ref": "#/definitions/dto.PaginationDTO"
}
}
},
"dto.ListDeviceCommandLogResponse": {
"type": "object",
"properties": {
@@ -5506,6 +5760,20 @@
}
}
},
"dto.ListDeviceThresholdAlarmResponse": {
"type": "object",
"properties": {
"list": {
"type": "array",
"items": {
"$ref": "#/definitions/dto.DeviceThresholdAlarmDTO"
}
},
"pagination": {
"$ref": "#/definitions/dto.PaginationDTO"
}
}
},
"dto.ListFeedUsageRecordResponse": {
"type": "object",
"properties": {

View File

@@ -464,12 +464,12 @@ definitions:
properties:
alarm_code:
$ref: '#/definitions/models.AlarmCode'
alarm_details:
type: string
alarm_summary:
type: string
id:
type: integer
json_details:
type: string
level:
$ref: '#/definitions/models.SeverityLevel'
resolve_method:
@@ -494,6 +494,15 @@ definitions:
pagination:
$ref: '#/definitions/dto.PaginationDTO'
type: object
dto.ListAreaThresholdAlarmResponse:
properties:
list:
items:
$ref: '#/definitions/dto.AreaThresholdAlarmDTO'
type: array
pagination:
$ref: '#/definitions/dto.PaginationDTO'
type: object
dto.ListDeviceCommandLogResponse:
properties:
list:
@@ -503,6 +512,15 @@ definitions:
pagination:
$ref: '#/definitions/dto.PaginationDTO'
type: object
dto.ListDeviceThresholdAlarmResponse:
properties:
list:
items:
$ref: '#/definitions/dto.DeviceThresholdAlarmDTO'
type: array
pagination:
$ref: '#/definitions/dto.PaginationDTO'
type: object
dto.ListFeedUsageRecordResponse:
properties:
list:
@@ -2401,6 +2419,90 @@ paths:
tags:
- 告警管理
/api/v1/alarm/threshold/area:
get:
consumes:
- application/json
description: 根据过滤条件和分页参数查询区域阈值告警列表
parameters:
- description: 按区域主控ID过滤
in: query
name: area_controller_id
type: integer
- 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: 排序字段,例如 "id DESC"
in: query
name: order_by
type: string
- in: query
name: page
type: integer
- in: query
name: page_size
type: integer
- description: 按传感器类型过滤
enum:
- 信号强度
- 电池电量
- 温度
- 湿度
- 重量
in: query
name: sensor_type
type: string
x-enum-comments:
SensorTypeBatteryLevel: 电池电量
SensorTypeHumidity: 湿度
SensorTypeSignalMetrics: 信号强度
SensorTypeTemperature: 温度
SensorTypeWeight: 重量
x-enum-descriptions:
- 信号强度
- 电池电量
- 温度
- 湿度
- 重量
x-enum-varnames:
- SensorTypeSignalMetrics
- SensorTypeBatteryLevel
- SensorTypeTemperature
- SensorTypeHumidity
- SensorTypeWeight
produces:
- application/json
responses:
"200":
description: 成功获取区域阈值告警列表
schema:
allOf:
- $ref: '#/definitions/controller.Response'
- properties:
data:
$ref: '#/definitions/dto.ListAreaThresholdAlarmResponse'
type: object
security:
- BearerAuth: []
summary: 批量查询区域阈值告警
tags:
- 告警管理
post:
consumes:
- application/json
@@ -2499,6 +2601,90 @@ paths:
tags:
- 告警管理
/api/v1/alarm/threshold/device:
get:
consumes:
- application/json
description: 根据过滤条件和分页参数查询设备阈值告警列表
parameters:
- description: 按设备ID过滤
in: query
name: device_id
type: integer
- 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: 排序字段,例如 "id DESC"
in: query
name: order_by
type: string
- in: query
name: page
type: integer
- in: query
name: page_size
type: integer
- description: 按传感器类型过滤
enum:
- 信号强度
- 电池电量
- 温度
- 湿度
- 重量
in: query
name: sensor_type
type: string
x-enum-comments:
SensorTypeBatteryLevel: 电池电量
SensorTypeHumidity: 湿度
SensorTypeSignalMetrics: 信号强度
SensorTypeTemperature: 温度
SensorTypeWeight: 重量
x-enum-descriptions:
- 信号强度
- 电池电量
- 温度
- 湿度
- 重量
x-enum-varnames:
- SensorTypeSignalMetrics
- SensorTypeBatteryLevel
- SensorTypeTemperature
- SensorTypeHumidity
- SensorTypeWeight
produces:
- application/json
responses:
"200":
description: 成功获取设备阈值告警列表
schema:
allOf:
- $ref: '#/definitions/controller.Response'
- properties:
data:
$ref: '#/definitions/dto.ListDeviceThresholdAlarmResponse'
type: object
security:
- BearerAuth: []
summary: 批量查询设备阈值告警
tags:
- 告警管理
post:
consumes:
- application/json

View File

@@ -199,12 +199,14 @@ func (a *API) setupRoutes() {
thresholdGroup.GET("/historical-alarms", a.alarmController.ListHistoricalAlarms) // 获取历史告警
// 设备阈值告警配置
thresholdGroup.GET("/device", a.alarmController.ListDeviceThresholdAlarms)
thresholdGroup.POST("/device", a.alarmController.CreateDeviceThresholdAlarm)
thresholdGroup.GET("/device/:task_id", a.alarmController.GetDeviceThresholdAlarm)
thresholdGroup.PUT("/device/:task_id", a.alarmController.UpdateDeviceThresholdAlarm)
thresholdGroup.DELETE("/device/:task_id", a.alarmController.DeleteDeviceThresholdAlarm)
// 区域阈值告警配置
thresholdGroup.GET("/area", a.alarmController.ListAreaThresholdAlarms)
thresholdGroup.POST("/area", a.alarmController.CreateAreaThresholdAlarm)
thresholdGroup.GET("/area/:task_id", a.alarmController.GetAreaThresholdAlarm)
thresholdGroup.PUT("/area/:task_id", a.alarmController.UpdateAreaThresholdAlarm)

View File

@@ -179,6 +179,76 @@ func (t *ThresholdAlarmController) ListHistoricalAlarms(ctx echo.Context) error
return controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "成功获取历史告警列表", resp, actionType, "成功获取历史告警列表", req)
}
// ListDeviceThresholdAlarms godoc
// @Summary 批量查询设备阈值告警
// @Description 根据过滤条件和分页参数查询设备阈值告警列表
// @Tags 告警管理
// @Security BearerAuth
// @Accept json
// @Produce json
// @Param query query dto.ListDeviceThresholdAlarmRequest true "查询参数"
// @Success 200 {object} controller.Response{data=dto.ListDeviceThresholdAlarmResponse} "成功获取设备阈值告警列表"
// @Router /api/v1/alarm/threshold/device [get]
func (t *ThresholdAlarmController) ListDeviceThresholdAlarms(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), t.ctx, "ListDeviceThresholdAlarms")
const actionType = "批量查询设备阈值告警"
var req dto.ListDeviceThresholdAlarmRequest
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.ListDeviceThresholdAlarms(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)
}
// ListAreaThresholdAlarms godoc
// @Summary 批量查询区域阈值告警
// @Description 根据过滤条件和分页参数查询区域阈值告警列表
// @Tags 告警管理
// @Security BearerAuth
// @Accept json
// @Produce json
// @Param query query dto.ListAreaThresholdAlarmRequest true "查询参数"
// @Success 200 {object} controller.Response{data=dto.ListAreaThresholdAlarmResponse} "成功获取区域阈值告警列表"
// @Router /api/v1/alarm/threshold/area [get]
func (t *ThresholdAlarmController) ListAreaThresholdAlarms(ctx echo.Context) error {
reqCtx, logger := logs.Trace(ctx.Request().Context(), t.ctx, "ListAreaThresholdAlarms")
const actionType = "批量查询区域阈值告警"
var req dto.ListAreaThresholdAlarmRequest
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.ListAreaThresholdAlarms(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)
}
// CreateDeviceThresholdAlarm godoc
// @Summary 创建设备阈值告警
// @Description 为单个设备创建一条新的阈值告警规则

View File

@@ -69,7 +69,7 @@ type HistoricalAlarmDTO struct {
AlarmCode models.AlarmCode `json:"alarm_code"`
AlarmSummary string `json:"alarm_summary"`
Level models.SeverityLevel `json:"level"`
AlarmDetails string `json:"alarm_details"`
AlarmDetails string `json:"json_details"`
TriggerTime time.Time `json:"trigger_time"`
ResolveTime time.Time `json:"resolve_time"`
ResolveMethod string `json:"resolve_method"`
@@ -138,3 +138,35 @@ type DeviceThresholdAlarmDTO struct {
Operator models.Operator `json:"operator"`
Level models.SeverityLevel `json:"level"`
}
// ListDeviceThresholdAlarmRequest 定义了获取设备阈值告警列表的请求参数
type ListDeviceThresholdAlarmRequest struct {
Page int `json:"page" query:"page"`
PageSize int `json:"page_size" query:"page_size"`
DeviceID *uint32 `json:"device_id" query:"device_id"` // 按设备ID过滤
SensorType *models.SensorType `json:"sensor_type" query:"sensor_type"` // 按传感器类型过滤
Level *models.SeverityLevel `json:"level" query:"level"` // 按告警等级过滤
OrderBy string `json:"order_by" query:"order_by"` // 排序字段,例如 "id DESC"
}
// ListDeviceThresholdAlarmResponse 是获取设备阈值告警列表的响应结构
type ListDeviceThresholdAlarmResponse struct {
List []DeviceThresholdAlarmDTO `json:"list"`
Pagination PaginationDTO `json:"pagination"`
}
// ListAreaThresholdAlarmRequest 定义了获取区域阈值告警列表的请求参数
type ListAreaThresholdAlarmRequest struct {
Page int `json:"page" query:"page"`
PageSize int `json:"page_size" query:"page_size"`
AreaControllerID *uint32 `json:"area_controller_id" query:"area_controller_id"` // 按区域主控ID过滤
SensorType *models.SensorType `json:"sensor_type" query:"sensor_type"` // 按传感器类型过滤
Level *models.SeverityLevel `json:"level" query:"level"` // 按告警等级过滤
OrderBy string `json:"order_by" query:"order_by"` // 排序字段,例如 "id DESC"
}
// ListAreaThresholdAlarmResponse 是获取区域阈值告警列表的响应结构
type ListAreaThresholdAlarmResponse struct {
List []AreaThresholdAlarmDTO `json:"list"`
Pagination PaginationDTO `json:"pagination"`
}

View File

@@ -36,6 +36,8 @@ type ThresholdAlarmService interface {
DeleteDeviceThresholdAlarm(ctx context.Context, taskID int, req *dto.DeleteDeviceThresholdAlarmDTO) error
// DeleteDeviceThresholdAlarmByDeviceID 实现了根据设备ID删除一个设备下所有设备阈值告警的逻辑。
DeleteDeviceThresholdAlarmByDeviceID(ctx context.Context, deviceID uint32) error
// ListDeviceThresholdAlarms 批量查询设备阈值告警配置。
ListDeviceThresholdAlarms(ctx context.Context, req *dto.ListDeviceThresholdAlarmRequest) (*dto.ListDeviceThresholdAlarmResponse, error)
// CreateAreaThresholdAlarm 创建一个区域阈值告警。
CreateAreaThresholdAlarm(ctx context.Context, req *dto.CreateAreaThresholdAlarmDTO) error
@@ -47,6 +49,8 @@ type ThresholdAlarmService interface {
DeleteAreaThresholdAlarm(ctx context.Context, taskID int) error
// DeleteAreaThresholdAlarmByAreaControllerID 实现了根据区域ID删除一个区域下所有区域阈值告警的逻辑。
DeleteAreaThresholdAlarmByAreaControllerID(ctx context.Context, areaControllerID uint32) error
// ListAreaThresholdAlarms 批量查询区域阈值告警配置。
ListAreaThresholdAlarms(ctx context.Context, req *dto.ListAreaThresholdAlarmRequest) (*dto.ListAreaThresholdAlarmResponse, error)
}
// thresholdAlarmService 是 ThresholdAlarmService 接口的具体实现。
@@ -444,6 +448,110 @@ func (s *thresholdAlarmService) DeleteDeviceThresholdAlarmByDeviceID(ctx context
}
// ListDeviceThresholdAlarms 实现了批量查询设备阈值告警配置的逻辑。
func (s *thresholdAlarmService) ListDeviceThresholdAlarms(ctx context.Context, req *dto.ListDeviceThresholdAlarmRequest) (*dto.ListDeviceThresholdAlarmResponse, error) {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "ListDeviceThresholdAlarms")
// 1. 准备调用 planRepo.ListTasks 的选项
taskType := models.TaskTypeDeviceThresholdCheck
opts := repository.TaskListOptions{
Type: &taskType,
DeviceID: req.DeviceID,
SensorType: req.SensorType,
Level: req.Level,
OrderBy: req.OrderBy,
}
// 2. 调用底层的 ListTasks 方法
tasks, total, err := s.planRepo.ListTasks(serviceCtx, opts, req.Page, req.PageSize)
if err != nil {
return nil, fmt.Errorf("查询设备阈值告警任务失败: %w", err)
}
// 3. 将查询到的 models.Task 列表转换为 dto.DeviceThresholdAlarmDTO 列表
alarmDTOs := make([]dto.DeviceThresholdAlarmDTO, 0, len(tasks))
for _, t := range tasks {
var params task.DeviceThresholdCheckParams
if err := t.ParseParameters(&params); err != nil {
logger.Warnf("解析任务 %d 的参数失败: %v已在列表中跳过", t.ID, err)
continue
}
alarmDTOs = append(alarmDTOs, dto.DeviceThresholdAlarmDTO{
ID: t.ID,
DeviceID: params.DeviceID,
SensorType: params.SensorType,
Thresholds: params.Thresholds,
Operator: params.Operator,
Level: params.Level,
})
}
// 4. 构建并返回响应
response := &dto.ListDeviceThresholdAlarmResponse{
List: alarmDTOs,
Pagination: dto.PaginationDTO{
Total: total,
Page: req.Page,
PageSize: req.PageSize,
},
}
return response, nil
}
// ListAreaThresholdAlarms 实现了批量查询区域阈值告警配置的逻辑。
func (s *thresholdAlarmService) ListAreaThresholdAlarms(ctx context.Context, req *dto.ListAreaThresholdAlarmRequest) (*dto.ListAreaThresholdAlarmResponse, error) {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "ListAreaThresholdAlarms")
// 1. 准备调用 planRepo.ListTasks 的选项
taskType := models.TaskTypeAreaCollectorThresholdCheck
opts := repository.TaskListOptions{
Type: &taskType,
AreaControllerID: req.AreaControllerID,
SensorType: req.SensorType,
Level: req.Level,
OrderBy: req.OrderBy,
}
// 2. 调用底层的 ListTasks 方法
tasks, total, err := s.planRepo.ListTasks(serviceCtx, opts, req.Page, req.PageSize)
if err != nil {
return nil, fmt.Errorf("查询区域阈值告警任务失败: %w", err)
}
// 3. 将查询到的 models.Task 列表转换为 dto.AreaThresholdAlarmDTO 列表
alarmDTOs := make([]dto.AreaThresholdAlarmDTO, 0, len(tasks))
for _, t := range tasks {
var params task.AreaThresholdCheckParams
if err := t.ParseParameters(&params); err != nil {
logger.Warnf("解析区域任务 %d 的参数失败: %v已在列表中跳过", t.ID, err)
continue
}
alarmDTOs = append(alarmDTOs, dto.AreaThresholdAlarmDTO{
ID: t.ID,
AreaControllerID: params.AreaControllerID,
SensorType: params.SensorType,
Thresholds: params.Thresholds,
Operator: params.Operator,
Level: params.Level,
})
}
// 4. 构建并返回响应
response := &dto.ListAreaThresholdAlarmResponse{
List: alarmDTOs,
Pagination: dto.PaginationDTO{
Total: total,
Page: req.Page,
PageSize: req.PageSize,
},
}
return response, nil
}
// CreateAreaThresholdAlarm 实现了创建一个区域阈值告警的逻辑。
func (s *thresholdAlarmService) CreateAreaThresholdAlarm(ctx context.Context, req *dto.CreateAreaThresholdAlarmDTO) error {
serviceCtx, logger := logs.Trace(ctx, s.ctx, "CreateAreaThresholdAlarm")

View File

@@ -100,7 +100,7 @@ func (app *Application) initializePeriodicSystemHealthCheckPlan(ctx context.Cont
delayParams := task.DelayTaskParams{DelayDuration: 10} // 延时10秒
delayTask := models.Task{
Name: "延时任务",
Description: "系统预设延时任务,用于错峰处理",
Description: "系统预设延时任务,用于等待设备上传数据",
ExecutionOrder: 2,
Type: models.TaskTypeWaiting,
}

View File

@@ -38,6 +38,29 @@ type ListPlansOptions struct {
PlanType PlanTypeFilter
}
// TaskListOptions 定义了查询任务时的可选参数
type TaskListOptions struct {
// --- 通用筛选 ---
Name *string // 按任务名称进行模糊查询
PlanID *uint32 // 按所属的计划ID进行精确查询
Type *models.TaskType // 按任务类型精确查询
// --- 关联筛选 ---
// 用于通过 device_tasks 关联表筛选与特定设备ID关联的任务
DeviceID *uint32
// --- JSON 参数内筛选 (仅对特定任务类型有效) ---
// 用于筛选 TaskTypeAreaCollectorThresholdCheck 类型的任务
AreaControllerID *uint32
// 用于筛选 TaskTypeDeviceThresholdCheck 和 TaskTypeAreaCollectorThresholdCheck 类型的任务
SensorType *models.SensorType
// 用于筛选 TaskTypeDeviceThresholdCheck 和 TaskTypeAreaCollectorThresholdCheck 类型的任务
Level *models.SeverityLevel
// --- 排序 ---
OrderBy string // 例如 "id desc"
}
// PlanRepository 定义了与计划模型相关的数据库操作接口
// 这是为了让业务逻辑层依赖于抽象,而不是具体的数据库实现
type PlanRepository interface {
@@ -89,6 +112,8 @@ type PlanRepository interface {
UpdatePlanStateAfterExecution(ctx context.Context, planID uint32, newCount uint32, newStatus models.PlanStatus) error
// ListTasksByDeviceID 根据设备ID获取关联任务列表
ListTasksByDeviceID(ctx context.Context, deviceID uint32) ([]*models.Task, error)
// ListTasks 支持分页和过滤的任务列表查询
ListTasks(ctx context.Context, opts TaskListOptions, page, pageSize int) ([]models.Task, int64, error)
}
// gormPlanRepository 是 PlanRepository 的 GORM 实现
@@ -896,3 +921,74 @@ func (r *gormPlanRepository) ListTasksByDeviceID(ctx context.Context, deviceID u
return tasks, nil
}
// ListTasks 实现了分页和过滤查询任务的功能,并优化了 JOIN 后的计数逻辑
func (r *gormPlanRepository) ListTasks(ctx context.Context, opts TaskListOptions, page, pageSize int) ([]models.Task, int64, error) {
repoCtx := logs.AddFuncName(ctx, r.ctx, "ListTasks")
if page <= 0 || pageSize <= 0 {
return nil, 0, ErrInvalidPagination
}
var results []models.Task
var total int64
// 1. 构建基础查询,应用所有筛选条件
query := r.db.WithContext(repoCtx).Model(&models.Task{})
if opts.Name != nil && *opts.Name != "" {
query = query.Where("tasks.name LIKE ?", "%"+*opts.Name+"%")
}
if opts.PlanID != nil {
query = query.Where("tasks.plan_id = ?", *opts.PlanID)
}
if opts.Type != nil {
query = query.Where("tasks.type = ?", *opts.Type)
}
// --- JSON 字段查询 ---
if opts.AreaControllerID != nil {
// 使用 ->> 操作符查询 JSON 字段的值(作为文本)
query = query.Where("parameters->>'area_controller_id' = ?", *opts.AreaControllerID)
}
if opts.SensorType != nil {
query = query.Where("parameters->>'sensor_type' = ?", *opts.SensorType)
}
if opts.Level != nil {
query = query.Where("parameters->>'level' = ?", *opts.Level)
}
// --- 结束 ---
if opts.DeviceID != nil {
query = query.Joins("JOIN device_tasks ON device_tasks.task_id = tasks.id").Where("device_tasks.device_id = ?", *opts.DeviceID)
}
// 2. 执行计数查询
countQuery := query
if opts.DeviceID != nil {
if err := countQuery.Distinct("tasks.id").Count(&total).Error; err != nil {
return nil, 0, err
}
} else {
if err := countQuery.Count(&total).Error; err != nil {
return nil, 0, err
}
}
if total == 0 {
return []models.Task{}, 0, nil
}
// 3. 为数据查询应用排序、分页和预加载
orderBy := "tasks.id DESC"
if opts.OrderBy != "" {
orderBy = opts.OrderBy
}
err := query.Order(orderBy).
Limit(pageSize).
Offset((page - 1) * pageSize).
Preload("Devices").
Find(&results).Error
return results, total, err
}

View File

@@ -32,7 +32,7 @@ design/archive/2025-11-05-provide-logger-with-mothed/task-service.md
design/archive/2025-11-05-provide-logger-with-mothed/task-webhook.md
design/archive/2025-11-06-health-check-routing/index.md
design/archive/2025-11-06-system-plan-continuously-triggered/index.md
design/exceeding-threshold-alarm/index.md
design/archive/2025-11-10-exceeding-threshold-alarm/index.md
docs/docs.go
docs/swagger.json
docs/swagger.yaml