diff --git a/src/main/java/javalab/umc7th_mission/domain/membermission/controller/MemberMissionController.java b/src/main/java/javalab/umc7th_mission/domain/membermission/controller/MemberMissionController.java new file mode 100644 index 0000000..2b053ec --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/domain/membermission/controller/MemberMissionController.java @@ -0,0 +1,44 @@ +package javalab.umc7th_mission.domain.membermission.controller; + +import javalab.umc7th_mission.config.annotation.CheckPage; +import javalab.umc7th_mission.config.apipayload.ApiResponse; +import javalab.umc7th_mission.domain.membermission.dto.MemberMissionResponseDTO; +import javalab.umc7th_mission.domain.membermission.service.MemberMissionService; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/missions") +public class MemberMissionController { + + private final MemberMissionService memberMissionService; + private static final Integer PAGE_SIZE = 10; + + @GetMapping("/member/{memberId}/ongoing") + public ApiResponse> getOngoingMissionsByMember( + @PathVariable Long memberId, + @RequestParam @CheckPage Integer page + ) { + Pageable pageable = PageRequest.of(page, PAGE_SIZE); + return ApiResponse.onSuccess( + memberMissionService.getOngoingMissionsByMember(memberId, pageable)); + } + + @PatchMapping("/member/{memberId}/complete/{missionId}") + public ResponseEntity completeMission( + @PathVariable Long memberId, + @PathVariable Long missionId + ) { + memberMissionService.completeMission(memberId, missionId); + return ResponseEntity.ok("Mission marked as complete"); + } +} diff --git a/src/main/java/javalab/umc7th_mission/domain/membermission/dto/MemberMissionResponseDTO.java b/src/main/java/javalab/umc7th_mission/domain/membermission/dto/MemberMissionResponseDTO.java new file mode 100644 index 0000000..2fbaf68 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/domain/membermission/dto/MemberMissionResponseDTO.java @@ -0,0 +1,11 @@ +package javalab.umc7th_mission.domain.membermission.dto; + +public record MemberMissionResponseDTO( + Long missionId, + String missionSpec, + Integer reward, + String status, + String storeName +) { + +} diff --git a/src/main/java/javalab/umc7th_mission/domain/membermission/repository/MemberMissionRepository.java b/src/main/java/javalab/umc7th_mission/domain/membermission/repository/MemberMissionRepository.java new file mode 100644 index 0000000..86d6d4e --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/domain/membermission/repository/MemberMissionRepository.java @@ -0,0 +1,14 @@ +package javalab.umc7th_mission.domain.membermission.repository; + +import java.util.Optional; +import javalab.umc7th_mission.domain.membermission.MemberMission; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MemberMissionRepository extends JpaRepository { + + Page findByMemberIdAndStatus(Long memberId, String status, Pageable pageable); + + Optional findByMemberIdAndMissionId(Long memberId, Long missionId); +} diff --git a/src/main/java/javalab/umc7th_mission/domain/membermission/service/MemberMissionService.java b/src/main/java/javalab/umc7th_mission/domain/membermission/service/MemberMissionService.java new file mode 100644 index 0000000..f54b5f1 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/domain/membermission/service/MemberMissionService.java @@ -0,0 +1,46 @@ +package javalab.umc7th_mission.domain.membermission.service; + +import javalab.umc7th_mission.config.apipayload.code.status.ErrorStatus; +import javalab.umc7th_mission.config.apipayload.exception.GeneralException; +import javalab.umc7th_mission.domain.membermission.MemberMission; +import javalab.umc7th_mission.domain.membermission.dto.MemberMissionResponseDTO; +import javalab.umc7th_mission.domain.membermission.repository.MemberMissionRepository; +import javalab.umc7th_mission.domain.mission.MissionStatus; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class MemberMissionService { + + private final MemberMissionRepository memberMissionRepository; + + public Page getOngoingMissionsByMember(Long memberId, + Pageable pageable) { + String status = MissionStatus.CHALLENGING.name(); + + return memberMissionRepository.findByMemberIdAndStatus(memberId, status, pageable) + .map(memberMission -> new MemberMissionResponseDTO( + memberMission.getMission().getId(), + memberMission.getMission().getMissionSpec(), + memberMission.getMission().getReward(), + memberMission.getStatus().name(), + memberMission.getMission().getStore().getName() + )); + } + + @Transactional + public void completeMission(Long memberId, Long missionId) { + MemberMission memberMission = memberMissionRepository.findByMemberIdAndMissionId(memberId, + missionId) + .orElseThrow(() -> new GeneralException(ErrorStatus._BAD_REQUEST)); + if (!memberMission.getStatus().equals(MissionStatus.CHALLENGING)) { + throw new GeneralException(ErrorStatus._BAD_REQUEST); + } + memberMission.complete(); + } +} diff --git a/src/main/java/javalab/umc7th_mission/domain/mission/controller/MissionController.java b/src/main/java/javalab/umc7th_mission/domain/mission/controller/MissionController.java new file mode 100644 index 0000000..a2964e7 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/domain/mission/controller/MissionController.java @@ -0,0 +1,34 @@ +package javalab.umc7th_mission.domain.mission.controller; + +import javalab.umc7th_mission.config.annotation.CheckPage; +import javalab.umc7th_mission.config.apipayload.ApiResponse; +import javalab.umc7th_mission.domain.mission.dto.MissionResponseDto; +import javalab.umc7th_mission.domain.mission.service.MissionService; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/missions") +public class MissionController { + + private static final Integer PAGE_SIZE = 10; + private final MissionService service; + + @GetMapping("/store/{storeId}") + public ApiResponse> getMissionsByStore( + @PathVariable Long storeId, + @RequestParam @CheckPage Integer page + ) { + Pageable pageable = PageRequest.of(page, PAGE_SIZE); + Page missions = service.getMissionsByStore(storeId, pageable); + return ApiResponse.onSuccess(missions); + } +} diff --git a/src/main/java/javalab/umc7th_mission/domain/mission/dto/MissionResponseDto.java b/src/main/java/javalab/umc7th_mission/domain/mission/dto/MissionResponseDto.java new file mode 100644 index 0000000..ea61e71 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/domain/mission/dto/MissionResponseDto.java @@ -0,0 +1,11 @@ +package javalab.umc7th_mission.domain.mission.dto; + +public record MissionResponseDto( + Long missionId, + Integer reward, + String missionSpec, + String storeName +) { + +} + diff --git a/src/main/java/javalab/umc7th_mission/domain/mission/repository/MissionRepository.java b/src/main/java/javalab/umc7th_mission/domain/mission/repository/MissionRepository.java new file mode 100644 index 0000000..6c7d301 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/domain/mission/repository/MissionRepository.java @@ -0,0 +1,12 @@ +package javalab.umc7th_mission.domain.mission.repository; + +import javalab.umc7th_mission.domain.mission.Mission; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MissionRepository extends JpaRepository { + + Page findByStoreId(Long storeId, Pageable pageable); + +} diff --git a/src/main/java/javalab/umc7th_mission/domain/mission/service/MissionService.java b/src/main/java/javalab/umc7th_mission/domain/mission/service/MissionService.java new file mode 100644 index 0000000..239a963 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/domain/mission/service/MissionService.java @@ -0,0 +1,27 @@ +package javalab.umc7th_mission.domain.mission.service; + +import javalab.umc7th_mission.domain.mission.dto.MissionResponseDto; +import javalab.umc7th_mission.domain.mission.repository.MissionRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class MissionService { + + private final MissionRepository repository; + + public Page getMissionsByStore(Long storeId, Pageable pageable) { + return repository.findByStoreId(storeId, pageable) + .map(mission -> new MissionResponseDto( + mission.getId(), + mission.getReward(), + mission.getMissionSpec(), + mission.getStore().getName() + )); + } +} diff --git a/src/main/java/javalab/umc7th_mission/domain/review/controller/ReviewController.java b/src/main/java/javalab/umc7th_mission/domain/review/controller/ReviewController.java new file mode 100644 index 0000000..1dbdee0 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/domain/review/controller/ReviewController.java @@ -0,0 +1,31 @@ +package javalab.umc7th_mission.domain.review.controller; + +import javalab.umc7th_mission.config.apipayload.ApiResponse; +import javalab.umc7th_mission.domain.review.dto.ReviewResponse.ReviewsDTO; +import javalab.umc7th_mission.domain.review.service.ReviewService; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +public class ReviewController { + + private final ReviewService reviewService; + + private static final Integer PAGE_SIZE = 10; + + @GetMapping("/member") + public ApiResponse getReviewsByMember( + Long memberId, // 로그인 되어있다고 가정 + @RequestParam(defaultValue = "0") int page + ) { + memberId = 0L; // 추후 argumentResolver 이용 + Pageable pageable = PageRequest.of(page, PAGE_SIZE); + ReviewsDTO result = reviewService.getReviewsByMember(memberId, pageable); + return ApiResponse.onSuccess(result); + } +} diff --git a/src/main/java/javalab/umc7th_mission/domain/review/dto/ReviewRequest.java b/src/main/java/javalab/umc7th_mission/domain/review/dto/ReviewRequest.java new file mode 100644 index 0000000..b05ba74 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/domain/review/dto/ReviewRequest.java @@ -0,0 +1,5 @@ +package javalab.umc7th_mission.domain.review.dto; + +public class ReviewRequest { + +} diff --git a/src/main/java/javalab/umc7th_mission/domain/review/dto/ReviewResponse.java b/src/main/java/javalab/umc7th_mission/domain/review/dto/ReviewResponse.java new file mode 100644 index 0000000..3b161e4 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/domain/review/dto/ReviewResponse.java @@ -0,0 +1,25 @@ +package javalab.umc7th_mission.domain.review.dto; + +import java.time.LocalDate; +import java.util.List; + +public final class ReviewResponse { + + private ReviewResponse() { + } + + public record ReviewsDTO( + List reviews + ) { + + } + + public record ReviewDTO( + String nickname, + Double score, + String body, + LocalDate createdAt + ) { + + } +} diff --git a/src/main/java/javalab/umc7th_mission/domain/review/repository/ReviewRepository.java b/src/main/java/javalab/umc7th_mission/domain/review/repository/ReviewRepository.java new file mode 100644 index 0000000..b477460 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/domain/review/repository/ReviewRepository.java @@ -0,0 +1,12 @@ +package javalab.umc7th_mission.domain.review.repository; + +import javalab.umc7th_mission.domain.review.Review; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ReviewRepository extends JpaRepository { + + Page findByMemberId(Long memberId, Pageable pageable); + +} diff --git a/src/main/java/javalab/umc7th_mission/domain/review/service/ReviewService.java b/src/main/java/javalab/umc7th_mission/domain/review/service/ReviewService.java new file mode 100644 index 0000000..fd53143 --- /dev/null +++ b/src/main/java/javalab/umc7th_mission/domain/review/service/ReviewService.java @@ -0,0 +1,38 @@ +package javalab.umc7th_mission.domain.review.service; + +import java.util.ArrayList; +import java.util.List; +import javalab.umc7th_mission.domain.review.Review; +import javalab.umc7th_mission.domain.review.dto.ReviewResponse; +import javalab.umc7th_mission.domain.review.dto.ReviewResponse.ReviewDTO; +import javalab.umc7th_mission.domain.review.repository.ReviewRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class ReviewService { + + private final ReviewRepository reviewRepository; + + public ReviewResponse.ReviewsDTO getReviewsByMember(Long memberId, Pageable pageable) { + Page reviews = reviewRepository.findByMemberId(memberId, pageable); + + List reviewDTOs = new ArrayList<>(); + for (Review review : reviews) { + ReviewDTO reviewDTO = new ReviewDTO( + review.getMember().getName(), + review.getScore(), + review.getBody(), + review.getCreatedAt().toLocalDate() + ); + reviewDTOs.add(reviewDTO); + } + + return new ReviewResponse.ReviewsDTO(reviewDTOs); + + } +} +