golang实现动态路由和权限管理

一、动态路由

1.结构体(数据库的定义)

包含了角色数据库、菜单数据库、角色和菜单关系表。

type Role struct {
	gorm.Model
	Rolename  string `json:"rolename"`
	Authority string `json:"authority"`
	Order     int    `json:"order" gorm:"column:order"`
	Status    bool   `json:"status"`
	Menus     []Menu `json:"menus" gorm:"many2many:role_menu_table"`
	Remark    string `json:"remark"`
}
type Menu struct {
	gorm.Model
	ParentID  uint   `json:"parentid" gorm:"column:parentid"`
	Path      string `json:"path"`
	Name      string `json:"name"`
	Component string `json:"component"`
	Sort      int    `json:"sort"`
	Meta      `json:"meta"`
	Children  []Menu `json:"children" gorm:"-"`
	Roles     []Role `json:"rolse" gorm:"many2many:role_menu_table"`
}

type Meta struct {
	ActiveName  string `json:"activeName" gorm:"comment:高亮菜单"`
	KeepAlive   bool   `json:"keepalive" gorm:"comment:是否缓存"`           // 是否缓存
	DefaultMenu bool   `json:"defaultmenu" gorm:"comment:是否是基础路由(开发中)"` // 是否是基础路由(开发中)
	Title       string `json:"title" gorm:"comment:菜单名"`                // 菜单名
	Icon        string `json:"icon" gorm:"comment:菜单图标"`                // 菜单图标
	CloseTab    bool   `json:"closeTab" gorm:"comment:自动关闭tab"`         // 自动关闭tab
}
type RoleMenu struct {
	MenuId string `json:"menuid" gorm:"colume:menuid"`
	RoleId string `json:"roleid" gorm:"colume:roleid"`
}

2.预加载preload

var role Role
err = db.Preload("Menus").Find(&role,roleid).Error
if err != nil {
	fmt.Println("Error:", err)
	return
}else{
    fmt.Printf("Role's Menus: %+v\n", role.Menus)
}

Preload("Menus"):在查询 Role 时,预加载 Menus 字段,即查询出 Role 对应的所有 Menu 数据。通过这种方式,可以避免在访问 role.Menus 时,再次触发数据库查询,出现 N+1 查询问题。

3.添加关联的方法

var role models.Role
role.ID = reqRole.ID
role.Rolename = reqRole.Rolename
role.Authority = reqRole.Authority
role.Order = reqRole.Order
role.Status = reqRole.Status
role.Menus = menus
role.Remark = reqRole.Remark

if err := config.DB.Create(&role).Error; err != nil {
	return err
}

创建新用户时,用户Menus字段为要添加的路由(从数据库中查询出来的),然后直接create即可。创建之后,数据库中不会显示Menus字段,但是role_menu_table会自动添加关联。

默认情况下,Updates 方法只更新主表的数据,不会自动更新关联关系,因为 Menus 是通过 many2many 关系维护的,因此需要显式操作来同步 Menusrole_menu_table 的关联数据:

if err := config.DB.Model(&role).Association("Menus").Replace(menus); err != nil {
    return err
}

删除时,要先删除关联。First时也要Preload,否则会clear失败导致最终删除失败

//找到实例并删除
if err := tx.Preload("Menus").First(&role, id).Error; err != nil {
	return err
}

//删除关联Menus
if len(role.Menus) > 0 {
	if err := tx.Model(&role).Association("Menus").Clear(); err != nil {
		return err
	}
}

//删除实例
if err := tx.Unscoped().Delete(&role).Error; err != nil {
	return err
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值