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

qiaoshuai951123 · · 1846 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

### **goshop开源项目的更新** >备注:前面项目中用到的代码已经分享到`GitHub`中去了,并且以后所有项目中会出现的代码都会提交上去,欢迎查阅。 > 地址 [`goshop`](https://gitee.com/jobhandsome/goshop/) 感兴趣的可以点个`star`哦~  [`goshop开源项目的更新` ](https://gitee.com/jobhandsome/goshop/) #### **今天咱们做一个`无限级结构树形数据格式`:** 1. **做一个菜单列表形式的一个树形结构,以满足后续的功能业务开发,类似于下图的功能** ![image.png](https://static.golangjob.cn/220430/32ab8fdc438fe082b729edd3e6c96fd0.png) 2. **做成方便扩展的方式** **** #### **接下来咱们就来实现以上的问题和功能:** * **先修改一下分页获取全部数据的方法 `findAll`,将之前`[]Roles`改为`[]*Roles`,如果这里不明白的话,请看之前的的文章: [`Go项目实战之开发完善分页插件(易扩展方式)-------【goshop开源项目】【第12次更新】`](https://studygolang.com/topics/15435)** ```go // 根据检索条件,获取记录行,并获取总记录条数 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` 结构体数据,处理成咱们预想的数据格式** ```go // 对应的数据结构体 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`中进行调用:** ```go // 查询数据 var roles model.Roles Result, totalCount := roles.FindAll(DB, params) TreeResult := roles.ToTree(Result) ``` ### **走到这里就实现了`无限级结构树形数据格式`~~~** ### **更多功能请持续关注!!!!! ** ### **欢迎各位加我的微信(`jobhandsome`)跟我一起完成并推动项目的发展!** ![加入我们.png](https://static.golangjob.cn/220428/76016202be4db073f7b6c7598e4f1f26.png)

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

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

1846 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传