Files
mayfly-go/server/pkg/utils/tree_utils.go

75 lines
1.6 KiB
Go
Raw Normal View History

package utils
// ConvertToINodeArray 其他的结构体想要生成菜单树,直接实现这个接口
type INode interface {
// GetId获取id
GetId() int
// GetPid 获取父id
GetPid() int
// IsRoot 判断当前节点是否是顶层根节点
IsRoot() bool
SetChildren(childern interface{})
}
type INodes []INode
func (nodes INodes) Len() int {
return len(nodes)
}
func (nodes INodes) Swap(i, j int) {
nodes[i], nodes[j] = nodes[j], nodes[i]
}
func (nodes INodes) Less(i, j int) bool {
return nodes[i].GetId() < nodes[j].GetId()
}
// GenerateTree 自定义的结构体实现 INode 接口后调用此方法生成树结构
// nodes 需要生成树的节点
// selectedNode 生成树后选中的节点
// menuTrees 生成成功后的树结构对象
func GenerateTree(nodes []INode) (trees []INode) {
trees = []INode{}
// 定义顶层根和子节点
var roots, childs []INode
for _, v := range nodes {
if v.IsRoot() {
// 判断顶层根节点
roots = append(roots, v)
}
childs = append(childs, v)
}
for _, v := range roots {
// 递归
setChildren(v, childs)
trees = append(trees, v)
}
return
}
// recursiveTree 递归生成树结构
// tree 递归的树对象
// nodes 递归的节点
// selectedNodes 选中的节点
func setChildren(parent INode, nodes []INode) {
children := []INode{}
for _, v := range nodes {
if v.IsRoot() {
// 如果当前节点是顶层根节点就跳过
continue
}
if parent.GetId() == v.GetPid() {
children = append(children, v)
}
}
if len(children) == 0 {
return
}
parent.SetChildren(children)
for _, c := range children {
setChildren(c, nodes)
}
}