mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-02-04 04:30:05 +00:00
implement notification group (#450)
* implement notification group * some fixes * fix sql * add listNotification * retrieve notification from map * create notification_group_notification if non-exist * NotificationIDToGroup -> NotificationIDToGroups * clean
This commit is contained in:
@@ -66,10 +66,20 @@ func routers(r *gin.Engine) {
|
||||
auth.PATCH("/server-group/:id", commonHandler(updateServerGroup))
|
||||
auth.POST("/batch-delete/server-group", commonHandler(batchDeleteServerGroup))
|
||||
|
||||
auth.GET("/notification-group", commonHandler(listNotificationGroup))
|
||||
auth.POST("/notification-group", commonHandler(createNotificationGroup))
|
||||
auth.PATCH("/notification-group/:id", commonHandler(updateNotificationGroup))
|
||||
auth.POST("/batch-delete/notification-group", commonHandler(batchDeleteNotificationGroup))
|
||||
|
||||
auth.GET("/server", commonHandler(listServer))
|
||||
auth.PATCH("/server/:id", commonHandler(updateServer))
|
||||
auth.POST("/batch-delete/server", commonHandler(batchDeleteServer))
|
||||
|
||||
auth.GET("/notification", commonHandler(listNotification))
|
||||
auth.POST("/notification", commonHandler(createNotification))
|
||||
auth.PATCH("/notification/:id", commonHandler(updateNotification))
|
||||
auth.POST("/batch-delete/notification", commonHandler(batchDeleteNotification))
|
||||
|
||||
auth.GET("/ddns", commonHandler(listDDNS))
|
||||
auth.GET("/ddns/providers", commonHandler(listProviders))
|
||||
auth.POST("/ddns", commonHandler(createDDNS))
|
||||
|
||||
@@ -37,8 +37,8 @@ func createDDNS(c *gin.Context) (uint64, error) {
|
||||
}
|
||||
|
||||
p.Name = df.Name
|
||||
enableIPv4 := df.EnableIPv4 == "on"
|
||||
enableIPv6 := df.EnableIPv6 == "on"
|
||||
enableIPv4 := df.EnableIPv4
|
||||
enableIPv6 := df.EnableIPv6
|
||||
p.EnableIPv4 = &enableIPv4
|
||||
p.EnableIPv6 = &enableIPv6
|
||||
p.MaxRetries = df.MaxRetries
|
||||
@@ -107,8 +107,8 @@ func updateDDNS(c *gin.Context) (any, error) {
|
||||
|
||||
p.Name = df.Name
|
||||
p.ID = id
|
||||
enableIPv4 := df.EnableIPv4 == "on"
|
||||
enableIPv6 := df.EnableIPv6 == "on"
|
||||
enableIPv4 := df.EnableIPv4
|
||||
enableIPv6 := df.EnableIPv6
|
||||
p.EnableIPv4 = &enableIPv4
|
||||
p.EnableIPv6 = &enableIPv6
|
||||
p.MaxRetries = df.MaxRetries
|
||||
|
||||
@@ -173,16 +173,7 @@ func (ma *memberAPI) delete(c *gin.Context) {
|
||||
|
||||
var err error
|
||||
switch c.Param("model") {
|
||||
case "notification":
|
||||
err = singleton.DB.Unscoped().Delete(&model.Notification{}, "id = ?", id).Error
|
||||
if err == nil {
|
||||
singleton.OnDeleteNotification(id)
|
||||
}
|
||||
case "ddns":
|
||||
err = singleton.DB.Unscoped().Delete(&model.DDNSProfile{}, "id = ?", id).Error
|
||||
if err == nil {
|
||||
singleton.OnDDNSUpdate()
|
||||
}
|
||||
|
||||
case "nat":
|
||||
err = singleton.DB.Unscoped().Delete(&model.NAT{}, "id = ?", id).Error
|
||||
if err == nil {
|
||||
@@ -224,13 +215,13 @@ func (ma *memberAPI) delete(c *gin.Context) {
|
||||
}
|
||||
|
||||
type monitorForm struct {
|
||||
ID uint64
|
||||
Name string
|
||||
Target string
|
||||
Type uint8
|
||||
Cover uint8
|
||||
Notify string
|
||||
NotificationTag string
|
||||
ID uint64
|
||||
Name string
|
||||
Target string
|
||||
Type uint8
|
||||
Cover uint8
|
||||
Notify string
|
||||
//NotificationTag string
|
||||
SkipServersRaw string
|
||||
Duration uint64
|
||||
MinLatency float32
|
||||
@@ -254,7 +245,7 @@ func (ma *memberAPI) addOrEditMonitor(c *gin.Context) {
|
||||
m.SkipServersRaw = mf.SkipServersRaw
|
||||
m.Cover = mf.Cover
|
||||
m.Notify = mf.Notify == "on"
|
||||
m.NotificationTag = mf.NotificationTag
|
||||
//m.NotificationTag = mf.NotificationTag
|
||||
m.Duration = mf.Duration
|
||||
m.LatencyNotify = mf.LatencyNotify == "on"
|
||||
m.MinLatency = mf.MinLatency
|
||||
@@ -267,9 +258,9 @@ func (ma *memberAPI) addOrEditMonitor(c *gin.Context) {
|
||||
}
|
||||
if err == nil {
|
||||
// 保证NotificationTag不为空
|
||||
if m.NotificationTag == "" {
|
||||
m.NotificationTag = "default"
|
||||
}
|
||||
//if m.NotificationTag == "" {
|
||||
// m.NotificationTag = "default"
|
||||
//}
|
||||
err = utils.Json.Unmarshal([]byte(mf.FailTriggerTasksRaw), &m.FailTriggerTasks)
|
||||
}
|
||||
if err == nil {
|
||||
@@ -327,7 +318,7 @@ func (ma *memberAPI) addOrEditCron(c *gin.Context) {
|
||||
cr.Command = cf.Command
|
||||
cr.ServersRaw = cf.ServersRaw
|
||||
cr.PushSuccessful = cf.PushSuccessful == "on"
|
||||
cr.NotificationTag = cf.NotificationTag
|
||||
//cr.NotificationTag = cf.NotificationTag
|
||||
cr.ID = cf.ID
|
||||
cr.Cover = cf.Cover
|
||||
err = utils.Json.Unmarshal([]byte(cf.ServersRaw), &cr.Servers)
|
||||
@@ -346,9 +337,9 @@ func (ma *memberAPI) addOrEditCron(c *gin.Context) {
|
||||
tx := singleton.DB.Begin()
|
||||
if err == nil {
|
||||
// 保证NotificationTag不为空
|
||||
if cr.NotificationTag == "" {
|
||||
cr.NotificationTag = "default"
|
||||
}
|
||||
//if cr.NotificationTag == "" {
|
||||
// cr.NotificationTag = "default"
|
||||
//}
|
||||
if cf.ID == 0 {
|
||||
err = tx.Create(&cr).Error
|
||||
} else {
|
||||
@@ -507,7 +498,6 @@ func (ma *memberAPI) forceUpdate(c *gin.Context) {
|
||||
type notificationForm struct {
|
||||
ID uint64
|
||||
Name string
|
||||
Tag string // 分组名
|
||||
URL string
|
||||
RequestMethod int
|
||||
RequestType int
|
||||
@@ -523,7 +513,6 @@ func (ma *memberAPI) addOrEditNotification(c *gin.Context) {
|
||||
err := c.ShouldBindJSON(&nf)
|
||||
if err == nil {
|
||||
n.Name = nf.Name
|
||||
n.Tag = nf.Tag
|
||||
n.RequestMethod = nf.RequestMethod
|
||||
n.RequestType = nf.RequestType
|
||||
n.RequestHeader = nf.RequestHeader
|
||||
@@ -543,10 +532,6 @@ func (ma *memberAPI) addOrEditNotification(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
// 保证Tag不为空
|
||||
if n.Tag == "" {
|
||||
n.Tag = "default"
|
||||
}
|
||||
if n.ID == 0 {
|
||||
err = singleton.DB.Create(&n).Error
|
||||
} else {
|
||||
@@ -730,7 +715,7 @@ func (ma *memberAPI) addOrEditAlertRule(c *gin.Context) {
|
||||
r.RulesRaw = arf.RulesRaw
|
||||
r.FailTriggerTasksRaw = arf.FailTriggerTasksRaw
|
||||
r.RecoverTriggerTasksRaw = arf.RecoverTriggerTasksRaw
|
||||
r.NotificationTag = arf.NotificationTag
|
||||
//r.NotificationTag = arf.NotificationTag
|
||||
enable := arf.Enable == "on"
|
||||
r.TriggerMode = arf.TriggerMode
|
||||
r.Enable = &enable
|
||||
@@ -744,9 +729,9 @@ func (ma *memberAPI) addOrEditAlertRule(c *gin.Context) {
|
||||
}
|
||||
//保证NotificationTag不为空
|
||||
if err == nil {
|
||||
if r.NotificationTag == "" {
|
||||
r.NotificationTag = "default"
|
||||
}
|
||||
//if r.NotificationTag == "" {
|
||||
// r.NotificationTag = "default"
|
||||
//}
|
||||
if r.ID == 0 {
|
||||
err = singleton.DB.Create(&r).Error
|
||||
} else {
|
||||
|
||||
170
cmd/dashboard/controller/notification.go
Normal file
170
cmd/dashboard/controller/notification.go
Normal file
@@ -0,0 +1,170 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/naiba/nezha/model"
|
||||
"github.com/naiba/nezha/service/singleton"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// List notification
|
||||
// @Summary List notification
|
||||
// @Security BearerAuth
|
||||
// @Schemes
|
||||
// @Description List notification
|
||||
// @Tags auth required
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[any]
|
||||
// @Router /notification [get]
|
||||
func listNotification(c *gin.Context) ([]model.Notification, error) {
|
||||
singleton.NotificationsLock.RLock()
|
||||
defer singleton.NotificationsLock.RUnlock()
|
||||
notifications := make([]model.Notification, 0, len(singleton.NotificationMap))
|
||||
for _, n := range singleton.NotificationMap {
|
||||
notifications = append(notifications, *n)
|
||||
}
|
||||
return notifications, nil
|
||||
}
|
||||
|
||||
// Add notification
|
||||
// @Summary Add notification
|
||||
// @Security BearerAuth
|
||||
// @Schemes
|
||||
// @Description Add notification
|
||||
// @Tags auth required
|
||||
// @Accept json
|
||||
// @param request body model.NotificationForm true "NotificationForm"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[any]
|
||||
// @Router /notification [post]
|
||||
func createNotification(c *gin.Context) (uint64, error) {
|
||||
var nf model.NotificationForm
|
||||
if err := c.ShouldBindJSON(&nf); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var n model.Notification
|
||||
n.Name = nf.Name
|
||||
n.RequestMethod = nf.RequestMethod
|
||||
n.RequestType = nf.RequestType
|
||||
n.RequestHeader = nf.RequestHeader
|
||||
n.RequestBody = nf.RequestBody
|
||||
n.URL = nf.URL
|
||||
verifySSL := nf.VerifySSL
|
||||
n.VerifySSL = &verifySSL
|
||||
n.ID = nf.ID
|
||||
ns := model.NotificationServerBundle{
|
||||
Notification: &n,
|
||||
Server: nil,
|
||||
Loc: singleton.Loc,
|
||||
}
|
||||
// 未勾选跳过检查
|
||||
if !nf.SkipCheck {
|
||||
if err := ns.Send("这是测试消息"); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := singleton.DB.Create(&n).Error; err != nil {
|
||||
return 0, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnRefreshOrAddNotification(&n)
|
||||
return n.ID, nil
|
||||
}
|
||||
|
||||
// Edit notification
|
||||
// @Summary Edit notification
|
||||
// @Security BearerAuth
|
||||
// @Schemes
|
||||
// @Description Edit notification
|
||||
// @Tags auth required
|
||||
// @Accept json
|
||||
// @Param id path uint true "Notification ID"
|
||||
// @Param body body model.NotificationForm true "NotificationForm"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[any]
|
||||
// @Router /notification/{id} [patch]
|
||||
func updateNotification(c *gin.Context) (any, error) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var nf model.NotificationForm
|
||||
if err := c.ShouldBindJSON(&nf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var n model.Notification
|
||||
if err := singleton.DB.First(&n, id).Error; err != nil {
|
||||
return nil, fmt.Errorf("notification id %d does not exist", id)
|
||||
}
|
||||
|
||||
n.Name = nf.Name
|
||||
n.RequestMethod = nf.RequestMethod
|
||||
n.RequestType = nf.RequestType
|
||||
n.RequestHeader = nf.RequestHeader
|
||||
n.RequestBody = nf.RequestBody
|
||||
n.URL = nf.URL
|
||||
verifySSL := nf.VerifySSL
|
||||
n.VerifySSL = &verifySSL
|
||||
n.ID = nf.ID
|
||||
ns := model.NotificationServerBundle{
|
||||
Notification: &n,
|
||||
Server: nil,
|
||||
Loc: singleton.Loc,
|
||||
}
|
||||
// 未勾选跳过检查
|
||||
if !nf.SkipCheck {
|
||||
if err := ns.Send("这是测试消息"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := singleton.DB.Save(&n).Error; err != nil {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnRefreshOrAddNotification(&n)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Batch delete notifications
|
||||
// @Summary Batch delete notifications
|
||||
// @Security BearerAuth
|
||||
// @Schemes
|
||||
// @Description Batch delete notifications
|
||||
// @Tags auth required
|
||||
// @Accept json
|
||||
// @param request body []uint64 true "id list"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[any]
|
||||
// @Router /batch-delete/notification [post]
|
||||
func batchDeleteNotification(c *gin.Context) (any, error) {
|
||||
var n []uint64
|
||||
|
||||
if err := c.ShouldBindJSON(&n); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err := singleton.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Unscoped().Delete(&model.Notification{}, "id in (?)", n).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Unscoped().Delete(&model.NotificationGroupNotification{}, "notification_id in (?)", n).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnDeleteNotification(n)
|
||||
return nil, nil
|
||||
}
|
||||
205
cmd/dashboard/controller/notification_group.go
Normal file
205
cmd/dashboard/controller/notification_group.go
Normal file
@@ -0,0 +1,205 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/naiba/nezha/model"
|
||||
"github.com/naiba/nezha/service/singleton"
|
||||
)
|
||||
|
||||
// List notification group
|
||||
// @Summary List notification group
|
||||
// @Schemes
|
||||
// @Description List notification group
|
||||
// @Security BearerAuth
|
||||
// @Tags common
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[[]model.NotificationGroupResponseItem]
|
||||
// @Router /notification-group [get]
|
||||
func listNotificationGroup(c *gin.Context) ([]model.NotificationGroupResponseItem, error) {
|
||||
var ng []model.NotificationGroup
|
||||
if err := singleton.DB.Find(&ng).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ngn []model.NotificationGroupNotification
|
||||
if err := singleton.DB.Find(&ngn).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
groupNotifications := make(map[uint64][]uint64, len(ng))
|
||||
for _, n := range ngn {
|
||||
if _, ok := groupNotifications[n.NotificationGroupID]; !ok {
|
||||
groupNotifications[n.NotificationGroupID] = make([]uint64, 0)
|
||||
}
|
||||
groupNotifications[n.NotificationGroupID] = append(groupNotifications[n.NotificationGroupID], n.NotificationID)
|
||||
}
|
||||
|
||||
ngRes := make([]model.NotificationGroupResponseItem, 0, len(ng))
|
||||
for _, n := range ng {
|
||||
ngRes = append(ngRes, model.NotificationGroupResponseItem{
|
||||
Group: n,
|
||||
Notifications: groupNotifications[n.ID],
|
||||
})
|
||||
}
|
||||
|
||||
return ngRes, nil
|
||||
}
|
||||
|
||||
// New notification group
|
||||
// @Summary New notification group
|
||||
// @Schemes
|
||||
// @Description New notification group
|
||||
// @Security BearerAuth
|
||||
// @Tags auth required
|
||||
// @Accept json
|
||||
// @Param body body model.NotificationGroupForm true "NotificationGroupForm"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[any]
|
||||
// @Router /notification-group [post]
|
||||
func createNotificationGroup(c *gin.Context) (uint64, error) {
|
||||
var ngf model.NotificationGroupForm
|
||||
if err := c.ShouldBindJSON(&ngf); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
ngf.Notifications = slices.Compact(ngf.Notifications)
|
||||
|
||||
var ng model.NotificationGroup
|
||||
ng.Name = ngf.Name
|
||||
|
||||
var count int64
|
||||
if err := singleton.DB.Model(&model.Notification{}).Where("id in (?)", ngf.Notifications).Count(&count).Error; err != nil {
|
||||
return 0, newGormError("%v", err)
|
||||
}
|
||||
|
||||
if count != int64(len(ngf.Notifications)) {
|
||||
return 0, fmt.Errorf("have invalid notification id")
|
||||
}
|
||||
|
||||
err := singleton.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Create(&ng).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range ngf.Notifications {
|
||||
if err := tx.Create(&model.NotificationGroupNotification{
|
||||
NotificationGroupID: ng.ID,
|
||||
NotificationID: n,
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return 0, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnRefreshOrAddNotificationGroup(&ng, ngf.Notifications)
|
||||
return ng.ID, nil
|
||||
}
|
||||
|
||||
// Edit notification group
|
||||
// @Summary Edit notification group
|
||||
// @Schemes
|
||||
// @Description Edit notification group
|
||||
// @Security BearerAuth
|
||||
// @Tags auth required
|
||||
// @Accept json
|
||||
// @Param id path string true "ID"
|
||||
// @Param body body model.NotificationGroupForm true "NotificationGroupForm"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[any]
|
||||
// @Router /notification-group/{id} [patch]
|
||||
func updateNotificationGroup(c *gin.Context) (any, error) {
|
||||
idStr := c.Param("id")
|
||||
|
||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ngf model.NotificationGroupForm
|
||||
if err := c.ShouldBindJSON(&ngf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ngDB model.NotificationGroup
|
||||
if err := singleton.DB.First(&ngDB, id).Error; err != nil {
|
||||
return nil, fmt.Errorf("group id %d does not exist", id)
|
||||
}
|
||||
|
||||
ngDB.Name = ngf.Name
|
||||
ngf.Notifications = slices.Compact(ngf.Notifications)
|
||||
|
||||
var count int64
|
||||
if err := singleton.DB.Model(&model.Server{}).Where("id in (?)", ngf.Notifications).Count(&count).Error; err != nil {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
if count != int64(len(ngf.Notifications)) {
|
||||
return nil, fmt.Errorf("have invalid notification id")
|
||||
}
|
||||
|
||||
err = singleton.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Save(&ngDB).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Delete(&model.NotificationGroupNotification{}, "notification_group_id = ?", id).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, n := range ngf.Notifications {
|
||||
if err := tx.Create(&model.NotificationGroupNotification{
|
||||
NotificationGroupID: ngDB.ID,
|
||||
NotificationID: n,
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnRefreshOrAddNotificationGroup(&ngDB, ngf.Notifications)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Batch delete notification group
|
||||
// @Summary Batch delete notification group
|
||||
// @Security BearerAuth
|
||||
// @Schemes
|
||||
// @Description Batch delete notification group
|
||||
// @Tags auth required
|
||||
// @Accept json
|
||||
// @param request body []uint64 true "id list"
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.CommonResponse[any]
|
||||
// @Router /batch-delete/notification-group [post]
|
||||
func batchDeleteNotificationGroup(c *gin.Context) (any, error) {
|
||||
var ngn []uint64
|
||||
if err := c.ShouldBindJSON(&ngn); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err := singleton.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Unscoped().Delete(&model.NotificationGroup{}, "id in (?)", ngn).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Unscoped().Delete(&model.NotificationGroupNotification{}, "notification_group_id in (?)", ngn).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnDeleteNotificationGroup(ngn)
|
||||
return nil, nil
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
@@ -64,13 +66,14 @@ func createServerGroup(c *gin.Context) (uint64, error) {
|
||||
if err := c.ShouldBindJSON(&sgf); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
sgf.Servers = slices.Compact(sgf.Servers)
|
||||
|
||||
var sg model.ServerGroup
|
||||
sg.Name = sgf.Name
|
||||
|
||||
var count int64
|
||||
if err := singleton.DB.Model(&model.Server{}).Where("id = ?", sgf.Servers).Count(&count).Error; err != nil {
|
||||
return 0, err
|
||||
if err := singleton.DB.Model(&model.Server{}).Where("id in (?)", sgf.Servers).Count(&count).Error; err != nil {
|
||||
return 0, newGormError("%v", err)
|
||||
}
|
||||
if count != int64(len(sgf.Servers)) {
|
||||
return 0, fmt.Errorf("have invalid server id")
|
||||
@@ -110,26 +113,34 @@ func createServerGroup(c *gin.Context) (uint64, error) {
|
||||
// @Success 200 {object} model.CommonResponse[any]
|
||||
// @Router /server-group/{id} [patch]
|
||||
func updateServerGroup(c *gin.Context) (any, error) {
|
||||
id := c.Param("id")
|
||||
idStr := c.Param("id")
|
||||
|
||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var sg model.ServerGroupForm
|
||||
if err := c.ShouldBindJSON(&sg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sg.Servers = slices.Compact(sg.Servers)
|
||||
|
||||
var sgDB model.ServerGroup
|
||||
if err := singleton.DB.First(&sgDB, id).Error; err != nil {
|
||||
return nil, fmt.Errorf("group id %s does not exist", id)
|
||||
return nil, fmt.Errorf("group id %d does not exist", id)
|
||||
}
|
||||
sgDB.Name = sg.Name
|
||||
|
||||
var count int64
|
||||
if err := singleton.DB.Model(&model.Server{}).Where("id = ?", sg.Servers).Count(&count).Error; err != nil {
|
||||
if err := singleton.DB.Model(&model.Server{}).Where("id in (?)", sg.Servers).Count(&count).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count != int64(len(sg.Servers)) {
|
||||
return nil, fmt.Errorf("have invalid server id")
|
||||
}
|
||||
|
||||
err := singleton.DB.Transaction(func(tx *gorm.DB) error {
|
||||
err = singleton.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Save(&sgDB).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user