92 lines
2.2 KiB
Go
92 lines
2.2 KiB
Go
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)
|
||
}
|
||
}
|