package utils import ( "container/list" "fmt" "git.qianqiusoft.com/qianqiusoft/light-apiengine/models" "github.com/xormplus/xorm" ) // 树形结构 func TreeSearch(engine *xorm.Engine, controllername string, apiname string, tableName string, paramMap map[string]interface{}) ([]*models.TreeNode, error) { stplkey := fmt.Sprintf("%s_%s.tpl", controllername, apiname) result, err := engine.SqlTemplateClient(stplkey, ¶mMap).Query().List() if err != nil { fmt.Println(err) return nil, err } return BuildTree("", result) } func BuildTree(root string, treeSrcs []map[string]interface{}) ([]*models.TreeNode, error) { rootArr := []*models.TreeNode{} paramsArr := treeSrcs valueFiled := "id" parentField := "parent" textFiled := "name" parentValue := root treeNodeList := list.New() originNodeList := list.New() // 区分root节点和子节点数组 for _, params := range paramsArr { value := toString(params[valueFiled], "") parent := toString(params[parentField], "") text := toString(params[textFiled], "") //json,_ := xorm.JSONString(params, true) // 如果根节点root为空,则从parent为空中获取root节点数组 // 如果root不为空,则获取id等于的节点为root节点数组 if (parentValue == "" && parent == "") || value == parentValue { node := &models.TreeNode{ Id: value, Text: text, Parent: parent, Tag: params, } treeNodeList.PushBack(node) rootArr = append(rootArr, node) } else { originNodeList.PushBack(&models.TreeNode{ Id: value, Text: text, Parent: parent, Tag: params, }) } } // 把子节点根据parent分配到对应的父节点上 for ele := treeNodeList.Front(); ele != nil; ele = ele.Next() { treeNode := ele.Value.(*models.TreeNode) originEle := originNodeList.Front() if originEle == nil { break } for originEle != nil { originNextEle := originEle.Next() originNode := originEle.Value.(*models.TreeNode) if originNode.Parent == treeNode.Id { treeNodeList.InsertAfter(originNode, ele) treeNode.Nodes = append(treeNode.Nodes, originNode) originNodeList.Remove(originEle) } originEle = originNextEle } } return rootArr, nil } func toString(v interface{}, defaultValue string) interface{} { if v == nil { return defaultValue } switch t := v.(type) { case int: return t case string: return t default: return t } //strv, flag := v.(string) //if !flag { // return defaultValue //} else { // return result //} }