This commit is contained in:
2026-10-25 22:47:13 +08:00
parent 897d6c4483
commit b34fba352b
20 changed files with 2615 additions and 0 deletions
+139
View File
@@ -0,0 +1,139 @@
package admin
import (
"context"
"gorm.io/gorm"
"portal-mini-go/internal/model/admin"
"portal-mini-go/internal/pkg/errors"
)
// RoleRepository 角色与权限关联的数据访问。
type RoleRepository struct {
db *gorm.DB
}
func NewRoleRepository(db *gorm.DB) *RoleRepository { return &RoleRepository{db: db} }
// GetByID 按 ID 查询角色,不存在返回 ErrNotFound。
func (r *RoleRepository) GetByID(ctx context.Context, id uint64) (*admin.Role, error) {
var m admin.Role
if err := r.db.WithContext(ctx).Where("id = ?", id).First(&m).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.ErrNotFound
}
return nil, errors.Wrap(50000, "query role", err)
}
return &m, nil
}
// GetByCode 按 code 查询角色,不存在返回 ErrNotFound。
func (r *RoleRepository) GetByCode(ctx context.Context, code string) (*admin.Role, error) {
var m admin.Role
if err := r.db.WithContext(ctx).Where("code = ?", code).First(&m).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.ErrNotFound
}
return nil, errors.Wrap(50000, "query role", err)
}
return &m, nil
}
// Create 新建角色。
func (r *RoleRepository) Create(ctx context.Context, m *admin.Role) error {
if err := r.db.WithContext(ctx).Create(m).Error; err != nil {
return errors.Wrap(50000, "create role", err)
}
return nil
}
// RoleListFilter 角色列表过滤条件。
type RoleListFilter struct {
Keyword string
Status int8
Page int
Size int
}
// List 分页查询角色,支持关键字与状态过滤。
func (r *RoleRepository) List(ctx context.Context, f RoleListFilter) ([]admin.Role, int64, error) {
q := r.db.WithContext(ctx).Model(&admin.Role{})
if f.Status >= 0 {
q = q.Where("status = ?", f.Status)
}
if f.Keyword != "" {
kw := "%" + f.Keyword + "%"
q = q.Where("name LIKE ? OR code LIKE ?", kw, kw)
}
var total int64
if err := q.Count(&total).Error; err != nil {
return nil, 0, errors.Wrap(50000, "count role", err)
}
var list []admin.Role
if err := q.Order("id DESC").Offset((f.Page - 1) * f.Size).Limit(f.Size).Find(&list).Error; err != nil {
return nil, 0, errors.Wrap(50000, "list role", err)
}
return list, total, nil
}
// Update 按 ID 局部更新角色非零值字段。
func (r *RoleRepository) Update(ctx context.Context, id uint64, cols map[string]interface{}) error {
res := r.db.WithContext(ctx).Model(&admin.Role{}).Where("id = ?", id).Updates(cols)
if res.Error != nil {
return errors.Wrap(50000, "update role", res.Error)
}
if res.RowsAffected == 0 {
return errors.ErrNotFound
}
return nil
}
// Delete 删除角色,并清理角色-权限与管理员-角色关联。
func (r *RoleRepository) Delete(ctx context.Context, id uint64) error {
if err := r.db.WithContext(ctx).Where("role_id = ?", id).Delete(&admin.RolePermission{}).Error; err != nil {
return errors.Wrap(50000, "delete role permissions", err)
}
if err := r.db.WithContext(ctx).Where("role_id = ?", id).Delete(&admin.UserRole{}).Error; err != nil {
return errors.Wrap(50000, "delete user roles", err)
}
res := r.db.WithContext(ctx).Where("id = ?", id).Delete(&admin.Role{})
if res.Error != nil {
return errors.Wrap(50000, "delete role", res.Error)
}
if res.RowsAffected == 0 {
return errors.ErrNotFound
}
return nil
}
// SetPermissions 全量替换角色所拥有的权限(先删后插)。
func (r *RoleRepository) SetPermissions(ctx context.Context, roleID uint64, permIDs []uint64) error {
if err := r.db.WithContext(ctx).Where("role_id = ?", roleID).Delete(&admin.RolePermission{}).Error; err != nil {
return errors.Wrap(50000, "reset role permissions", err)
}
if len(permIDs) == 0 {
return nil
}
rows := make([]admin.RolePermission, 0, len(permIDs))
for _, pid := range permIDs {
rows = append(rows, admin.RolePermission{RoleID: roleID, PermissionID: pid})
}
if err := r.db.WithContext(ctx).Create(&rows).Error; err != nil {
return errors.Wrap(50000, "assign role permissions", err)
}
return nil
}
// PermissionCodesOf 返回角色拥有的权限 code 列表。
func (r *RoleRepository) PermissionCodesOf(ctx context.Context, roleID uint64) ([]string, error) {
var codes []string
if err := r.db.WithContext(ctx).
Table("admin_role_permissions rp").
Joins("JOIN admin_permissions p ON p.id = rp.permission_id").
Where("rp.role_id = ?", roleID).
Pluck("p.code", &codes).Error; err != nil {
return nil, errors.Wrap(50000, "query role permission codes", err)
}
return codes, nil
}