package handler import ( "fmt" "math/rand" "net/http" "sync" "time" "silk-server-go/internal/middleware" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // notificationItem 通知项 type notificationItem struct { ID string `json:"id"` Channel string `json:"channel"` Target string `json:"target"` Title string `json:"title"` Body string `json:"body"` CreatedAt string `json:"createdAt"` } // 通知内存存储(后续可替换为 Redis) var ( notificationStore []notificationItem notificationMu sync.Mutex ) // RegisterNotificationRoutes 注册通知路由 func RegisterNotificationRoutes(rg *gin.RouterGroup, db *gorm.DB) { readPerm := middleware.RequirePermission(db, "alarm:read") rg.GET("/notifications", readPerm, listNotifications()) rg.POST("/notifications", readPerm, createNotification()) } // listNotifications 通知列表(上限200) func listNotifications() gin.HandlerFunc { return func(c *gin.Context) { notificationMu.Lock() defer notificationMu.Unlock() limit := 200 if len(notificationStore) < limit { limit = len(notificationStore) } // 返回最新的 limit 条(存储已按新到旧排序) result := make([]notificationItem, limit) copy(result, notificationStore[:limit]) c.JSON(http.StatusOK, result) } } // createNotification 手动发通知 func createNotification() gin.HandlerFunc { return func(c *gin.Context) { var body struct { Channel string `json:"channel"` Target string `json:"target"` Title string `json:"title"` Body string `json:"body"` } if err := c.ShouldBindJSON(&body); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } ntf := notificationItem{ ID: fmt.Sprintf("%d%d", time.Now().UnixNano(), rand.Intn(1000000)), Channel: body.Channel, Target: body.Target, Title: body.Title, Body: body.Body, CreatedAt: time.Now().Format(time.RFC3339), } notificationMu.Lock() // 插入到头部(最新在前) notificationStore = append([]notificationItem{ntf}, notificationStore...) // 保留最近 500 条 if len(notificationStore) > 500 { notificationStore = notificationStore[:500] } notificationMu.Unlock() c.JSON(http.StatusCreated, ntf) } }