From c8409db7fc43d8f2b733f0a7c87fca99db77b21e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=98=84=EC=95=84?= <52688527+hyeonahhh@users.noreply.github.com> Date: Sun, 24 Aug 2025 20:42:15 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EB=82=B4=20=EB=85=B8?= =?UTF-8?q?=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20=EC=95=88=EB=90=A8=20=EC=9D=B4?= =?UTF-8?q?=EC=8A=88=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/SharedNoteQueryService.java | 339 +++++++++--------- 1 file changed, 167 insertions(+), 172 deletions(-) diff --git a/src/main/java/umc/th/juinjang/api/note/shared/service/SharedNoteQueryService.java b/src/main/java/umc/th/juinjang/api/note/shared/service/SharedNoteQueryService.java index 55a34169..f4abec7d 100644 --- a/src/main/java/umc/th/juinjang/api/note/shared/service/SharedNoteQueryService.java +++ b/src/main/java/umc/th/juinjang/api/note/shared/service/SharedNoteQueryService.java @@ -1,20 +1,11 @@ package umc.th.juinjang.api.note.shared.service; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import umc.th.juinjang.api.checklist.service.ChecklistAnswerFinder; import umc.th.juinjang.api.checklist.service.ReportFinder; import umc.th.juinjang.api.checklist.service.response.ChecklistAnswerResponseDTO; @@ -40,170 +31,174 @@ import umc.th.juinjang.domain.pencil.used.model.UsedPencil; import umc.th.juinjang.domain.report.model.Report; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + @Service @Slf4j @RequiredArgsConstructor public class SharedNoteQueryService { - private final UsedPencilFinder usedPencilFinder; - private final SharedNoteFinder sharedNoteFinder; - private final LikedNoteFinder likedNoteFinder; - private final ChecklistAnswerFinder checklistAnswerFinder; - private final ViewCountService viewCountService; - private final ReportFinder reportFinder; - - @Transactional - public SharedNoteGetResponse findSharedNote(Member member, Long sharedNoteId) { - SharedNote sharedNote = sharedNoteFinder.findByIdWithNoteAndAddress(sharedNoteId); - Limjang limjang = sharedNote.getLimjang(); - - boolean isBuyerOrOwner = getIsBuyerOrOwner(member, sharedNote); - - long viewCount = viewCountService.getViewCount(member, sharedNote); - - Integer countBuyer = makeBuyerCount(usedPencilFinder.countBySharedNoteId(sharedNoteId)); - boolean isLiked = likedNoteFinder.existsByMemberAndSharedNote(member, sharedNote); - - if (isBuyerOrOwner) { - return SharedNoteGetResponse.ofPurchased(isBuyerOrOwner, limjang, limjang.getAddressEntity(), sharedNote, - sharedNote.getMember(), countBuyer, isLiked, viewCount); - } else { - return SharedNoteGetResponse.ofNotPurchased(isBuyerOrOwner, limjang, limjang.getAddressEntity(), sharedNote, - sharedNote.getMember(), countBuyer, isLiked, viewCount); - } - } - - private boolean getIsBuyerOrOwner(Member requestMember, SharedNote sharedNote) { - return usedPencilFinder.existsByMemberAndSharedNoteId(requestMember, sharedNote.getSharedNoteId()) || - sharedNote.getMember().getMemberId().equals(requestMember.getMemberId()); - } - - private Integer makeBuyerCount(int count) { - if (count >= 100) { - return 100; - } else if (count >= 50) { - return 50; - } else if (count >= 30) { - return 30; - } else if (count >= 10) { - return 10; - } - return null; - } - - @Transactional(readOnly = true) - public SharedNoteExploreGetResponse findExploreSharedNote(Member member, List code, - ExploreSortType sort, - LimjangPropertyType propertyType, LimjangPriceType priceType, String keyword, - Pageable pageable) { - - Page pages = sharedNoteFinder.findSharedNoteInExployer(code, sort, propertyType, priceType, keyword, - pageable); - List sharedNotes = pages.getContent(); - List ids = sharedNotes.stream().map(SharedNote::getSharedNoteId).toList(); - - Set likedNoteIds = new HashSet<>(likedNoteFinder.findLikedSharedNoteIds(member, sharedNotes)); - Set purchasedIds = new HashSet<>(usedPencilFinder.findByMemberInSharedNoteIdsAndTypeIsOwned(member, ids)); - - Map viewcountMap = mapIdsAndViewcount(sharedNotes); - return SharedNoteExploreGetResponse.of(pages.getTotalElements(), sharedNotes, purchasedIds, likedNoteIds, - viewcountMap, member.getMemberId()); - } - - private Map mapIdsAndViewcount(List sharedNotes) { - return sharedNotes.stream().collect(Collectors.toMap( - SharedNote::getSharedNoteId, - SharedNote::getViewCount - )); - } - - public UserSharedNotesGetResponse findUserSharedNotes(Member member, NoteType noteType, - LimjangPropertyType propertyType, LimjangPriceType priceType, String keyword) { - - switch (noteType) { - case LIKED -> { - return getUserLikedSharedNotes(member, propertyType, priceType, keyword); - } - case SHARED -> { - return getUserSharedNotes(member, noteType, propertyType, priceType, keyword); - } - case OWNED -> { - return getUserOwnedSharedNotes(member, noteType, propertyType, priceType, keyword); - } - default -> throw new SharedNoteHandler(ErrorStatus.SHAREDNOTE_TYPE_ERROR); - } - } - - private UserSharedNotesGetResponse getUserOwnedSharedNotes(Member member, NoteType noteType, - LimjangPropertyType propertyType, LimjangPriceType priceType, String keyword) { - - List usedPencils = usedPencilFinder.findAllByMemberAndTypeIsOwnedOrderByCreatedAtDesc(member); - List sharedNoteIds = usedPencils.stream().map(UsedPencil::getSharedNoteId).toList(); - - List sharedNotes = sharedNoteFinder.findUserSharedNotes(member, noteType, propertyType, priceType, - keyword, sharedNoteIds); - List sortedSharedNotes = sortByUsedPencilCreatedAt(sharedNoteIds, sharedNotes); - - Map viewcountMap = mapIdsAndViewcount(sharedNotes); - Set likedNoteIds = new HashSet<>(likedNoteFinder.findLikedSharedNoteIds(member, sharedNotes)); - - return UserSharedNotesGetResponse.ofOwned(sortedSharedNotes, likedNoteIds, viewcountMap); - } - - private List sortByUsedPencilCreatedAt(List sharedNoteIds, List sharedNotes) { - Map orderMap = IntStream.range(0, sharedNoteIds.size()) - .boxed() - .collect(Collectors.toMap(sharedNoteIds::get, i -> i)); - - return sharedNotes.stream() - .sorted(Comparator.comparingInt(note -> orderMap.get(note.getSharedNoteId()))) - .toList(); - } - - private UserSharedNotesGetResponse getUserSharedNotes(Member member, NoteType noteType, - LimjangPropertyType propertyType, LimjangPriceType priceType, String keyword) { - List sharedNotes = sharedNoteFinder.findUserSharedNotes(member, noteType, propertyType, priceType, - keyword, List.of()); - Map viewcountMap = mapIdsAndViewcount(sharedNotes); - - Set likedNoteIds = new HashSet<>(likedNoteFinder.findLikedSharedNoteIds(member, sharedNotes)); - return UserSharedNotesGetResponse.ofShared(member, sharedNotes, likedNoteIds, viewcountMap); - } - - private UserSharedNotesGetResponse getUserLikedSharedNotes(Member member, LimjangPropertyType propertyType, - LimjangPriceType priceType, String keyword) { - - List userLikedNotes = likedNoteFinder.findAllByMemberAndDynamic(member, propertyType, - priceType, keyword); - List sharedNotes = userLikedNotes.stream().map(LikedNote::getSharedNote).toList(); - - Set purchasedIds = new HashSet<>(usedPencilFinder.findByMemberInSharedNoteIdsAndTypeIsOwned(member, - sharedNotes.stream().map(SharedNote::getSharedNoteId).toList())); - Map viewcountMap = mapIdsAndViewcount(sharedNotes); - - return UserSharedNotesGetResponse.ofLiked(sharedNotes, purchasedIds, viewcountMap, member.getMemberId()); - } - - @Transactional(readOnly = true) - public SharedNoteCheckListAndReviewResponse findChecklistAndReview(Member member, Long sharedNoteId) { - SharedNote sharedNote = sharedNoteFinder.findByIdWithNoteAndAddress(sharedNoteId); - Limjang note = sharedNote.getLimjang(); - List answers = checklistAnswerFinder.findByLimjangId( - note.getLimjangId()); - - Report report = reportFinder.findReportByNote(note); - - boolean isOwned = usedPencilFinder.existsByMemberAndSharedNoteId(member, sharedNoteId); - // 구매했다면 review 포함, 아니면 null - String review = isOwned ? sharedNote.getReview() : null; - Float totalRate = isOwned ? report.getTotalRate() : null; - return new SharedNoteCheckListAndReviewResponse(review, totalRate, answers); - } - - public ReportWithLimjangResponseDTO getReportBySharedNoteId(Long sharedNoteId) { - SharedNote sharedNote = sharedNoteFinder.findByIdWithNoteAndAddress(sharedNoteId); - Limjang note = sharedNote.getLimjang(); - Report report = reportFinder.findReportByNote(note); - return new ReportWithLimjangResponseDTO(ReportGetResponse.of(report), LimjangDetailGetResponse.of(note)); - } + private final UsedPencilFinder usedPencilFinder; + private final SharedNoteFinder sharedNoteFinder; + private final LikedNoteFinder likedNoteFinder; + private final ChecklistAnswerFinder checklistAnswerFinder; + private final ViewCountService viewCountService; + private final ReportFinder reportFinder; + + @Transactional + public SharedNoteGetResponse findSharedNote(Member member, Long sharedNoteId) { + SharedNote sharedNote = sharedNoteFinder.findByIdWithNoteAndAddress(sharedNoteId); + Limjang limjang = sharedNote.getLimjang(); + + boolean isBuyerOrOwner = getIsBuyerOrOwner(member, sharedNote); + + long viewCount = viewCountService.getViewCount(member, sharedNote); + + Integer countBuyer = makeBuyerCount(usedPencilFinder.countBySharedNoteId(sharedNoteId)); + boolean isLiked = likedNoteFinder.existsByMemberAndSharedNote(member, sharedNote); + + if (isBuyerOrOwner) { + return SharedNoteGetResponse.ofPurchased(isBuyerOrOwner, limjang, limjang.getAddressEntity(), sharedNote, + sharedNote.getMember(), countBuyer, isLiked, viewCount); + } else { + return SharedNoteGetResponse.ofNotPurchased(isBuyerOrOwner, limjang, limjang.getAddressEntity(), sharedNote, + sharedNote.getMember(), countBuyer, isLiked, viewCount); + } + } + + private boolean getIsBuyerOrOwner(Member requestMember, SharedNote sharedNote) { + return usedPencilFinder.existsByMemberAndSharedNoteId(requestMember, sharedNote.getSharedNoteId()) || + sharedNote.getMember().getMemberId().equals(requestMember.getMemberId()); + } + + private Integer makeBuyerCount(int count) { + if (count >= 100) { + return 100; + } else if (count >= 50) { + return 50; + } else if (count >= 30) { + return 30; + } else if (count >= 10) { + return 10; + } + return null; + } + + @Transactional(readOnly = true) + public SharedNoteExploreGetResponse findExploreSharedNote(Member member, List code, + ExploreSortType sort, + LimjangPropertyType propertyType, LimjangPriceType priceType, String keyword, + Pageable pageable) { + + Page pages = sharedNoteFinder.findSharedNoteInExployer(code, sort, propertyType, priceType, keyword, + pageable); + List sharedNotes = pages.getContent(); + List ids = sharedNotes.stream().map(SharedNote::getSharedNoteId).toList(); + + Set likedNoteIds = new HashSet<>(likedNoteFinder.findLikedSharedNoteIds(member, sharedNotes)); + Set purchasedIds = new HashSet<>(usedPencilFinder.findByMemberInSharedNoteIdsAndTypeIsOwned(member, ids)); + + Map viewcountMap = mapIdsAndViewcount(sharedNotes); + return SharedNoteExploreGetResponse.of(pages.getTotalElements(), sharedNotes, purchasedIds, likedNoteIds, + viewcountMap, member.getMemberId()); + } + + private Map mapIdsAndViewcount(List sharedNotes) { + return sharedNotes.stream().collect(Collectors.toMap( + SharedNote::getSharedNoteId, + SharedNote::getViewCount + )); + } + + public UserSharedNotesGetResponse findUserSharedNotes(Member member, NoteType noteType, + LimjangPropertyType propertyType, LimjangPriceType priceType, String keyword) { + + switch (noteType) { + case LIKED -> { + return getUserLikedSharedNotes(member, propertyType, priceType, keyword); + } + case SHARED -> { + return getUserSharedNotes(member, noteType, propertyType, priceType, keyword); + } + case OWNED -> { + return getUserOwnedSharedNotes(member, noteType, propertyType, priceType, keyword); + } + default -> throw new SharedNoteHandler(ErrorStatus.SHAREDNOTE_TYPE_ERROR); + } + } + + private UserSharedNotesGetResponse getUserOwnedSharedNotes(Member member, NoteType noteType, + LimjangPropertyType propertyType, LimjangPriceType priceType, String keyword) { + + List usedPencils = usedPencilFinder.findAllByMemberAndTypeIsOwnedOrderByCreatedAtDesc(member); + List sharedNoteIds = usedPencils.stream().map(UsedPencil::getSharedNoteId).toList(); + + List sharedNotes = sharedNoteFinder.findUserSharedNotes(member, noteType, propertyType, priceType, + keyword, sharedNoteIds); + List sortedSharedNotes = sortByUsedPencilCreatedAt(sharedNoteIds, sharedNotes); + + Map viewcountMap = mapIdsAndViewcount(sharedNotes); + Set likedNoteIds = new HashSet<>(likedNoteFinder.findLikedSharedNoteIds(member, sharedNotes)); + + return UserSharedNotesGetResponse.ofOwned(sortedSharedNotes, likedNoteIds, viewcountMap); + } + + private List sortByUsedPencilCreatedAt(List sharedNoteIds, List sharedNotes) { + Map orderMap = IntStream.range(0, sharedNoteIds.size()) + .boxed() + .collect(Collectors.toMap(sharedNoteIds::get, i -> i)); + + return sharedNotes.stream() + .sorted(Comparator.comparingInt(note -> orderMap.get(note.getSharedNoteId()))) + .toList(); + } + + private UserSharedNotesGetResponse getUserSharedNotes(Member member, NoteType noteType, + LimjangPropertyType propertyType, LimjangPriceType priceType, String keyword) { + List sharedNotes = sharedNoteFinder.findUserSharedNotes(member, noteType, propertyType, priceType, + keyword, List.of()); + Map viewcountMap = mapIdsAndViewcount(sharedNotes); + + Set likedNoteIds = new HashSet<>(likedNoteFinder.findLikedSharedNoteIds(member, sharedNotes)); + return UserSharedNotesGetResponse.ofShared(member, sharedNotes, likedNoteIds, viewcountMap); + } + + private UserSharedNotesGetResponse getUserLikedSharedNotes(Member member, LimjangPropertyType propertyType, + LimjangPriceType priceType, String keyword) { + + List userLikedNotes = likedNoteFinder.findAllByMemberAndDynamic(member, propertyType, + priceType, keyword); + List sharedNotes = userLikedNotes.stream().map(LikedNote::getSharedNote).toList(); + + Set purchasedIds = new HashSet<>(usedPencilFinder.findByMemberInSharedNoteIdsAndTypeIsOwned(member, + sharedNotes.stream().map(SharedNote::getSharedNoteId).toList())); + Map viewcountMap = mapIdsAndViewcount(sharedNotes); + + return UserSharedNotesGetResponse.ofLiked(sharedNotes, purchasedIds, viewcountMap, member.getMemberId()); + } + + @Transactional(readOnly = true) + public SharedNoteCheckListAndReviewResponse findChecklistAndReview(Member member, Long sharedNoteId) { + SharedNote sharedNote = sharedNoteFinder.findByIdWithNoteAndAddress(sharedNoteId); + Limjang note = sharedNote.getLimjang(); + List answers = checklistAnswerFinder.findByLimjangId( + note.getLimjangId()); + + Report report = reportFinder.findReportByNote(note); + + boolean isBuyerOrOwner = getIsBuyerOrOwner(member, sharedNote); + // 구매했다면 review 포함, 아니면 null + String review = isBuyerOrOwner ? sharedNote.getReview() : null; + Float totalRate = isBuyerOrOwner ? report.getTotalRate() : null; + return new SharedNoteCheckListAndReviewResponse(review, totalRate, answers); + } + + public ReportWithLimjangResponseDTO getReportBySharedNoteId(Long sharedNoteId) { + SharedNote sharedNote = sharedNoteFinder.findByIdWithNoteAndAddress(sharedNoteId); + Limjang note = sharedNote.getLimjang(); + Report report = reportFinder.findReportByNote(note); + return new ReportWithLimjangResponseDTO(ReportGetResponse.of(report), LimjangDetailGetResponse.of(note)); + } }