Compare commits

...

1 Commits

Author SHA1 Message Date
Snowykami
a57f5ae479 feat: add builtinpayloads api (#2980) 2025-11-29 13:33:56 +08:00
3 changed files with 112 additions and 1 deletions

View File

@@ -411,6 +411,35 @@ func (b *BuiltinPayloadInFileType) GetBuiltinPayloadCates(typ string, componentI
return result, nil
}
// GetAllBuiltinPayloads 获取所有内置 payload遍历所有组件、类型和分类
// query: 可选,用于过滤 payload 名称或标签
func (b *BuiltinPayloadInFileType) GetAllBuiltinPayloads(query string) ([]*models.BuiltinPayload, error) {
var result []*models.BuiltinPayload
// 遍历所有组件 (Data map 的 key 是 component_id)
for _, source := range b.Data {
if source == nil {
continue
}
// 遍历该组件下的所有类型 (type -> cate -> payloads)
for _, typeMap := range source {
for _, payloads := range typeMap {
// 使用已有的 filterByQuery 进行过滤并追加到结果集
result = append(result, filterByQuery(payloads, query)...)
}
}
}
// 对结果按名称排序,保证输出稳定
if len(result) > 0 {
sort.Slice(result, func(i, j int) bool {
return result[i].Name < result[j].Name
})
}
return result, nil
}
func filterByQuery(payloads []*models.BuiltinPayload, query string) []*models.BuiltinPayload {
if query == "" {
return payloads

View File

@@ -530,6 +530,8 @@ func (rt *Router) Config(r *gin.Engine) {
pages.DELETE("/builtin-payloads", rt.auth(), rt.user(), rt.perm("/components/del"), rt.builtinPayloadsDel)
pages.GET("/builtin-payload", rt.auth(), rt.user(), rt.builtinPayloadsGetByUUID)
pages.GET("/builtin-components-and-payloads", rt.auth(), rt.user(), rt.builtinComponentsAndPayloadsGets)
pages.POST("/message-templates", rt.auth(), rt.user(), rt.perm("/notification-templates/add"), rt.messageTemplatesAdd)
pages.DELETE("/message-templates", rt.auth(), rt.user(), rt.perm("/notification-templates/del"), rt.messageTemplatesDel)
pages.PUT("/message-template/:id", rt.auth(), rt.user(), rt.perm("/notification-templates/put"), rt.messageTemplatePut)

View File

@@ -1,11 +1,14 @@
package router
import (
"fmt"
"net/http"
"sort"
"strings"
"github.com/ccfos/nightingale/v6/center/integration"
"github.com/ccfos/nightingale/v6/models"
"github.com/ccfos/nightingale/v6/pkg/ctx"
"github.com/gin-gonic/gin"
"github.com/toolkits/pkg/ginx"
"gorm.io/gorm"
@@ -91,3 +94,80 @@ func (rt *Router) builtinComponentsDel(c *gin.Context) {
ginx.NewRender(c).Message(models.BuiltinComponentDels(rt.Ctx, req.Ids))
}
func (rt *Router) builtinComponentsAndPayloadsGets(c *gin.Context) {
query := ginx.QueryStr(c, "query", "")
lowerQuery := strings.ToLower(query)
dbPayloads, err := models.BuiltinPayloadGets(rt.Ctx, 0, "", "", "")
ginx.Dangerous(err)
filePayloads, err := integration.BuiltinPayloadInFile.GetAllBuiltinPayloads("")
ginx.Dangerous(err)
allPayloads := make([]*models.BuiltinPayload, 0, len(dbPayloads)+len(filePayloads))
allPayloads = append(allPayloads, dbPayloads...)
allPayloads = append(allPayloads, filePayloads...)
compToCatesMap := make(map[string]map[string]struct{})
for i := range allPayloads {
payload := allPayloads[i]
if payload == nil {
continue
}
compName := payload.Component
if compName == "" {
comp, err := models.BuiltinComponentGet(rt.Ctx, "id = ?", payload.ComponentID)
ginx.Dangerous(err)
if comp != nil {
compName = comp.Ident
} else {
compName = fmt.Sprintf("unknown_component_id_%d", payload.ComponentID)
}
}
// 查询
if lowerQuery != "" {
if !strings.Contains(strings.ToLower(compName), lowerQuery) &&
!strings.Contains(strings.ToLower(payload.Cate), lowerQuery) {
continue
}
}
if payload.Cate == "" {
continue
}
if _, ok := compToCatesMap[compName]; !ok {
compToCatesMap[compName] = make(map[string]struct{})
}
compToCatesMap[compName][payload.Cate] = struct{}{}
}
ret := make([]map[string]interface{}, 0, len(compToCatesMap))
for compName, cateSet := range compToCatesMap {
cates := make([]string, 0, len(cateSet))
for cate := range cateSet {
cates = append(cates, cate)
}
sort.Strings(cates) // cate 排序
item := make(map[string]interface{})
item["component_name"] = compName
item["cates"] = cates
ret = append(ret, item)
}
// 对结果按 component_name 排序,保证分页/截断的稳定性
sort.Slice(ret, func(i, j int) bool {
return ret[i]["component_name"].(string) < ret[j]["component_name"].(string)
})
// 如果 query 为空,只返回前 20 个
if query == "" && len(ret) > 20 {
ret = ret[:20]
}
ginx.NewRender(c).Data(ret, nil)
}