Files
user-system/internal/repository/role_permission.go
long-agent 2a18a6fb47 fix(n+1): 批量查询替代循环单查
- IsAdminBootstrapRequired: userRepo.GetByID 循环 → GetByIDs 批量
- AssignRoles: roleRepo.GetByID 循环 → GetByIDs 批量
- 在 userRepositoryInterface 补充 GetByIDs 方法签名
2026-05-08 08:05:26 +08:00

197 lines
6.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package repository
import (
"context"
"gorm.io/gorm"
"github.com/user-management-system/internal/domain"
)
// RolePermissionRepository 角色权限关联数据访问层
type RolePermissionRepository struct {
db *gorm.DB
}
// NewRolePermissionRepository 创建角色权限关联数据访问层
func NewRolePermissionRepository(db *gorm.DB) *RolePermissionRepository {
return &RolePermissionRepository{db: db}
}
// Create 创建角色权限关联
func (r *RolePermissionRepository) Create(ctx context.Context, rolePermission *domain.RolePermission) error {
return r.db.WithContext(ctx).Create(rolePermission).Error
}
// Delete 删除角色权限关联
func (r *RolePermissionRepository) Delete(ctx context.Context, id int64) error {
return r.db.WithContext(ctx).Delete(&domain.RolePermission{}, id).Error
}
// DeleteByRoleID 删除角色的所有权限
func (r *RolePermissionRepository) DeleteByRoleID(ctx context.Context, roleID int64) error {
return r.db.WithContext(ctx).Where("role_id = ?", roleID).Delete(&domain.RolePermission{}).Error
}
// DeleteByPermissionID 删除权限的所有角色
func (r *RolePermissionRepository) DeleteByPermissionID(ctx context.Context, permissionID int64) error {
return r.db.WithContext(ctx).Where("permission_id = ?", permissionID).Delete(&domain.RolePermission{}).Error
}
// GetByRoleID 根据角色ID获取权限列表
func (r *RolePermissionRepository) GetByRoleID(ctx context.Context, roleID int64) ([]*domain.RolePermission, error) {
var rolePermissions []*domain.RolePermission
err := r.db.WithContext(ctx).Where("role_id = ?", roleID).Find(&rolePermissions).Error
if err != nil {
return nil, err
}
return rolePermissions, nil
}
// GetByPermissionID 根据权限ID获取角色列表
func (r *RolePermissionRepository) GetByPermissionID(ctx context.Context, permissionID int64) ([]*domain.RolePermission, error) {
var rolePermissions []*domain.RolePermission
err := r.db.WithContext(ctx).Where("permission_id = ?", permissionID).Find(&rolePermissions).Error
if err != nil {
return nil, err
}
return rolePermissions, nil
}
// GetPermissionIDsByRoleID 根据角色ID获取权限ID列表
func (r *RolePermissionRepository) GetPermissionIDsByRoleID(ctx context.Context, roleID int64) ([]int64, error) {
var permissionIDs []int64
err := r.db.WithContext(ctx).Model(&domain.RolePermission{}).Where("role_id = ?", roleID).Pluck("permission_id", &permissionIDs).Error
if err != nil {
return nil, err
}
return permissionIDs, nil
}
// GetRoleIDByPermissionID 根据权限ID获取角色ID列表
func (r *RolePermissionRepository) GetRoleIDByPermissionID(ctx context.Context, permissionID int64) ([]int64, error) {
var roleIDs []int64
err := r.db.WithContext(ctx).Model(&domain.RolePermission{}).Where("permission_id = ?", permissionID).Pluck("role_id", &roleIDs).Error
if err != nil {
return nil, err
}
return roleIDs, nil
}
// Exists 检查角色权限关联是否存在
func (r *RolePermissionRepository) Exists(ctx context.Context, roleID, permissionID int64) (bool, error) {
var count int64
err := r.db.WithContext(ctx).Model(&domain.RolePermission{}).
Where("role_id = ? AND permission_id = ?", roleID, permissionID).
Count(&count).Error
return count > 0, err
}
// BatchCreate 批量创建角色权限关联
func (r *RolePermissionRepository) BatchCreate(ctx context.Context, rolePermissions []*domain.RolePermission) error {
if len(rolePermissions) == 0 {
return nil
}
return r.db.WithContext(ctx).Create(&rolePermissions).Error
}
// BatchDelete 批量删除角色权限关联
func (r *RolePermissionRepository) BatchDelete(ctx context.Context, rolePermissions []*domain.RolePermission) error {
if len(rolePermissions) == 0 {
return nil
}
var ids []int64
for _, rp := range rolePermissions {
ids = append(ids, rp.ID)
}
return r.db.WithContext(ctx).Delete(&domain.RolePermission{}, ids).Error
}
// GetPermissionByID 根据权限ID获取权限信息
func (r *RolePermissionRepository) GetPermissionByID(ctx context.Context, permissionID int64) (*domain.Permission, error) {
var permission domain.Permission
err := r.db.WithContext(ctx).First(&permission, permissionID).Error
if err != nil {
return nil, err
}
return &permission, nil
}
// GetRoleAncestorIDs 递归获取角色的所有祖先角色ID含自身
// 包含循环检测(最大深度 5 层)
func (r *RolePermissionRepository) GetRoleAncestorIDs(ctx context.Context, roleID int64) ([]int64, error) {
var ancestors []int64
visited := make(map[int64]bool)
current := roleID
depth := 0
maxDepth := 5
for current > 0 && depth < maxDepth {
if visited[current] {
break // 循环检测
}
visited[current] = true
ancestors = append(ancestors, current)
var role domain.Role
err := r.db.WithContext(ctx).Select("parent_id").First(&role, current).Error
if err != nil || role.ParentID == nil {
break
}
current = *role.ParentID
depth++
}
return ancestors, nil
}
// GetPermissionIDsByRoleIDs 根据角色ID列表批量获取权限ID含继承的父角色权限
func (r *RolePermissionRepository) GetPermissionIDsByRoleIDs(ctx context.Context, roleIDs []int64) ([]int64, error) {
if len(roleIDs) == 0 {
return []int64{}, nil
}
// 收集所有角色ID含继承的父角色
allRoleIDs := make(map[int64]bool)
for _, roleID := range roleIDs {
ancestors, err := r.GetRoleAncestorIDs(ctx, roleID)
if err != nil {
return nil, err
}
for _, id := range ancestors {
allRoleIDs[id] = true
}
}
// 转换为 slice
ids := make([]int64, 0, len(allRoleIDs))
for id := range allRoleIDs {
ids = append(ids, id)
}
var permissionIDs []int64
err := r.db.WithContext(ctx).Model(&domain.RolePermission{}).
Where("role_id IN ?", ids).
Pluck("permission_id", &permissionIDs).Error
if err != nil {
return nil, err
}
return permissionIDs, nil
}
// GetPermissionsByIDs 根据权限ID列表批量获取权限
func (r *RolePermissionRepository) GetPermissionsByIDs(ctx context.Context, permissionIDs []int64) ([]*domain.Permission, error) {
if len(permissionIDs) == 0 {
return []*domain.Permission{}, nil
}
var permissions []*domain.Permission
err := r.db.WithContext(ctx).Where("id IN ?", permissionIDs).Find(&permissions).Error
if err != nil {
return nil, err
}
return permissions, nil
}