-
Notifications
You must be signed in to change notification settings - Fork 0
UMC 9주차 과제 #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UMC 9주차 과제 #8
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| package com.example.UMC.domain.mission.converter; | ||
|
|
||
| import com.example.UMC.domain.mission.dto.response.StoreMissionResponse; | ||
| import com.example.UMC.domain.mission.dto.response.UserMissionInProgressResponse; | ||
| import com.example.UMC.domain.mission.entity.Mission; | ||
| import com.example.UMC.domain.mission.entity.UserMission; | ||
| import org.springframework.stereotype.Component; | ||
| import org.springframework.data.domain.Page; | ||
|
|
||
| import java.util.List; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| @Component | ||
| public class MissionConverter { | ||
|
|
||
| public List<StoreMissionResponse> toStoreMissionList(Page<Mission> missions) { | ||
| return missions.getContent().stream() | ||
| .map(m -> StoreMissionResponse.builder() | ||
| .missionId(m.getId()) | ||
| .title(m.getTitle()) | ||
| .minSpend(m.getMinSpend()) | ||
| .point(m.getPoint()) | ||
| .build()) | ||
| .collect(Collectors.toList()); | ||
| } | ||
|
|
||
| public List<UserMissionInProgressResponse> toUserMissionList(Page<UserMission> missions) { | ||
| return missions.getContent().stream() | ||
| .map(um -> UserMissionInProgressResponse.builder() | ||
| .userMissionId(um.getId()) | ||
| .missionTitle(um.getMission().getTitle()) | ||
| .status(um.getStatus()) | ||
| .build()) | ||
| .collect(Collectors.toList()); | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package com.example.UMC.domain.mission.dto.response; | ||
|
|
||
| import lombok.Builder; | ||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| @Builder | ||
| public class StoreMissionResponse { | ||
| private Long missionId; | ||
| private String title; | ||
| private Integer minSpend; | ||
| private Integer point; | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package com.example.UMC.domain.mission.dto.response; | ||
|
|
||
| import com.example.UMC.domain.enums.entity.MissionStatus; | ||
| import lombok.Builder; | ||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| @Builder | ||
| public class UserMissionInProgressResponse { | ||
| private Long userMissionId; | ||
| private String missionTitle; | ||
| private MissionStatus status; | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,10 @@ | ||
| package com.example.UMC.domain.mission.service; | ||
|
|
||
| import com.example.UMC.domain.enums.entity.MissionStatus; | ||
| import com.example.UMC.domain.mission.converter.MissionConverter; | ||
| import com.example.UMC.domain.mission.dto.response.MissionChallengeResponse; | ||
| import com.example.UMC.domain.mission.dto.response.StoreMissionResponse; | ||
| import com.example.UMC.domain.mission.dto.response.UserMissionInProgressResponse; | ||
| import com.example.UMC.domain.mission.entity.Mission; | ||
| import com.example.UMC.domain.mission.entity.UserMission; | ||
| import com.example.UMC.domain.mission.exception.MissionException; | ||
|
|
@@ -13,17 +16,21 @@ | |
| import com.example.UMC.domain.user.exception.code.UserErrorCode; | ||
| import com.example.UMC.domain.user.repository.UserRepository; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.data.domain.PageRequest; | ||
| import org.springframework.data.domain.Pageable; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| import java.time.LocalDateTime; | ||
| import java.util.List; | ||
|
|
||
| @Service | ||
| @RequiredArgsConstructor | ||
| public class MissionService { | ||
| private final MissionRepository missionRepository; | ||
| private final UserRepository userRepository; | ||
| private final UserMissionRepository userMissionRepository; | ||
| private final MissionConverter converter; | ||
|
|
||
| /** | ||
| * 미션 도전하기 API | ||
|
|
@@ -72,4 +79,16 @@ public MissionChallengeResponse challengeMission(Long userId, Long missionId) { | |
| .status(saved.getStatus()) | ||
| .build(); | ||
| } | ||
|
|
||
| public List<StoreMissionResponse> getStoreMissions(Long storeId, int pageIndex) { | ||
| Pageable pageable = PageRequest.of(pageIndex, 10); | ||
| return converter.toStoreMissionList(missionRepository.findByStoreId(storeId, pageable)); | ||
| } | ||
|
|
||
| public List<UserMissionInProgressResponse> getUserInProgress(Long userId, int pageIndex) { | ||
| Pageable pageable = PageRequest.of(pageIndex, 10); | ||
| return converter.toUserMissionList( | ||
| userMissionRepository.findByUserIdAndStatus(userId, MissionStatus.PROCESS, pageable) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. repository에서 조회하는 부분은 따로 빼서 가독성을 높여줍시다 |
||
| ); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,21 +1,30 @@ | ||
| package com.example.UMC.domain.review.controller; | ||
|
|
||
| import com.example.UMC.domain.review.dto.request.ReviewCreateRequest; | ||
| import com.example.UMC.domain.review.dto.response.MyReviewResponse; | ||
| import com.example.UMC.domain.review.dto.response.ReviewResponse; | ||
| import com.example.UMC.domain.review.entity.Review; | ||
| import com.example.UMC.domain.review.repository.ReviewQueryRepository; | ||
| import com.example.UMC.domain.review.service.ReviewService; | ||
| import com.example.UMC.global.annotation.ValidPage; | ||
| import com.example.UMC.global.apiPayload.ApiResponse; | ||
| import com.example.UMC.global.apiPayload.code.GeneralSucessCode; | ||
| import io.swagger.v3.oas.annotations.Operation; | ||
| import jakarta.validation.Valid; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.data.domain.Page; | ||
| import org.springframework.data.domain.PageRequest; | ||
| import org.springframework.data.domain.Pageable; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.validation.annotation.Validated; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @RestController | ||
| @RequiredArgsConstructor | ||
| @RequestMapping("/api/stores") | ||
| @RequestMapping("/api/reviews") | ||
| @Validated | ||
| public class ReviewController { | ||
|
|
||
| private final ReviewQueryRepository reviewQueryRepository; | ||
|
|
@@ -25,7 +34,7 @@ public class ReviewController { | |
| * [POST] /api/stores/{storeId}/reviews | ||
| * 가게에 리뷰 작성 API | ||
| */ | ||
| @PostMapping("/{storeId}/reviews") | ||
| @PostMapping("/stores/{storeId}") | ||
| public ResponseEntity<ReviewResponse> createReview( | ||
| @RequestHeader("X-USER-ID") Long userId, | ||
| @PathVariable Long storeId, | ||
|
|
@@ -40,7 +49,7 @@ public ResponseEntity<ReviewResponse> createReview( | |
| * 현재 이코드는 무한순회가 도는중 유저 - 리뷰 가 양방향 매핑이라 그래서 entity구조 그대로 하고 무한순회 안돌게 | ||
| * DTO사용이 필요해 보임. | ||
| */ | ||
| @GetMapping | ||
| @GetMapping("/stores/test") | ||
| public Page<Review> getReviews( | ||
| @RequestParam(required = false) Long storeId, | ||
| @RequestParam(required = false) String storeName, | ||
|
|
@@ -53,5 +62,17 @@ public Page<Review> getReviews( | |
| Pageable pageable = PageRequest.of(page, size); | ||
| return reviewQueryRepository.findReviews(storeId, storeName, regionId, star, pageable); | ||
| } | ||
|
|
||
| @GetMapping("/me") | ||
| @Operation(summary = "내가 작성한 리뷰 목록 조회") | ||
| public ApiResponse<List<MyReviewResponse>> getMyReviews( | ||
| @RequestParam Long userId, | ||
| @RequestParam(defaultValue = "1") @ValidPage Integer page | ||
| ) { | ||
| int pageIndex = page - 1; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이런 로직은 서비스에서... |
||
| List<MyReviewResponse> result = reviewService.getMyReviews(userId, pageIndex); | ||
|
|
||
| return ApiResponse.onSucess(GeneralSucessCode.OK, result); | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package com.example.UMC.domain.review.converter; | ||
|
|
||
| import com.example.UMC.domain.review.dto.response.MyReviewResponse; | ||
| import com.example.UMC.domain.review.entity.Review; | ||
| import org.springframework.data.domain.Page; | ||
| import org.springframework.stereotype.Component; | ||
|
|
||
| import java.util.List; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| @Component | ||
| public class ReviewConverter { | ||
|
|
||
| public List<MyReviewResponse> toMyReviews(Page<Review> reviewPage) { | ||
|
|
||
| return reviewPage.getContent() | ||
| .stream() | ||
| .map(r -> MyReviewResponse.builder() | ||
| .reviewId(r.getId()) | ||
| .rating(r.getRating()) | ||
| .content(r.getContent()) | ||
| .storeName(r.getStore().getName()) | ||
| .createdAt(r.getCreatedAt()) | ||
| .build()) | ||
| .collect(Collectors.toList()); | ||
| } | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.example.UMC.domain.review.dto.response; | ||
|
|
||
| import lombok.Builder; | ||
| import lombok.Getter; | ||
|
|
||
| import java.time.LocalDateTime; | ||
|
|
||
| @Getter | ||
| @Builder | ||
| public class MyReviewResponse { | ||
| private Long reviewId; | ||
| private Integer rating; | ||
| private String content; | ||
| private String storeName; | ||
| private LocalDateTime createdAt; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| package com.example.UMC.domain.review.service; | ||
|
|
||
| import com.example.UMC.domain.review.converter.ReviewConverter; | ||
| import com.example.UMC.domain.review.dto.request.ReviewCreateRequest; | ||
| import com.example.UMC.domain.review.dto.response.MyReviewResponse; | ||
| import com.example.UMC.domain.review.dto.response.ReviewResponse; | ||
| import com.example.UMC.domain.review.entity.Review; | ||
| import com.example.UMC.domain.review.repository.ReviewRepository; | ||
|
|
@@ -14,14 +16,18 @@ | |
| import com.example.UMC.domain.user.repository.UserRepository; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.data.domain.*; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @Service | ||
| @RequiredArgsConstructor | ||
| public class ReviewService { | ||
| private final ReviewRepository reviewRepository; | ||
| private final UserRepository userRepository; | ||
| private final StoreRepository storeRepository; | ||
| private final ReviewConverter converter; | ||
|
|
||
| @Transactional | ||
| public ReviewResponse createReview(Long userId, Long storeId, ReviewCreateRequest request) { | ||
|
|
@@ -54,4 +60,12 @@ public ReviewResponse createReview(Long userId, Long storeId, ReviewCreateReques | |
| saved.getContent() | ||
| ); | ||
| } | ||
|
|
||
| public List<MyReviewResponse> getMyReviews(Long userId, int pageIndex) { | ||
|
|
||
| Pageable pageable = PageRequest.of(pageIndex, 10, Sort.by("createdAt").descending()); | ||
| Page<?> result = reviewRepository.findByUserId(userId, pageable); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 타입에 맞는 제네릭 타입을 쓰는게 좋을 듯 합니다. |
||
|
|
||
| return converter.toMyReviews((Page) result); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package com.example.UMC.global.annotation; | ||
|
|
||
| import jakarta.validation.ConstraintValidator; | ||
| import jakarta.validation.ConstraintValidatorContext; | ||
|
|
||
| public class PageValidator implements ConstraintValidator<ValidPage, Integer> { | ||
|
|
||
| @Override | ||
| public boolean isValid(Integer value, ConstraintValidatorContext context) { | ||
| if (value == null) return false; // 반드시 포함하도록 | ||
| return value > 0; // 1 이상만 OK | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
단순히 값을 변환하는 컨버터에는 빈으로 등록하지 않고 static 메서드로 선언해도 충분해요!