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) }