package usecase import ( "backend/pkg/permission/domain" "backend/pkg/permission/domain/entity" "backend/pkg/permission/domain/repository" "backend/pkg/permission/domain/usecase" "context" "fmt" "time" "go.mongodb.org/mongo-driver/v2/bson" ) type UserRoleUseCaseParam struct { UserRoleRepo repository.UserRoleRepository RoleRepo repository.RoleRepository } type userRoleUseCase struct { UserRoleUseCaseParam } // NewUserRoleUseCase 建立使用者角色 UseCase func NewUserRoleUseCase(param UserRoleUseCaseParam) usecase.UserRoleUseCase { return &userRoleUseCase{ UserRoleUseCaseParam: param, } } func (uc *userRoleUseCase) Assign(ctx context.Context, req usecase.AssignRoleRequest) (*usecase.UserRoleResponse, error) { // 檢查角色是否存在 role, err := uc.RoleRepo.GetByUID(ctx, req.RoleUID) if err != nil { return nil, err } if !role.Status.IsActive() { return nil, fmt.Errorf("role is not active") } // 檢查使用者是否已有角色 exists, err := uc.UserRoleRepo.Exists(ctx, req.UserUID) if err != nil { return nil, err } if exists { return nil, fmt.Errorf("user role already exists") } // 建立使用者角色 now := time.Now().Unix() userRole := &entity.UserRole{ ID: bson.NewObjectID(), UID: req.UserUID, RoleID: req.RoleUID, Brand: req.Brand, Status: domain.RecordActive, } userRole.CreateTime = now userRole.UpdateTime = now if err := uc.UserRoleRepo.Create(ctx, userRole); err != nil { return nil, err } return uc.toResponse(userRole), nil } func (uc *userRoleUseCase) Update(ctx context.Context, userUID, roleUID string) (*usecase.UserRoleResponse, error) { // 檢查角色是否存在 role, err := uc.RoleRepo.GetByUID(ctx, roleUID) if err != nil { return nil, err } if !role.Status.IsActive() { return nil, fmt.Errorf("role is not active") } // 更新使用者角色 userRole, err := uc.UserRoleRepo.Update(ctx, userUID, roleUID) if err != nil { return nil, err } return uc.toResponse(userRole), nil } func (uc *userRoleUseCase) Remove(ctx context.Context, userUID string) error { return uc.UserRoleRepo.Delete(ctx, userUID) } func (uc *userRoleUseCase) Get(ctx context.Context, userUID string) (*usecase.UserRoleResponse, error) { userRole, err := uc.UserRoleRepo.Get(ctx, userUID) if err != nil { return nil, err } return uc.toResponse(userRole), nil } func (uc *userRoleUseCase) GetByRole(ctx context.Context, roleUID string) ([]*usecase.UserRoleResponse, error) { // 檢查角色是否存在 if _, err := uc.RoleRepo.GetByUID(ctx, roleUID); err != nil { return nil, err } userRoles, err := uc.UserRoleRepo.GetByRoleID(ctx, roleUID) if err != nil { return nil, err } result := make([]*usecase.UserRoleResponse, 0, len(userRoles)) for _, ur := range userRoles { result = append(result, uc.toResponse(ur)) } return result, nil } func (uc *userRoleUseCase) List(ctx context.Context, filter usecase.UserRoleFilterRequest) ([]*usecase.UserRoleResponse, error) { repoFilter := repository.UserRoleFilter{ Brand: filter.Brand, RoleID: filter.RoleID, Status: filter.Status, } userRoles, err := uc.UserRoleRepo.List(ctx, repoFilter) if err != nil { return nil, err } result := make([]*usecase.UserRoleResponse, 0, len(userRoles)) for _, ur := range userRoles { result = append(result, uc.toResponse(ur)) } return result, nil } func (uc *userRoleUseCase) toResponse(userRole *entity.UserRole) *usecase.UserRoleResponse { return &usecase.UserRoleResponse{ UserUID: userRole.UID, RoleUID: userRole.RoleID, Brand: userRole.Brand, CreateTime: time.Unix(userRole.CreateTime, 0).UTC().Format(time.RFC3339), UpdateTime: time.Unix(userRole.UpdateTime, 0).UTC().Format(time.RFC3339), } }