作者 yangfu

tree 遍历

@@ -5,7 +5,7 @@ go 1.16 @@ -5,7 +5,7 @@ go 1.16
5 require ( 5 require (
6 github.com/ajg/form v1.5.1 // indirect 6 github.com/ajg/form v1.5.1 // indirect
7 github.com/beego/beego/v2 v2.0.1 7 github.com/beego/beego/v2 v2.0.1
8 - github.com/emirpasic/gods v1.12.0 // indirect 8 + github.com/emirpasic/gods v1.12.0
9 github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 // indirect 9 github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 // indirect
10 github.com/fatih/structs v1.1.0 // indirect 10 github.com/fatih/structs v1.1.0 // indirect
11 github.com/gavv/httpexpect v2.0.0+incompatible 11 github.com/gavv/httpexpect v2.0.0+incompatible
@@ -19,6 +19,7 @@ require ( @@ -19,6 +19,7 @@ require (
19 github.com/onsi/gomega v1.11.0 19 github.com/onsi/gomega v1.11.0
20 github.com/sergi/go-diff v1.2.0 // indirect 20 github.com/sergi/go-diff v1.2.0 // indirect
21 github.com/smartystreets/goconvey v1.6.4 // indirect 21 github.com/smartystreets/goconvey v1.6.4 // indirect
  22 + github.com/stretchr/testify v1.7.0
22 github.com/valyala/fasthttp v1.23.0 // indirect 23 github.com/valyala/fasthttp v1.23.0 // indirect
23 github.com/xeipuuv/gojsonschema v1.2.0 // indirect 24 github.com/xeipuuv/gojsonschema v1.2.0 // indirect
24 github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect 25 github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect
@@ -142,10 +142,18 @@ func (orgService *OrgService) GetOrgSubDepartment(getOrgSubDepartmentQuery *quer @@ -142,10 +142,18 @@ func (orgService *OrgService) GetOrgSubDepartment(getOrgSubDepartmentQuery *quer
142 defer func() { 142 defer func() {
143 transactionContext.RollbackTransaction() 143 transactionContext.RollbackTransaction()
144 }() 144 }()
  145 +
  146 + orgRepository, org, err := factory.FastPgOrg(transactionContext, getOrgSubDepartmentQuery.OrgId)
  147 +
  148 + _, orgs, err := orgRepository.Find(map[string]interface{}{"companyId": org.CompanyId, "parentId": getOrgSubDepartmentQuery.OrgId})
  149 + if err != nil {
  150 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  151 + }
  152 +
145 if err := transactionContext.CommitTransaction(); err != nil { 153 if err := transactionContext.CommitTransaction(); err != nil {
146 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) 154 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
147 } 155 }
148 - return nil, nil 156 + return orgs, nil
149 } 157 }
150 158
151 // 返回组织列表 159 // 返回组织列表
@@ -214,6 +222,9 @@ func (orgService *OrgService) RemoveOrg(removeOrgCommand *command.RemoveOrgComma @@ -214,6 +222,9 @@ func (orgService *OrgService) RemoveOrg(removeOrgCommand *command.RemoveOrgComma
214 if org == nil { 222 if org == nil {
215 return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeOrgCommand.OrgId))) 223 return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeOrgCommand.OrgId)))
216 } 224 }
  225 +
  226 + // 存在下级部门
  227 +
217 if org, err := orgRepository.Remove(org); err != nil { 228 if org, err := orgRepository.Remove(org); err != nil {
218 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) 229 return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
219 } else { 230 } else {
@@ -255,7 +266,7 @@ func (orgService *OrgService) UpdateOrg(updateOrgCommand *command.UpdateOrgComma @@ -255,7 +266,7 @@ func (orgService *OrgService) UpdateOrg(updateOrgCommand *command.UpdateOrgComma
255 if err := org.Update(tool_funs.SimpleStructToMap(updateOrgCommand)); err != nil { 266 if err := org.Update(tool_funs.SimpleStructToMap(updateOrgCommand)); err != nil {
256 return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error()) 267 return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
257 } 268 }
258 - //上组织 269 + //上组织
259 if updateOrgCommand.ParentId != 0 { 270 if updateOrgCommand.ParentId != 0 {
260 _, parentOrg, err := factory.FastPgOrg(transactionContext, updateOrgCommand.ParentId) 271 _, parentOrg, err := factory.FastPgOrg(transactionContext, updateOrgCommand.ParentId)
261 if err != nil { 272 if err != nil {
@@ -15,23 +15,6 @@ type Tree struct { @@ -15,23 +15,6 @@ type Tree struct {
15 Nodes []*Tree `json:"nodes"` 15 Nodes []*Tree `json:"nodes"`
16 } 16 }
17 17
18 -func traverse(tree *Tree, node TreeNode) bool {  
19 - list := tree.Nodes  
20 - var match bool = false  
21 - for i := range list {  
22 - id, pid := list[i].Node.ID(), node.PID() //list[i].Node.PID() == node.ID()  
23 - if pid == id {  
24 - list[i].Nodes = append(list[i].Nodes, NewTree(node))  
25 - return true  
26 - }  
27 - if match || traverse(list[i], node) {  
28 - match = true  
29 - break  
30 - }  
31 - }  
32 - return match  
33 -}  
34 -  
35 func NewTrees(nodes []TreeNode) *Tree { 18 func NewTrees(nodes []TreeNode) *Tree {
36 var tree = &Tree{ 19 var tree = &Tree{
37 Node: nil, 20 Node: nil,
@@ -52,3 +35,73 @@ func NewTree(node TreeNode) *Tree { @@ -52,3 +35,73 @@ func NewTree(node TreeNode) *Tree {
52 Nodes: make([]*Tree, 0), 35 Nodes: make([]*Tree, 0),
53 } 36 }
54 } 37 }
  38 +
  39 +// AllChildNodes 返回node下所有子节点
  40 +func (tree *Tree) AllChildNodes(node TreeNode) []TreeNode {
  41 + treeNode := tree.find(node)
  42 + if treeNode == nil {
  43 + return []TreeNode{}
  44 + }
  45 + return tree.allChild(treeNode)
  46 +}
  47 +
  48 +// find 查询node所在的tree,并且返回
  49 +func (tree *Tree) find(node TreeNode) *Tree {
  50 + var stack []*Tree
  51 + stack = append(stack, tree)
  52 + var find *Tree
  53 + for {
  54 + if len(stack) == 0 {
  55 + break
  56 + }
  57 + pop := stack[0]
  58 + stack = stack[1:]
  59 + stack = append(stack, pop.Nodes...)
  60 + if pop == nil || pop.Node == nil {
  61 + continue
  62 + }
  63 + if pop.Node.ID() == node.ID() {
  64 + find = pop
  65 + break
  66 + }
  67 + }
  68 + return find
  69 +}
  70 +
  71 +// allChild 返回treeNode下所有子节点
  72 +func (tree *Tree) allChild(treeNode *Tree) []TreeNode {
  73 + var stack []*Tree
  74 + stack = append(stack, treeNode)
  75 + var res []TreeNode
  76 + for {
  77 + if len(stack) == 0 {
  78 + break
  79 + }
  80 + pop := stack[0]
  81 + stack = stack[1:]
  82 + stack = append(stack, pop.Nodes...)
  83 + res = append(res, pop.Node)
  84 + }
  85 + return res
  86 +}
  87 +
  88 +// traverse 遍历节点
  89 +//
  90 +// tree 当前树
  91 +// node 判断的节点
  92 +func traverse(tree *Tree, node TreeNode) bool {
  93 + list := tree.Nodes
  94 + var match bool = false
  95 + for i := range list {
  96 + id, pid := list[i].Node.ID(), node.PID() //list[i].Node.PID() == node.ID()
  97 + if pid == id {
  98 + list[i].Nodes = append(list[i].Nodes, NewTree(node))
  99 + return true
  100 + }
  101 + if match || traverse(list[i], node) {
  102 + match = true
  103 + break
  104 + }
  105 + }
  106 + return match
  107 +}
  1 +package domain
  2 +
  3 +import (
  4 + "github.com/stretchr/testify/assert"
  5 + "strconv"
  6 + "testing"
  7 +)
  8 +
  9 +func Test_Tree(t *testing.T) {
  10 + table := []struct {
  11 + Input []TreeNode
  12 + Text string
  13 + Except []string
  14 + }{
  15 + {
  16 + 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}},
  17 + Text: `
  18 +树形结构:
  19 + 1
  20 +2 3 4
  21 + 5
  22 + 6 7
  23 +`,
  24 + Except: []string{"5", "6", "7"},
  25 + },
  26 + }
  27 +
  28 + for i := range table {
  29 + tree := NewTrees(table[i].Input)
  30 + out := tree.AllChildNodes(&st{Id: 5, Pid: 3})
  31 + var res []string
  32 + for i := range out {
  33 + res = append(res, out[i].ID())
  34 + }
  35 + assert.Equal(t, res, table[i].Except)
  36 + }
  37 +}
  38 +
  39 +type st struct {
  40 + Id int
  41 + Pid int
  42 +}
  43 +
  44 +func (t *st) PID() string {
  45 + return strconv.Itoa(t.Pid)
  46 +}
  47 +func (t *st) ID() string {
  48 + return strconv.Itoa(t.Id)
  49 +}
@@ -189,6 +189,7 @@ func (repository *OrgRepository) Find(queryOptions map[string]interface{}) (int6 @@ -189,6 +189,7 @@ func (repository *OrgRepository) Find(queryOptions map[string]interface{}) (int6
189 query.SetWhereByQueryOption("is_org = ?", "isOrg") 189 query.SetWhereByQueryOption("is_org = ?", "isOrg")
190 query.SetWhereByQueryOption("org_name = ?", "depName") 190 query.SetWhereByQueryOption("org_name = ?", "depName")
191 query.SetWhereByQueryOption("org_code = ?", "orgCode") 191 query.SetWhereByQueryOption("org_code = ?", "orgCode")
  192 + query.SetWhereByQueryOption("parent_id = ?", "parentId")
192 query.SetOrderDirect("org_id", "ASC") 193 query.SetOrderDirect("org_id", "ASC")
193 if count, err := query.SelectAndCount(); err != nil { 194 if count, err := query.SelectAndCount(); err != nil {
194 return 0, orgs, err 195 return 0, orgs, err