diff --git a/src/main/java/com/hansung/leafly/domain/member/entity/Member.java b/src/main/java/com/hansung/leafly/domain/member/entity/Member.java index 265b37a..703a5e9 100644 --- a/src/main/java/com/hansung/leafly/domain/member/entity/Member.java +++ b/src/main/java/com/hansung/leafly/domain/member/entity/Member.java @@ -9,7 +9,9 @@ import lombok.*; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; @Entity @Getter @@ -31,6 +33,8 @@ public class Member extends BaseEntity { @Column(nullable = false, name = "nick_name") private String nickName; + private String image; + @Enumerated(EnumType.STRING) private MemberRole role; @@ -38,10 +42,10 @@ public class Member extends BaseEntity { private Onboarding onboarding; @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) - private List bookmarks = new ArrayList<>(); + private Set bookmarks = new HashSet<>(); @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) - private List libraries = new ArrayList<>(); + private Set libraries = new HashSet<>(); public static Member toEntity(String email, String encoded, String nickName){ return Member.builder() diff --git a/src/main/java/com/hansung/leafly/domain/member/repository/MemberRepository.java b/src/main/java/com/hansung/leafly/domain/member/repository/MemberRepository.java index 6ec6b82..db2a3cc 100644 --- a/src/main/java/com/hansung/leafly/domain/member/repository/MemberRepository.java +++ b/src/main/java/com/hansung/leafly/domain/member/repository/MemberRepository.java @@ -2,6 +2,7 @@ import com.hansung.leafly.domain.member.entity.Member; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import java.util.Optional; @@ -12,4 +13,12 @@ public interface MemberRepository extends JpaRepository { boolean existsByEmail(String email); Optional findByEmail(String email); + + @Query(""" + select m from Member m + left join fetch m.libraries + left join fetch m.bookmarks + where m.id = :memberId + """) + Optional findDetailById(Long memberId); } diff --git a/src/main/java/com/hansung/leafly/domain/member/service/MemberService.java b/src/main/java/com/hansung/leafly/domain/member/service/MemberService.java index 22e96b6..647d775 100644 --- a/src/main/java/com/hansung/leafly/domain/member/service/MemberService.java +++ b/src/main/java/com/hansung/leafly/domain/member/service/MemberService.java @@ -10,4 +10,6 @@ public interface MemberService { LoginRes login(LoginReq loginReq); void onboarding(Member member, OnboardingReq req); + + MemberDetailsRes details(Member member); } diff --git a/src/main/java/com/hansung/leafly/domain/member/service/MemberServiceImpl.java b/src/main/java/com/hansung/leafly/domain/member/service/MemberServiceImpl.java index 4ee417f..056730a 100644 --- a/src/main/java/com/hansung/leafly/domain/member/service/MemberServiceImpl.java +++ b/src/main/java/com/hansung/leafly/domain/member/service/MemberServiceImpl.java @@ -1,5 +1,7 @@ package com.hansung.leafly.domain.member.service; +import com.hansung.leafly.domain.bookmark.entity.Bookmark; +import com.hansung.leafly.domain.library.entity.Library; import com.hansung.leafly.domain.member.entity.Genre; import com.hansung.leafly.domain.member.entity.Member; import com.hansung.leafly.domain.member.entity.Onboarding; @@ -7,20 +9,25 @@ import com.hansung.leafly.domain.member.exception.AlreadyOnboardedException; import com.hansung.leafly.domain.member.exception.InvalidCredentialsException; import com.hansung.leafly.domain.member.exception.MemberAlreadyExistException; +import com.hansung.leafly.domain.member.exception.MemberNotFoundException; import com.hansung.leafly.domain.member.repository.GenreRepository; import com.hansung.leafly.domain.member.repository.MemberRepository; import com.hansung.leafly.domain.member.repository.OnboardingRepository; import com.hansung.leafly.domain.member.web.dto.*; +import com.hansung.leafly.domain.member.web.dto.info.BookSimple; import com.hansung.leafly.global.auth.jwt.JwtTokenProvider; import lombok.RequiredArgsConstructor; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.hansung.leafly.domain.library.entity.enums.LibraryStatus; import java.util.List; +import java.util.Set; @Service @RequiredArgsConstructor +@Transactional(readOnly = true) public class MemberServiceImpl implements MemberService { private final MemberRepository memberRepository; private final PasswordEncoder passwordEncoder; @@ -80,4 +87,51 @@ public void onboarding(Member member, OnboardingReq req) { onboardingRepository.save(onboarding); } + + @Override + public MemberDetailsRes details(Member m) { + Member member = memberRepository.findDetailById(m.getId()) + .orElseThrow(MemberNotFoundException::new); + + String nickName = member.getNickName(); + String profileImage = member.getImage(); // null 가능 + + // 서재, 북마크 가져오기 + Set libraries = member.getLibraries(); + Set bookmarks = member.getBookmarks(); + + // 서재: 완독 책 + List finishedBooks = libraries.stream() + .filter(lib -> lib.getStatus() == LibraryStatus.DONE) + .map(lib -> new BookSimple(lib.getIsbn(), lib.getCover())) + .toList(); + + int finishedCount = finishedBooks.size(); + + // 서재: 읽고 싶음 책 + List wantBooks = libraries.stream() + .filter(lib -> lib.getStatus() == LibraryStatus.WANT_TO_READ) + .map(lib -> new BookSimple(lib.getIsbn(), lib.getCover())) + .toList(); + + int wantCount = wantBooks.size(); + + // 좋아요 LIST + List likeBooks = bookmarks.stream() + .map(bm -> new BookSimple(String.valueOf(bm.getIsbn()), bm.getCover())) + .toList(); + + int likeCount = likeBooks.size(); + + return MemberDetailsRes.of( + nickName, + profileImage, + finishedCount, + finishedBooks, + wantCount, + wantBooks, + likeCount, + likeBooks + ); + } } diff --git a/src/main/java/com/hansung/leafly/domain/member/web/controller/MemberController.java b/src/main/java/com/hansung/leafly/domain/member/web/controller/MemberController.java index a3b32e1..75fbb8b 100644 --- a/src/main/java/com/hansung/leafly/domain/member/web/controller/MemberController.java +++ b/src/main/java/com/hansung/leafly/domain/member/web/controller/MemberController.java @@ -45,4 +45,13 @@ public ResponseEntity> onboarding( memberService.onboarding(memberDetails.getMember(), req); return ResponseEntity.status(HttpStatus.CREATED).body(SuccessResponse.created(null)); } + + //회원 정보 반환 + @GetMapping + public ResponseEntity> details( + @AuthenticationPrincipal CustomMemberDetails memberDetails + ){ + MemberDetailsRes res = memberService.details(memberDetails.getMember()); + return ResponseEntity.status(HttpStatus.OK).body(SuccessResponse.from(res)); + } } diff --git a/src/main/java/com/hansung/leafly/domain/member/web/dto/MemberDetailsRes.java b/src/main/java/com/hansung/leafly/domain/member/web/dto/MemberDetailsRes.java new file mode 100644 index 0000000..f9ed8a4 --- /dev/null +++ b/src/main/java/com/hansung/leafly/domain/member/web/dto/MemberDetailsRes.java @@ -0,0 +1,40 @@ +package com.hansung.leafly.domain.member.web.dto; + +import com.hansung.leafly.domain.member.web.dto.info.BookSimple; +import com.hansung.leafly.domain.member.web.dto.info.LibrarySection; +import com.hansung.leafly.domain.member.web.dto.info.LikeSection; + +import java.util.List; + +public record MemberDetailsRes ( + String nickName, + String profileImage, + LibrarySection library, + LikeSection likes +){ + public static MemberDetailsRes of( + String nickName, + String profileImage, + int finishedCount, + List finishedBooks, + int wantCount, + List wantBooks, + int likeCount, + List likeBooks + ) { + return new MemberDetailsRes( + nickName, + profileImage, + new LibrarySection( + finishedCount, + finishedBooks, + wantCount, + wantBooks + ), + new LikeSection( + likeCount, + likeBooks + ) + ); + } +} diff --git a/src/main/java/com/hansung/leafly/domain/member/web/dto/info/BookSimple.java b/src/main/java/com/hansung/leafly/domain/member/web/dto/info/BookSimple.java new file mode 100644 index 0000000..b3b388c --- /dev/null +++ b/src/main/java/com/hansung/leafly/domain/member/web/dto/info/BookSimple.java @@ -0,0 +1,6 @@ +package com.hansung.leafly.domain.member.web.dto.info; + +public record BookSimple( + String isbn, + String coverUrl +) {} diff --git a/src/main/java/com/hansung/leafly/domain/member/web/dto/info/LibrarySection.java b/src/main/java/com/hansung/leafly/domain/member/web/dto/info/LibrarySection.java new file mode 100644 index 0000000..0255465 --- /dev/null +++ b/src/main/java/com/hansung/leafly/domain/member/web/dto/info/LibrarySection.java @@ -0,0 +1,10 @@ +package com.hansung.leafly.domain.member.web.dto.info; + +import java.util.List; + +public record LibrarySection( + int finishedCount, + List finishedBooks, + int wantCount, + List wantBooks +) {} diff --git a/src/main/java/com/hansung/leafly/domain/member/web/dto/info/LikeSection.java b/src/main/java/com/hansung/leafly/domain/member/web/dto/info/LikeSection.java new file mode 100644 index 0000000..de1a5a8 --- /dev/null +++ b/src/main/java/com/hansung/leafly/domain/member/web/dto/info/LikeSection.java @@ -0,0 +1,8 @@ +package com.hansung.leafly.domain.member.web.dto.info; + +import java.util.List; + +public record LikeSection( + int likeCount, + List likeBooks +) {}