![]() |
1 jaar geleden | |
---|---|---|
.idea | 1 jaar geleden | |
config | 1 jaar geleden | |
domain | 1 jaar geleden | |
handler | 1 jaar geleden | |
key | 1 jaar geleden | |
proto | 1 jaar geleden | |
test | 1 jaar geleden | |
utils | 1 jaar geleden | |
.drone.yml | 1 jaar geleden | |
Dockerfile | 1 jaar geleden | |
Makefile | 1 jaar geleden | |
README.md | 1 jaar geleden | |
go.mod | 1 jaar geleden | |
go.sum | 1 jaar geleden | |
install.sh | 1 jaar geleden | |
main.go | 1 jaar geleden |
type NodePermission struct {
NodeID int64 `gorm:"primaryKey;autoIncrement:false"`
PermissionID int64 `gorm:"primaryKey;autoIncrement:false"`
}
在上述示例中,我们使用 primaryKey 标签将 NodeID 和 PermissionID 设置为联合主键,并且通过 autoIncrement:false 来禁止自增。这样,NodePermission 表就能够记录节点和权限的关联关系,而不需要额外的独立的 ID。 // 在关联表中添加联合主键约束 db.AutoMigrate(&NodePermission{})
# 假设要删除 RoleID 为 1 且 PermissionID 为 2 的记录
result := db.Where("role_id = ? AND permission_id = ?", 1, 2).Delete(&RolePermission{})
if result.Error != nil {
// 处理错误
} else {
// 处理成功
}
Clauses 是 Gorm 中用于添加查询子句(Clauses)的方法。在这个上下文中,Clauses(clause.OnConflict{UpdateAll: true}) 是为了使用 Gorm 的 Upsert(插入或更新)功能。 具体来说,clause.OnConflict{UpdateAll: true} 表示当发生冲突(即主键或唯一索引冲突)时,使用更新所有字段的方式进行更新。这意味着如果数据库中已经存在具有相同主键或唯一索引的记录,那么会更新已存在记录的所有字段,而不是报错或忽略。 在示例中,Create(&defaultUser) 会尝试向数据库插入一条记录,如果该记录已经存在(主键冲突),则会根据 clause.OnConflict{UpdateAll: true} 中定义的规则进行更新。这样可以保证在执行初始化操作时,如果默认用户已经存在,就更新用户信息而不是报错。 总体来说,Clauses 允许您在 Gorm 中添加灵活的查询子句,而这里特别使用了 Upsert 功能。
package main
import (
"fmt"
"time"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
// 数据模型定义
type User struct {
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
Username string `json:"username"`
Nickname string `json:"nickname"`
Email string `json:"email"`
Phone string `json:"phone"` // 新增手机号字段
Password string `json:"-"` // 这里使用 "-" 表示在 JSON 输出时不包含密码字段
Teams []Team `gorm:"many2many:user_teams;" json:"teams"`
Roles []Role `gorm:"many2many:user_roles;" json:"roles"`
CreatedBy int64 `json:"created_by"`
}
type Role struct {
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
Name string `json:"name"`
}
type Node struct {
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
ParentID int64 `json:"parent_id"` // 父节点ID,根节点为0
Name string `json:"name"` // 节点名称
}
type Permission struct {
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
Name string `json:"name"`
}
type Team struct {
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
Name string `json:"name"` // 团队名称
Description string `json:"description"` // 团队描述
LeaderID int64 `json:"leader_id"` // 团队领导的用户 ID
CreatedBy string `json:"created_by"` // 创建团队的用户
CreateTime int64 `json:"create_time"` // 团队创建时间
Leader User `gorm:"foreignkey:LeaderID" json:"leader"`
Members []User `gorm:"many2many:user_teams;" json:"members"`
Roles []Role `gorm:"many2many:team_roles;" json:"roles"`
Permissions []Permission `gorm:"many2many:team_permissions;" json:"permissions"`
Website string `json:"website"` // 团队网站
MaxMembers int `json:"max_members"` // 团队最大成员数
}
// 关联表
type UserTeam struct {
UserID int64 `gorm:"index"`
TeamID int64 `gorm:"index"`
}
type UserRole struct {
UserID int64 `gorm:"index"`
RoleID int64 `gorm:"index"`
}
type NodePermission struct {
NodeID int64 `gorm:"index"`
PermissionID int64 `gorm:"index"`
}
type TeamPermission struct {
TeamID int64 `gorm:"index"`
PermissionID int64 `gorm:"index"`
}
// 权限常量
const (
// 用户权限
UserRead = "user:read"
UserWrite = "user:write"
UserDelete = "user:delete"
// 团队权限
TeamRead = "team:read"
TeamWrite = "team:write"
TeamDelete = "team:delete"
// 角色权限
RoleRead = "role:read"
RoleWrite = "role:write"
RoleDelete = "role:delete"
// 通用权限
ManageAll = "*:manage"
ViewAll = "*:view"
// 节点权限
NodeRead = "node:read"
NodeWrite = "node:write"
NodeDelete = "node:delete"
)
// 数据填充函数
func seedData(db *gorm.DB) {
// 创建用户、角色、节点、权限、团队
user1 := User{Username: "user1", Nickname: "User 1", Email: "user1@example.com", Phone: "123456789", CreatedBy: 1}
user2 := User{Username: "user2", Nickname: "User 2", Email: "user2@example.com", Phone: "987654321", CreatedBy: 1}
user3 := User{Username: "user3", Nickname: "User 3", Email: "user3@example.com", Phone: "111222333", CreatedBy: 2}
role1 := Role{Name: "Admin"}
role2 := Role{Name: "Member"}
node1 := Node{Name: "Node 1"}
node2 := Node{Name: "Node 2"}
node3 := Node{Name: "Node 3"}
permission1 := Permission{Name: "Permission 1"}
permission2 := Permission{Name: "Permission 2"}
permission3 := Permission{Name: "Permission 3"}
team1 := Team{Name: "Team 1", Description: "Description 1", LeaderID: 1, CreatedBy: "Admin", CreateTime: 1637190745}
team2 := Team{Name: "Team 2", Description: "Description 2", LeaderID: 2, CreatedBy: "Admin", CreateTime: 1637190745}
team3 := Team{Name: "Team 3", Description: "Description 3", LeaderID: 3, CreatedBy: "User2", CreateTime: 1637190745}
// 创建关联关系
db.Create(&user1)
db.Create(&user2)
db.Create(&user3)
db.Create(&role1)
db.Create(&role2)
db.Create(&node1)
db.Create(&node2)
db.Create(&node3)
db.Create(&permission1)
db.Create(&permission2)
db.Create(&permission3)
db.Create(&team1)
db.Create(&team2)
db.Create(&team3)
db.Create(&UserTeam{UserID: user1.ID, TeamID: team1.ID})
db.Create(&UserTeam{UserID: user2.ID, TeamID: team2.ID})
db.Create(&UserTeam{UserID: user3.ID, TeamID: team3.ID})
db.Create(&UserRole{UserID: user1.ID, RoleID: role1.ID})
db.Create(&UserRole{UserID: user2.ID, RoleID: role2.ID})
db.Create(&UserRole{UserID: user3.ID, RoleID: role2.ID})
db.Create(&NodePermission{NodeID: node1.ID, PermissionID: permission1.ID})
db.Create(&NodePermission{NodeID: node2.ID, PermissionID: permission2.ID})
db.Create(&NodePermission{NodeID: node3.ID, PermissionID: permission3.ID})
db.Create(&TeamPermission{TeamID: team1.ID, PermissionID: permission1.ID})
db.Create(&TeamPermission{TeamID: team2.ID, PermissionID: permission2.ID})
db.Create(&TeamPermission{TeamID: team3.ID, PermissionID: permission3.ID})
}
func main() {
// 连接数据库
dsn := "test.db"
db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// 自动迁移模型
err = db.AutoMigrate(&User{}, &Role{}, &Node{}, &Permission{}, &Team{}, &UserTeam{}, &UserRole{}, &NodePermission{}, &TeamPermission{})
if err != nil {
panic("failed to migrate database")
}
// 数据填充
seedData(db)
fmt.Println("Database seeded successfully.")
}
下面是关于 Permission, Role, 和 RolePermission 的基本流程:
# Permission 模型
type Permission struct {
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Roles []Role `gorm:"many2many:role_permissions;" json:"roles"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
# Role 模型
type Role struct {
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Permissions []Permission `gorm:"many2many:role_permissions;" json:"permissions"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
# RolePermission 模型
type RolePermission struct {
RoleID int64 `gorm:"index"`
PermissionID int64 `gorm:"index"`
Grant bool `json:"grant"` // 表示角色是否被授予相应的权限
}
关联模型:
Permission 和 Role 通过 many2many 关联表 RolePermission 关联。 RolePermission 中有 Grant 字段,表示角色是否被授予相应的权限。
创建和查询流程:
# 创建权限
permission := Permission{
Name: "ReadUser",
Description: "Permission to read user information",
}
db.Create(&permission)
# 创建角色
role := Role{
Name: "Admin",
Description: "Administrator role",
}
db.Create(&role)
# 关联权限和角色
rolePermission := RolePermission{
RoleID: role.ID,
PermissionID: permission.ID,
Grant: true, // 授予角色相应权限
}
db.Create(&rolePermission)
# 查询角色的所有权限
db.Preload("Permissions").Find(&role)
# 查询权限的所有角色
db.Preload("Roles").Find(&permission)
更新和删除流程:
# 更新权限信息
db.Model(&permission).Update("Description", "Updated description")
# 更新角色信息
db.Model(&role).Update("Description", "Updated description")
# 撤销角色的权限
db.Where("RoleID = ? AND PermissionID = ?", role.ID, permission.ID).Delete(&RolePermission{})
# 删除权限
db.Delete(&permission)
# 删除角色
db.Delete(&role)
这个流程展示了如何创建、关联、查询、更新和删除 Permission, Role, 和 RolePermission 的基本操作。请根据你的具体需求和系统设计进行调整。
在 GORM 中,如果你的 Team 模型有一个名为 Members 的字段,表示与 User 模型之间的多对多关系,你可以使用以下方式来向团队添加成员。 通过关联模型创建:
// 假设 teamID 为团队的 ID,userID 为要添加的用户的 ID
// 首先查询要添加的用户和团队
var team Team
var user User
if err := db.First(&team, teamID).Error; err != nil {
// 处理团队不存在的情况
}
if err := db.First(&user, userID).Error; err != nil {
// 处理用户不存在的情况
}
// 将用户添加到团队的 Members 中
db.Model(&team).Association("Members").Append(&user)
上述代码首先通过团队 ID 和用户 ID 查询相应的团队和用户,然后使用 Association 和 Append 方法将用户添加到团队的 Members 中。
直接更新模型字段:
// 假设 teamID 为团队的 ID,userID 为要添加的用户的 ID
// 查询要添加的用户和团队
var team Team
var user User
if err := db.First(&team, teamID).Error; err != nil {
// 处理团队不存在的情况
}
if err := db.First(&user, userID).Error; err != nil {
// 处理用户不存在的情况
}
// 直接将用户添加到团队的 Members 中
db.Model(&team).Update("Members", gorm.Expr("ARRAY_APPEND(members, ?)", userID))
这种方法通过直接更新模型字段来添加用户到团队的 Members 中,使用了 ARRAY_APPEND 函数。 你可以根据你的具体需求选择其中的一种方法。如果你使用的是 PostgreSQL,ARRAY_APPEND 函数是合适的。确保替换代码中的数据库查询和错误处理,以适应你的应用程序逻辑。
team 下有多少角色:
// 假设 teamID 为团队的 ID
var team Team
if err := db.Preload("Roles").First(&team, teamID).Error; err != nil {
// 处理团队不存在的情况
}
// 现在你可以访问 team.Roles,这是一个包含团队下所有角色的切片
team 下有多少用户:
// 假设 teamID 为团队的 ID
var team Team
if err := db.Preload("Members").First(&team, teamID).Error; err != nil {
// 处理团队不存在的情况
}
// 现在你可以访问 team.Members,这是一个包含团队下所有用户的切片
如果在创建角色时,关联的权限已经存在,您可以首先查询权限,然后再关联到角色。以下是一个示例:
// 假设您已经有一个名为 "Admin" 的权限存在,并且知道它的 PermissionID
// 查询权限
var adminPermission Permission
db.Where("name = ?", "Admin").First(&adminPermission)
// 创建角色并关联权限
adminRole := Role{
Name: "Admin",
Description: "Administrator role",
Permissions: []Permission{adminPermission},
}
db.Create(&adminRole)
// 获取以 "Employee:" 前缀开头的权限
var employeePermissions []Permission
db.Where("name LIKE ?", "Employee:%").Find(&employeePermissions)
ALTER DATABASE paas CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
SHOW VARIABLES LIKE 'character_set_database';