增加权限系统

This commit is contained in:
yml2213
2026-05-27 05:41:59 +08:00
parent a04327fd05
commit 1458fc279c
29 changed files with 2276 additions and 46 deletions
@@ -11,9 +11,17 @@ type AdminDTO struct {
Username string `json:"username"`
Nickname string `json:"nickname"`
Status string `json:"status"`
Roles []RoleDTO `json:"roles"`
Permissions []string `json:"permissions"`
LastLoginAt *time.Time `json:"last_login_at"`
}
type RoleDTO struct {
ID uint64 `json:"id"`
Code string `json:"code"`
Name string `json:"name"`
}
type LoginRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
@@ -4,6 +4,7 @@ import (
"context"
"crypto/rand"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"html"
@@ -87,7 +88,9 @@ func (r *Repository) Login(username string, password string, captchaID string, c
if err != nil {
return LoginResult{}, err
}
return LoginResult{Admin: toDTO(admin), Tokens: tokens}, nil
dto := toDTO(admin)
r.loadRolesAndPerms(&dto)
return LoginResult{Admin: dto, Tokens: tokens}, nil
}
func (r *Repository) verifyCaptcha(captchaID string, captchaCode string) error {
@@ -119,6 +122,7 @@ func (r *Repository) FindByID(id uint64) (*AdminDTO, error) {
return nil, ErrAdminDisabled
}
dto := toDTO(admin)
r.loadRolesAndPerms(&dto)
return &dto, nil
}
@@ -153,6 +157,37 @@ func toDTO(admin model.AdminUser) AdminDTO {
}
}
func (r *Repository) loadRolesAndPerms(dto *AdminDTO) {
if r.db == nil {
return
}
// 加载角色
var roles []RoleDTO
r.db.Table("roles").
Joins("JOIN admin_user_roles aur ON aur.role_id = roles.id").
Where("aur.admin_user_id = ?", dto.ID).
Find(&roles)
dto.Roles = roles
// 加载权限
var permCodes []string
r.db.Table("permissions").
Select("DISTINCT permissions.code").
Joins("JOIN role_permissions rp ON rp.permission_id = permissions.id").
Joins("JOIN admin_user_roles aur ON aur.role_id = rp.role_id").
Where("aur.admin_user_id = ?", dto.ID).
Pluck("code", &permCodes)
dto.Permissions = permCodes
// 缓存权限到 Redis
if r.redis != nil && len(permCodes) > 0 {
ctx := context.Background()
key := fmt.Sprintf("admin:perms:%d", dto.ID)
raw, _ := json.Marshal(permCodes)
r.redis.Set(ctx, key, string(raw), 2*time.Hour)
}
}
func captchaKey(id string) string {
return "admin:captcha:" + id
}