backend/tmp/reborn/repository/role_permission_repository.go

141 lines
4.1 KiB
Go

package repository
import (
"context"
"permission/reborn/domain/entity"
"permission/reborn/domain/errors"
"permission/reborn/domain/repository"
"gorm.io/gorm"
)
type rolePermissionRepository struct {
db *gorm.DB
}
// NewRolePermissionRepository 建立角色權限 Repository
func NewRolePermissionRepository(db *gorm.DB) repository.RolePermissionRepository {
return &rolePermissionRepository{db: db}
}
func (r *rolePermissionRepository) Create(ctx context.Context, roleID int64, permissionIDs []int64) error {
if len(permissionIDs) == 0 {
return nil
}
rolePerms := make([]*entity.RolePermission, 0, len(permissionIDs))
for _, permID := range permissionIDs {
rolePerms = append(rolePerms, &entity.RolePermission{
RoleID: roleID,
PermissionID: permID,
})
}
if err := r.db.WithContext(ctx).Create(&rolePerms).Error; err != nil {
return errors.Wrap(errors.ErrCodeDBQuery, "failed to create role permissions", err)
}
return nil
}
func (r *rolePermissionRepository) Update(ctx context.Context, roleID int64, permissionIDs []int64) error {
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
// 刪除舊的權限關聯
if err := tx.Where("role_id = ?", roleID).Delete(&entity.RolePermission{}).Error; err != nil {
return errors.Wrap(errors.ErrCodeDBTransaction, "failed to delete old role permissions", err)
}
// 建立新的權限關聯
if len(permissionIDs) > 0 {
rolePerms := make([]*entity.RolePermission, 0, len(permissionIDs))
for _, permID := range permissionIDs {
rolePerms = append(rolePerms, &entity.RolePermission{
RoleID: roleID,
PermissionID: permID,
})
}
if err := tx.Create(&rolePerms).Error; err != nil {
return errors.Wrap(errors.ErrCodeDBTransaction, "failed to create new role permissions", err)
}
}
return nil
})
}
func (r *rolePermissionRepository) Delete(ctx context.Context, roleID int64) error {
if err := r.db.WithContext(ctx).Where("role_id = ?", roleID).Delete(&entity.RolePermission{}).Error; err != nil {
return errors.Wrap(errors.ErrCodeDBQuery, "failed to delete role permissions", err)
}
return nil
}
func (r *rolePermissionRepository) GetByRoleID(ctx context.Context, roleID int64) ([]*entity.RolePermission, error) {
var rolePerms []*entity.RolePermission
err := r.db.WithContext(ctx).
Where("role_id = ?", roleID).
Find(&rolePerms).Error
if err != nil {
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get role permissions", err)
}
return rolePerms, nil
}
// GetByRoleIDs 批量取得多個角色的權限關聯 (解決 N+1 查詢問題)
func (r *rolePermissionRepository) GetByRoleIDs(ctx context.Context, roleIDs []int64) (map[int64][]*entity.RolePermission, error) {
if len(roleIDs) == 0 {
return make(map[int64][]*entity.RolePermission), nil
}
var rolePerms []*entity.RolePermission
err := r.db.WithContext(ctx).
Where("role_id IN ?", roleIDs).
Find(&rolePerms).Error
if err != nil {
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get role permissions by role ids", err)
}
// 按 role_id 分組
result := make(map[int64][]*entity.RolePermission)
for _, rp := range rolePerms {
result[rp.RoleID] = append(result[rp.RoleID], rp)
}
return result, nil
}
func (r *rolePermissionRepository) GetByPermissionIDs(ctx context.Context, permissionIDs []int64) ([]*entity.RolePermission, error) {
if len(permissionIDs) == 0 {
return []*entity.RolePermission{}, nil
}
var rolePerms []*entity.RolePermission
err := r.db.WithContext(ctx).
Where("permission_id IN ?", permissionIDs).
Find(&rolePerms).Error
if err != nil {
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get role permissions by permission ids", err)
}
return rolePerms, nil
}
func (r *rolePermissionRepository) GetRolesByPermission(ctx context.Context, permissionID int64) ([]int64, error) {
var roleIDs []int64
err := r.db.WithContext(ctx).
Model(&entity.RolePermission{}).
Where("permission_id = ?", permissionID).
Pluck("role_id", &roleIDs).Error
if err != nil {
return nil, errors.Wrap(errors.ErrCodeDBQuery, "failed to get roles by permission", err)
}
return roleIDs, nil
}