backend/pkg/permission/usecase/user_role.go

226 lines
5.4 KiB
Go
Raw Normal View History

2025-10-03 08:38:12 +00:00
package usecase
import (
"backend/pkg/library/errs/code"
"backend/pkg/permission/domain/permission"
"backend/pkg/permission/utils"
"context"
"backend/pkg/library/errs"
"backend/pkg/permission/domain/entity"
"backend/pkg/permission/domain/repository"
"backend/pkg/permission/domain/usecase"
)
type UserRoleUseCaseParam struct {
UserRoleRepo repository.UserRoleRepository
RoleRepo repository.RoleRepository
}
type UserRoleUseCase struct {
userRoleRepo repository.UserRoleRepository
roleRepo repository.RoleRepository
}
// MustUserRoleUseCase 創建用戶角色用例實例
func MustUserRoleUseCase(param UserRoleUseCaseParam) usecase.UserRoleUseCase {
return &UserRoleUseCase{
userRoleRepo: param.UserRoleRepo,
roleRepo: param.RoleRepo,
}
}
func (uc *UserRoleUseCase) AssignRole(ctx context.Context, req usecase.AssignRoleRequest) (*entity.UserRole, error) {
// 驗證請求
if req.UID == "" {
return nil, errs.InvalidFormat("uid is required")
}
if req.RoleUID == "" {
return nil, errs.InvalidFormat("role_uid is required")
}
if req.Brand == "" {
return nil, errs.InvalidFormat("brand is required")
}
// 檢查角色是否存在
role, err := uc.roleRepo.GetByUID(ctx, req.RoleUID)
if err != nil {
return nil, err
}
if !utils.IsActive(role.Status) {
return nil, errs.InvalidFormat("role is not active")
}
// 檢查用戶是否已經有此角色
existingUserRole, err := uc.userRoleRepo.GetByUserAndRole(ctx, req.UID, req.RoleUID)
if err == nil && existingUserRole != nil && utils.IsActive(existingUserRole.Status) {
return nil, errs.ResourceAlreadyExistWithScope(code.CloudEPPermission, req.UID+":"+req.RoleUID)
}
userRole := &entity.UserRole{
Brand: req.Brand,
UID: req.UID,
RoleUID: req.RoleUID,
Status: permission.StatusActive,
}
if err := uc.userRoleRepo.Create(ctx, userRole); err != nil {
return nil, err
}
return userRole, nil
}
func (uc *UserRoleUseCase) RevokeRole(ctx context.Context, uid, roleUID string) error {
// 驗證參數
if uid == "" {
return errs.InvalidFormat("uid is required")
}
if roleUID == "" {
return errs.InvalidFormat("role_uid is required")
}
return uc.userRoleRepo.DeleteByUserAndRole(ctx, uid, roleUID)
}
func (uc *UserRoleUseCase) GetUserRole(ctx context.Context, id string) (*entity.UserRole, error) {
return uc.userRoleRepo.GetByID(ctx, id)
}
func (uc *UserRoleUseCase) UpdateUserRole(ctx context.Context, req usecase.UpdateUserRoleRequest) (*entity.UserRole, error) {
// 獲取現有用戶角色
userRole, err := uc.userRoleRepo.GetByID(ctx, req.ID)
if err != nil {
return nil, err
}
// 更新狀態
if req.Status != nil {
userRole.Status = *req.Status
}
if err := uc.userRoleRepo.Update(ctx, req.ID, userRole); err != nil {
return nil, err
}
return userRole, nil
}
func (uc *UserRoleUseCase) ListUserRoles(ctx context.Context, req usecase.ListUserRolesRequest) ([]*entity.UserRole, error) {
filter := repository.UserRoleFilter{
Brand: req.Brand,
UID: req.UID,
RoleUID: req.RoleUID,
Status: req.Status,
Limit: req.Limit,
Skip: req.Skip,
}
return uc.userRoleRepo.List(ctx, filter)
}
func (uc *UserRoleUseCase) GetUserRoles(ctx context.Context, uid string) ([]*entity.UserRole, error) {
if uid == "" {
return nil, errs.InvalidFormat("uid is required")
}
return uc.userRoleRepo.GetUserRolesByUID(ctx, uid)
}
func (uc *UserRoleUseCase) GetUserRoleDetails(ctx context.Context, uid string) ([]*usecase.UserRoleDetail, error) {
// 獲取用戶角色
userRoles, err := uc.GetUserRoles(ctx, uid)
if err != nil {
return nil, err
}
var details []*usecase.UserRoleDetail
for _, userRole := range userRoles {
if !utils.IsActive(userRole.Status) {
continue
}
// 獲取角色詳情
role, err := uc.roleRepo.GetByUID(ctx, userRole.RoleUID)
if err != nil {
continue // 忽略獲取失敗的角色
}
detail := &usecase.UserRoleDetail{
UserRole: userRole,
Role: role,
}
details = append(details, detail)
}
return details, nil
}
func (uc *UserRoleUseCase) BatchAssignRoles(ctx context.Context, uid string, roleUIDs []string, brand string) error {
if uid == "" {
return errs.InvalidFormat("uid is required")
}
if brand == "" {
return errs.InvalidFormat("brand is required")
}
// 逐個分配角色
for _, roleUID := range roleUIDs {
req := usecase.AssignRoleRequest{
Brand: brand,
UID: uid,
RoleUID: roleUID,
}
_, err := uc.AssignRole(ctx, req)
if err != nil {
// 如果是已存在錯誤,忽略繼續
e := errs.FromError(err)
if e.Is(errs.ResourceAlreadyExist()) {
continue
}
return err
}
}
return nil
}
func (uc *UserRoleUseCase) BatchRevokeRoles(ctx context.Context, uid string, roleUIDs []string) error {
if uid == "" {
return errs.InvalidFormat("uid is required")
}
// 逐個撤銷角色
for _, roleUID := range roleUIDs {
err := uc.RevokeRole(ctx, uid, roleUID)
if err != nil {
continue
}
}
return nil
}
func (uc *UserRoleUseCase) ReplaceUserRoles(ctx context.Context, uid string, roleUIDs []string, brand string) error {
// 獲取用戶當前的所有角色
currentUserRoles, err := uc.GetUserRoles(ctx, uid)
if err != nil {
return err
}
// 撤銷所有現有角色
for _, userRole := range currentUserRoles {
if utils.IsActive(userRole.Status) {
if err := uc.RevokeRole(ctx, uid, userRole.RoleUID); err != nil {
return err
}
}
}
// 分配新角色
return uc.BatchAssignRoles(ctx, uid, roleUIDs, brand)
}