diff --git a/src/main/java/gg/agit/konect/domain/club/controller/ClubApi.java b/src/main/java/gg/agit/konect/domain/club/controller/ClubApi.java index d437d094..b7fc87a2 100644 --- a/src/main/java/gg/agit/konect/domain/club/controller/ClubApi.java +++ b/src/main/java/gg/agit/konect/domain/club/controller/ClubApi.java @@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import gg.agit.konect.domain.club.dto.ClubApplicationAnswersResponse; +import gg.agit.konect.domain.club.dto.ClubAppliedClubsResponse; import gg.agit.konect.domain.club.dto.ClubApplicationsResponse; import gg.agit.konect.domain.club.dto.ClubApplyQuestionsReplaceRequest; import gg.agit.konect.domain.club.dto.ClubApplyQuestionsResponse; @@ -107,6 +108,12 @@ ResponseEntity getManagedClubs( @UserId Integer userId ); + @Operation(summary = "가입 승인 대기 중인 동아리 리스트를 조회한다.") + @GetMapping("/applied") + ResponseEntity getAppliedClubs( + @UserId Integer userId + ); + @Operation(summary = "동아리 지원 내역을 조회한다.", description = """ - 동아리 관리자만 해당 동아리의 지원 내역을 조회할 수 있습니다. - 현재 지정된 모집 일정 범위에 지원한 내역만 볼 수 있습니다. diff --git a/src/main/java/gg/agit/konect/domain/club/controller/ClubController.java b/src/main/java/gg/agit/konect/domain/club/controller/ClubController.java index dacf88ae..ce0a7d93 100644 --- a/src/main/java/gg/agit/konect/domain/club/controller/ClubController.java +++ b/src/main/java/gg/agit/konect/domain/club/controller/ClubController.java @@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.RestController; import gg.agit.konect.domain.club.dto.ClubApplicationAnswersResponse; +import gg.agit.konect.domain.club.dto.ClubAppliedClubsResponse; import gg.agit.konect.domain.club.dto.ClubApplicationsResponse; import gg.agit.konect.domain.club.dto.ClubApplyQuestionsReplaceRequest; import gg.agit.konect.domain.club.dto.ClubApplyQuestionsResponse; @@ -100,6 +101,14 @@ public ResponseEntity getManagedClubs( return ResponseEntity.ok(response); } + @Override + public ResponseEntity getAppliedClubs( + @UserId Integer userId + ) { + ClubAppliedClubsResponse response = clubService.getAppliedClubs(userId); + return ResponseEntity.ok(response); + } + @Override public ResponseEntity getClubApplications( @PathVariable(name = "clubId") Integer clubId, diff --git a/src/main/java/gg/agit/konect/domain/club/dto/ClubAppliedClubsResponse.java b/src/main/java/gg/agit/konect/domain/club/dto/ClubAppliedClubsResponse.java new file mode 100644 index 00000000..167b7c7e --- /dev/null +++ b/src/main/java/gg/agit/konect/domain/club/dto/ClubAppliedClubsResponse.java @@ -0,0 +1,54 @@ +package gg.agit.konect.domain.club.dto; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; + +import java.time.LocalDateTime; +import java.util.List; + +import gg.agit.konect.domain.club.model.ClubApply; +import io.swagger.v3.oas.annotations.media.Schema; + +public record ClubAppliedClubsResponse( + @Schema(description = "가입 승인 대기 중인 동아리 리스트", requiredMode = REQUIRED) + List appliedClubs +) { + + public record InnerAppliedClubResponse( + @Schema(description = "동아리 고유 ID", example = "1", requiredMode = REQUIRED) + Integer id, + + @Schema(description = "동아리 이름", example = "BCSD", requiredMode = REQUIRED) + String name, + + @Schema( + description = "동아리 이미지 링크", + example = "https://bcsdlab.com/static/img/logo.d89d9cc.png", + requiredMode = REQUIRED + ) + String imageUrl, + + @Schema(description = "동아리 분과", example = "학술", requiredMode = REQUIRED) + String categoryName, + + @Schema(description = "가입 신청 일시", example = "2025-01-13T10:30:00", requiredMode = REQUIRED) + LocalDateTime appliedAt + ) { + public static InnerAppliedClubResponse from(ClubApply clubApply) { + return new InnerAppliedClubResponse( + clubApply.getClub().getId(), + clubApply.getClub().getName(), + clubApply.getClub().getImageUrl(), + clubApply.getClub().getClubCategory().getDescription(), + clubApply.getCreatedAt() + ); + } + } + + public static ClubAppliedClubsResponse from(List clubApplies) { + return new ClubAppliedClubsResponse( + clubApplies.stream() + .map(InnerAppliedClubResponse::from) + .toList() + ); + } +} diff --git a/src/main/java/gg/agit/konect/domain/club/repository/ClubApplyRepository.java b/src/main/java/gg/agit/konect/domain/club/repository/ClubApplyRepository.java index 5eac324e..fc71a0c4 100644 --- a/src/main/java/gg/agit/konect/domain/club/repository/ClubApplyRepository.java +++ b/src/main/java/gg/agit/konect/domain/club/repository/ClubApplyRepository.java @@ -45,6 +45,21 @@ default ClubApply getByIdAndClubId(Integer id, Integer clubId) { """) List findAllByClubIdWithUser(@Param("clubId") Integer clubId); + @Query(""" + SELECT clubApply + FROM ClubApply clubApply + JOIN FETCH clubApply.club club + WHERE clubApply.user.id = :userId + AND NOT EXISTS ( + SELECT 1 + FROM ClubMember clubMember + WHERE clubMember.club.id = clubApply.club.id + AND clubMember.user.id = clubApply.user.id + ) + ORDER BY clubApply.createdAt DESC + """) + List findAllPendingByUserIdWithClub(@Param("userId") Integer userId); + @Query(""" SELECT clubApply FROM ClubApply clubApply diff --git a/src/main/java/gg/agit/konect/domain/club/service/ClubService.java b/src/main/java/gg/agit/konect/domain/club/service/ClubService.java index e006191e..f4ed5149 100644 --- a/src/main/java/gg/agit/konect/domain/club/service/ClubService.java +++ b/src/main/java/gg/agit/konect/domain/club/service/ClubService.java @@ -21,6 +21,7 @@ import gg.agit.konect.domain.bank.repository.BankRepository; import gg.agit.konect.domain.club.dto.ClubApplicationAnswersResponse; +import gg.agit.konect.domain.club.dto.ClubAppliedClubsResponse; import gg.agit.konect.domain.club.dto.ClubApplicationsResponse; import gg.agit.konect.domain.club.dto.ClubApplyQuestionsReplaceRequest; import gg.agit.konect.domain.club.dto.ClubApplyQuestionsResponse; @@ -169,6 +170,11 @@ public ClubMembershipsResponse getManagedClubs(Integer userId) { return ClubMembershipsResponse.from(clubMembers); } + public ClubAppliedClubsResponse getAppliedClubs(Integer userId) { + List clubApplies = clubApplyRepository.findAllPendingByUserIdWithClub(userId); + return ClubAppliedClubsResponse.from(clubApplies); + } + public ClubApplicationsResponse getClubApplications(Integer clubId, Integer userId) { clubRepository.getById(clubId);