最近的网关管理平台使用到了etcd,想通过前端管理etcd的节点信息,由于etcd的key具有路径的特性,存在层级关系,将从etcd获得的key、value转化为适合前端展示的层级json数据结构。
使用了递归。
前端效果类似如下:

package main
import (
"encoding/json"
"fmt"
"log"
"strings"
)
//层级节点
type Node struct {
Name string `json:"name"`
Key string `json:"key"`
Value string `json:"value"`
Children []*Node `json:"children"`
}
func NewNode(path string, value string,key string) *Node {
return &Node{
Name: path,
Value: value,
Key:key,
Children: []*Node{},
}
}
func (n *Node)Insert(path string, value string){
n.insert(path,value,path)
}
//根据路径插入值
func (n *Node) insert(path string, value string,orginPath string) {
if string(path[0])=="/"{
path=path[1:]
}
ps := strings.Split(path, "/")
length := len(ps)
is_exist := false
for _, p := range n.Children {
if ps[0] == p.Name {
is_exist = true
if length==1{
p.Value = value
p.Key=orginPath
}
if length>1{
p.insert(path[len(ps[0]):], value,orginPath)
p.Key=orginPath[:strings.LastIndex(orginPath,ps[0])+len(ps[0])]
}
}
}
if !is_exist {
newNode := &Node{
Name: ps[0],
Children: []*Node{},
}
if length == 1 {
newNode.Value = value
newNode.Key=orginPath
} else if length > 1 {
newNode.insert(path[len(ps[0]):], value,orginPath)
newNode.Key=orginPath[:strings.LastIndex(orginPath,ps[0])+len(ps[0])]
}
n.Children = append(n.Children, newNode)
}
return
}
func main() {
node := NewNode("/", "","/")
node.Insert("/hello/world", `{"env":"dev"}`)
node.Insert("/hello1/world", `{"env":"dev"}`)
node.Insert("/hello1/world/haha", `{"env":"dev"}`)
node.Insert("/hello1/world1/haha", `{"env":"dev"}`)
node.Insert("/hello2/world", `{"env":"dev3"}`)
node.Insert("/hello3/world3/haha/hehe/aa", `{"env":"dev"}`)
res, err := json.Marshal(node)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(res))
}