Skip to content
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

[FEAT] 마이페이지 즐겨찾기 조회 API 구현 #79

Merged
merged 9 commits into from
Mar 19, 2024
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package org.sopt.lequuServer.domain.book.repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import org.sopt.lequuServer.domain.book.model.Book;
import org.sopt.lequuServer.global.exception.enums.ErrorType;
import org.sopt.lequuServer.global.exception.model.CustomException;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import org.springframework.data.repository.query.Param;

public interface BookRepository extends JpaRepository<Book, Long> {

Expand All @@ -21,6 +21,9 @@ default Book findByIdOrThrow(Long id) {
() -> new CustomException(ErrorType.NOT_FOUND_BOOK_ERROR));
}

@Query("select b from Book b where b.member.id = :memberId")
List<Book> findByMemberId(@Param("memberId") Long id);

Optional<Book> findByUuid(String uuid);

default Book findByUuidOrThrow(String uuid) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,23 @@
import org.sopt.lequuServer.domain.book.model.Book;
import org.sopt.lequuServer.domain.favorite.model.Favorite;
import org.sopt.lequuServer.domain.member.model.Member;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface FavoriteRepository extends JpaRepository<Favorite, Long> {
List<Favorite> findByMemberOrderByCreatedAtDesc(Member member);

Optional<Favorite> findByMemberAndBook(Member member, Book book);

List<Favorite> findByMember(Member member);

@EntityGraph(attributePaths = {"book"})
@Query("select f from Favorite f where f.member.id = :memberId")
List<Favorite> findByMemberId(@Param("memberId") Long memberId);
}

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.springframework.web.bind.annotation.RequestHeader;

import java.security.Principal;
import java.util.List;

@Tag(name = "Member", description = "마이페이지 & 로그인 관련 API")
public interface MemberApi {
Expand Down Expand Up @@ -77,18 +78,18 @@ public ResponseEntity<ApiResponse<?>> kakaoAccessToken(
@SecurityRequirement(name = "JWT Authorization")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "마이페이지의 유저 닉네임과 내 레큐북 조회에 성공했습니다.",
description = "마이페이지의 내 레큐북 조회에 성공했습니다.",
content = @Content(schema = @Schema(implementation = MypageBookResponseDto.class))
)
@Operation(summary = "마이페이지 레큐북 조회")
public ResponseEntity<ApiResponse<MypageBookResponseDto>> getMypageBook(Principal principal);
public ResponseEntity<ApiResponse<List<MypageBookResponseDto>>> getMypageBook(Principal principal);

@SecurityRequirement(name = "JWT Authorization")
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "마이페이지의 유저 닉네임과 내 레큐노트 조회에 성공했습니다.",
description = "마이페이지의 내 레큐노트 조회에 성공했습니다.",
content = @Content(schema = @Schema(implementation = MypageNoteResponseDto.class))
)
@Operation(summary = "마이페이지 레큐노트 조회")
public ResponseEntity<ApiResponse<MypageNoteResponseDto>> getMypageNote(Principal principal);
}
public ResponseEntity<ApiResponse<List<MypageNoteResponseDto>>> getMypageNote(Principal principal);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.sopt.lequuServer.domain.favorite.dto.response.FavoriteBookResponseDto;
import org.sopt.lequuServer.domain.member.dto.request.MemberNicknameRequestDto;
import org.sopt.lequuServer.domain.member.dto.request.SocialLoginRequestDto;
import org.sopt.lequuServer.domain.member.dto.response.MemberLoginResponseDto;
import org.sopt.lequuServer.domain.member.dto.response.MemberNicknameResponseDto;
import org.sopt.lequuServer.domain.member.dto.response.MypageBookResponseDto;
import org.sopt.lequuServer.domain.member.dto.response.MypageNoteResponseDto;
import org.sopt.lequuServer.domain.member.dto.response.*;
import org.sopt.lequuServer.domain.member.service.MemberService;
import org.sopt.lequuServer.global.auth.fegin.kakao.KakaoLoginService;
import org.sopt.lequuServer.global.auth.jwt.JwtProvider;
Expand All @@ -18,6 +16,7 @@
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.List;

import static org.sopt.lequuServer.global.exception.enums.SuccessType.*;

Expand Down Expand Up @@ -64,12 +63,22 @@ public ResponseEntity<ApiResponse<MemberNicknameResponseDto>> setMemberNickname(
}

@GetMapping("/mypage/book")
public ResponseEntity<ApiResponse<MypageBookResponseDto>> getMypageBook(Principal principal) {
public ResponseEntity<ApiResponse<List<MypageBookResponseDto>>> getMypageBook(Principal principal) {
return ResponseEntity.ok(ApiResponse.success(GET_MYPAGE_BOOK_SUCCESS, memberService.getMypageBook(JwtProvider.getUserFromPrincial(principal))));
}

@GetMapping("/mypage/note")
public ResponseEntity<ApiResponse<MypageNoteResponseDto>> getMypageNote(Principal principal) {
public ResponseEntity<ApiResponse<List<MypageNoteResponseDto>>> getMypageNote(Principal principal) {
return ResponseEntity.ok(ApiResponse.success(GET_MYPAGE_NOTE_SUCCESS, memberService.getMypageNote(JwtProvider.getUserFromPrincial(principal))));
}

@GetMapping("/mypage/favorite")
public ResponseEntity<ApiResponse<List<FavoriteBookResponseDto>>> getMypageFavorite(Principal principal) {
return ResponseEntity.ok(ApiResponse.success(GET_MYPAGE_FAVORITE_SUCCESS, memberService.getMypageFavorite(JwtProvider.getUserFromPrincial(principal))));
}

@GetMapping("/mypage")
public ResponseEntity<ApiResponse<MypageResponseDto>> getMypage(Principal principal) {
return ResponseEntity.ok(ApiResponse.success(GET_MYPAGE_SUCCESS, memberService.getMypage(JwtProvider.getUserFromPrincial(principal))));
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] DTO 단에서 트랜잭션(혹은 Database 서버와의 통신)이 발생하는 것이 좋을지 한번 고민해보는 것도 좋을 것 같습니다~
(3tier architecture와 계층 분리 측면에서 생각해보면 좋을 것 같아요~ 고민 결과 공유해주시면 감사하겠습니다 😊)

Original file line number Diff line number Diff line change
@@ -1,26 +1,50 @@
package org.sopt.lequuServer.domain.member.dto.response;

import static java.util.Comparator.comparing;

import io.swagger.v3.oas.annotations.media.Schema;
import java.time.format.DateTimeFormatter;
import java.util.List;
import org.sopt.lequuServer.domain.book.model.Book;

import java.util.List;
public record MypageBookResponseDto(

import static java.util.Comparator.comparing;
@Schema(description = "레큐북 고유 id", example = "1")
Long bookId,

public record MypageBookResponseDto(
@Schema(description = "레큐북 UUID", example = "ee4f66f9-9cf4-4b28-90f4-f71d0ecba021")
String bookUuid,

@Schema(description = "레큐북 즐겨찾기 등록 여부", example = "true")
Boolean isFavorite,

@Schema(description = "최애 이름", example = "LeoJ")
String favoriteName,

@Schema(description = "유저 닉네임", example = "레큐")
String memberNickname,
@Schema(description = "레큐북 제목", example = "1번째 레큐북")
String title,

List<MypageBooksResponseDto> bookList
@Schema(description = "레큐북 생성 일시", example = "2024.01.11")
String bookDate,

@Schema(description = "레큐노트 개수", example = "1974")
int noteNum
) {
public static MypageBookResponseDto of(String nickName, List<Book> books) {
public static List<MypageBookResponseDto> of(List<Book> books, List<Book> favoriteBooks) {

List<MypageBooksResponseDto> bookList = books.stream()
return books.stream()
.sorted(comparing(Book::getCreatedAt).reversed())
.map(MypageBooksResponseDto::of)
.map(book ->
new MypageBookResponseDto(
book.getId(),
book.getUuid(),
favoriteBooks.contains(book),
book.getFavoriteName(),
book.getTitle(),
book.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy.MM.dd")),
book.getNotes().size()
)
)
.toList();

return new MypageBookResponseDto(nickName, bookList);
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,54 @@
import io.swagger.v3.oas.annotations.media.Schema;
import org.sopt.lequuServer.domain.note.model.Note;

import java.time.format.DateTimeFormatter;
import java.util.List;

import static java.util.Comparator.comparing;

public record MypageNoteResponseDto(

@Schema(description = "유저 닉네임", example = "레큐")
String memberNickname,
@Schema(description = "레큐북 UUID", example = "ee4f66f9-9cf4-4b28-90f4-f71d0ecba021")
String bookUuid,

List<MypageNotesResponseDto> noteList
@Schema(description = "최애 이름", example = "LeoJ")
String favoriteName,

@Schema(description = "레큐북 제목", example = "1번째 레큐북")
String title,

@Schema(description = "레큐노트 고유 id", example = "1")
Long noteId,

@Schema(description = "레큐노트 내용", example = "레큐노트 내용입니다.")
String content,

@Schema(description = "레큐노트 생성 일시", example = "2024.01.11")
String noteDate,

@Schema(description = "레큐노트 텍스트 컬러 번호", example = "#191919")
String noteTextColor,

@Schema(description = "레큐노트 배경 (#929DD9 or 이미지 URL(*.jpg))", example = "https://dzfv99wxq6tx0.cloudfront.net/notes/background_image/676c2ca3-f868-423f-8000-a0bcb67dc797.jpg")
String noteBackground
) {
public static MypageNoteResponseDto of(String nickName, List<Note> notes) {
public static List<MypageNoteResponseDto> of(List<Note> notes) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd");

List<MypageNotesResponseDto> noteList = notes.stream()
List<MypageNoteResponseDto> noteList = notes.stream()
.sorted(comparing(Note::getCreatedAt).reversed())
.map(MypageNotesResponseDto::of)
.map(note -> new MypageNoteResponseDto(
note.getBook().getUuid(),
note.getBook().getFavoriteName(),
note.getBook().getTitle(),
note.getId(),
note.getContent(),
note.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy.MM.dd")),
note.getTextColor(),
note.getBackground()
))
.toList();

return new MypageNoteResponseDto(nickName, noteList);
return noteList;
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.sopt.lequuServer.domain.member.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;

public record MypageResponseDto(

@Schema(description = "유저 닉네임", example = "레큐")
String memberNickname
) {
public static MypageResponseDto of(String nickName) {
return new MypageResponseDto(nickName);
}
}
Loading
Loading