package controller import ( "encoding/json" "net/http" "strings" "ezops/model" "github.com/gin-gonic/gin" ) // categoryLabels 告警集合中文名 // Logan.Li var categoryLabels = map[model.AlertNotifyCategory]string{ model.AlertNotifyHost: "主机监控", model.AlertNotifyMiddleware: "中间件监控", model.AlertNotifySite: "站点拨测", model.AlertNotifySNMP: "SNMP 监控", } // ensureNotifyPolicies 确保四类默认策略存在 // Logan.Li func (h *AlertHandler) ensureNotifyPolicies() { for _, cat := range model.AllAlertNotifyCategories { var p model.AlertNotifyPolicy h.db.Where("category = ?", cat).First(&p) if p.ID == 0 { h.db.Create(&model.AlertNotifyPolicy{ Category: cat, Label: categoryLabels[cat], Enabled: false, }) } } } // ListNotifyPolicies GET /alerts/notify-policies func (h *AlertHandler) ListNotifyPolicies(c *gin.Context) { h.ensureNotifyPolicies() var policies []model.AlertNotifyPolicy h.db.Order("id ASC").Find(&policies) c.JSON(http.StatusOK, model.Response{Code: 200, Data: gin.H{"list": policies, "total": len(policies)}}) } // UpsertNotifyPolicy PUT /alerts/notify-policies/:category func (h *AlertHandler) UpsertNotifyPolicy(c *gin.Context) { cat := model.AlertNotifyCategory(strings.TrimSpace(c.Param("category"))) if !isValidNotifyCategory(cat) { c.JSON(http.StatusBadRequest, model.Response{Code: 400, Message: "无效的告警集合类型"}) return } var req struct { Enabled *bool `json:"enabled"` ContactGroupIDs []uint `json:"contact_group_ids"` ContactIDs []uint `json:"contact_ids"` NotifyMode string `json:"notify_mode"` Description string `json:"description"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, model.Response{Code: 400, Message: "请求参数错误: " + err.Error()}) return } h.ensureNotifyPolicies() var policy model.AlertNotifyPolicy h.db.Where("category = ?", cat).First(&policy) updates := map[string]interface{}{} if req.Enabled != nil { updates["enabled"] = *req.Enabled } if req.ContactGroupIDs != nil { b, _ := json.Marshal(req.ContactGroupIDs) updates["contact_group_ids"] = string(b) } if req.ContactIDs != nil { b, _ := json.Marshal(req.ContactIDs) updates["contact_ids"] = string(b) } if req.NotifyMode != "" { updates["notify_mode"] = req.NotifyMode } if req.Description != "" || c.Request.ContentLength > 0 { updates["description"] = req.Description } if len(updates) > 0 { h.db.Model(&policy).Updates(updates) } h.db.Where("category = ?", cat).First(&policy) c.JSON(http.StatusOK, model.Response{Code: 200, Data: policy}) } // TestNotifyPolicy POST /alerts/notify-policies/:category/test func (h *AlertHandler) TestNotifyPolicy(c *gin.Context) { cat := model.AlertNotifyCategory(strings.TrimSpace(c.Param("category"))) if !isValidNotifyCategory(cat) { c.JSON(http.StatusBadRequest, model.Response{Code: 400, Message: "无效的告警集合类型"}) return } h.ensureNotifyPolicies() var policy model.AlertNotifyPolicy h.db.Where("category = ?", cat).First(&policy) label := categoryLabels[cat] title := buildNotifyTitle(h.db, "通知策略测试", label, "test", "info") content := buildAlertContent("通知策略测试", label, "test", "info", "这是一条测试通知,用于验证该告警集合的通知对象配置是否正确。", 0, 0) sent, skipped := dispatchToPolicyContacts(h.db, &policy, title, content, "info", true) if sent == 0 { msg := "未发送任何通知" if skipped > 0 { msg += "(策略未启用或未配置联系人)" } c.JSON(http.StatusBadRequest, model.Response{Code: 400, Message: msg}) return } c.JSON(http.StatusOK, model.Response{Code: 200, Data: gin.H{"sent": sent, "skipped": skipped}, Message: "测试通知已发送"}) } func isValidNotifyCategory(cat model.AlertNotifyCategory) bool { for _, c := range model.AllAlertNotifyCategories { if c == cat { return true } } return false }