124 lines
3.2 KiB
Go
124 lines
3.2 KiB
Go
package models
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type RoleName string
|
|
|
|
const (
|
|
RoleSystemAdmin RoleName = "system_admin"
|
|
RoleAdmin RoleName = "admin"
|
|
RoleUser RoleName = "user"
|
|
)
|
|
|
|
func (r RoleName) String() string { return string(r) }
|
|
|
|
func (r RoleName) Rank() int {
|
|
switch r {
|
|
case RoleSystemAdmin:
|
|
return 3
|
|
case RoleAdmin:
|
|
return 2
|
|
case RoleUser:
|
|
return 1
|
|
default:
|
|
return 0
|
|
}
|
|
}
|
|
|
|
func (r RoleName) CanManage(target RoleName) bool {
|
|
return r.Rank() > target.Rank()
|
|
}
|
|
|
|
func ParseRoleName(s string) (RoleName, error) {
|
|
switch s {
|
|
case "system_admin":
|
|
return RoleSystemAdmin, nil
|
|
case "admin":
|
|
return RoleAdmin, nil
|
|
case "user":
|
|
return RoleUser, nil
|
|
default:
|
|
return "", fmt.Errorf("unknown role: %s", s)
|
|
}
|
|
}
|
|
|
|
type Role struct {
|
|
ID int32 `json:"id" gorm:"primaryKey;autoIncrement"`
|
|
Name string `json:"name" gorm:"uniqueIndex;size:32;not null"`
|
|
Description *string `json:"description"`
|
|
Permissions string `json:"permissions" gorm:"type:jsonb;default:'[]'"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
Users []User `json:"-" gorm:"foreignKey:RoleID"`
|
|
}
|
|
|
|
func (r *Role) NameEnum() RoleName {
|
|
role, _ := ParseRoleName(r.Name)
|
|
return role
|
|
}
|
|
|
|
type User struct {
|
|
ID string `json:"id" gorm:"type:uuid;primaryKey;default:gen_random_uuid()"`
|
|
Username string `json:"username" gorm:"uniqueIndex;size:32;not null"`
|
|
Email *string `json:"email" gorm:"uniqueIndex;size:128"`
|
|
PasswordHash string `json:"-" gorm:"size:255"`
|
|
RoleID int32 `json:"role_id" gorm:"not null"`
|
|
Role Role `json:"role,omitempty" gorm:"foreignKey:RoleID;references:ID"`
|
|
Status string `json:"status" gorm:"size:16;default:active"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
}
|
|
|
|
type PublicUserInfo struct {
|
|
ID string `json:"id"`
|
|
Username string `json:"username"`
|
|
Email *string `json:"email"`
|
|
Role RoleName `json:"role"`
|
|
Status string `json:"status"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
func (u *User) ToPublicInfo() PublicUserInfo {
|
|
return PublicUserInfo{
|
|
ID: u.ID,
|
|
Username: u.Username,
|
|
Email: u.Email,
|
|
Role: u.Role.NameEnum(),
|
|
Status: u.Status,
|
|
CreatedAt: u.CreatedAt,
|
|
}
|
|
}
|
|
|
|
func AutoMigrate(db *gorm.DB) error {
|
|
return db.AutoMigrate(&Role{}, &User{})
|
|
}
|
|
|
|
func SeedRoles(db *gorm.DB) error {
|
|
roles := []Role{
|
|
{Name: string(RoleSystemAdmin), Description: strPtr("系统管理员,可管理管理员与系统配置"), Permissions: `["*"]`},
|
|
{Name: string(RoleAdmin), Description: strPtr("管理员,可管理普通用户"), Permissions: `["users.read", "users.write", "users.create"]`},
|
|
{Name: string(RoleUser), Description: strPtr("普通用户,可访问业务功能"), Permissions: `["dashboard.read", "profile.write"]`},
|
|
}
|
|
for _, role := range roles {
|
|
var existing Role
|
|
if err := db.Where("name = ?", role.Name).First(&existing).Error; err != nil {
|
|
if err == gorm.ErrRecordNotFound {
|
|
if err := db.Create(&role).Error; err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func strPtr(s string) *string {
|
|
return &s
|
|
}
|