Files
stock/backend/internal/models/user.go
T
2026-07-03 23:40:33 +08:00

128 lines
3.4 KiB
Go

package models
import (
"fmt"
"time"
"gorm.io/gorm"
)
type RoleName string
const (
RoleSystemAdmin RoleName = "system_admin"
RoleAdmin RoleName = "admin"
RoleUser RoleName = "user"
RoleGuest RoleName = "guest"
)
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
case "guest":
return RoleGuest, nil
default:
return RoleGuest, 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"]`},
{Name: string(RoleGuest), Description: strPtr("游客,仅可查看公开内容"), Permissions: `["public.read"]`},
}
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
}