授课语音

RBAC 数据模型的定义与迁移

在 RBAC(角色权限控制)系统中,数据模型的设计和迁移非常重要,它涉及如何存储和管理用户、角色、权限等信息。RBAC 的数据模型通常包括用户表、角色表、权限表和关系表等。下面我们将详细介绍 RBAC 数据模型的定义,并展示相应的代码案例。


1. 数据模型概述

1.1 用户模型 (SysUser)

用户模型通常包含用户的基本信息,比如用户名、密码、角色等信息。在 RBAC 系统中,每个用户可以被分配一个或多个角色,而角色则决定了用户的权限。

1.2 角色模型 (SysAuthority)

角色模型用于定义不同的角色,每个角色有不同的权限。一个角色可以包含多个权限,同时也可以被多个用户所拥有。

1.3 权限模型 (SysApi, SysMenu)

权限模型用于定义系统中的 API 和菜单权限。每个 API 路径和每个菜单项都可以绑定特定的角色,进而控制访问权限。

1.4 关系模型

  • 用户与角色:通过 SysUserAuthority 关系表关联用户和角色。
  • 角色与权限:通过 SysAuthorityMenuSysAuthorityBtn 关系表关联角色和菜单/按钮权限。

2. 数据模型代码定义

2.1 用户模型 (SysUser)

package permission

import (
   "github.com/gofrs/uuid/v5"
   "rbac_project/internal/global"
   "rbac_project/internal/global/common"
)

type SysUser struct {
   global.GlobalModel
   UUID          uuid.UUID      `json:"uuid" gorm:"index;comment:用户UUID"`              // 用户UUID
   Username      string         `json:"userName" gorm:"index;comment:用户登录名"`         // 用户登录名
   Password      string         `json:"-" gorm:"comment:用户登录密码"`                    // 用户登录密码
   NickName      string         `json:"nickName" gorm:"default:系统用户;comment:用户昵称"` // 用户昵称
   HeaderImg     string         `json:"headerImg" gorm:"default:'';comment:用户头像"`      // 用户头像
   AuthorityId   uint           `json:"authorityId" gorm:"default:888;comment:用户角色ID"` // 用户角色ID
   Authority     SysAuthority   `json:"authority" gorm:"foreignKey:AuthorityId;references:AuthorityId;comment:用户角色"` // 用户角色
   Authorities   []SysAuthority `json:"authorities" gorm:"many2many:sys_user_authority;"` // 多用户角色
   Phone         string         `json:"phone" gorm:"comment:用户手机号"`                  // 用户手机号
   Email         string         `json:"email" gorm:"comment:用户邮箱"`                   // 用户邮箱
   Enable        int            `json:"enable" gorm:"default:1;comment:用户是否被冻结"`    // 用户是否被冻结
   OriginSetting common.JSONMap `json:"originSetting" gorm:"type:text;comment:配置;"`     // 配置
}

func (SysUser) TableName() string {
   return "sys_users"
}

代码说明:

  • SysUser 结构体包含用户的基本信息,如 UsernamePasswordNickName 等。
  • AuthorityId 字段关联了用户的角色。
  • Authorities 使用多对多关联,表示一个用户可以有多个角色。

2.2 角色模型 (SysAuthority)

package permission

import (
   "gorm.io/gorm"
   "time"
)

type SysAuthority struct {
   CreatedAt       time.Time       `gorm:"type:timestamp;default:CURRENT_TIMESTAMP;comment:创建时间"`  // 创建时间
   UpdatedAt       time.Time       `gorm:"type:timestamp;default:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;comment:更新时间"` // 更新时间
   DeletedAt       gorm.DeletedAt  `gorm:"index;comment:删除时间" json:"-"`                             // 删除时间
   AuthorityId     uint            `json:"authorityId" gorm:"not null;unique;primary_key;comment:角色ID"`  // 角色ID
   AuthorityName   string          `json:"authorityName" gorm:"comment:角色名"`                          // 角色名
   ParentId        *uint           `json:"parentId" gorm:"comment:父角色ID"`                             // 父角色ID
   DataAuthorityId []*SysAuthority `json:"dataAuthorityId" gorm:"many2many:sys_data_authority_id;"`      // 数据权限
   Children        []SysAuthority  `json:"children" gorm:"-"`                                           // 子角色
   SysBaseMenus    []SysBaseMenu   `json:"menus" gorm:"many2many:sys_authority_menus;"`                  // 关联的菜单
   Users           []SysUser       `json:"-" gorm:"many2many:sys_user_authority;"`                       // 关联的用户
   DefaultRouter   string          `json:"defaultRouter" gorm:"default:dashboard;comment:默认菜单"`        // 默认菜单
}

func (SysAuthority) TableName() string {
   return "sys_authorities"
}

代码说明:

  • SysAuthority 结构体表示角色,包含角色的 AuthorityIdAuthorityNameParentId 等字段。
  • 角色和菜单、用户之间通过 many2many 关系建立关联。
  • DataAuthorityId 字段用于表示数据权限。

2.3 权限模型 (SysApi)

package permission

import (
   "rbac_project/internal/global"
)

type SysApi struct {
   global.GlobalModel
   Path        string `json:"path" gorm:"comment:api路径"`              // API路径
   Description string `json:"description" gorm:"comment:api描述"`      // API描述
   ApiGroup    string `json:"apiGroup" gorm:"comment:API组"`            // API组
   Method      string `json:"method" gorm:"default:POST;comment:方法"`  // 请求方法
}

// TableName 设置表名
func (SysApi) TableName() string {
   return "sys_apis"
}

代码说明:

  • SysApi 结构体用于存储系统中的 API 信息,包括 PathDescriptionApiGroupMethod 字段。

3. 数据库迁移

数据库迁移是将模型定义映射到数据库表的过程。在 Go 中,通常使用 GORM 作为 ORM 来实现这一过程。GORM 提供了迁移功能,可以根据模型自动生成数据库表。

3.1 自动迁移

通过 GORM 提供的 AutoMigrate 方法,我们可以自动将模型同步到数据库:

package main

import (
   "gorm.io/gorm"
   "rbac_project/internal/global"
   "rbac_project/permission"
)

func migrateDB(db *gorm.DB) {
   // 自动迁移数据库表
   err := db.AutoMigrate(
      &permission.SysUser{},
      &permission.SysAuthority{},
      &permission.SysApi{},
      &permission.SysMenu{},
      &permission.SysBaseMenu{},
   )
   if err != nil {
      panic("迁移失败")
   }
   fmt.Println("数据库迁移完成")
}

func main() {
   // 假设 db 是 GORM 数据库连接实例
   var db *gorm.DB
   migrateDB(db)
}

代码说明:

  • AutoMigrate 会自动创建或更新数据库表结构以匹配模型定义。表会根据模型自动生成,如果表已存在,GORM 会比较模型和现有表结构,自动进行必要的更改。

4. 总结

  • 本节课介绍了 RBAC 系统的数据模型设计,包括用户模型、角色模型、权限模型和关系模型。
  • 通过 GORM 定义模型,并使用自动迁移功能同步数据库。
  • 角色与权限的关联通过多对多关系表实现,用户和角色的关联也通过多对多关系表进行管理。

通过这种结构化的设计,可以有效地管理系统中的用户、角色、权限和菜单等信息,为 RBAC 系统的实现提供支持。

去1:1私密咨询

系列课程: