8

Go项目实战之无限级结构树形数据格式(易扩展方式)【goshop开源项目 | 20220430更新...

 3 years ago
source link: https://studygolang.com/articles/35623
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Go项目实战之无限级结构树形数据格式(易扩展方式)【goshop开源项目 | 20220430更新】

qiaoshuai951123 · 大约18小时之前 · 50 次点击 · 预计阅读时间 4 分钟 · 大约8小时之前 开始浏览    

goshop开源项目的更新

备注:前面项目中用到的代码已经分享到GitHub中去了,并且以后所有项目中会出现的代码都会提交上去,欢迎查阅。

地址 goshop 感兴趣的可以点个star哦~ goshop开源项目的更新

今天咱们做一个无限级结构树形数据格式

  1. 做一个菜单列表形式的一个树形结构,以满足后续的功能业务开发,类似于下图的功能 image.png

  2. 做成方便扩展的方式


接下来咱们就来实现以上的问题和功能:

// 根据检索条件,获取记录行,并获取总记录条数
func (Roles) FindAll(DB *gorm.DB, params map[string]interface{}) ([]*Roles, int64) {
    var GoodResult []*Roles
    page := params["page"].(string)         // 对返回的interface类型进行转换成字符串
    pageSize := params["pageSize"].(string) // 对返回的interface类型进行转换成字符串
    // 这里使用了过滤,在下面使用Where条件时过滤掉page,pageSize
    ParamsFilter := utils.ParamsFilter(params, "page,pageSize")
    // 通过 Scopes 引用加载 分页类中返回的 DB指针
    DB.Scopes(Paginate.Paginate(page, pageSize)).Where(ParamsFilter).Order("created_at desc").Find(&Result)
    // 这里时查询全部数据,用于返回总记录条数
    TotalCount := DB.Find(&Goods{})
    return Result, TotalCount.RowsAffected
}

// 这是过滤的封装,一起贴出来了
func ParamsFilter(params map[string]interface{}, isFilterStr string) map[string]interface{} {
    var data = make(map[string]interface{})
    for key, value := range params {
        if find := strings.Contains(isFilterStr, key); !find {
            data[key] = value
        }
    }
    return data
}
  • 接下来就是重头戏了,将查询出来的[]*Roles 结构体数据,处理成咱们预想的数据格式
// 对应的数据结构体
type Roles struct {
    Model
    Name     string     `json:"name" gorm:"size:100;index;default:'';not null;"`    // 角色名称
    Alias    string     `json:"alias" grom:"size:255;index;default:'';not nill;"`   // 别名
    ParentID uint       `json:"parent_id" gorm:"size:10;index;default:0;not null;"` // 父级ID
    Sort     uint       `json:"sort" gorm:"size:1;index;default:0;"`                // 排序值
    Remark   string     `json:"remark" gorm:"size:255;"`                            // 备注
    Status   uint       `json:"status" gorm:"size:1;index;default:0;"`              // 状态(1:启用   2:禁用)
    Children *RoleTrees `json:"children"`   // 这里是最关键的一步
}

// RoleTrees 二叉树列表
type RoleTrees []*Roles

// ToTree 转换为树形结构
func (Roles) ToTree(data RoleTrees) RoleTrees {
    // 定义 HashMap 的变量,并初始化
    TreeData := make(map[uint]*Roles)
    // 先重组数据:以数据的ID作为外层的key编号,以便下面进行子树的数据组合
    for _, item := range data {
        TreeData[item.ID] = item
    }
    // 定义 RoleTrees 结构体
    var TreeDataList RoleTrees
    // 开始生成树形
    for _, item := range TreeData {
        // 如果没有根节点树,则为根节点
        if item.ParentID == 0 {
            // 追加到 TreeDataList 结构体中
            TreeDataList = append(TreeDataList, item)
            // 跳过该次循环
            continue
        }
        // 通过 上面的 TreeData HashMap的组合,进行判断是否存在根节点
        // 如果存在根节点,则对应该节点进行处理
        if p_item, ok := TreeData[item.ParentID]; ok {
            // 判断当次循环是否存在子节点,如果没有则作为子节点进行组合
            if p_item.Children == nil {
                // 写入子节点
                children := RoleTrees{item}
                // 插入到 当次结构体的子节点字段中,以指针的方式
                p_item.Children = &children
                // 跳过当前循环
                continue
            }
            // 以指针地址的形式进行追加到结构体中
            *p_item.Children = append(*p_item.Children, item)
        }
    }
    return TreeDataList
}
  • 到这里逻辑代码已经全部完成了,但是如何使用呢? 下面咱们就来说一下如何使用?在controller中进行调用:
// 查询数据
var roles model.Roles
Result, totalCount := roles.FindAll(DB, params)
TreeResult := roles.ToTree(Result)

走到这里就实现了无限级结构树形数据格式~~~

更多功能请持续关注!!!!!

欢迎各位加我的微信(jobhandsome)跟我一起完成并推动项目的发展!

加入我们.png


有疑问加站长微信联系(非本文作者))

280

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK