From 37f16c6fb03e3d17664f40ee31aaa0eb703e32b3 Mon Sep 17 00:00:00 2001 From: like Date: Thu, 29 Jun 2023 17:52:40 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=A2=84=E8=AD=A6=E5=88=86=E7=B1=BB?= =?UTF-8?q?=E6=A0=91=E5=BD=A2=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bean/vo/response/alert_class.go | 9 ++- src/bean/vo/response/alert_class_test.go | 74 ++++++++++++++++++++++++ src/controller/alert_class.go | 15 +++++ src/router/metricconfigrouter.go | 1 + src/service/alert_class.go | 54 +++++++++++++++++ 5 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 src/bean/vo/response/alert_class_test.go diff --git a/src/bean/vo/response/alert_class.go b/src/bean/vo/response/alert_class.go index f9179ea..5cfa2bc 100644 --- a/src/bean/vo/response/alert_class.go +++ b/src/bean/vo/response/alert_class.go @@ -1,6 +1,8 @@ package response -import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" +import ( + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" +) type AlertClassItem struct { entity.AlertClass `xorm:"extends"` @@ -10,3 +12,8 @@ type AlertClassList struct { TotalCount int64 `json:"total_count"` List []AlertClassItem `json:"list"` } + +type AlertClassNode struct { + entity.AlertClass + Children []*AlertClassNode `json:"children"` +} diff --git a/src/bean/vo/response/alert_class_test.go b/src/bean/vo/response/alert_class_test.go new file mode 100644 index 0000000..cdb03d5 --- /dev/null +++ b/src/bean/vo/response/alert_class_test.go @@ -0,0 +1,74 @@ +package response + +import ( + "fmt" + json "github.com/json-iterator/go" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" + "sort" + "testing" +) + +func BuildTree(nodes []entity.AlertClass) ([]*AlertClassNode, error) { + nodeMap := make(map[int]*AlertClassNode) + + // 创建所有节点并存储到映射表中 + for _, node := range nodes { + tree := &AlertClassNode{ + AlertClass: node, + Children: []*AlertClassNode{}, + } + nodeMap[node.ClassId] = tree + } + + var rootNodes []*AlertClassNode + for _, node := range nodes { + if node.ParentId == 0 { + rootNodes = append(rootNodes, nodeMap[node.ClassId]) + } else { + parent := nodeMap[node.ParentId] + if parent == nil { + return nil, fmt.Errorf("parent node not found for ClassId: %d", node.ClassId) + } + parent.Children = append(parent.Children, nodeMap[node.ClassId]) + } + } + sortTree(rootNodes) + + return rootNodes, nil +} + +func sortTree(nodes []*AlertClassNode) { + sort.Slice(nodes, func(i, j int) bool { + return nodes[i].SortOrder < nodes[j].SortOrder + }) + for _, node := range nodes { + sortTree(node.Children) + } +} + +func TestTree(t *testing.T) { + // 示例数据 + data := []entity.AlertClass{ + {ClassId: 1, ClassName: "Root", ParentId: 0, SortOrder: 0}, + {ClassId: 2, ClassName: "Child 1", ParentId: 1, SortOrder: 0}, + {ClassId: 3, ClassName: "Child 2", ParentId: 1, SortOrder: 0}, + {ClassId: 4, ClassName: "Grandchild 3", ParentId: 2, SortOrder: 3}, + {ClassId: 5, ClassName: "Grandchild 1", ParentId: 2, SortOrder: 1}, + {ClassId: 6, ClassName: "Grandchild 2", ParentId: 2, SortOrder: 2}, + } + + rootNodes, err := BuildTree(data) + if err != nil { + fmt.Println("Failed to build tree:", err) + return + } + + // 将树形结构转换为 JSON 字符串 + jsonData, err := json.Marshal(rootNodes) + if err != nil { + fmt.Println("Failed to marshal tree:", err) + return + } + + fmt.Println(string(jsonData)) +} diff --git a/src/controller/alert_class.go b/src/controller/alert_class.go index f9015d5..976d16e 100644 --- a/src/controller/alert_class.go +++ b/src/controller/alert_class.go @@ -90,6 +90,21 @@ func ListAlertClass(c *gin.Context) { SendJsonResponse(c, resp.OK, data) } +func TreeAlertClass(c *gin.Context) { + var req request.ListAlertClass + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + svc := service.AlertClassSvc{User: header.GetUser(c)} + data, err := svc.Tree(req) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, data) +} + func DeleteAlertClass(c *gin.Context) { var req request.DeleteAlertClass if err := c.ShouldBind(&req); err != nil { diff --git a/src/router/metricconfigrouter.go b/src/router/metricconfigrouter.go index ffeeebe..133ca69 100644 --- a/src/router/metricconfigrouter.go +++ b/src/router/metricconfigrouter.go @@ -26,5 +26,6 @@ func InitMetricConfigRouter(e *gin.Engine) { acGroup.DELETE("", controller.DeleteAlertClass) acGroup.GET("", controller.DetailAlertClass) acGroup.GET("list", controller.ListAlertClass) + acGroup.GET("tree", controller.TreeAlertClass) } } diff --git a/src/service/alert_class.go b/src/service/alert_class.go index 9f36055..5da821e 100644 --- a/src/service/alert_class.go +++ b/src/service/alert_class.go @@ -2,6 +2,7 @@ package service import ( "errors" + "fmt" "github.com/jinzhu/copier" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" @@ -9,6 +10,7 @@ import ( "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" + "sort" ) type AlertClassSvc struct { @@ -156,6 +158,58 @@ func (m *AlertClassSvc) List(req request.ListAlertClass) (resp response.AlertCla return } +func (m *AlertClassSvc) Tree(req request.ListAlertClass) (resp []*response.AlertClassNode, err error) { + db, err := client.GetDbClient() + if err != nil { + return + } + session := db.NewSession() + defer session.Close() + var list []entity.AlertClass + _, err = session.OrderBy("sort_order").FindAndCount(&list) + // TODO 对req进行过滤 + resp, err = AlertClassTree(list) + return +} + +func AlertClassTree(nodes []entity.AlertClass) ([]*response.AlertClassNode, error) { + nodeMap := make(map[int]*response.AlertClassNode) + + // 创建所有节点并存储到映射表中 + for _, node := range nodes { + tree := &response.AlertClassNode{ + AlertClass: node, + Children: []*response.AlertClassNode{}, + } + nodeMap[node.ClassId] = tree + } + + var rootNodes []*response.AlertClassNode + for _, node := range nodes { + if node.ParentId == 0 { + rootNodes = append(rootNodes, nodeMap[node.ClassId]) + } else { + parent := nodeMap[node.ParentId] + if parent == nil { + return nil, fmt.Errorf("parent node not found for ClassId: %d", node.ClassId) + } + parent.Children = append(parent.Children, nodeMap[node.ClassId]) + } + } + sortTree(rootNodes) + + return rootNodes, nil +} + +func sortTree(nodes []*response.AlertClassNode) { + sort.Slice(nodes, func(i, j int) bool { + return nodes[i].SortOrder < nodes[j].SortOrder + }) + for _, node := range nodes { + sortTree(node.Children) + } +} + func (m *AlertClassSvc) SortOrderMax(parentId int) (max int, err error) { db, err := client.GetDbClient() if err != nil { -- 2.26.0