fix list apis (#453)

This commit is contained in:
UUBulb 2024-10-24 10:21:59 +08:00 committed by GitHub
parent 6b650169df
commit 7c784b31b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 112 additions and 69 deletions

View File

@ -7,12 +7,35 @@ import (
"strings" "strings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/jinzhu/copier"
"golang.org/x/net/idna" "golang.org/x/net/idna"
"github.com/naiba/nezha/model" "github.com/naiba/nezha/model"
"github.com/naiba/nezha/service/singleton" "github.com/naiba/nezha/service/singleton"
) )
// List DDNS Profiles
// @Summary List DDNS profiles
// @Schemes
// @Description List DDNS profiles
// @Security BearerAuth
// @Tags auth required
// @Produce json
// @Success 200 {object} model.CommonResponse[[]*model.DDNSProfile]
// @Router /ddns [get]
func listDDNS(c *gin.Context) ([]*model.DDNSProfile, error) {
var ddnsProfiles []*model.DDNSProfile
singleton.DDNSCacheLock.RLock()
defer singleton.DDNSCacheLock.RUnlock()
if err := copier.Copy(&ddnsProfiles, &singleton.DDNSList); err != nil {
return nil, err
}
return ddnsProfiles, nil
}
// Add DDNS profile // Add DDNS profile
// @Summary Add DDNS profile // @Summary Add DDNS profile
// @Security BearerAuth // @Security BearerAuth
@ -66,7 +89,8 @@ func createDDNS(c *gin.Context) (uint64, error) {
return 0, newGormError("%v", err) return 0, newGormError("%v", err)
} }
singleton.OnDDNSUpdate() singleton.OnDDNSUpdate(&p)
singleton.UpdateDDNSList()
return p.ID, nil return p.ID, nil
} }
@ -136,7 +160,8 @@ func updateDDNS(c *gin.Context) (any, error) {
return nil, newGormError("%v", err) return nil, newGormError("%v", err)
} }
singleton.OnDDNSUpdate() singleton.OnDDNSUpdate(&p)
singleton.UpdateDDNSList()
return nil, nil return nil, nil
} }
@ -163,60 +188,12 @@ func batchDeleteDDNS(c *gin.Context) (any, error) {
return nil, newGormError("%v", err) return nil, newGormError("%v", err)
} }
singleton.OnDDNSUpdate() singleton.OnDDNSDelete(ddnsConfigs)
singleton.UpdateDDNSList()
return nil, nil return nil, nil
} }
// List DDNS Profiles
// @Summary List DDNS profiles
// @Schemes
// @Description List DDNS profiles
// @Security BearerAuth
// @Tags auth required
// @param id query string false "Profile ID"
// @Produce json
// @Success 200 {object} model.CommonResponse[[]model.DDNSProfile]
// @Router /ddns [get]
func listDDNS(c *gin.Context) ([]model.DDNSProfile, error) {
var idList []uint64
idQuery := c.Query("id")
if idQuery != "" {
idListStr := strings.Split(idQuery, ",")
idList = make([]uint64, 0, len(idListStr))
for _, v := range idListStr {
id, err := strconv.ParseUint(v, 10, 64)
if err != nil {
return nil, err
}
idList = append(idList, id)
}
}
var ddnsProfiles []model.DDNSProfile
singleton.DDNSCacheLock.RLock()
if len(idList) > 0 {
ddnsProfiles = make([]model.DDNSProfile, 0, len(idList))
for _, id := range idList {
if profile, ok := singleton.DDNSCache[id]; ok {
ddnsProfiles = append(ddnsProfiles, *profile)
} else {
return nil, fmt.Errorf("profile id %d not found", id)
}
}
} else {
ddnsProfiles = make([]model.DDNSProfile, 0, len(singleton.DDNSCache))
for _, profile := range singleton.DDNSCache {
ddnsProfiles = append(ddnsProfiles, *profile)
}
}
singleton.DDNSCacheLock.RUnlock()
return ddnsProfiles, nil
}
// List DDNS Providers // List DDNS Providers
// @Summary List DDNS providers // @Summary List DDNS providers
// @Schemes // @Schemes

View File

@ -533,7 +533,7 @@ func (ma *memberAPI) addOrEditDDNS(c *gin.Context) {
}) })
return return
} }
singleton.OnDDNSUpdate() //singleton.OnDDNSUpdate()
c.JSON(http.StatusOK, model.Response{ c.JSON(http.StatusOK, model.Response{
Code: http.StatusOK, Code: http.StatusOK,
}) })

View File

@ -5,6 +5,7 @@ import (
"strconv" "strconv"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/jinzhu/copier"
"github.com/naiba/nezha/model" "github.com/naiba/nezha/model"
"github.com/naiba/nezha/service/singleton" "github.com/naiba/nezha/service/singleton"
"gorm.io/gorm" "gorm.io/gorm"
@ -17,14 +18,15 @@ import (
// @Description List notification // @Description List notification
// @Tags auth required // @Tags auth required
// @Produce json // @Produce json
// @Success 200 {object} model.CommonResponse[any] // @Success 200 {object} model.CommonResponse[[]*model.Notification]
// @Router /notification [get] // @Router /notification [get]
func listNotification(c *gin.Context) ([]model.Notification, error) { func listNotification(c *gin.Context) ([]*model.Notification, error) {
singleton.NotificationsLock.RLock() singleton.NotificationsLock.RLock()
defer singleton.NotificationsLock.RUnlock() defer singleton.NotificationsLock.RUnlock()
notifications := make([]model.Notification, 0, len(singleton.NotificationMap))
for _, n := range singleton.NotificationMap { var notifications []*model.Notification
notifications = append(notifications, *n) if err := copier.Copy(&notifications, &singleton.NotificationListSorted); err != nil {
return nil, err
} }
return notifications, nil return notifications, nil
} }
@ -73,6 +75,7 @@ func createNotification(c *gin.Context) (uint64, error) {
} }
singleton.OnRefreshOrAddNotification(&n) singleton.OnRefreshOrAddNotification(&n)
singleton.UpdateNotificationList()
return n.ID, nil return n.ID, nil
} }
@ -130,6 +133,7 @@ func updateNotification(c *gin.Context) (any, error) {
} }
singleton.OnRefreshOrAddNotification(&n) singleton.OnRefreshOrAddNotification(&n)
singleton.UpdateNotificationList()
return nil, nil return nil, nil
} }
@ -166,5 +170,6 @@ func batchDeleteNotification(c *gin.Context) (any, error) {
} }
singleton.OnDeleteNotification(n) singleton.OnDeleteNotification(n)
singleton.UpdateNotificationList()
return nil, nil return nil, nil
} }

View File

@ -5,6 +5,7 @@ import (
"strconv" "strconv"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/jinzhu/copier"
"github.com/naiba/nezha/model" "github.com/naiba/nezha/model"
"github.com/naiba/nezha/pkg/utils" "github.com/naiba/nezha/pkg/utils"
@ -18,12 +19,17 @@ import (
// @Description List server // @Description List server
// @Tags auth required // @Tags auth required
// @Produce json // @Produce json
// @Success 200 {object} model.CommonResponse[any] // @Success 200 {object} model.CommonResponse[[]*model.Server]
// @Router /server [get] // @Router /server [get]
func listServer(c *gin.Context) ([]*model.Server, error) { func listServer(c *gin.Context) ([]*model.Server, error) {
singleton.SortedServerLock.RLock() singleton.SortedServerLock.RLock()
defer singleton.SortedServerLock.RUnlock() defer singleton.SortedServerLock.RUnlock()
return singleton.SortedServerList, nil
var ssl []*model.Server
if err := copier.Copy(&ssl, &singleton.SortedServerList); err != nil {
return nil, err
}
return ssl, nil
} }
// Edit server // Edit server

View File

@ -2,6 +2,7 @@ package singleton
import ( import (
"fmt" "fmt"
"slices"
"sync" "sync"
"github.com/libdns/cloudflare" "github.com/libdns/cloudflare"
@ -16,22 +17,54 @@ import (
var ( var (
DDNSCache map[uint64]*model.DDNSProfile DDNSCache map[uint64]*model.DDNSProfile
DDNSCacheLock sync.RWMutex DDNSCacheLock sync.RWMutex
DDNSList []*model.DDNSProfile
) )
func initDDNS() { func initDDNS() {
OnDDNSUpdate()
OnNameserverUpdate()
}
func OnDDNSUpdate() {
var ddns []*model.DDNSProfile var ddns []*model.DDNSProfile
DB.Find(&ddns) DB.Find(&ddns)
DDNSCacheLock.Lock() DDNSCacheLock.Lock()
defer DDNSCacheLock.Unlock()
DDNSCache = make(map[uint64]*model.DDNSProfile) DDNSCache = make(map[uint64]*model.DDNSProfile)
for i := 0; i < len(ddns); i++ { for i := 0; i < len(ddns); i++ {
DDNSCache[ddns[i].ID] = ddns[i] DDNSCache[ddns[i].ID] = ddns[i]
} }
DDNSCacheLock.Unlock()
UpdateDDNSList()
OnNameserverUpdate()
}
func OnDDNSUpdate(p *model.DDNSProfile) {
DDNSCacheLock.Lock()
defer DDNSCacheLock.Unlock()
DDNSCache[p.ID] = p
}
func OnDDNSDelete(id []uint64) {
DDNSCacheLock.Lock()
defer DDNSCacheLock.Unlock()
for _, i := range id {
delete(DDNSCache, i)
}
}
func UpdateDDNSList() {
DDNSCacheLock.RLock()
defer DDNSCacheLock.RUnlock()
DDNSList = make([]*model.DDNSProfile, 0, len(DDNSCache))
for _, p := range DDNSCache {
DDNSList = append(DDNSList, p)
}
slices.SortFunc(DDNSList, func(a, b *model.DDNSProfile) int {
if a.ID < b.ID {
return -1
} else if a.ID == b.ID {
return 0
}
return 1
})
} }
func OnNameserverUpdate() { func OnNameserverUpdate() {

View File

@ -3,6 +3,7 @@ package singleton
import ( import (
"fmt" "fmt"
"log" "log"
"slices"
"sync" "sync"
"time" "time"
@ -19,6 +20,7 @@ var (
NotificationIDToGroups map[uint64]map[uint64]struct{} // [NotificationID] -> NotificationGroupID NotificationIDToGroups map[uint64]map[uint64]struct{} // [NotificationID] -> NotificationGroupID
NotificationMap map[uint64]*model.Notification NotificationMap map[uint64]*model.Notification
NotificationListSorted []*model.Notification
NotificationGroup map[uint64]string // [NotificationGroupID] -> [NotificationGroupName] NotificationGroup map[uint64]string // [NotificationGroupID] -> [NotificationGroupName]
NotificationsLock sync.RWMutex NotificationsLock sync.RWMutex
@ -36,7 +38,6 @@ func InitNotification() {
func loadNotifications() { func loadNotifications() {
InitNotification() InitNotification()
NotificationsLock.Lock() NotificationsLock.Lock()
defer NotificationsLock.Unlock()
groupNotifications := make(map[uint64][]uint64) groupNotifications := make(map[uint64][]uint64)
var ngn []model.NotificationGroupNotification var ngn []model.NotificationGroupNotification
@ -72,6 +73,27 @@ func loadNotifications() {
} }
} }
} }
NotificationsLock.Unlock()
UpdateNotificationList()
}
func UpdateNotificationList() {
NotificationsLock.RLock()
defer NotificationsLock.RUnlock()
NotificationListSorted = make([]*model.Notification, 0, len(NotificationMap))
for _, n := range NotificationMap {
NotificationListSorted = append(NotificationListSorted, n)
}
slices.SortFunc(NotificationListSorted, func(a, b *model.Notification) int {
if a.ID < b.ID {
return -1
} else if a.ID == b.ID {
return 0
}
return 1
})
} }
// OnRefreshOrAddNotificationGroup 刷新通知方式组相关参数 // OnRefreshOrAddNotificationGroup 刷新通知方式组相关参数