diff --git a/src/bean/entity/alert_list.go b/src/bean/entity/alert_list.go index 0829ffc99c5100397d7c37bb3123182eb3374048..6b5d9c6f0267fb6e5b90ef8f461e94c87e08ae23 100644 --- a/src/bean/entity/alert_list.go +++ b/src/bean/entity/alert_list.go @@ -24,6 +24,7 @@ type AlertList struct { Status int `json:"status"` // 状态,1:已恢复 2:未恢复 3:已关闭 IsDisposed int `json:"is_disposed"` // 是否处置(工单管理),1:已处置,2:未处置 DisposalContent string `json:"disposal_content"` // 处置内容(工单管理,结果反馈) + CloseRemark string `json:"close_remark"` // 关闭备注,预警关闭提醒 CreatedBy string `json:"created_by" xorm:"'created_by'"` // 创建人 CreatedAt jsontime.Time `json:"created_at" xorm:"'created_at'"` // 创建时间 UpdatedBy string `json:"updated_by" xorm:"'updated_by'"` // 更新人 diff --git a/src/bean/entity/alert_overview.go b/src/bean/entity/alert_overview.go index af85db31d6455d3e99ed6fde5b65fdb58b7c6b53..b29b092a7b1a10532b0feaddb3372ea53729e366 100644 --- a/src/bean/entity/alert_overview.go +++ b/src/bean/entity/alert_overview.go @@ -45,5 +45,5 @@ type AlertFrequencyDistribution struct { } func (a *AlertOverview) TableName() string { - return "alert_overview.go" + return "alert_overview" } diff --git a/src/bean/entity/alert_rules.go b/src/bean/entity/alert_rules.go index 65960812abeb457439310c4ec8f89d25d15a65f9..1033f80882f37ddfe161f5296a66b0ed9698332f 100644 --- a/src/bean/entity/alert_rules.go +++ b/src/bean/entity/alert_rules.go @@ -14,7 +14,7 @@ type AlertRules struct { Duration int `json:"duration" xorm:"'duration'"` // 持续时间 DurationUnit string `json:"duration_unit" xorm:"'duration_unit'"` // 持续时间单位 s m h CheckPeriod int `json:"check_period" xorm:"'check_period'"` // 检查周期 单位:分钟 - NotifyMethod string `json:"notify_method" xorm:"'notify_method'"` // 预警通知方式 all dingtalk sms + NotifyMethod string `json:"notify_method" xorm:"'notify_method'"` // 预警通知方式 dingtalk sms NotifyRecipients string `json:"notify_recipients" xorm:"notify_recipients"` // 预警推送用户 NotifyPushCount int `json:"notify_push_count" xorm:"'notify_push_count'"` // 消息推送次数 NotifyPushFrequency int `json:"notify_push_frequency" xorm:"'notify_push_frequency'"` // 消息推送频率 分钟 @@ -44,5 +44,5 @@ type AlertCondition struct { type NotifyRecipients struct { SystemAccount string `json:"system_account" form:"system_account" binding:"required"` UserName string `json:"user_name" form:"user_name" binding:"required"` - Phone string `json:"phone" form:"phone" binding:"required"` + Phone string `json:"phone" form:"phone" binding:"required,phone"` } diff --git a/src/bean/entity/push_record.go b/src/bean/entity/push_record.go index fafad4ff7395b1ef388c4b4d8ce8b4665c52f49f..9a01572b6fbe0ed0a0130941eb952327af9d2af4 100644 --- a/src/bean/entity/push_record.go +++ b/src/bean/entity/push_record.go @@ -6,7 +6,7 @@ type PushRecord struct { Id int `json:"id" xorm:"'id' pk autoincr"` // 主键id AlertRulesId string `json:"alert_rules_id" xorm:"'alert_rules_id'"` // 告警规则id RiskLevel int `json:"risk_level" xorm:"'risk_level'"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险 - NotifyMethod string `json:"notify_method" xorm:"'notify_method'"` // 预警通知方式 all dingtalk sms + NotifyMethod string `json:"notify_method" xorm:"'notify_method'"` // 预警通知方式 dingtalk sms SystemAccount string `json:"system_account" xorm:"system_account"` // 预警推送用户(NotifyRecipient) // 账号 PushTime jsontime.Time `json:"push_time" xorm:"'push_time'"` // 推送时间 PushType int `json:"push_type" xorm:"'push_type'"` // 推送类型,1:自动推送,2:手动推送 diff --git a/src/bean/vo/request/alert_list.go b/src/bean/vo/request/alert_list.go index cd84c796e7fbac83001944edbd68910867364458..4e10d2af6d729ffc8e4d33026e4a01c4749971bf 100644 --- a/src/bean/vo/request/alert_list.go +++ b/src/bean/vo/request/alert_list.go @@ -1,5 +1,7 @@ package request +import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" + type DetailAlertList struct { Id int `json:"id" form:"id" binding:"required"` } @@ -10,6 +12,20 @@ type UpdateAlertList struct { Keyword string `json:"keyword" form:"keyword"` // 预警点/分类/指标 } +type BatchPushAlertList struct { + Id string `json:"id" form:"id"` + Ids []string `json:"ids" form:"ids" binding:"required_without=Id"` // 预警ids + NotifyMethod []string `json:"notify_method" form:"notify_method" binding:"max=2,dive,oneof=dingtalk sms"` // 预警通知方式 dingtalk sms + NotifyRecipients []entity.NotifyRecipients `json:"notify_recipients" form:"notify_recipients" binding:"dive"` // 预警推送用户 +} + +type BatchCloseAlertList struct { + Id string `json:"id" form:"id"` + Ids []string `json:"ids" form:"ids" binding:"required_without=Id"` // 预警ids + CloseRemark string `json:"close_remark" form:"close_remark" binding:"required"` // 关闭备注 + DeferPush int `json:"defer_push" form:"defer_push" binding:"omitempty,oneof=0 1"` // 延迟三天推送: 0:否 1:是 三天内将不再自动推送该告警信息给处置人员,可手动推送,但告警数据依然会出现 +} + type ListAlertList struct { Id int `json:"id" form:"id"` RiskLevel int `json:"risk_level" form:"risk_level" binding:"omitempty,oneof=1 2 3 4"` // 风险等级,1:低风险,2:一般风险,3:较大风险,4:重大风险 diff --git a/src/bean/vo/request/alert_rules.go b/src/bean/vo/request/alert_rules.go index 388aed62fa07ac40c85f947485ee73e79517bd3f..2b624fea143605befbbf7a26a7b4991db82b2985 100644 --- a/src/bean/vo/request/alert_rules.go +++ b/src/bean/vo/request/alert_rules.go @@ -19,7 +19,7 @@ type AddAlertRules struct { Duration int `json:"duration" form:"duration" binding:"gte=0"` // 持续时间 DurationUnit string `json:"duration_unit" form:"duration_unit" binding:"oneof=s m h"` // 持续时间单位 s m h CheckPeriod int `json:"check_period" form:"check_period" binding:"oneof=1 3 5 10 20 30"` // 检查周期 单位:分钟 - NotifyMethod []string `json:"notify_method" form:"notify_method" binding:"max=2,dive,oneof=dingtalk sms"` // 预警通知方式 all dingtalk sms + NotifyMethod []string `json:"notify_method" form:"notify_method" binding:"max=2,dive,oneof=dingtalk sms"` // 预警通知方式 dingtalk sms NotifyRecipients []entity.NotifyRecipients `json:"notify_recipients" form:"notify_recipients" binding:"dive"` // 预警推送用户 NotifyPushCount int `json:"notify_push_count" form:"notify_push_count" binding:"gte=1"` // 消息推送次数 NotifyPushFrequency int `json:"notify_push_frequency" form:"notify_push_frequency" binding:"gte=1"` // 消息推送频率 分钟 @@ -42,7 +42,7 @@ type UpdateAlertRules struct { Duration int `json:"duration" form:"duration" binding:"gte=0"` // 持续时间 DurationUnit string `json:"duration_unit" form:"duration_unit" binding:"oneof=s m h"` // 持续时间单位 s m h CheckPeriod int `json:"check_period" form:"check_period" binding:"oneof=1 3 5 10 20 30"` // 检查周期 单位:分钟 - NotifyMethod []string `json:"notify_method" form:"notify_method" binding:"max=2,dive,oneof=dingtalk sms"` // 预警通知方式 all dingtalk sms + NotifyMethod []string `json:"notify_method" form:"notify_method" binding:"max=2,dive,oneof=dingtalk sms"` // 预警通知方式 dingtalk sms NotifyRecipients []entity.NotifyRecipients `json:"notify_recipients" form:"notify_recipients" binding:"dive"` // 预警推送用户 NotifyPushCount int `json:"notify_push_count" form:"notify_push_count" binding:"gte=1"` // 消息推送次数 NotifyPushFrequency int `json:"notify_push_frequency" form:"notify_push_frequency" binding:"gte=1"` // 消息推送频率 分钟 @@ -66,7 +66,7 @@ type DetailAlertRules struct { type ListAlertRules struct { // 请输入预警规则名称/预警对象/预警分类/预警指标 Id string `json:"id" form:"id"` - NotifyMethod string `json:"notify_method" form:"notify_method" binding:"omitempty,oneof=all dingtalk sms"` // 预警通知方式 all dingtalk sms + NotifyMethod string `json:"notify_method" form:"notify_method" binding:"omitempty,oneof=all dingtalk sms"` // 预警通知方式 dingtalk sms IsEnabled int `json:"is_enabled" form:"is_enabled" binding:"omitempty,oneof=1 2"` // 是否开启 1:是 2:否 Keyword string `json:"keyword" form:"keyword"` // 预警规则名称(指标名称) StartTime string `json:"start_time" form:"start_time" binding:"omitempty,datetime=2006-01-02 15:04:05"` diff --git a/src/bean/vo/response/alert_class_test.go b/src/bean/vo/response/alert_class_test.go deleted file mode 100644 index cdb03d5a91962faae25546e6c9e4ea3e1ad0a20f..0000000000000000000000000000000000000000 --- a/src/bean/vo/response/alert_class_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package response - -import ( - "fmt" - json "github.com/json-iterator/go" - "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" - "sort" - "testing" -) - -func BuildTree(nodes []entity.AlertClass) ([]*AlertClassNode, error) { - nodeMap := make(map[int]*AlertClassNode) - - // 创建所有节点并存储到映射表中 - for _, node := range nodes { - tree := &AlertClassNode{ - AlertClass: node, - Children: []*AlertClassNode{}, - } - nodeMap[node.ClassId] = tree - } - - var rootNodes []*AlertClassNode - for _, node := range nodes { - if node.ParentId == 0 { - rootNodes = append(rootNodes, nodeMap[node.ClassId]) - } else { - parent := nodeMap[node.ParentId] - if parent == nil { - return nil, fmt.Errorf("parent node not found for ClassId: %d", node.ClassId) - } - parent.Children = append(parent.Children, nodeMap[node.ClassId]) - } - } - sortTree(rootNodes) - - return rootNodes, nil -} - -func sortTree(nodes []*AlertClassNode) { - sort.Slice(nodes, func(i, j int) bool { - return nodes[i].SortOrder < nodes[j].SortOrder - }) - for _, node := range nodes { - sortTree(node.Children) - } -} - -func TestTree(t *testing.T) { - // 示例数据 - data := []entity.AlertClass{ - {ClassId: 1, ClassName: "Root", ParentId: 0, SortOrder: 0}, - {ClassId: 2, ClassName: "Child 1", ParentId: 1, SortOrder: 0}, - {ClassId: 3, ClassName: "Child 2", ParentId: 1, SortOrder: 0}, - {ClassId: 4, ClassName: "Grandchild 3", ParentId: 2, SortOrder: 3}, - {ClassId: 5, ClassName: "Grandchild 1", ParentId: 2, SortOrder: 1}, - {ClassId: 6, ClassName: "Grandchild 2", ParentId: 2, SortOrder: 2}, - } - - rootNodes, err := BuildTree(data) - if err != nil { - fmt.Println("Failed to build tree:", err) - return - } - - // 将树形结构转换为 JSON 字符串 - jsonData, err := json.Marshal(rootNodes) - if err != nil { - fmt.Println("Failed to marshal tree:", err) - return - } - - fmt.Println(string(jsonData)) -} diff --git a/src/controller/alert_list.go b/src/controller/alert_list.go index aa21524220d60c5b24e647547b5118ff0ba20716..770e25f95b87951408224d9dd82e438648e4ff6d 100644 --- a/src/controller/alert_list.go +++ b/src/controller/alert_list.go @@ -30,6 +30,48 @@ func UpdateAlertList(c *gin.Context) { SendJsonResponse(c, resp.OK, nil) } +func BatchPushAlertList(c *gin.Context) { + var req request.BatchPushAlertList + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.AlertListSvc{User: header.GetUser(c)} + db, err := client.GetDbClient() + if err != nil { + SendJsonResponse(c, resp.DbConnectError.WithError(err), nil) + return + } + err = svc.BatchPushAlertList(db.NewSession(), req) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, nil) +} + +func BatchCloseAlertList(c *gin.Context) { + var req request.BatchCloseAlertList + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.AlertListSvc{User: header.GetUser(c)} + db, err := client.GetDbClient() + if err != nil { + SendJsonResponse(c, resp.DbConnectError.WithError(err), nil) + return + } + err = svc.BatchCloseAlertList(db.NewSession(), req) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, nil) +} + func DetailAlertList(c *gin.Context) { var req request.DetailAlertList if err := c.ShouldBind(&req); err != nil { diff --git a/src/router/alertlistrouter.go.go b/src/router/alertlistrouter.go.go index 8bc089b3225e2f015f3a0f9f4927b2b3eedbe717..da144bfbf24f40d84997cf74d9718243de45b92f 100644 --- a/src/router/alertlistrouter.go.go +++ b/src/router/alertlistrouter.go.go @@ -14,5 +14,7 @@ func InitAlertListRouter(e *gin.Engine) { group.GET("", controller.DetailAlertList) group.GET("list", controller.ListAlertList) group.PUT("", controller.UpdateAlertList) + group.PUT("batch/push", controller.BatchPushAlertList) + group.PUT("batch/close", controller.BatchCloseAlertList) } } diff --git a/src/service/alert_list.go b/src/service/alert_list.go index c597a122015af061868896f2aa108ffd7cab473f..a1b5ae6b4b79f43327ebd6f55379194c3acc6247 100644 --- a/src/service/alert_list.go +++ b/src/service/alert_list.go @@ -5,7 +5,9 @@ import ( "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" + "go.uber.org/zap" "xorm.io/xorm" ) @@ -27,6 +29,22 @@ func (a *AlertListSvc) Update(session *xorm.Session, req request.UpdateAlertList return nil } +func (a *AlertListSvc) BatchPushAlertList(session *xorm.Session, req request.BatchPushAlertList) error { + now := jsontime.Now() + _ = now + // TODO 批量推送用户告警 + conf.Logger.Info("batch push", zap.Any("payload", req)) + return nil +} + +func (a *AlertListSvc) BatchCloseAlertList(session *xorm.Session, req request.BatchCloseAlertList) error { + now := jsontime.Now() + _ = now + // TODO 批量推送用户告警 + conf.Logger.Info("batch close", zap.Any("payload", req)) + return nil +} + func (a *AlertListSvc) GetDataById(req request.DetailAlertList) (resp response.AlertListItem, err error) { now := jsontime.Now() data := response.AlertListItem{ diff --git a/src/util/uuid.go b/src/util/uuid.go deleted file mode 100644 index 4509538811da8760ba6a29a81265826ddf96679b..0000000000000000000000000000000000000000 --- a/src/util/uuid.go +++ /dev/null @@ -1,15 +0,0 @@ -package util - -import ( - "github.com/google/uuid" - "strings" -) - -func NewUUID() string { - return uuid.New().String() -} - -func NewUUIDNoHyphens() string { - id := uuid.New().String() - return strings.Replace(id, "-", "", -1) -} diff --git a/src/util/valid.go b/src/util/valid.go index 352dae4f40b17157abdee828fd2b3dc7a7636879..a93fd793ebed36e71cfaa988abc2731cc8941c9d 100644 --- a/src/util/valid.go +++ b/src/util/valid.go @@ -7,7 +7,10 @@ import ( ut "github.com/go-playground/universal-translator" "github.com/go-playground/validator/v10" translations "github.com/go-playground/validator/v10/translations/zh" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" + "go.uber.org/zap" "reflect" + "regexp" ) var ( @@ -34,5 +37,35 @@ func RegValid() { return fld.Name }) - //validate.RegisterValidation("required_if", requiredIf) + err := validate.RegisterValidation("phone", validatePhone) + if err != nil { + conf.Logger.Info("validate register failed", zap.Error(err)) + } + setTranslation(validate, Trans) +} + +// 校验手机号 +func validatePhone(fl validator.FieldLevel) bool { + phone := fl.Field().String() + pattern := "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$" + regex, err := regexp.Compile(pattern) + if err != nil { + return false + } + isValid := regex.MatchString(phone) + return isValid +} + +// 中文翻译 +func setTranslation(validate *validator.Validate, trans ut.Translator) { + validate.RegisterTranslation( + "phone", + trans, + func(ut ut.Translator) error { + return ut.Add("phone", "{0}不是一个有效的手机号码!", true) + }, + func(ut ut.Translator, fe validator.FieldError) string { + return fmt.Sprintf("%s不是一个有效的手机号码!", fe.Field()) + }, + ) }