diff --git a/src/main/java/com/example/cp_main_be/domain/home/HomeController.java b/src/main/java/com/example/cp_main_be/domain/home/HomeController.java index 7ee9673f..bb4bae3c 100644 --- a/src/main/java/com/example/cp_main_be/domain/home/HomeController.java +++ b/src/main/java/com/example/cp_main_be/domain/home/HomeController.java @@ -27,4 +27,10 @@ public ResponseEntity> getHomeScreenData( HomeResponseDto response = homeService.getHomeScreenData(user.getId()); return ResponseEntity.ok(ApiResponse.success(response)); } + + @GetMapping("/panel") + public ApiResponse getPannelData(@AuthenticationPrincipal User user) { + PannelResponseDTO responseDTO = homeService.getPannelData(user); + return ApiResponse.success(responseDTO); + } } diff --git a/src/main/java/com/example/cp_main_be/domain/home/PannelResponseDTO.java b/src/main/java/com/example/cp_main_be/domain/home/PannelResponseDTO.java new file mode 100644 index 00000000..8e7a48ab --- /dev/null +++ b/src/main/java/com/example/cp_main_be/domain/home/PannelResponseDTO.java @@ -0,0 +1,16 @@ +package com.example.cp_main_be.domain.home; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class PannelResponseDTO { + private boolean isDairyCompleted; + private boolean isCheckingCompleted; + private boolean isQuizCompleted; +} diff --git a/src/main/java/com/example/cp_main_be/domain/home/service/HomeService.java b/src/main/java/com/example/cp_main_be/domain/home/service/HomeService.java index 31e76f2f..b189a67c 100644 --- a/src/main/java/com/example/cp_main_be/domain/home/service/HomeService.java +++ b/src/main/java/com/example/cp_main_be/domain/home/service/HomeService.java @@ -2,11 +2,17 @@ import com.example.cp_main_be.domain.garden.garden.domain.repository.GardenRepository; import com.example.cp_main_be.domain.home.HomeResponseDto; +import com.example.cp_main_be.domain.home.PannelResponseDTO; import com.example.cp_main_be.domain.member.notification.domain.repository.NotificationRepository; import com.example.cp_main_be.domain.member.user.domain.User; import com.example.cp_main_be.domain.member.user.domain.repository.UserRepository; +import com.example.cp_main_be.domain.mission.diary.domain.Diary; +import com.example.cp_main_be.domain.mission.diary.domain.repository.DiaryRepository; +import com.example.cp_main_be.domain.mission.diary.service.DiaryService; import com.example.cp_main_be.domain.mission.user_daily_mission.domain.UserDailyMission; import com.example.cp_main_be.domain.mission.user_daily_mission.domain.repository.UserDailyMissionRepository; +import com.example.cp_main_be.domain.realquiz.UserQuiz; +import com.example.cp_main_be.domain.realquiz.repository.UserQuizRepository; import com.example.cp_main_be.global.common.CustomApiException; import com.example.cp_main_be.global.common.ErrorCode; import java.time.LocalDate; @@ -30,6 +36,9 @@ public class HomeService { private final GardenRepository gardenRepository; private final UserDailyMissionRepository userDailyMissionRepository; private final NotificationRepository notificationRepository; + private final DiaryRepository diaryRepository; + private final DiaryService diaryService; + private final UserQuizRepository userQuizRepository; // GardenService에서 가져오거나, 공통 유틸리티로 분리하면 더 좋습니다. private LocalDateTime getStartOfCurrentWateringDay() { @@ -149,4 +158,27 @@ private List createWeeklyMissionStatus(Long userId) { .map(completedDates::contains) .collect(Collectors.toList()); } + + public PannelResponseDTO getPannelData(User user) { + boolean isDiaryCompleted = false; + boolean isQuizCompleted = false; + boolean isCheckingCompleted = false; + LocalDateTime startOfDay = LocalDate.now().atStartOfDay(); + LocalDateTime endOfDay = LocalDate.now().atTime(23, 59, 59); + + Diary diary = diaryService.findMyDiaries(user).get(0); + if (diary.getCreatedAt().isAfter(LocalDate.now().atStartOfDay())) { + isDiaryCompleted = true; + } + UserQuiz userQuiz = + userQuizRepository.findAllTodayUserQuizByUser(user, startOfDay, endOfDay).get(0); + if (userQuiz != null && userQuiz.getIsCompleted()) { // 오늘의 퀴즈 성공시 + isQuizCompleted = true; + } + return PannelResponseDTO.builder() + .isDairyCompleted(isDiaryCompleted) + .isQuizCompleted(isQuizCompleted) + .isCheckingCompleted(isCheckingCompleted) + .build(); + } } diff --git a/src/main/java/com/example/cp_main_be/domain/mission/quiz/enums/QuizType.java b/src/main/java/com/example/cp_main_be/domain/mission/quiz/enums/QuizType.java index acbeabcd..c5334978 100644 --- a/src/main/java/com/example/cp_main_be/domain/mission/quiz/enums/QuizType.java +++ b/src/main/java/com/example/cp_main_be/domain/mission/quiz/enums/QuizType.java @@ -2,6 +2,5 @@ public enum QuizType { OX, - MULTI_CHOICE, - CHOICE_WITH_PICTURE; + MULTI_CHOICE } diff --git a/src/main/java/com/example/cp_main_be/domain/mission/user_daily_mission/presentation/UserDailyMissionController.java b/src/main/java/com/example/cp_main_be/domain/mission/user_daily_mission/presentation/UserDailyMissionController.java index 9f3a1124..5d1fbff9 100644 --- a/src/main/java/com/example/cp_main_be/domain/mission/user_daily_mission/presentation/UserDailyMissionController.java +++ b/src/main/java/com/example/cp_main_be/domain/mission/user_daily_mission/presentation/UserDailyMissionController.java @@ -2,10 +2,6 @@ import com.example.cp_main_be.domain.member.user.domain.User; import com.example.cp_main_be.domain.mission.daily_mission_master.dto.response.DailyMissionResponseDTO; -import com.example.cp_main_be.domain.mission.quiz.dto.CompletedQuizResponseDTO; -import com.example.cp_main_be.domain.mission.quiz.dto.QuizRequestDTO; -import com.example.cp_main_be.domain.mission.quiz.dto.QuizResponseDTO; -import com.example.cp_main_be.domain.mission.quiz.enums.QuizType; import com.example.cp_main_be.domain.mission.quiz.service.QuizService; import com.example.cp_main_be.domain.mission.user_daily_mission.dto.MissionPanelResponse; import com.example.cp_main_be.domain.mission.user_daily_mission.service.UserDailyMissionService; @@ -54,23 +50,24 @@ public ResponseEntity> completeDailyMission( return ResponseEntity.ok(ApiResponse.success(null)); } - @GetMapping("/quiz/{userDailyMissionId}") - @Operation(summary = "퀴즈 문제 조회 API") - public ResponseEntity> getQuiz( - @PathVariable(name = "userDailyMissionId") Long userDailyMissionId) { - - QuizResponseDTO result = quizService.getQuiz(userDailyMissionId); - return ResponseEntity.ok(ApiResponse.success(result)); - } - - @GetMapping("/quiz/") - @Operation(summary = "퀴즈 타입에 맞는 퀴즈 문제 랜덤 조회 API") - public ResponseEntity> getQuizByQuizType( - @RequestParam QuizType quizType) { + // + // @GetMapping("/quiz/{userDailyMissionId}") + // @Operation(summary = "퀴즈 문제 조회 API") + // public ResponseEntity> getQuiz( + // @PathVariable(name = "userDailyMissionId") Long userDailyMissionId) { + // + // QuizResponseDTO result = quizService.getQuiz(userDailyMissionId); + // return ResponseEntity.ok(ApiResponse.success(result)); + // } - QuizResponseDTO result = quizService.getQuizByType(quizType); - return ResponseEntity.ok(ApiResponse.success(result)); - } + // @GetMapping("/quiz/") + // @Operation(summary = "퀴즈 타입에 맞는 퀴즈 문제 랜덤 조회 API") + // public ResponseEntity> getQuizByQuizType( + // @RequestParam QuizType quizType) { + // + // QuizResponseDTO result = quizService.getQuizByType(quizType); + // return ResponseEntity.ok(ApiResponse.success(result)); + // } // // 새로운 엔드포인트 - 완료된 퀴즈 결과 조회 // @GetMapping("/quiz/{userDailyMissionId}/result") @@ -93,12 +90,12 @@ public ResponseEntity> uploadPictureForMission( return ResponseEntity.ok(ApiResponse.success(imageUrl)); } - @PostMapping("/quiz/{userDailyMissionId}/answer") - @Operation(summary = "퀴즈 답변 제출 API") - public ResponseEntity> summitAnswerToQuiz( - @PathVariable(name = "userDailyMissionId") Long userDailyMissionId, - @RequestBody QuizRequestDTO request) { - CompletedQuizResponseDTO result = quizService.summitQuizAnswer(request, userDailyMissionId); - return ResponseEntity.ok(ApiResponse.success(result)); - } + // @PostMapping("/quiz/{userDailyMissionId}/answer") + // @Operation(summary = "퀴즈 답변 제출 API") + // public ResponseEntity> summitAnswerToQuiz( + // @PathVariable(name = "userDailyMissionId") Long userDailyMissionId, + // @RequestBody QuizRequestDTO request) { + // CompletedQuizResponseDTO result = quizService.summitQuizAnswer(request, userDailyMissionId); + // return ResponseEntity.ok(ApiResponse.success(result)); + // } } diff --git a/src/main/java/com/example/cp_main_be/domain/mission/user_daily_mission/service/UserDailyMissionService.java b/src/main/java/com/example/cp_main_be/domain/mission/user_daily_mission/service/UserDailyMissionService.java index 18c08b94..294c9284 100644 --- a/src/main/java/com/example/cp_main_be/domain/mission/user_daily_mission/service/UserDailyMissionService.java +++ b/src/main/java/com/example/cp_main_be/domain/mission/user_daily_mission/service/UserDailyMissionService.java @@ -120,6 +120,7 @@ public MissionPanelResponse getMissionPanelData(Long userId) { .isCompleted(mission.isCompleted()) .build()) .collect(Collectors.toList()); + Integer count = 0; for (MissionPanelResponse.DailyMissionStatusDto mission : missionDtos) { if (mission.isCompleted()) count++; diff --git a/src/main/java/com/example/cp_main_be/domain/realquiz/RealQuiz.java b/src/main/java/com/example/cp_main_be/domain/realquiz/RealQuiz.java index b5ab31aa..d5f96d5c 100644 --- a/src/main/java/com/example/cp_main_be/domain/realquiz/RealQuiz.java +++ b/src/main/java/com/example/cp_main_be/domain/realquiz/RealQuiz.java @@ -32,7 +32,5 @@ public class RealQuiz { @Column(name = "reward_point") private Long rewardPoints; - @Column private Boolean isCompleted; - @Column @CreationTimestamp private LocalDateTime createdAt; } diff --git a/src/main/java/com/example/cp_main_be/domain/realquiz/UserQuiz.java b/src/main/java/com/example/cp_main_be/domain/realquiz/UserQuiz.java index cf4f45a1..bee6f5ce 100644 --- a/src/main/java/com/example/cp_main_be/domain/realquiz/UserQuiz.java +++ b/src/main/java/com/example/cp_main_be/domain/realquiz/UserQuiz.java @@ -2,7 +2,9 @@ import com.example.cp_main_be.domain.member.user.domain.User; import jakarta.persistence.*; +import java.time.LocalDateTime; import lombok.*; +import org.hibernate.annotations.CreationTimestamp; @Entity @Getter @@ -22,4 +24,8 @@ public class UserQuiz { @JoinColumn(name = "real_quiz_id") @ManyToOne(fetch = FetchType.LAZY) private RealQuiz realQuiz; + + @Column @Builder.Default private Boolean isCompleted = false; + + @Column @CreationTimestamp private LocalDateTime createdAt; } diff --git a/src/main/java/com/example/cp_main_be/domain/realquiz/presentation/RealQuizController.java b/src/main/java/com/example/cp_main_be/domain/realquiz/presentation/RealQuizController.java index 76aa8da5..e8e6ec3d 100644 --- a/src/main/java/com/example/cp_main_be/domain/realquiz/presentation/RealQuizController.java +++ b/src/main/java/com/example/cp_main_be/domain/realquiz/presentation/RealQuizController.java @@ -52,8 +52,11 @@ public ApiResponse getRealQuiz( @PostMapping("/{quizId}/answer") @Operation(summary = "퀴즈 정답 제출 API") public ApiResponse getRealQuizAnswer( - @PathVariable Long quizId, @RequestBody RealQuizAnswerRequestDTO requestDTO) { - RealQuizAnswerResponseDTO responseDTO = realQuizService.getRealQuizAnswer(quizId, requestDTO); + @PathVariable Long quizId, + @RequestBody RealQuizAnswerRequestDTO requestDTO, + @AuthenticationPrincipal User user) { + RealQuizAnswerResponseDTO responseDTO = + realQuizService.getRealQuizAnswer(quizId, requestDTO, user); return ApiResponse.success(responseDTO); } } diff --git a/src/main/java/com/example/cp_main_be/domain/realquiz/repository/UserQuizRepository.java b/src/main/java/com/example/cp_main_be/domain/realquiz/repository/UserQuizRepository.java index 903cef91..381a0e18 100644 --- a/src/main/java/com/example/cp_main_be/domain/realquiz/repository/UserQuizRepository.java +++ b/src/main/java/com/example/cp_main_be/domain/realquiz/repository/UserQuizRepository.java @@ -2,9 +2,22 @@ import com.example.cp_main_be.domain.member.user.domain.User; import com.example.cp_main_be.domain.realquiz.UserQuiz; +import java.time.LocalDateTime; +import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; public interface UserQuizRepository extends JpaRepository { Optional findByUser(User user); + + @Query( + "SELECT uq FROM UserQuiz uq " + + "WHERE uq.user = :user " + + "AND uq.createdAt BETWEEN :startDate AND :endDate") + List findAllTodayUserQuizByUser( + @Param("user") User user, + @Param("startDate") LocalDateTime startDate, + @Param("endDate") LocalDateTime endDate); } diff --git a/src/main/java/com/example/cp_main_be/domain/realquiz/service/RealQuizService.java b/src/main/java/com/example/cp_main_be/domain/realquiz/service/RealQuizService.java index d697071a..19359fb2 100644 --- a/src/main/java/com/example/cp_main_be/domain/realquiz/service/RealQuizService.java +++ b/src/main/java/com/example/cp_main_be/domain/realquiz/service/RealQuizService.java @@ -16,6 +16,8 @@ import com.example.cp_main_be.domain.realquiz.repository.UserQuizRepository; import com.example.cp_main_be.global.exception.QuizNotFoundException; import com.example.cp_main_be.global.exception.UserNotFoundException; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; import java.util.Random; import lombok.RequiredArgsConstructor; @@ -36,7 +38,6 @@ public RealQuizResponseDTO createRealQuiz(RealQuizCreateRequestDTO requestDTO) { // 퀴즈 생성 RealQuiz realQuiz = RealQuiz.builder() - .isCompleted(false) .quizQuestion(requestDTO.getQuizQuestion()) .quizType(requestDTO.getQuizType()) .answerDescription(requestDTO.getAnswerDescription()) @@ -62,7 +63,6 @@ public RealQuizResponseDTO createRealQuiz(RealQuizCreateRequestDTO requestDTO) { List result = transformToRealQuizOptionResponseDTO(realQuizOptionList); return RealQuizResponseDTO.builder() - .isCompleted(realQuiz.getIsCompleted()) .quizId(realQuiz.getId()) .quizQuestion(realQuiz.getQuizQuestion()) .quizType(realQuiz.getQuizType()) @@ -83,7 +83,7 @@ public UserQuizCreateResponseDTO createUserQuiz(Long userId, Long realQuizId) { .findById(realQuizId) .orElseThrow(() -> new RuntimeException("퀴즈를 찾을 수 없습니다")); - UserQuiz userQuiz = UserQuiz.builder().realQuiz(realQuiz).user(user).build(); + UserQuiz userQuiz = UserQuiz.builder().realQuiz(realQuiz).user(user).isCompleted(false).build(); UserQuiz savedUserQuiz = userQuizRepository.save(userQuiz); return UserQuizCreateResponseDTO.builder() @@ -97,7 +97,10 @@ public UserQuizCreateResponseDTO createUserQuiz(Long userId, Long realQuizId) { public RealQuizResponseDTO getRealQuiz(User user, QuizType quizType) { - UserQuiz userQuiz = userQuizRepository.findByUser(user).orElse(null); + LocalDateTime startOfDay = LocalDate.now().atStartOfDay(); + LocalDateTime endOfDay = LocalDate.now().atTime(23, 59, 59); + UserQuiz userQuiz = + userQuizRepository.findAllTodayUserQuizByUser(user, startOfDay, endOfDay).get(0); // 퀴즈가 할당되지 않은 경우 if (userQuiz == null) { @@ -108,7 +111,7 @@ public RealQuizResponseDTO getRealQuiz(User user, QuizType quizType) { RealQuiz realQuiz = realQuizList.get(rand); // 할당한다. - userQuiz = UserQuiz.builder().realQuiz(realQuiz).user(user).build(); + userQuiz = UserQuiz.builder().realQuiz(realQuiz).user(user).isCompleted(false).build(); userQuizRepository.save(userQuiz); return transformToRealQuizResponseDTO(realQuiz); @@ -125,15 +128,17 @@ public RealQuizResponseDTO getRealQuiz(User user, QuizType quizType) { } public RealQuizAnswerResponseDTO getRealQuizAnswer( - Long quizId, RealQuizAnswerRequestDTO requestDTO) { + Long quizId, RealQuizAnswerRequestDTO requestDTO, User user) { RealQuiz realQuiz = realQuizRepostitory .findById(quizId) .orElseThrow(() -> new QuizNotFoundException("퀴즈를 찾을 수 없습니다.")); - List realQuizOptionList = realQuizOptionRepository.findAllByRealQuiz(realQuiz); - - realQuiz.setIsCompleted(true); + UserQuiz userQuiz = + userQuizRepository + .findByUser(user) + .orElseThrow(() -> new RuntimeException("할당 된 퀴즈가 없습니다.")); + userQuiz.setIsCompleted(true); return RealQuizAnswerResponseDTO.builder() .answerDescription(realQuiz.getAnswerDescription()) @@ -158,7 +163,6 @@ private RealQuizResponseDTO transformToRealQuizResponseDTO(RealQuiz realQuiz) { .quizQuestion(realQuiz.getQuizQuestion()) .answerDescription(realQuiz.getAnswerDescription()) .quizOptions(result) - .isCompleted(realQuiz.getIsCompleted()) .build(); }