diff --git a/src/main/java/OneQ/OnSurvey/domain/survey/controller/SurveyStatsController.java b/src/main/java/OneQ/OnSurvey/domain/survey/controller/SurveyStatsController.java index e7f12677..ebcb6e38 100644 --- a/src/main/java/OneQ/OnSurvey/domain/survey/controller/SurveyStatsController.java +++ b/src/main/java/OneQ/OnSurvey/domain/survey/controller/SurveyStatsController.java @@ -1,8 +1,11 @@ package OneQ.OnSurvey.domain.survey.controller; import OneQ.OnSurvey.domain.survey.model.dto.GlobalStats; +import OneQ.OnSurvey.domain.survey.model.dto.OpenSurveyStats; import OneQ.OnSurvey.domain.survey.model.response.GlobalStatsResponse; +import OneQ.OnSurvey.domain.survey.model.response.OpenSurveyStatsResponse; import OneQ.OnSurvey.domain.survey.service.SurveyGlobalStatsService; +import OneQ.OnSurvey.domain.survey.service.query.SurveyQuery; import OneQ.OnSurvey.global.common.response.SuccessResponse; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; @@ -16,6 +19,7 @@ public class SurveyStatsController { private final SurveyGlobalStatsService surveyGlobalStatsService; + private final SurveyQuery surveyQuery; @GetMapping("/global-stats") @Operation(summary = "전체 설문 전역 통계 조회", description = "전체 설문에 대한 총 목표 수/참여자 수/프로모션 지급자 수/일간 활성 사용자 수를 반환합니다.") @@ -23,4 +27,11 @@ public SuccessResponse getGlobalStats() { GlobalStats stats = surveyGlobalStatsService.getStats(); return SuccessResponse.ok(GlobalStatsResponse.from(stats)); } + + @GetMapping("/open-stats") + @Operation(summary = "열린 설문 통계 조회", description = "현재 진행 중인 설문 수와 가장 높은 참여 보상 코인 금액을 반환합니다.") + public SuccessResponse getOpenStats() { + OpenSurveyStats stats = surveyQuery.getOpenSurveyStats(); + return SuccessResponse.ok(OpenSurveyStatsResponse.from(stats)); + } } diff --git a/src/main/java/OneQ/OnSurvey/domain/survey/model/dto/OpenSurveyStats.java b/src/main/java/OneQ/OnSurvey/domain/survey/model/dto/OpenSurveyStats.java new file mode 100644 index 00000000..d7c83b30 --- /dev/null +++ b/src/main/java/OneQ/OnSurvey/domain/survey/model/dto/OpenSurveyStats.java @@ -0,0 +1,13 @@ +package OneQ.OnSurvey.domain.survey.model.dto; + +public record OpenSurveyStats( + Long openSurveyCount, + Integer maxRewardCoin +) { + public static OpenSurveyStats of(Long openSurveyCount, Integer maxRewardCoin) { + return new OpenSurveyStats( + openSurveyCount != null ? openSurveyCount : 0L, + maxRewardCoin != null ? maxRewardCoin : 0 + ); + } +} diff --git a/src/main/java/OneQ/OnSurvey/domain/survey/model/response/OpenSurveyStatsResponse.java b/src/main/java/OneQ/OnSurvey/domain/survey/model/response/OpenSurveyStatsResponse.java new file mode 100644 index 00000000..cf0af95f --- /dev/null +++ b/src/main/java/OneQ/OnSurvey/domain/survey/model/response/OpenSurveyStatsResponse.java @@ -0,0 +1,12 @@ +package OneQ.OnSurvey.domain.survey.model.response; + +import OneQ.OnSurvey.domain.survey.model.dto.OpenSurveyStats; + +public record OpenSurveyStatsResponse( + Long openSurveyCount, + Integer maxRewardCoin +) { + public static OpenSurveyStatsResponse from(OpenSurveyStats stats) { + return new OpenSurveyStatsResponse(stats.openSurveyCount(), stats.maxRewardCoin()); + } +} diff --git a/src/main/java/OneQ/OnSurvey/domain/survey/repository/SurveyRepository.java b/src/main/java/OneQ/OnSurvey/domain/survey/repository/SurveyRepository.java index cc83e59d..621e0cfe 100644 --- a/src/main/java/OneQ/OnSurvey/domain/survey/repository/SurveyRepository.java +++ b/src/main/java/OneQ/OnSurvey/domain/survey/repository/SurveyRepository.java @@ -5,6 +5,7 @@ import OneQ.OnSurvey.domain.survey.entity.Survey; import OneQ.OnSurvey.domain.survey.model.SurveyStatus; import OneQ.OnSurvey.domain.survey.model.dto.OngoingSurveyStats; +import OneQ.OnSurvey.domain.survey.model.dto.OpenSurveyStats; import OneQ.OnSurvey.domain.survey.model.dto.SurveyDetailData; import OneQ.OnSurvey.domain.survey.model.dto.SurveyListView; import OneQ.OnSurvey.domain.survey.model.dto.SurveySearchQuery; @@ -37,4 +38,5 @@ Slice getSurveyListWithEligibility( List closeDueSurveys(); List findOngoingSurveys(); + OpenSurveyStats findOpenSurveyStats(); } diff --git a/src/main/java/OneQ/OnSurvey/domain/survey/repository/SurveyRepositoryImpl.java b/src/main/java/OneQ/OnSurvey/domain/survey/repository/SurveyRepositoryImpl.java index fe1a13ac..42a6935c 100644 --- a/src/main/java/OneQ/OnSurvey/domain/survey/repository/SurveyRepositoryImpl.java +++ b/src/main/java/OneQ/OnSurvey/domain/survey/repository/SurveyRepositoryImpl.java @@ -9,6 +9,7 @@ import OneQ.OnSurvey.domain.survey.model.Residence; import OneQ.OnSurvey.domain.survey.model.SurveyStatus; import OneQ.OnSurvey.domain.survey.model.dto.OngoingSurveyStats; +import OneQ.OnSurvey.domain.survey.model.dto.OpenSurveyStats; import OneQ.OnSurvey.domain.survey.model.dto.SurveyDetailData; import OneQ.OnSurvey.domain.survey.model.dto.SurveyListView; import OneQ.OnSurvey.domain.survey.model.dto.SurveySearchQuery; @@ -319,4 +320,21 @@ public List findOngoingSurveys() { .orderBy(survey.id.desc()) .fetch(); } + + @Override + public OpenSurveyStats findOpenSurveyStats() { + Tuple result = jpaQueryFactory + .select(survey.count(), surveyInfo.promotionAmount.max()) + .from(survey) + .leftJoin(surveyInfo).on(survey.id.eq(surveyInfo.surveyId)) + .where(survey.status.eq(SurveyStatus.ONGOING)) + .fetchOne(); + + if (result == null) { + return OpenSurveyStats.of(0L, null); + } + Long count = result.get(survey.count()); + Integer maxCoin = result.get(surveyInfo.promotionAmount.max()); + return OpenSurveyStats.of(count, maxCoin); + } } diff --git a/src/main/java/OneQ/OnSurvey/domain/survey/service/query/SurveyQuery.java b/src/main/java/OneQ/OnSurvey/domain/survey/service/query/SurveyQuery.java index ea3f5614..ad53bf23 100644 --- a/src/main/java/OneQ/OnSurvey/domain/survey/service/query/SurveyQuery.java +++ b/src/main/java/OneQ/OnSurvey/domain/survey/service/query/SurveyQuery.java @@ -4,6 +4,7 @@ import OneQ.OnSurvey.domain.survey.entity.Survey; import OneQ.OnSurvey.domain.survey.model.SurveyStatus; import OneQ.OnSurvey.domain.survey.model.dto.OngoingSurveyStats; +import OneQ.OnSurvey.domain.survey.model.dto.OpenSurveyStats; import OneQ.OnSurvey.domain.survey.model.dto.ScreeningViewData; import OneQ.OnSurvey.domain.survey.model.dto.SurveyDetailData; import OneQ.OnSurvey.domain.survey.model.dto.SurveyListView; @@ -47,6 +48,7 @@ ParticipationScreeningListResponse getScreeningList( // 외부 PORT Page getPagedSurveyListViewByQuery(Pageable pageable, SurveySearchQuery query); List getOngoingSurveyStats(); + OpenSurveyStats getOpenSurveyStats(); SurveyDetailData getSurveyDetailById(Long surveyId); ScreeningViewData getScreeningIntroBySurveyId(Long surveyId); List getSectionDtoListBySurveyId(Long surveyId); diff --git a/src/main/java/OneQ/OnSurvey/domain/survey/service/query/SurveyQueryService.java b/src/main/java/OneQ/OnSurvey/domain/survey/service/query/SurveyQueryService.java index 3dec0a24..2daa19ee 100644 --- a/src/main/java/OneQ/OnSurvey/domain/survey/service/query/SurveyQueryService.java +++ b/src/main/java/OneQ/OnSurvey/domain/survey/service/query/SurveyQueryService.java @@ -17,6 +17,7 @@ import OneQ.OnSurvey.domain.survey.model.Residence; import OneQ.OnSurvey.domain.survey.model.SurveyStatus; import OneQ.OnSurvey.domain.survey.model.dto.OngoingSurveyStats; +import OneQ.OnSurvey.domain.survey.model.dto.OpenSurveyStats; import OneQ.OnSurvey.domain.survey.model.dto.ScreeningIntroData; import OneQ.OnSurvey.domain.survey.model.dto.ScreeningViewData; import OneQ.OnSurvey.domain.survey.model.dto.SurveyDetailData; @@ -531,4 +532,9 @@ public List getSectionDtoListBySurveyId(Long surveyId) { public List getOngoingSurveyStats() { return surveyRepository.findOngoingSurveys(); } + + @Override + public OpenSurveyStats getOpenSurveyStats() { + return surveyRepository.findOpenSurveyStats(); + } }