141 lines
4.1 KiB
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
|
|
}
|