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 }