slice_tree.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package utils
  2. import (
  3. "fmt"
  4. "github.com/gogf/gf/frame/g"
  5. "github.com/gogf/gf/util/gconv"
  6. "reflect"
  7. "strings"
  8. )
  9. //有层级关系的数组,父级-》子级 排序
  10. func ParentSonSort(list g.List, params ...interface{}) g.List {
  11. args := make([]interface{}, 8)
  12. for k, v := range params {
  13. if k == 8 {
  14. break
  15. }
  16. args[k] = v
  17. }
  18. var (
  19. pid int //父级id
  20. level int //层级数
  21. fieldName string //父级id键名
  22. id string //id键名
  23. levelName string //层级名称
  24. title string //标题名称
  25. breaks int //中断层级
  26. prefixStr string //字符串前缀
  27. )
  28. pid = gconv.Int(GetSliceByKey(args, 0, 0))
  29. level = gconv.Int(GetSliceByKey(args, 1, 0))
  30. fieldName = gconv.String(GetSliceByKey(args, 2, "pid"))
  31. id = gconv.String(GetSliceByKey(args, 3, "id"))
  32. levelName = gconv.String(GetSliceByKey(args, 4, "flg"))
  33. title = gconv.String(GetSliceByKey(args, 5, "title"))
  34. breaks = gconv.Int(GetSliceByKey(args, 6, -1))
  35. prefixStr = gconv.String(GetSliceByKey(args, 7, " "))
  36. //定义一个新slice用于返回
  37. var returnSlice g.List
  38. for _, v := range list {
  39. if pid == gconv.Int(v[fieldName]) {
  40. v[levelName] = level
  41. levelClone := level
  42. titlePrefix := ""
  43. for {
  44. if levelClone < 0 {
  45. break
  46. }
  47. titlePrefix += strings.Repeat(prefixStr, 2)
  48. levelClone--
  49. }
  50. titlePrefix += "├"
  51. if level == 0 {
  52. v["title_prefix"] = ""
  53. } else {
  54. v["title_prefix"] = titlePrefix
  55. }
  56. v["title_show"] = fmt.Sprintf("%s%s", v["title_prefix"], v[title])
  57. returnSlice = append(returnSlice, v)
  58. if breaks != -1 && breaks == level {
  59. continue
  60. }
  61. args[0] = v[id]
  62. args[1] = level + 1
  63. newSlice2 := ParentSonSort(list, args...)
  64. if len(newSlice2) > 0 {
  65. returnSlice = append(returnSlice, newSlice2...)
  66. }
  67. }
  68. }
  69. return returnSlice
  70. }
  71. //有层级关系的数组 ,将子级压入到父级(树形结构)
  72. func PushSonToParent(list g.List, params ...interface{}) g.List {
  73. args := make([]interface{}, 7)
  74. for k, v := range params {
  75. if k == 7 {
  76. break
  77. }
  78. args[k] = v
  79. }
  80. var (
  81. pid int //父级id
  82. fieldName string //父级id键名
  83. id string //id键名
  84. key string //子级数组键名
  85. filter string //过滤键名
  86. filterVal interface{} //过滤的值
  87. showNoChild bool //是否显示不存在的子级健
  88. )
  89. pid = gconv.Int(GetSliceByKey(args, 0, 0))
  90. fieldName = gconv.String(GetSliceByKey(args, 1, "pid"))
  91. id = gconv.String(GetSliceByKey(args, 2, "id"))
  92. key = gconv.String(GetSliceByKey(args, 3, "children"))
  93. filter = gconv.String(GetSliceByKey(args, 4, ""))
  94. filterVal = GetSliceByKey(args, 5, nil)
  95. showNoChild = gconv.Bool(GetSliceByKey(args, 6, true))
  96. var returnList g.List
  97. for _, v := range list {
  98. if gconv.Int(v[fieldName]) == pid {
  99. if filter != "" {
  100. if reflect.DeepEqual(v[filter], filterVal) {
  101. args[0] = v[id]
  102. child := PushSonToParent(list, args...)
  103. if child != nil || showNoChild {
  104. v[key] = child
  105. }
  106. returnList = append(returnList, v)
  107. }
  108. } else {
  109. args[0] = v[id]
  110. child := PushSonToParent(list, args...)
  111. if child != nil || showNoChild {
  112. v[key] = child
  113. }
  114. returnList = append(returnList, v)
  115. }
  116. }
  117. }
  118. return returnList
  119. }
  120. //获取切片里的值 若为nil 可设置默认值val
  121. func GetSliceByKey(args []interface{}, key int, val interface{}) interface{} {
  122. var value interface{}
  123. if args[key] != nil {
  124. value = args[key]
  125. } else {
  126. value = val
  127. }
  128. return value
  129. }