| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- package utils
- import (
- "fmt"
- "github.com/gogf/gf/container/garray"
- "github.com/gogf/gf/frame/g"
- "github.com/gogf/gf/util/gconv"
- "reflect"
- )
- // 有层级关系的数组,父级-》子级 排序
- func ParentSonSort(list g.List, params ...interface{}) g.List {
- args := make([]interface{}, 8)
- for k, v := range params {
- if k == 8 {
- break
- }
- args[k] = v
- }
- var (
- pid int //父级id
- level int //层级数
- fieldName string //父级id键名
- id string //id键名
- levelName string //层级名称
- title string //标题名称
- breaks int //中断层级
- prefixStr string //字符串前缀
- )
- pid = gconv.Int(GetSliceByKey(args, 0, 0))
- level = gconv.Int(GetSliceByKey(args, 1, 0))
- fieldName = gconv.String(GetSliceByKey(args, 2, "pid"))
- id = gconv.String(GetSliceByKey(args, 3, "id"))
- levelName = gconv.String(GetSliceByKey(args, 4, "flg"))
- title = gconv.String(GetSliceByKey(args, 5, "title"))
- breaks = gconv.Int(GetSliceByKey(args, 6, -1))
- prefixStr = gconv.String(GetSliceByKey(args, 7, "─"))
- //定义一个新slice用于返回
- var returnSlice g.List
- for _, v := range list {
- if pid == gconv.Int(v[fieldName]) {
- v[levelName] = level
- levelClone := level
- titlePrefix := ""
- for {
- if levelClone < 0 {
- break
- }
- titlePrefix += prefixStr
- levelClone--
- }
- titlePrefix = "├" + titlePrefix
- if level == 0 {
- v["title_prefix"] = ""
- } else {
- v["title_prefix"] = titlePrefix
- }
- v["title_show"] = fmt.Sprintf("%s%s", v["title_prefix"], v[title])
- returnSlice = append(returnSlice, v)
- if breaks != -1 && breaks == level {
- continue
- }
- args[0] = v[id]
- args[1] = level + 1
- newSlice2 := ParentSonSort(list, args...)
- if len(newSlice2) > 0 {
- returnSlice = append(returnSlice, newSlice2...)
- }
- }
- }
- return returnSlice
- }
- // 有层级关系的数组 ,将子级压入到父级(树形结构)
- func PushSonToParent(list g.List, params ...interface{}) g.List {
- args := make([]interface{}, 7)
- for k, v := range params {
- if k == 7 {
- break
- }
- args[k] = v
- }
- var (
- pid string //父级id
- fieldName string //父级id键名
- id string //id键名
- key string //子级数组键名
- filter string //过滤键名
- filterVal interface{} //过滤的值
- showNoChild bool //是否显示不存在的子级健
- )
- pid = gconv.String(GetSliceByKey(args, 0, 0))
- fieldName = gconv.String(GetSliceByKey(args, 1, "pid"))
- id = gconv.String(GetSliceByKey(args, 2, "id"))
- key = gconv.String(GetSliceByKey(args, 3, "children"))
- filter = gconv.String(GetSliceByKey(args, 4, ""))
- filterVal = GetSliceByKey(args, 5, nil)
- showNoChild = gconv.Bool(GetSliceByKey(args, 6, true))
- var returnList g.List
- for _, v := range list {
- if gconv.String(v[fieldName]) == pid {
- if filter != "" {
- if reflect.DeepEqual(v[filter], filterVal) {
- args[0] = v[id]
- child := PushSonToParent(list, args...)
- if child != nil || showNoChild {
- v[key] = child
- }
- returnList = append(returnList, v)
- }
- } else {
- args[0] = v[id]
- child := PushSonToParent(list, args...)
- if child != nil || showNoChild {
- v[key] = child
- }
- returnList = append(returnList, v)
- }
- }
- }
- return returnList
- }
- // 获取切片里的值 若为nil 可设置默认值val
- func GetSliceByKey(args []interface{}, key int, val interface{}) interface{} {
- var value interface{}
- if args[key] != nil {
- value = args[key]
- } else {
- value = val
- }
- return value
- }
- // 有层级关系的切片,通过父级id查找所有子级id数组
- // parentId 父级id
- // parentIndex 父级索引名称
- // idIndex id索引名称
- func FindSonByParentId(list g.List, parentId int, parentIndex, idIndex string) g.List {
- newList := make(g.List, 0, len(list))
- for _, v := range list {
- if gconv.Int(v[parentIndex]) == parentId {
- newList = append(newList, v)
- fList := FindSonByParentId(list, gconv.Int(v[idIndex]), parentIndex, idIndex)
- newList = append(newList, fList...)
- }
- }
- return newList
- }
- // 获取最顶层 parent Id
- func GetTopPidList(list g.List, parentIndex, idIndex string) *garray.Array {
- arr := garray.NewArray()
- for _, v1 := range list {
- tag := true
- for _, v2 := range list {
- if v1[parentIndex] == v2[idIndex] {
- tag = false
- break
- }
- }
- if tag {
- arr.PushRight(v1[parentIndex])
- }
- }
- return arr.Unique()
- }
- // 有层级关系的数组,通过子级fid查找所有父级数组
- func FindParentBySonPid(list g.List, id int, params ...interface{}) g.List {
- args := make([]interface{}, 4)
- for k, v := range params {
- if k == 4 {
- break
- }
- args[k] = v
- }
- var (
- filter = gconv.String(GetSliceByKey(args, 0, "filter")) //过滤键名
- fPid = gconv.String(GetSliceByKey(args, 1, "pid")) //父级id字段键名
- filterValue = GetSliceByKey(args, 2, nil) //过滤键值
- fid = gconv.String(GetSliceByKey(args, 3, "id")) //id字段键名
- )
- rList := make(g.List, 0, len(list))
- for _, v := range list {
- if gconv.Int(v[fid]) == id {
- if fv, ok := v[filter]; ok {
- if reflect.DeepEqual(fv, filterValue) {
- rList = append(rList, v)
- }
- } else {
- rList = append(rList, v)
- }
- r := FindParentBySonPid(list, gconv.Int(v[fPid]), filter, fPid, filterValue, fid)
- rList = append(rList, r...)
- }
- }
- return rList
- }
- /**
- * 根据id查询最顶层父级信息
- * @param list 有层级关系的数组
- * @param id 查找的id
- * @param string fpid 父级id键名
- * @param string fid 当前id键名
- * @return g.Map
- */
- func FindTopParent(list g.List, id int64, params ...interface{}) g.Map {
- if len(list) == 0 {
- return g.Map{}
- }
- args := make([]interface{}, 2)
- for k, v := range params {
- if k == 2 {
- break
- }
- args[k] = v
- }
- var (
- fPid = gconv.String(GetSliceByKey(args, 0, "pid")) //父级id字段键名
- fid = gconv.String(GetSliceByKey(args, 1, "id")) //id字段键名
- )
- hasParent := true
- top := g.Map{}
- //找到要查找id值的数组
- for _, v := range list {
- if gconv.Int64(v[fid]) == gconv.Int64(id) {
- top = v
- break
- }
- }
- for {
- if !hasParent {
- break
- }
- //查询最顶层
- for _, v := range list {
- if gconv.Int64(top[fPid]) == gconv.Int64(v[fid]) {
- top = v
- hasParent = true
- break
- }
- hasParent = false
- }
- }
- return top
- }
|