作者 yangfu

tree 遍历

... ... @@ -5,7 +5,7 @@ go 1.16
require (
github.com/ajg/form v1.5.1 // indirect
github.com/beego/beego/v2 v2.0.1
github.com/emirpasic/gods v1.12.0 // indirect
github.com/emirpasic/gods v1.12.0
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/gavv/httpexpect v2.0.0+incompatible
... ... @@ -19,6 +19,7 @@ require (
github.com/onsi/gomega v1.11.0
github.com/sergi/go-diff v1.2.0 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/stretchr/testify v1.7.0
github.com/valyala/fasthttp v1.23.0 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect
... ...
... ... @@ -142,10 +142,18 @@ func (orgService *OrgService) GetOrgSubDepartment(getOrgSubDepartmentQuery *quer
defer func() {
transactionContext.RollbackTransaction()
}()
orgRepository, org, err := factory.FastPgOrg(transactionContext, getOrgSubDepartmentQuery.OrgId)
_, orgs, err := orgRepository.Find(map[string]interface{}{"companyId": org.CompanyId, "parentId": getOrgSubDepartmentQuery.OrgId})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return nil, nil
return orgs, nil
}
// 返回组织列表
... ... @@ -214,6 +222,9 @@ func (orgService *OrgService) RemoveOrg(removeOrgCommand *command.RemoveOrgComma
if org == nil {
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeOrgCommand.OrgId)))
}
// 存在下级部门
if org, err := orgRepository.Remove(org); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
... ... @@ -255,7 +266,7 @@ func (orgService *OrgService) UpdateOrg(updateOrgCommand *command.UpdateOrgComma
if err := org.Update(tool_funs.SimpleStructToMap(updateOrgCommand)); err != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
}
//上组织
//上组织
if updateOrgCommand.ParentId != 0 {
_, parentOrg, err := factory.FastPgOrg(transactionContext, updateOrgCommand.ParentId)
if err != nil {
... ...
... ... @@ -15,23 +15,6 @@ type Tree struct {
Nodes []*Tree `json:"nodes"`
}
func traverse(tree *Tree, node TreeNode) bool {
list := tree.Nodes
var match bool = false
for i := range list {
id, pid := list[i].Node.ID(), node.PID() //list[i].Node.PID() == node.ID()
if pid == id {
list[i].Nodes = append(list[i].Nodes, NewTree(node))
return true
}
if match || traverse(list[i], node) {
match = true
break
}
}
return match
}
func NewTrees(nodes []TreeNode) *Tree {
var tree = &Tree{
Node: nil,
... ... @@ -52,3 +35,73 @@ func NewTree(node TreeNode) *Tree {
Nodes: make([]*Tree, 0),
}
}
// AllChildNodes 返回node下所有子节点
func (tree *Tree) AllChildNodes(node TreeNode) []TreeNode {
treeNode := tree.find(node)
if treeNode == nil {
return []TreeNode{}
}
return tree.allChild(treeNode)
}
// find 查询node所在的tree,并且返回
func (tree *Tree) find(node TreeNode) *Tree {
var stack []*Tree
stack = append(stack, tree)
var find *Tree
for {
if len(stack) == 0 {
break
}
pop := stack[0]
stack = stack[1:]
stack = append(stack, pop.Nodes...)
if pop == nil || pop.Node == nil {
continue
}
if pop.Node.ID() == node.ID() {
find = pop
break
}
}
return find
}
// allChild 返回treeNode下所有子节点
func (tree *Tree) allChild(treeNode *Tree) []TreeNode {
var stack []*Tree
stack = append(stack, treeNode)
var res []TreeNode
for {
if len(stack) == 0 {
break
}
pop := stack[0]
stack = stack[1:]
stack = append(stack, pop.Nodes...)
res = append(res, pop.Node)
}
return res
}
// traverse 遍历节点
//
// tree 当前树
// node 判断的节点
func traverse(tree *Tree, node TreeNode) bool {
list := tree.Nodes
var match bool = false
for i := range list {
id, pid := list[i].Node.ID(), node.PID() //list[i].Node.PID() == node.ID()
if pid == id {
list[i].Nodes = append(list[i].Nodes, NewTree(node))
return true
}
if match || traverse(list[i], node) {
match = true
break
}
}
return match
}
... ...
package domain
import (
"github.com/stretchr/testify/assert"
"strconv"
"testing"
)
func Test_Tree(t *testing.T) {
table := []struct {
Input []TreeNode
Text string
Except []string
}{
{
Input: []TreeNode{&st{Id: 1, Pid: 0}, &st{Id: 2, Pid: 1}, &st{Id: 3, Pid: 1}, &st{Id: 4, Pid: 1}, &st{Id: 5, Pid: 3}, &st{Id: 6, Pid: 5}, &st{Id: 7, Pid: 5}},
Text: `
树形结构:
1
2 3 4
5
6 7
`,
Except: []string{"5", "6", "7"},
},
}
for i := range table {
tree := NewTrees(table[i].Input)
out := tree.AllChildNodes(&st{Id: 5, Pid: 3})
var res []string
for i := range out {
res = append(res, out[i].ID())
}
assert.Equal(t, res, table[i].Except)
}
}
type st struct {
Id int
Pid int
}
func (t *st) PID() string {
return strconv.Itoa(t.Pid)
}
func (t *st) ID() string {
return strconv.Itoa(t.Id)
}
... ...
... ... @@ -189,6 +189,7 @@ func (repository *OrgRepository) Find(queryOptions map[string]interface{}) (int6
query.SetWhereByQueryOption("is_org = ?", "isOrg")
query.SetWhereByQueryOption("org_name = ?", "depName")
query.SetWhereByQueryOption("org_code = ?", "orgCode")
query.SetWhereByQueryOption("parent_id = ?", "parentId")
query.SetOrderDirect("org_id", "ASC")
if count, err := query.SelectAndCount(); err != nil {
return 0, orgs, err
... ...