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

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)跟我一起完成并推动项目的发展!

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码一行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值