From 15c3ffa47933d809505020cc4637d1da12c57f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EB=8F=99=ED=9B=88?= <2dh2@naver.com> Date: Fri, 23 Jan 2026 22:26:40 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=EC=8A=B9=EC=9D=B8=20=EB=8C=80?= =?UTF-8?q?=EA=B8=B0=20=EC=A4=91=EC=9D=B8=20=EB=8F=99=EC=95=84=EB=A6=AC=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20API=20=EB=AA=85=EC=84=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gg/agit/konect/domain/club/controller/ClubApi.java | 7 +++++++ 1 file changed, 7 insertions(+) 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 = """ - 동아리 관리자만 해당 동아리의 지원 내역을 조회할 수 있습니다. - 현재 지정된 모집 일정 범위에 지원한 내역만 볼 수 있습니다. From 3f9b4b0431e16995702489af2629505f6b1417ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EB=8F=99=ED=9B=88?= <2dh2@naver.com> Date: Fri, 23 Jan 2026 22:26:49 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=EC=8A=B9=EC=9D=B8=20=EB=8C=80?= =?UTF-8?q?=EA=B8=B0=20=EC=A4=91=EC=9D=B8=20=EB=8F=99=EC=95=84=EB=A6=AC=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../club/controller/ClubController.java | 9 ++++ .../club/dto/ClubAppliedClubsResponse.java | 54 +++++++++++++++++++ .../club/repository/ClubApplyRepository.java | 15 ++++++ .../domain/club/service/ClubService.java | 6 +++ 4 files changed, 84 insertions(+) create mode 100644 src/main/java/gg/agit/konect/domain/club/dto/ClubAppliedClubsResponse.java 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);