From c4642e13eb66ee46f8f708e380ba3e2532398f26 Mon Sep 17 00:00:00 2001 From: JunHyeongChoi Date: Sun, 6 Oct 2024 14:42:23 +0900 Subject: [PATCH 01/19] =?UTF-8?q?fix:=20Specification=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Member, Friend 엔티티에서 memberId를 member로 수정 --- .../dto/response/CommentsResponse.java | 3 +- .../dto/response/FriendDiariesResponse.java | 2 ++ .../dto/response/FriendListResponse.java | 2 ++ .../dto/response/MyDiariesResponse.java | 2 ++ .../response/OneFriendDiariesResponse.java | 2 ++ .../potatocake/everymoment/entity/Friend.java | 5 ++-- .../repository/FriendRepository.java | 4 +-- .../everymoment/service/DiaryService.java | 6 +--- .../service/FriendDiaryService.java | 30 ++++++++++--------- .../service/FriendRequestService.java | 4 +-- .../everymoment/service/FriendService.java | 26 ++++++++-------- .../service/FriendSpecification.java | 4 +-- 12 files changed, 48 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/potatocake/everymoment/dto/response/CommentsResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/CommentsResponse.java index 160b79c..e832e92 100644 --- a/src/main/java/com/potatocake/everymoment/dto/response/CommentsResponse.java +++ b/src/main/java/com/potatocake/everymoment/dto/response/CommentsResponse.java @@ -1,13 +1,14 @@ package com.potatocake.everymoment.dto.response; +import com.fasterxml.jackson.annotation.JsonInclude; import java.util.List; import lombok.Builder; import lombok.Getter; @Getter +@JsonInclude(JsonInclude.Include.NON_NULL) @Builder public class CommentsResponse { private List comments; private Integer next; } - diff --git a/src/main/java/com/potatocake/everymoment/dto/response/FriendDiariesResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/FriendDiariesResponse.java index f2f096f..b8536e7 100644 --- a/src/main/java/com/potatocake/everymoment/dto/response/FriendDiariesResponse.java +++ b/src/main/java/com/potatocake/everymoment/dto/response/FriendDiariesResponse.java @@ -1,10 +1,12 @@ package com.potatocake.everymoment.dto.response; +import com.fasterxml.jackson.annotation.JsonInclude; import java.util.List; import lombok.Builder; import lombok.Getter; @Getter +@JsonInclude(JsonInclude.Include.NON_NULL) @Builder public class FriendDiariesResponse { private List diaries; diff --git a/src/main/java/com/potatocake/everymoment/dto/response/FriendListResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/FriendListResponse.java index d5131e7..6a3d599 100644 --- a/src/main/java/com/potatocake/everymoment/dto/response/FriendListResponse.java +++ b/src/main/java/com/potatocake/everymoment/dto/response/FriendListResponse.java @@ -1,10 +1,12 @@ package com.potatocake.everymoment.dto.response; +import com.fasterxml.jackson.annotation.JsonInclude; import java.util.List; import lombok.Builder; import lombok.Getter; @Getter +@JsonInclude(JsonInclude.Include.NON_NULL) @Builder public class FriendListResponse { private List friends; diff --git a/src/main/java/com/potatocake/everymoment/dto/response/MyDiariesResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/MyDiariesResponse.java index 48de888..ddca95c 100644 --- a/src/main/java/com/potatocake/everymoment/dto/response/MyDiariesResponse.java +++ b/src/main/java/com/potatocake/everymoment/dto/response/MyDiariesResponse.java @@ -1,10 +1,12 @@ package com.potatocake.everymoment.dto.response; +import com.fasterxml.jackson.annotation.JsonInclude; import java.util.List; import lombok.Builder; import lombok.Getter; @Getter +@JsonInclude(JsonInclude.Include.NON_NULL) @Builder public class MyDiariesResponse { private List diaries; diff --git a/src/main/java/com/potatocake/everymoment/dto/response/OneFriendDiariesResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/OneFriendDiariesResponse.java index 31ae287..41dba26 100644 --- a/src/main/java/com/potatocake/everymoment/dto/response/OneFriendDiariesResponse.java +++ b/src/main/java/com/potatocake/everymoment/dto/response/OneFriendDiariesResponse.java @@ -1,10 +1,12 @@ package com.potatocake.everymoment.dto.response; +import com.fasterxml.jackson.annotation.JsonInclude; import java.util.List; import lombok.Builder; import lombok.Getter; @Getter +@JsonInclude(JsonInclude.Include.NON_NULL) @Builder public class OneFriendDiariesResponse { private List diaries; diff --git a/src/main/java/com/potatocake/everymoment/entity/Friend.java b/src/main/java/com/potatocake/everymoment/entity/Friend.java index b6818cb..81f115d 100644 --- a/src/main/java/com/potatocake/everymoment/entity/Friend.java +++ b/src/main/java/com/potatocake/everymoment/entity/Friend.java @@ -3,7 +3,6 @@ import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; -import jakarta.persistence.ForeignKey; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @@ -27,11 +26,11 @@ public class Friend { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(nullable = false) - private Member memberId; + private Member member; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(nullable = false) - private Member friendId; + private Member friend; @Column(nullable = false) @Builder.Default diff --git a/src/main/java/com/potatocake/everymoment/repository/FriendRepository.java b/src/main/java/com/potatocake/everymoment/repository/FriendRepository.java index 70794c6..4ac611f 100644 --- a/src/main/java/com/potatocake/everymoment/repository/FriendRepository.java +++ b/src/main/java/com/potatocake/everymoment/repository/FriendRepository.java @@ -9,8 +9,8 @@ public interface FriendRepository extends JpaRepository, JpaSpecificationExecutor { - Optional findByMemberIdAndFriendId(Member member, Member friend); + Optional findByMemberAndFriend(Member member, Member friend); - List findAllFriendIdsByMemberId(Member member); + List findFriendsByMember(Member member); } diff --git a/src/main/java/com/potatocake/everymoment/service/DiaryService.java b/src/main/java/com/potatocake/everymoment/service/DiaryService.java index 8debdc8..2e3747d 100644 --- a/src/main/java/com/potatocake/everymoment/service/DiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/DiaryService.java @@ -20,7 +20,6 @@ import com.potatocake.everymoment.repository.DiaryRepository; import com.potatocake.everymoment.repository.MemberRepository; import com.potatocake.everymoment.repository.NotificationRepository; -import com.potatocake.everymoment.security.MemberDetails; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -29,9 +28,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.domain.Specification; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -122,7 +118,7 @@ public MyDiariesResponse getMyDiaries(Long memberId, DiaryFilterRequest diaryFil Specification spec = DiarySpecification.filterDiaries(diaryFilterRequest.getKeyword(), diaryFilterRequest.getEmoji(), diaryFilterRequest.getDate(), diaryFilterRequest.getFrom(), diaryFilterRequest.getUntil(), diaryFilterRequest.getBookmark()) - .and((root, query, builder) -> builder.equal(root.get("memberId"), currentMember)); + .and((root, query, builder) -> builder.equal(root.get("member"), currentMember)); diaryPage = diaryRepository.findAll(spec, PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); diff --git a/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java b/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java index 7a8fa74..58292da 100644 --- a/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java @@ -9,6 +9,7 @@ import com.potatocake.everymoment.dto.response.ThumbnailResponse; import com.potatocake.everymoment.entity.Diary; import com.potatocake.everymoment.entity.DiaryCategory; +import com.potatocake.everymoment.entity.Friend; import com.potatocake.everymoment.entity.Member; import com.potatocake.everymoment.exception.ErrorCode; import com.potatocake.everymoment.exception.GlobalException; @@ -16,7 +17,6 @@ import com.potatocake.everymoment.repository.DiaryRepository; import com.potatocake.everymoment.repository.FriendRepository; import com.potatocake.everymoment.repository.MemberRepository; -import com.potatocake.everymoment.security.MemberDetails; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -24,8 +24,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.domain.Specification; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -43,9 +41,9 @@ public FriendDiariesResponse getFriendDiaries(Long memberId, DiaryFilterRequest Member currentMember = memberRepository.findById(memberId) .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); - List friends = friendRepository.findAllFriendIdsByMemberId(currentMember); + List friends = friendRepository.findFriendsByMember(currentMember); List friendIdList = friends.stream() - .map(Member::getId) + .map(Friend::getId) .collect(Collectors.toList()); Page diaryPage; @@ -55,22 +53,26 @@ public FriendDiariesResponse getFriendDiaries(Long memberId, DiaryFilterRequest Specification spec = DiarySpecification.filterDiaries(diaryFilterRequest.getKeyword(), diaryFilterRequest.getEmoji(), diaryFilterRequest.getDate(), diaryFilterRequest.getFrom(), diaryFilterRequest.getUntil(), diaryFilterRequest.getBookmark()) - .and((root, query, builder) -> root.get("memberId").in(friendIdList)); // memberIds 목록에서 검색 + .and((root, query, builder) -> root.get("member").in(friendIdList)); // memberIds 목록에서 검색 - diaryPage = diaryRepository.findAll(spec, PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); + diaryPage = diaryRepository.findAll(spec, + PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); } else { // category가 있는 경우 - DiaryCategory에서 category 같은 것 찾음 - List diaryCategories = diaryCategoryRepository.findByCategoryId(diaryFilterRequest.getCategory()); + List diaryCategories = diaryCategoryRepository.findByCategoryId( + diaryFilterRequest.getCategory()); // Diary중에 memberId같은 것 가져옴 List filteredDiaryIds = diaryCategories.stream() - .filter(diaryCategory -> friendIdList.contains(diaryCategory.getDiary().getMember())) // memberIds 목록에서 필터링 + .filter(diaryCategory -> friendIdList.contains( + diaryCategory.getDiary().getMember())) // memberIds 목록에서 필터링 .map(diaryCategory -> diaryCategory.getDiary().getId()) .collect(Collectors.toList()); // 가져온 diaryId로 일기 찾음 Specification spec = (root, query, builder) -> root.get("id").in(filteredDiaryIds); - diaryPage = diaryRepository.findAll(spec, PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); + diaryPage = diaryRepository.findAll(spec, + PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); } List friendDiarySimpleResponseList = diaryPage.getContent().stream() @@ -90,18 +92,18 @@ public FriendDiariesResponse getFriendDiaries(Long memberId, DiaryFilterRequest // 친구 다이어리 하나 조회 public FriendDiaryResponse getFriendDiary(Long memberId, Long diaryId) { Diary diary = diaryRepository.findById(diaryId) - .orElseThrow(() -> new IllegalArgumentException("Diary not found")); + .orElseThrow(() -> new GlobalException(ErrorCode.DIARY_NOT_FOUND)); //글쓴사람이 친구인지 확인 Member currentMember = memberRepository.findById(memberId) .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); - List friends = friendRepository.findAllFriendIdsByMemberId(currentMember); + List friends = friendRepository.findFriendsByMember(currentMember); List friendIdList = friends.stream() - .map(Member::getId) + .map(Friend::getId) .collect(Collectors.toList()); - if(!friendIdList.contains(diary.getMember())){ + if (!friendIdList.contains(diary.getMember())) { throw new GlobalException(ErrorCode.FRIEND_NOT_FOUND); } //카테고리 찾음 diff --git a/src/main/java/com/potatocake/everymoment/service/FriendRequestService.java b/src/main/java/com/potatocake/everymoment/service/FriendRequestService.java index 9aeff97..0373b19 100644 --- a/src/main/java/com/potatocake/everymoment/service/FriendRequestService.java +++ b/src/main/java/com/potatocake/everymoment/service/FriendRequestService.java @@ -93,8 +93,8 @@ private FriendRequest findAndValidateFriendRequest(Long requestId, Long memberId private Friend createFriend(Member member, Member friend) { return Friend.builder() - .memberId(member) - .friendId(friend) + .member(member) + .friend(friend) .build(); } diff --git a/src/main/java/com/potatocake/everymoment/service/FriendService.java b/src/main/java/com/potatocake/everymoment/service/FriendService.java index f6b5b88..8238bd1 100644 --- a/src/main/java/com/potatocake/everymoment/service/FriendService.java +++ b/src/main/java/com/potatocake/everymoment/service/FriendService.java @@ -13,7 +13,6 @@ import com.potatocake.everymoment.repository.DiaryRepository; import com.potatocake.everymoment.repository.FriendRepository; import com.potatocake.everymoment.repository.MemberRepository; -import com.potatocake.everymoment.security.MemberDetails; import java.time.LocalDate; import java.util.List; import java.util.stream.Collectors; @@ -22,8 +21,6 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -38,20 +35,23 @@ public class FriendService { //특정 친구 일기 조회 @Transactional(readOnly = true) - public OneFriendDiariesResponse OneFriendDiariesResponse(Long memberid, Long friendId, LocalDate date, int key, int size) { + public OneFriendDiariesResponse OneFriendDiariesResponse(Long memberid, Long friendId, LocalDate date, int key, + int size) { Member currentMember = memberRepository.findById(memberid) .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); //친구인지 확인 Member friend = memberRepository.findById(friendId) .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); - friendRepository.findByMemberIdAndFriendId(currentMember, friend) + friendRepository.findByMemberAndFriend(currentMember, friend) .orElseThrow(() -> new GlobalException(ErrorCode.FRIEND_NOT_FOUND)); Pageable pageable = PageRequest.of(key, size); - Page diaries = diaryRepository.findAll(DiarySpecification.filterDiaries(null, null, date, null, null, null) - .and((root, query, builder) -> builder.equal(root.get("memberId").get("id"), friendId)), pageable); + Page diaries = diaryRepository.findAll( + DiarySpecification.filterDiaries(null, null, date, null, null, null) + .and((root, query, builder) -> builder.equal(root.get("member").get("id"), friendId)), + pageable); List diaryList = diaries.getContent().stream() .map(this::convertToFriendDiariesResponseDTO) @@ -70,13 +70,13 @@ public OneFriendDiariesResponse OneFriendDiariesResponse(Long memberid, Long fri public FriendListResponse getFriendList(Long memberIdFromController, String nickname, int key, int size) { Member currentMember = memberRepository.findById(memberIdFromController) .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); - + Long memberId = currentMember.getId(); Pageable pageable = PageRequest.of(key, size); Specification spec = FriendSpecification.filterFriends(memberId, nickname) - .and((root, query, builder) -> builder.equal(root.get("memberId").get("id"), memberId)); + .and((root, query, builder) -> builder.equal(root.get("member").get("id"), memberId)); Page friends = friendRepository.findAll(spec, pageable); @@ -99,9 +99,9 @@ public void deleteFriend(Long memberId, Long firendId) { Member friendMember = memberRepository.findById(firendId) .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); - Friend friendMine = friendRepository.findByMemberIdAndFriendId(currentMember, friendMember) + Friend friendMine = friendRepository.findByMemberAndFriend(currentMember, friendMember) .orElseThrow(() -> new GlobalException(ErrorCode.FRIEND_NOT_FOUND)); - Friend friendFriends = friendRepository.findByMemberIdAndFriendId(friendMember, currentMember) + Friend friendFriends = friendRepository.findByMemberAndFriend(friendMember, currentMember) .orElseThrow(() -> new GlobalException(ErrorCode.FRIEND_NOT_FOUND)); friendRepository.delete(friendMine); @@ -115,7 +115,7 @@ public void toggleCloseFriend(Long memberId, Long friendId) { Member friendMember = memberRepository.findById(friendId) .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); - Friend friend = friendRepository.findByMemberIdAndFriendId(currentMember, friendMember) + Friend friend = friendRepository.findByMemberAndFriend(currentMember, friendMember) .orElseThrow(() -> new GlobalException(ErrorCode.FRIEND_NOT_FOUND)); friend.toggleIsClose(); @@ -144,7 +144,7 @@ private FriendDiarySimpleResponse convertToFriendDiariesResponseDTO(Diary savedD //친구 프로필 DTO 변환 private FriendProfileResponse convertToFriendProfileResponseDTO(Friend friend) { - Member friendMember = friend.getFriendId(); + Member friendMember = friend.getFriend(); return FriendProfileResponse.builder() .id(friendMember.getId()) .nickname(friendMember.getNickname()) diff --git a/src/main/java/com/potatocake/everymoment/service/FriendSpecification.java b/src/main/java/com/potatocake/everymoment/service/FriendSpecification.java index 71b9451..5375e97 100644 --- a/src/main/java/com/potatocake/everymoment/service/FriendSpecification.java +++ b/src/main/java/com/potatocake/everymoment/service/FriendSpecification.java @@ -14,10 +14,10 @@ public static Specification filterFriends(Long memberId, String nickname return (Root root, CriteriaQuery query, CriteriaBuilder builder) -> { Predicate predicate = builder.conjunction(); - predicate = builder.and(predicate, builder.equal(root.get("memberId").get("id"), memberId)); + predicate = builder.and(predicate, builder.equal(root.get("member").get("id"), memberId)); if (nickname != null) { - Join friendJoin = root.join("friendId"); + Join friendJoin = root.join("friend"); predicate = builder.and(predicate, builder.like(friendJoin.get("nickname"), "%" + nickname + "%")); } From 769f951ba7767398b80b30f1f4b29669ad4093c7 Mon Sep 17 00:00:00 2001 From: JunHyeongChoi Date: Sun, 6 Oct 2024 15:17:34 +0900 Subject: [PATCH 02/19] =?UTF-8?q?fix:=20=ED=9A=8C=EC=9B=90=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=88=98=EC=A0=95=20API=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - nickname, profileimage 둘중 하나만 null인 경우에 대한 처리 추가 --- .../everymoment/controller/MemberController.java | 5 ++++- .../java/com/potatocake/everymoment/entity/Member.java | 10 ++++++++-- .../potatocake/everymoment/service/MemberService.java | 7 +++++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/potatocake/everymoment/controller/MemberController.java b/src/main/java/com/potatocake/everymoment/controller/MemberController.java index e680a93..5988a30 100644 --- a/src/main/java/com/potatocake/everymoment/controller/MemberController.java +++ b/src/main/java/com/potatocake/everymoment/controller/MemberController.java @@ -97,7 +97,10 @@ public ResponseEntity> deleteMember(@AuthenticationPrincip } private void validateProfileUpdate(MultipartFile profileImage, String nickname) { - if (profileImage == null && !StringUtils.hasText(nickname)) { + boolean isProfileImageEmpty = profileImage == null || profileImage.isEmpty(); + boolean isNicknameEmpty = !StringUtils.hasText(nickname); + + if (isProfileImageEmpty && isNicknameEmpty) { throw new GlobalException(ErrorCode.INFO_REQUIRED); } } diff --git a/src/main/java/com/potatocake/everymoment/entity/Member.java b/src/main/java/com/potatocake/everymoment/entity/Member.java index 0142578..5c39300 100644 --- a/src/main/java/com/potatocake/everymoment/entity/Member.java +++ b/src/main/java/com/potatocake/everymoment/entity/Member.java @@ -1,5 +1,7 @@ package com.potatocake.everymoment.entity; +import static org.springframework.util.StringUtils.hasText; + import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -40,8 +42,12 @@ public class Member extends BaseTimeEntity { private boolean deleted = false; public void update(String nickname, String profileImageUrl) { - this.nickname = nickname; - this.profileImageUrl = profileImageUrl; + if (hasText(nickname)) { + this.nickname = nickname; + } + if (profileImageUrl != null) { + this.profileImageUrl = profileImageUrl; + } } } diff --git a/src/main/java/com/potatocake/everymoment/service/MemberService.java b/src/main/java/com/potatocake/everymoment/service/MemberService.java index 4ac4d15..b407335 100644 --- a/src/main/java/com/potatocake/everymoment/service/MemberService.java +++ b/src/main/java/com/potatocake/everymoment/service/MemberService.java @@ -70,7 +70,10 @@ public void updateMemberInfo(Long id, MultipartFile profileImage, String nicknam Member member = memberRepository.findById(id) .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); - String profileImageUrl = s3FileUploader.uploadFile(profileImage); + String profileImageUrl = null; + if (profileImage != null && !profileImage.isEmpty()) { + profileImageUrl = s3FileUploader.uploadFile(profileImage); + } member.update(nickname, profileImageUrl); } @@ -78,7 +81,7 @@ public void updateMemberInfo(Long id, MultipartFile profileImage, String nicknam public void deleteMember(Long memberId) { Member member = memberRepository.findById(memberId) .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); - + memberRepository.delete(member); } From 0a89607b2b869acddb1ea5d5305230e29b47afa1 Mon Sep 17 00:00:00 2001 From: JunHyeongChoi Date: Wed, 9 Oct 2024 15:41:34 +0900 Subject: [PATCH 03/19] =?UTF-8?q?refactor:=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EA=B2=B0=EA=B3=BC=20dto=EC=99=80=20=EB=82=B4=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20dto=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../everymoment/controller/MemberController.java | 8 ++++---- .../{MemberResponse.java => MemberMyResponse.java} | 2 +- .../dto/response/MemberSearchResponse.java | 2 +- .../dto/response/MemberSearchResultResponse.java | 14 ++++++++++++++ .../everymoment/service/MemberService.java | 13 +++++++------ .../controller/MemberControllerTest.java | 4 ++-- 6 files changed, 29 insertions(+), 14 deletions(-) rename src/main/java/com/potatocake/everymoment/dto/response/{MemberResponse.java => MemberMyResponse.java} (86%) create mode 100644 src/main/java/com/potatocake/everymoment/dto/response/MemberSearchResultResponse.java diff --git a/src/main/java/com/potatocake/everymoment/controller/MemberController.java b/src/main/java/com/potatocake/everymoment/controller/MemberController.java index 5988a30..d26b52c 100644 --- a/src/main/java/com/potatocake/everymoment/controller/MemberController.java +++ b/src/main/java/com/potatocake/everymoment/controller/MemberController.java @@ -4,7 +4,7 @@ import com.potatocake.everymoment.dto.request.MemberLoginRequest; import com.potatocake.everymoment.dto.response.JwtResponse; import com.potatocake.everymoment.dto.response.MemberDetailResponse; -import com.potatocake.everymoment.dto.response.MemberResponse; +import com.potatocake.everymoment.dto.response.MemberMyResponse; import com.potatocake.everymoment.dto.response.MemberSearchResponse; import com.potatocake.everymoment.exception.ErrorCode; import com.potatocake.everymoment.exception.GlobalException; @@ -69,8 +69,8 @@ public ResponseEntity> myInfo( } @GetMapping("/{memberId}") - public ResponseEntity> memberInfo(@PathVariable Long memberId) { - MemberResponse response = memberService.getMemberInfo(memberId); + public ResponseEntity> memberInfo(@PathVariable Long memberId) { + MemberMyResponse response = memberService.getMemberInfo(memberId); return ResponseEntity.ok() .body(SuccessResponse.ok(response)); @@ -99,7 +99,7 @@ public ResponseEntity> deleteMember(@AuthenticationPrincip private void validateProfileUpdate(MultipartFile profileImage, String nickname) { boolean isProfileImageEmpty = profileImage == null || profileImage.isEmpty(); boolean isNicknameEmpty = !StringUtils.hasText(nickname); - + if (isProfileImageEmpty && isNicknameEmpty) { throw new GlobalException(ErrorCode.INFO_REQUIRED); } diff --git a/src/main/java/com/potatocake/everymoment/dto/response/MemberResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/MemberMyResponse.java similarity index 86% rename from src/main/java/com/potatocake/everymoment/dto/response/MemberResponse.java rename to src/main/java/com/potatocake/everymoment/dto/response/MemberMyResponse.java index 57dfcc5..2d4ebdb 100644 --- a/src/main/java/com/potatocake/everymoment/dto/response/MemberResponse.java +++ b/src/main/java/com/potatocake/everymoment/dto/response/MemberMyResponse.java @@ -5,7 +5,7 @@ @Builder @Getter -public class MemberResponse { +public class MemberMyResponse { private Long id; private String profileImageUrl; diff --git a/src/main/java/com/potatocake/everymoment/dto/response/MemberSearchResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/MemberSearchResponse.java index cd1f71b..10c781c 100644 --- a/src/main/java/com/potatocake/everymoment/dto/response/MemberSearchResponse.java +++ b/src/main/java/com/potatocake/everymoment/dto/response/MemberSearchResponse.java @@ -10,7 +10,7 @@ @Getter public class MemberSearchResponse { - private List members; + private List members; private Long next; } diff --git a/src/main/java/com/potatocake/everymoment/dto/response/MemberSearchResultResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/MemberSearchResultResponse.java new file mode 100644 index 0000000..7069873 --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/dto/response/MemberSearchResultResponse.java @@ -0,0 +1,14 @@ +package com.potatocake.everymoment.dto.response; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class MemberSearchResultResponse { + + private Long id; + private String profileImageUrl; + private String nickname; + +} diff --git a/src/main/java/com/potatocake/everymoment/service/MemberService.java b/src/main/java/com/potatocake/everymoment/service/MemberService.java index b407335..1e052c4 100644 --- a/src/main/java/com/potatocake/everymoment/service/MemberService.java +++ b/src/main/java/com/potatocake/everymoment/service/MemberService.java @@ -3,8 +3,9 @@ import static org.springframework.data.domain.Sort.Direction.ASC; import com.potatocake.everymoment.dto.response.MemberDetailResponse; -import com.potatocake.everymoment.dto.response.MemberResponse; +import com.potatocake.everymoment.dto.response.MemberMyResponse; import com.potatocake.everymoment.dto.response.MemberSearchResponse; +import com.potatocake.everymoment.dto.response.MemberSearchResultResponse; import com.potatocake.everymoment.entity.Member; import com.potatocake.everymoment.exception.ErrorCode; import com.potatocake.everymoment.exception.GlobalException; @@ -33,7 +34,7 @@ public class MemberService { @Transactional(readOnly = true) public MemberSearchResponse searchMembers(String nickname, Long key, int size) { Window window = fetchMemberWindow(nickname, key, size); - List members = convertToMemberResponses(window.getContent()); + List members = convertToMemberResponses(window.getContent()); Long nextKey = pagingUtil.getNextKey(window, Member::getId); return MemberSearchResponse.builder() @@ -55,11 +56,11 @@ public MemberDetailResponse getMyInfo(Long memberId) { } @Transactional(readOnly = true) - public MemberResponse getMemberInfo(Long memberId) { + public MemberMyResponse getMemberInfo(Long memberId) { Member member = memberRepository.findById(memberId) .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); - return MemberResponse.builder() + return MemberMyResponse.builder() .id(member.getId()) .profileImageUrl(member.getProfileImageUrl()) .nickname(member.getNickname()) @@ -94,9 +95,9 @@ private Window fetchMemberWindow(String nickname, Long key, int size) { return memberRepository.findByNicknameContaining(searchNickname, scrollPosition, pageable); } - private List convertToMemberResponses(List members) { + private List convertToMemberResponses(List members) { return members.stream() - .map(member -> MemberResponse.builder() + .map(member -> MemberSearchResultResponse.builder() .id(member.getId()) .profileImageUrl(member.getProfileImageUrl()) .nickname(member.getNickname()) diff --git a/src/test/java/com/potatocake/everymoment/controller/MemberControllerTest.java b/src/test/java/com/potatocake/everymoment/controller/MemberControllerTest.java index c1a1ad1..aa330ee 100644 --- a/src/test/java/com/potatocake/everymoment/controller/MemberControllerTest.java +++ b/src/test/java/com/potatocake/everymoment/controller/MemberControllerTest.java @@ -14,8 +14,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.potatocake.everymoment.dto.response.MemberDetailResponse; -import com.potatocake.everymoment.dto.response.MemberResponse; import com.potatocake.everymoment.dto.response.MemberSearchResponse; +import com.potatocake.everymoment.dto.response.MemberSearchResultResponse; import com.potatocake.everymoment.entity.Member; import com.potatocake.everymoment.security.MemberDetails; import com.potatocake.everymoment.service.MemberService; @@ -96,7 +96,7 @@ void should_ReturnMyInfo_When_ValidMember() throws Exception { void should_ReturnMemberInfo_When_ValidMemberId() throws Exception { // given Long memberId = 1L; - MemberResponse response = MemberResponse.builder().build(); + MemberSearchResultResponse response = MemberSearchResultResponse.builder().build(); given(memberService.getMemberInfo(memberId)).willReturn(response); From de70f11cee9eece0c270bf5faa459b340457080f Mon Sep 17 00:00:00 2001 From: JunHyeongChoi Date: Wed, 9 Oct 2024 16:05:35 +0900 Subject: [PATCH 04/19] =?UTF-8?q?feat:=20=EA=B2=80=EC=83=89=20=EA=B2=B0?= =?UTF-8?q?=EA=B3=BC=20=ED=95=84=EB=93=9C=EC=97=90=20=EC=B9=9C=EA=B5=AC=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EC=83=81=ED=83=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 자기 자신, 미요청 상태, 요청 상태, 받은 상태, 친구 상태 --- .../controller/MemberController.java | 5 ++- .../dto/response/FriendRequestStatus.java | 5 +++ .../response/MemberSearchResultResponse.java | 1 + .../repository/FriendRepository.java | 2 + .../repository/FriendRequestRepository.java | 3 ++ .../everymoment/service/MemberService.java | 38 +++++++++++++++++-- 6 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/potatocake/everymoment/dto/response/FriendRequestStatus.java diff --git a/src/main/java/com/potatocake/everymoment/controller/MemberController.java b/src/main/java/com/potatocake/everymoment/controller/MemberController.java index d26b52c..b94885f 100644 --- a/src/main/java/com/potatocake/everymoment/controller/MemberController.java +++ b/src/main/java/com/potatocake/everymoment/controller/MemberController.java @@ -51,9 +51,10 @@ public ResponseEntity> login(@RequestBody MemberLog public ResponseEntity> searchMembers( @RequestParam(required = false) String nickname, @RequestParam(required = false) Long key, - @RequestParam(defaultValue = "10") int size) { + @RequestParam(defaultValue = "10") int size, + @AuthenticationPrincipal MemberDetails memberDetails) { - MemberSearchResponse response = memberService.searchMembers(nickname, key, size); + MemberSearchResponse response = memberService.searchMembers(nickname, key, size, memberDetails.getId()); return ResponseEntity.ok() .body(SuccessResponse.ok(response)); diff --git a/src/main/java/com/potatocake/everymoment/dto/response/FriendRequestStatus.java b/src/main/java/com/potatocake/everymoment/dto/response/FriendRequestStatus.java new file mode 100644 index 0000000..b7057ab --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/dto/response/FriendRequestStatus.java @@ -0,0 +1,5 @@ +package com.potatocake.everymoment.dto.response; + +public enum FriendRequestStatus { + NONE, SENT, RECEIVED, FRIENDS, SELF +} diff --git a/src/main/java/com/potatocake/everymoment/dto/response/MemberSearchResultResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/MemberSearchResultResponse.java index 7069873..c277f12 100644 --- a/src/main/java/com/potatocake/everymoment/dto/response/MemberSearchResultResponse.java +++ b/src/main/java/com/potatocake/everymoment/dto/response/MemberSearchResultResponse.java @@ -10,5 +10,6 @@ public class MemberSearchResultResponse { private Long id; private String profileImageUrl; private String nickname; + private FriendRequestStatus friendRequestStatus; } diff --git a/src/main/java/com/potatocake/everymoment/repository/FriendRepository.java b/src/main/java/com/potatocake/everymoment/repository/FriendRepository.java index 4ac611f..29ec334 100644 --- a/src/main/java/com/potatocake/everymoment/repository/FriendRepository.java +++ b/src/main/java/com/potatocake/everymoment/repository/FriendRepository.java @@ -13,4 +13,6 @@ public interface FriendRepository extends JpaRepository, JpaSpecif List findFriendsByMember(Member member); + boolean existsByMemberIdAndFriendId(Long memberId, Long friendId); + } diff --git a/src/main/java/com/potatocake/everymoment/repository/FriendRequestRepository.java b/src/main/java/com/potatocake/everymoment/repository/FriendRequestRepository.java index 154c385..55ea151 100644 --- a/src/main/java/com/potatocake/everymoment/repository/FriendRequestRepository.java +++ b/src/main/java/com/potatocake/everymoment/repository/FriendRequestRepository.java @@ -1,6 +1,7 @@ package com.potatocake.everymoment.repository; import com.potatocake.everymoment.entity.FriendRequest; +import java.util.Optional; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.ScrollPosition; import org.springframework.data.domain.Window; @@ -12,4 +13,6 @@ public interface FriendRequestRepository extends JpaRepository findByReceiverId(Long receiverId, ScrollPosition scrollPosition, Pageable pageable); + Optional findBySenderIdAndReceiverId(Long senderId, Long receiverId); + } diff --git a/src/main/java/com/potatocake/everymoment/service/MemberService.java b/src/main/java/com/potatocake/everymoment/service/MemberService.java index 1e052c4..39e5185 100644 --- a/src/main/java/com/potatocake/everymoment/service/MemberService.java +++ b/src/main/java/com/potatocake/everymoment/service/MemberService.java @@ -2,17 +2,22 @@ import static org.springframework.data.domain.Sort.Direction.ASC; +import com.potatocake.everymoment.dto.response.FriendRequestStatus; import com.potatocake.everymoment.dto.response.MemberDetailResponse; import com.potatocake.everymoment.dto.response.MemberMyResponse; import com.potatocake.everymoment.dto.response.MemberSearchResponse; import com.potatocake.everymoment.dto.response.MemberSearchResultResponse; +import com.potatocake.everymoment.entity.FriendRequest; import com.potatocake.everymoment.entity.Member; import com.potatocake.everymoment.exception.ErrorCode; import com.potatocake.everymoment.exception.GlobalException; +import com.potatocake.everymoment.repository.FriendRepository; +import com.potatocake.everymoment.repository.FriendRequestRepository; import com.potatocake.everymoment.repository.MemberRepository; import com.potatocake.everymoment.util.PagingUtil; import com.potatocake.everymoment.util.S3FileUploader; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; @@ -28,13 +33,15 @@ public class MemberService { private final MemberRepository memberRepository; + private final FriendRequestRepository friendRequestRepository; + private final FriendRepository friendRepository; private final PagingUtil pagingUtil; private final S3FileUploader s3FileUploader; @Transactional(readOnly = true) - public MemberSearchResponse searchMembers(String nickname, Long key, int size) { + public MemberSearchResponse searchMembers(String nickname, Long key, int size, Long currentMemberId) { Window window = fetchMemberWindow(nickname, key, size); - List members = convertToMemberResponses(window.getContent()); + List members = convertToMemberResponses(window.getContent(), currentMemberId); Long nextKey = pagingUtil.getNextKey(window, Member::getId); return MemberSearchResponse.builder() @@ -95,14 +102,39 @@ private Window fetchMemberWindow(String nickname, Long key, int size) { return memberRepository.findByNicknameContaining(searchNickname, scrollPosition, pageable); } - private List convertToMemberResponses(List members) { + private List convertToMemberResponses(List members, Long currentMemberId) { return members.stream() .map(member -> MemberSearchResultResponse.builder() .id(member.getId()) .profileImageUrl(member.getProfileImageUrl()) .nickname(member.getNickname()) + .friendRequestStatus(getFriendRequestStatus(currentMemberId, member.getId())) .build()) .collect(Collectors.toList()); } + private FriendRequestStatus getFriendRequestStatus(Long currentMemberId, Long targetUserId) { + if (currentMemberId.equals(targetUserId)) { + return FriendRequestStatus.SELF; + } + + if (friendRepository.existsByMemberIdAndFriendId(currentMemberId, targetUserId)) { + return FriendRequestStatus.FRIENDS; + } + + Optional sentRequest = friendRequestRepository.findBySenderIdAndReceiverId(currentMemberId, + targetUserId); + if (sentRequest.isPresent()) { + return FriendRequestStatus.SENT; + } + + Optional receivedRequest = friendRequestRepository.findBySenderIdAndReceiverId(targetUserId, + currentMemberId); + if (receivedRequest.isPresent()) { + return FriendRequestStatus.RECEIVED; + } + + return FriendRequestStatus.NONE; + } + } From 9ffdbe4c3bf8d5f7c5eb4e998ad9b79e4eaf64ee Mon Sep 17 00:00:00 2001 From: JunHyeongChoi Date: Wed, 9 Oct 2024 16:09:01 +0900 Subject: [PATCH 05/19] =?UTF-8?q?refactor:=20=EC=A7=80=EC=A0=80=EB=B6=84?= =?UTF-8?q?=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../everymoment/service/MemberService.java | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/potatocake/everymoment/service/MemberService.java b/src/main/java/com/potatocake/everymoment/service/MemberService.java index 39e5185..b53c4f0 100644 --- a/src/main/java/com/potatocake/everymoment/service/MemberService.java +++ b/src/main/java/com/potatocake/everymoment/service/MemberService.java @@ -7,7 +7,6 @@ import com.potatocake.everymoment.dto.response.MemberMyResponse; import com.potatocake.everymoment.dto.response.MemberSearchResponse; import com.potatocake.everymoment.dto.response.MemberSearchResultResponse; -import com.potatocake.everymoment.entity.FriendRequest; import com.potatocake.everymoment.entity.Member; import com.potatocake.everymoment.exception.ErrorCode; import com.potatocake.everymoment.exception.GlobalException; @@ -17,7 +16,6 @@ import com.potatocake.everymoment.util.PagingUtil; import com.potatocake.everymoment.util.S3FileUploader; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; @@ -113,28 +111,22 @@ private List convertToMemberResponses(List m .collect(Collectors.toList()); } - private FriendRequestStatus getFriendRequestStatus(Long currentMemberId, Long targetUserId) { - if (currentMemberId.equals(targetUserId)) { + private FriendRequestStatus getFriendRequestStatus(Long currentMemberId, Long targetMemberId) { + if (currentMemberId.equals(targetMemberId)) { return FriendRequestStatus.SELF; } - if (friendRepository.existsByMemberIdAndFriendId(currentMemberId, targetUserId)) { + if (friendRepository.existsByMemberIdAndFriendId(currentMemberId, targetMemberId)) { return FriendRequestStatus.FRIENDS; } - Optional sentRequest = friendRequestRepository.findBySenderIdAndReceiverId(currentMemberId, - targetUserId); - if (sentRequest.isPresent()) { - return FriendRequestStatus.SENT; - } - - Optional receivedRequest = friendRequestRepository.findBySenderIdAndReceiverId(targetUserId, - currentMemberId); - if (receivedRequest.isPresent()) { - return FriendRequestStatus.RECEIVED; - } - - return FriendRequestStatus.NONE; + return friendRequestRepository.findBySenderIdAndReceiverId(currentMemberId, targetMemberId) + .map(request -> FriendRequestStatus.SENT) + .orElseGet(() -> + friendRequestRepository.findBySenderIdAndReceiverId(targetMemberId, currentMemberId) + .map(request -> FriendRequestStatus.RECEIVED) + .orElse(FriendRequestStatus.NONE) + ); } } From eb14110ff261dbae3d0e37a1b2cbb0a7a002e4b6 Mon Sep 17 00:00:00 2001 From: JunHyeongChoi Date: Wed, 9 Oct 2024 16:15:37 +0900 Subject: [PATCH 06/19] =?UTF-8?q?test:=20=ED=9A=8C=EC=9B=90=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MemberControllerTest.java | 13 +++++-- .../service/MemberServiceTest.java | 37 ++++++++++++++++--- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/test/java/com/potatocake/everymoment/controller/MemberControllerTest.java b/src/test/java/com/potatocake/everymoment/controller/MemberControllerTest.java index aa330ee..c5ac5df 100644 --- a/src/test/java/com/potatocake/everymoment/controller/MemberControllerTest.java +++ b/src/test/java/com/potatocake/everymoment/controller/MemberControllerTest.java @@ -14,8 +14,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.potatocake.everymoment.dto.response.MemberDetailResponse; +import com.potatocake.everymoment.dto.response.MemberMyResponse; import com.potatocake.everymoment.dto.response.MemberSearchResponse; -import com.potatocake.everymoment.dto.response.MemberSearchResultResponse; import com.potatocake.everymoment.entity.Member; import com.potatocake.everymoment.security.MemberDetails; import com.potatocake.everymoment.service.MemberService; @@ -49,12 +49,17 @@ void should_SearchMembers_When_ValidInput() throws Exception { String nickname = "testUser"; Long key = 1L; int size = 10; + + Long memberId = 1L; + MemberDetails memberDetails = createMemberDetails(memberId, 1234L, "test"); + MemberSearchResponse response = MemberSearchResponse.builder().build(); - given(memberService.searchMembers(nickname, key, size)).willReturn(response); + given(memberService.searchMembers(nickname, key, size, memberId)).willReturn(response); // when ResultActions result = mockMvc.perform(get("/api/members") + .with(user(memberDetails)) .param("nickname", nickname) .param("key", key.toString()) .param("size", String.valueOf(size))); @@ -65,7 +70,7 @@ void should_SearchMembers_When_ValidInput() throws Exception { .andExpect(jsonPath("$.code").value(200)) .andExpect(jsonPath("$.message").value("success")); - then(memberService).should().searchMembers(nickname, key, size); + then(memberService).should().searchMembers(nickname, key, size, memberId); } @Test @@ -96,7 +101,7 @@ void should_ReturnMyInfo_When_ValidMember() throws Exception { void should_ReturnMemberInfo_When_ValidMemberId() throws Exception { // given Long memberId = 1L; - MemberSearchResultResponse response = MemberSearchResultResponse.builder().build(); + MemberMyResponse response = MemberMyResponse.builder().build(); given(memberService.getMemberInfo(memberId)).willReturn(response); diff --git a/src/test/java/com/potatocake/everymoment/service/MemberServiceTest.java b/src/test/java/com/potatocake/everymoment/service/MemberServiceTest.java index 5106a5e..df574a6 100644 --- a/src/test/java/com/potatocake/everymoment/service/MemberServiceTest.java +++ b/src/test/java/com/potatocake/everymoment/service/MemberServiceTest.java @@ -3,15 +3,20 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.then; import static org.mockito.Mockito.mock; +import static org.mockito.internal.verification.VerificationModeFactory.times; +import com.potatocake.everymoment.dto.response.FriendRequestStatus; import com.potatocake.everymoment.dto.response.MemberDetailResponse; import com.potatocake.everymoment.dto.response.MemberSearchResponse; import com.potatocake.everymoment.entity.Member; import com.potatocake.everymoment.exception.GlobalException; +import com.potatocake.everymoment.repository.FriendRepository; +import com.potatocake.everymoment.repository.FriendRequestRepository; import com.potatocake.everymoment.repository.MemberRepository; import com.potatocake.everymoment.util.PagingUtil; import com.potatocake.everymoment.util.S3FileUploader; @@ -36,6 +41,12 @@ class MemberServiceTest { @Mock private MemberRepository memberRepository; + @Mock + private FriendRequestRepository friendRequestRepository; + + @Mock + private FriendRepository friendRepository; + @Mock private PagingUtil pagingUtil; @@ -49,21 +60,35 @@ void should_ReturnMemberList_When_ValidSearchConditions() { String nickname = "testUser"; Long key = 1L; int size = 10; + Long currentMemberId = 1L; - List members = List.of(Member.builder().build()); + Member member1 = Member.builder().id(2L).nickname("testUser1").build(); + Member member2 = Member.builder().id(3L).nickname("testUser2").build(); + List members = List.of(member1, member2); Window window = Window.from(members, ScrollPosition::offset, false); + given(memberRepository.findByNicknameContaining(anyString(), any(), any())) .willReturn(window); + given(friendRepository.existsByMemberIdAndFriendId(anyLong(), anyLong())) + .willReturn(false); + given(friendRequestRepository.findBySenderIdAndReceiverId(anyLong(), anyLong())) + .willReturn(Optional.empty()); + given(pagingUtil.getNextKey(any(), any())).willReturn(null); // when - MemberSearchResponse result = memberService.searchMembers(nickname, key, size); + MemberSearchResponse result = memberService.searchMembers(nickname, key, size, currentMemberId); // then assertThat(result).isNotNull(); - assertThat(result.getMembers()).isNotEmpty(); - - then(memberRepository).should() - .findByNicknameContaining(anyString(), any(), any()); + assertThat(result.getMembers()).hasSize(2); + assertThat(result.getMembers().get(0).getFriendRequestStatus()).isEqualTo(FriendRequestStatus.NONE); + assertThat(result.getMembers().get(1).getFriendRequestStatus()).isEqualTo(FriendRequestStatus.NONE); + assertThat(result.getNext()).isNull(); + + then(memberRepository).should().findByNicknameContaining(anyString(), any(), any()); + then(friendRepository).should(times(2)).existsByMemberIdAndFriendId(anyLong(), anyLong()); + then(friendRequestRepository).should(times(4)).findBySenderIdAndReceiverId(anyLong(), anyLong()); + then(pagingUtil).should().getNextKey(any(), any()); } @Test From fdbaf3a0f77a87a27268108b0fa29189f106bf85 Mon Sep 17 00:00:00 2001 From: JunHyeongChoi Date: Wed, 9 Oct 2024 16:22:20 +0900 Subject: [PATCH 07/19] =?UTF-8?q?feat:=20=EC=B9=9C=EA=B5=AC=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=EB=A5=BC=20=EB=8B=A8=EC=88=98=ED=98=95=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95=20(FRIENDS=20->=20FRIEND)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../everymoment/dto/response/FriendRequestStatus.java | 2 +- .../java/com/potatocake/everymoment/service/MemberService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/potatocake/everymoment/dto/response/FriendRequestStatus.java b/src/main/java/com/potatocake/everymoment/dto/response/FriendRequestStatus.java index b7057ab..43961c7 100644 --- a/src/main/java/com/potatocake/everymoment/dto/response/FriendRequestStatus.java +++ b/src/main/java/com/potatocake/everymoment/dto/response/FriendRequestStatus.java @@ -1,5 +1,5 @@ package com.potatocake.everymoment.dto.response; public enum FriendRequestStatus { - NONE, SENT, RECEIVED, FRIENDS, SELF + NONE, SENT, RECEIVED, FRIEND, SELF } diff --git a/src/main/java/com/potatocake/everymoment/service/MemberService.java b/src/main/java/com/potatocake/everymoment/service/MemberService.java index b53c4f0..faad94e 100644 --- a/src/main/java/com/potatocake/everymoment/service/MemberService.java +++ b/src/main/java/com/potatocake/everymoment/service/MemberService.java @@ -117,7 +117,7 @@ private FriendRequestStatus getFriendRequestStatus(Long currentMemberId, Long ta } if (friendRepository.existsByMemberIdAndFriendId(currentMemberId, targetMemberId)) { - return FriendRequestStatus.FRIENDS; + return FriendRequestStatus.FRIEND; } return friendRequestRepository.findBySenderIdAndReceiverId(currentMemberId, targetMemberId) From b28ba1e99cb1ac4c3b0f6b6610eeb057e6630611 Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Thu, 10 Oct 2024 14:31:23 +0900 Subject: [PATCH 08/19] =?UTF-8?q?feat:=20=EC=9D=BC=EA=B8=B0=20=EC=B9=B4?= =?UTF-8?q?=ED=85=8C=EA=B3=A0=EB=A6=AC,=ED=8C=8C=EC=9D=BC=EC=9D=98=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5,=EC=A1=B0=ED=9A=8C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../everymoment/dto/request/FileRequest.java | 2 +- .../repository/DiaryCategoryRepository.java | 5 + .../repository/FileRepository.java | 4 + .../everymoment/service/DiaryService.java | 128 ++++++++++++++---- .../everymoment/service/FileService.java | 2 +- .../service/FriendDiaryService.java | 55 ++++---- .../everymoment/service/FriendService.java | 15 +- 7 files changed, 157 insertions(+), 54 deletions(-) diff --git a/src/main/java/com/potatocake/everymoment/dto/request/FileRequest.java b/src/main/java/com/potatocake/everymoment/dto/request/FileRequest.java index 9d22d27..8c2b494 100644 --- a/src/main/java/com/potatocake/everymoment/dto/request/FileRequest.java +++ b/src/main/java/com/potatocake/everymoment/dto/request/FileRequest.java @@ -4,6 +4,6 @@ @Getter public class FileRequest { - private String filename; + private String imageUrl; private int order; } diff --git a/src/main/java/com/potatocake/everymoment/repository/DiaryCategoryRepository.java b/src/main/java/com/potatocake/everymoment/repository/DiaryCategoryRepository.java index 2989173..2533727 100644 --- a/src/main/java/com/potatocake/everymoment/repository/DiaryCategoryRepository.java +++ b/src/main/java/com/potatocake/everymoment/repository/DiaryCategoryRepository.java @@ -1,9 +1,14 @@ package com.potatocake.everymoment.repository; +import com.potatocake.everymoment.entity.Diary; import com.potatocake.everymoment.entity.DiaryCategory; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; public interface DiaryCategoryRepository extends JpaRepository { List findByCategoryId(Long categoryId); + + List findByDiary(Diary diary); + + void deleteByDiary(Diary diary); } diff --git a/src/main/java/com/potatocake/everymoment/repository/FileRepository.java b/src/main/java/com/potatocake/everymoment/repository/FileRepository.java index 04fac6d..93db866 100644 --- a/src/main/java/com/potatocake/everymoment/repository/FileRepository.java +++ b/src/main/java/com/potatocake/everymoment/repository/FileRepository.java @@ -9,6 +9,10 @@ public interface FileRepository extends JpaRepository { List findByDiaryId(Long diaryId); + List findByDiary(Diary diary); + + File findByDiaryAndOrder(Diary diary, int order); + void deleteByDiary(Diary diary); } diff --git a/src/main/java/com/potatocake/everymoment/service/DiaryService.java b/src/main/java/com/potatocake/everymoment/service/DiaryService.java index 2e3747d..847730e 100644 --- a/src/main/java/com/potatocake/everymoment/service/DiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/DiaryService.java @@ -1,8 +1,10 @@ package com.potatocake.everymoment.service; +import com.potatocake.everymoment.dto.request.CategoryRequest; import com.potatocake.everymoment.dto.request.DiaryAutoCreateRequest; import com.potatocake.everymoment.dto.request.DiaryFilterRequest; import com.potatocake.everymoment.dto.request.DiaryManualCreateRequest; +import com.potatocake.everymoment.dto.request.FileRequest; import com.potatocake.everymoment.dto.response.CategoryResponse; import com.potatocake.everymoment.dto.response.FileResponse; import com.potatocake.everymoment.dto.response.MyDiariesResponse; @@ -12,14 +14,18 @@ import com.potatocake.everymoment.dto.response.ThumbnailResponse; import com.potatocake.everymoment.entity.Diary; import com.potatocake.everymoment.entity.DiaryCategory; +import com.potatocake.everymoment.entity.File; import com.potatocake.everymoment.entity.Member; import com.potatocake.everymoment.entity.Notification; import com.potatocake.everymoment.exception.ErrorCode; import com.potatocake.everymoment.exception.GlobalException; +import com.potatocake.everymoment.repository.CategoryRepository; import com.potatocake.everymoment.repository.DiaryCategoryRepository; import com.potatocake.everymoment.repository.DiaryRepository; +import com.potatocake.everymoment.repository.FileRepository; import com.potatocake.everymoment.repository.MemberRepository; import com.potatocake.everymoment.repository.NotificationRepository; +import com.potatocake.everymoment.security.MemberDetails; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -28,6 +34,9 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.domain.Specification; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -40,6 +49,8 @@ public class DiaryService { private final DiaryCategoryRepository diaryCategoryRepository; private final NotificationRepository notificationRepository; private final MemberRepository memberRepository; + private final CategoryRepository categoryRepository; + private final FileRepository fileRepository; // 자동 일기 저장 (LocationPoint, Name, Adress 만 저장) public NotificationResponse createDiaryAuto(Long memberId, DiaryAutoCreateRequest diaryAutoCreateRequest) { @@ -99,9 +110,36 @@ public void createDiaryManual(Long memberId, DiaryManualCreateRequest diaryManua Diary savedDiary = diaryRepository.save(diary); - Long diaryId = savedDiary.getId(); //카테고리 저장 + List categoryRequestList = diaryManualCreateRequest.getCategories(); + for (CategoryRequest categoryRequest : categoryRequestList) { + Long categoryId = categoryRequest.getCategoryId(); + + DiaryCategory diaryCategory = DiaryCategory.builder() + .diary(savedDiary) + .category(categoryRepository.findById(categoryId) + .map(category -> { + // Category가 현재 사용자의 소유인지 확인 + category.checkOwner(currentMember.getId()); + return category; + }) + .orElseThrow(() -> new GlobalException(ErrorCode.CATEGORY_NOT_FOUND))) + .build(); + + diaryCategoryRepository.save(diaryCategory); + + } //파일 저장 + List fileRequestList = diaryManualCreateRequest.getFile(); + for (FileRequest fileRequest : fileRequestList) { + File file = File.builder() + .diary(savedDiary) + .imageUrl(fileRequest.getImageUrl()) + .order(fileRequest.getOrder()) + .build(); + + fileRepository.save(file); + } } // 내 일기 전체 조회 (타임라인) @@ -118,7 +156,7 @@ public MyDiariesResponse getMyDiaries(Long memberId, DiaryFilterRequest diaryFil Specification spec = DiarySpecification.filterDiaries(diaryFilterRequest.getKeyword(), diaryFilterRequest.getEmoji(), diaryFilterRequest.getDate(), diaryFilterRequest.getFrom(), diaryFilterRequest.getUntil(), diaryFilterRequest.getBookmark()) - .and((root, query, builder) -> builder.equal(root.get("member"), currentMember)); + .and((root, query, builder) -> builder.equal(root.get("memberId"), currentMember)); diaryPage = diaryRepository.findAll(spec, PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); @@ -163,8 +201,43 @@ public MyDiaryResponse getMyDiary(Long memberId, Long diaryId) { public void updateDiary(Long memberId, Long diaryId, DiaryManualCreateRequest diaryManualCreateRequest) { Diary existingDiary = getExistDiary(memberId, diaryId); - //카테고리 업데이트 - //파일 업데이트 + // 카테고리 업데이트 + List categoryRequestList = diaryManualCreateRequest.getCategories(); + if (categoryRequestList != null && !categoryRequestList.isEmpty()) { + diaryCategoryRepository.deleteByDiary(existingDiary); + + for (CategoryRequest categoryRequest : categoryRequestList) { + Long categoryId = categoryRequest.getCategoryId(); + + DiaryCategory diaryCategory = DiaryCategory.builder() + .diary(existingDiary) + .category(categoryRepository.findById(categoryId) + .map(category -> { + category.checkOwner(memberId); + return category; + }) + .orElseThrow(() -> new GlobalException(ErrorCode.CATEGORY_NOT_FOUND))) + .build(); + + diaryCategoryRepository.save(diaryCategory); + } + } + + // 파일 업데이트 + List fileRequestList = diaryManualCreateRequest.getFile(); + if (fileRequestList != null && !fileRequestList.isEmpty()) { + fileRepository.deleteByDiary(existingDiary); + + for (FileRequest fileRequest : fileRequestList) { + File file = File.builder() + .diary(existingDiary) + .imageUrl(fileRequest.getImageUrl()) + .order(fileRequest.getOrder()) + .build(); + + fileRepository.save(file); + } + } //다이어리 업데이트 existingDiary.updateContent(diaryManualCreateRequest.getContent()); @@ -212,22 +285,24 @@ private Diary getExistDiary(Long memberId, Long diaryId) { //상세 조회시 일기DTO 변환 private MyDiaryResponse convertToMyDiaryResponseDto(Diary savedDiary) { - //카테고리 찾음 - CategoryResponse categoryResponse = CategoryResponse.builder() - .id(1L) - .categoryName("일상") - .build(); - List categoryResponseList = new ArrayList<>(); - categoryResponseList.add(categoryResponse); - - //파일 찾음 - FileResponse fileResponse = FileResponse.builder() - .id(1L) - .imageUrl("image1.url") - .order(1) - .build(); - List fileResponseList = new ArrayList<>(); - fileResponseList.add(fileResponse); + // 카테고리 찾음 + List diaryCategories = diaryCategoryRepository.findByDiary(savedDiary); + List categoryResponseList = diaryCategories.stream() + .map(diaryCategory -> CategoryResponse.builder() + .id(diaryCategory.getCategory().getId()) + .categoryName(diaryCategory.getCategory().getCategoryName()) + .build()) + .collect(Collectors.toList()); + + // 파일 찾음 + List files = fileRepository.findByDiary(savedDiary); + List fileResponseList = files.stream() + .map(file -> FileResponse.builder() + .id(file.getId()) + .imageUrl(file.getImageUrl()) + .order(file.getOrder()) + .build()) + .collect(Collectors.toList()); return MyDiaryResponse.builder() .id(savedDiary.getId()) @@ -244,11 +319,14 @@ private MyDiaryResponse convertToMyDiaryResponseDto(Diary savedDiary) { //일기 전체 불러올 때, 일기DTO 변환 private MyDiarySimpleResponse convertToMyDiarySimpleResponseDto(Diary savedDiary) { - //파일 찾음 - ThumbnailResponse thumbnailResponse = ThumbnailResponse.builder() - .id(1L) - .imageUrl("image1.url") - .build(); + File thumbnailFile = fileRepository.findByDiaryAndOrder(savedDiary, 1); + ThumbnailResponse thumbnailResponse = null; + if (thumbnailFile != null) { + thumbnailResponse = ThumbnailResponse.builder() + .id(thumbnailFile.getId()) + .imageUrl(thumbnailFile.getImageUrl()) + .build(); + } return MyDiarySimpleResponse.builder() .id(savedDiary.getId()) diff --git a/src/main/java/com/potatocake/everymoment/service/FileService.java b/src/main/java/com/potatocake/everymoment/service/FileService.java index 771129e..5ab7bb6 100644 --- a/src/main/java/com/potatocake/everymoment/service/FileService.java +++ b/src/main/java/com/potatocake/everymoment/service/FileService.java @@ -46,7 +46,7 @@ public void uploadFiles(Long diaryId, Long memberId, List files, List fileEntities = new ArrayList<>(); for (FileRequest info : infos) { - MultipartFile file = fileMap.get(info.getFilename()); + MultipartFile file = fileMap.get(info.getImageUrl()); if (file == null) { throw new GlobalException(ErrorCode.FILE_NOT_FOUND); } diff --git a/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java b/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java index 58292da..9284931 100644 --- a/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java @@ -9,12 +9,14 @@ import com.potatocake.everymoment.dto.response.ThumbnailResponse; import com.potatocake.everymoment.entity.Diary; import com.potatocake.everymoment.entity.DiaryCategory; +import com.potatocake.everymoment.entity.File; import com.potatocake.everymoment.entity.Friend; import com.potatocake.everymoment.entity.Member; import com.potatocake.everymoment.exception.ErrorCode; import com.potatocake.everymoment.exception.GlobalException; import com.potatocake.everymoment.repository.DiaryCategoryRepository; import com.potatocake.everymoment.repository.DiaryRepository; +import com.potatocake.everymoment.repository.FileRepository; import com.potatocake.everymoment.repository.FriendRepository; import com.potatocake.everymoment.repository.MemberRepository; import java.util.ArrayList; @@ -35,6 +37,7 @@ public class FriendDiaryService { private final DiaryCategoryRepository diaryCategoryRepository; private final FriendRepository friendRepository; private final MemberRepository memberRepository; + private final FileRepository fileRepository; //친구 일기 조회 public FriendDiariesResponse getFriendDiaries(Long memberId, DiaryFilterRequest diaryFilterRequest) { @@ -106,32 +109,35 @@ public FriendDiaryResponse getFriendDiary(Long memberId, Long diaryId) { if (!friendIdList.contains(diary.getMember())) { throw new GlobalException(ErrorCode.FRIEND_NOT_FOUND); } - //카테고리 찾음 - CategoryResponse categoryResponseDTO = CategoryResponse.builder() - .id(1L) - .categoryName("일상") - .build(); - List categoryResponseDTOList = new ArrayList<>(); - categoryResponseDTOList.add(categoryResponseDTO); - - //파일 찾음 - FileResponse fileResponse = FileResponse.builder() - .id(1L) - .imageUrl("image1.url") - .order(1) - .build(); - List fileResponseDTOList = new ArrayList<>(); - fileResponseDTOList.add(fileResponse); + + // 카테고리 찾음 + List diaryCategories = diaryCategoryRepository.findByDiary(diary); + List categoryResponseList = diaryCategories.stream() + .map(diaryCategory -> CategoryResponse.builder() + .id(diaryCategory.getCategory().getId()) + .categoryName(diaryCategory.getCategory().getCategoryName()) + .build()) + .collect(Collectors.toList()); + + // 파일 찾음 + List files = fileRepository.findByDiary(diary); + List fileResponseList = files.stream() + .map(file -> FileResponse.builder() + .id(file.getId()) + .imageUrl(file.getImageUrl()) + .order(file.getOrder()) + .build()) + .collect(Collectors.toList()); //like 갯수 반환 Integer likeCount = 11; FriendDiaryResponse diaryResponseDTO = FriendDiaryResponse.builder() .id(diary.getId()) - .categories(categoryResponseDTOList) + .categories(categoryResponseList) .locationName(diary.getLocationName()) .emoji(diary.getEmoji()) - .file(fileResponseDTOList) + .file(fileResponseList) .content(diary.getContent()) .likeCount(likeCount) .createAt(diary.getCreateAt()) @@ -142,11 +148,14 @@ public FriendDiaryResponse getFriendDiary(Long memberId, Long diaryId) { //친구 일기 DTO변환 private FriendDiarySimpleResponse convertToFriendDiariesResponseDTO(Diary savedDiary) { - //파일 찾음 - ThumbnailResponse thumbnailResponse = ThumbnailResponse.builder() - .id(1L) - .imageUrl("image1.url") - .build(); + File thumbnailFile = fileRepository.findByDiaryAndOrder(savedDiary, 1); + ThumbnailResponse thumbnailResponse = null; + if (thumbnailFile != null) { + thumbnailResponse = ThumbnailResponse.builder() + .id(thumbnailFile.getId()) + .imageUrl(thumbnailFile.getImageUrl()) + .build(); + } return FriendDiarySimpleResponse.builder() .id(savedDiary.getId()) diff --git a/src/main/java/com/potatocake/everymoment/service/FriendService.java b/src/main/java/com/potatocake/everymoment/service/FriendService.java index 8238bd1..d134bae 100644 --- a/src/main/java/com/potatocake/everymoment/service/FriendService.java +++ b/src/main/java/com/potatocake/everymoment/service/FriendService.java @@ -6,11 +6,13 @@ import com.potatocake.everymoment.dto.response.OneFriendDiariesResponse; import com.potatocake.everymoment.dto.response.ThumbnailResponse; import com.potatocake.everymoment.entity.Diary; +import com.potatocake.everymoment.entity.File; import com.potatocake.everymoment.entity.Friend; import com.potatocake.everymoment.entity.Member; import com.potatocake.everymoment.exception.ErrorCode; import com.potatocake.everymoment.exception.GlobalException; import com.potatocake.everymoment.repository.DiaryRepository; +import com.potatocake.everymoment.repository.FileRepository; import com.potatocake.everymoment.repository.FriendRepository; import com.potatocake.everymoment.repository.MemberRepository; import java.time.LocalDate; @@ -32,6 +34,7 @@ public class FriendService { private final FriendRepository friendRepository; private final MemberRepository memberRepository; private final DiaryRepository diaryRepository; + private final FileRepository fileRepository; //특정 친구 일기 조회 @Transactional(readOnly = true) @@ -124,10 +127,14 @@ public void toggleCloseFriend(Long memberId, Long friendId) { //다이어리 DTO 변환 private FriendDiarySimpleResponse convertToFriendDiariesResponseDTO(Diary savedDiary) { //파일 찾음 - ThumbnailResponse thumbnailResponse = ThumbnailResponse.builder() - .id(1L) - .imageUrl("image1.url") - .build(); + File thumbnailFile = fileRepository.findByDiaryAndOrder(savedDiary, 1); + ThumbnailResponse thumbnailResponse = null; + if (thumbnailFile != null) { + thumbnailResponse = ThumbnailResponse.builder() + .id(thumbnailFile.getId()) + .imageUrl(thumbnailFile.getImageUrl()) + .build(); + } return FriendDiarySimpleResponse.builder() .id(savedDiary.getId()) From c1dec83b79cd1ef9a7bfa671d46aedf4e59c3303 Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Thu, 10 Oct 2024 14:38:28 +0900 Subject: [PATCH 09/19] =?UTF-8?q?feat:=20=EC=9D=BC=EA=B8=B0=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../everymoment/controller/DiaryController.java | 14 ++++++++++++++ .../potatocake/everymoment/dto/LocationPoint.java | 2 ++ .../everymoment/service/DiaryService.java | 12 ++++++++++++ 3 files changed, 28 insertions(+) diff --git a/src/main/java/com/potatocake/everymoment/controller/DiaryController.java b/src/main/java/com/potatocake/everymoment/controller/DiaryController.java index 66047a9..65a7d95 100644 --- a/src/main/java/com/potatocake/everymoment/controller/DiaryController.java +++ b/src/main/java/com/potatocake/everymoment/controller/DiaryController.java @@ -1,5 +1,6 @@ package com.potatocake.everymoment.controller; +import com.potatocake.everymoment.dto.LocationPoint; import com.potatocake.everymoment.dto.SuccessResponse; import com.potatocake.everymoment.dto.request.CommentRequest; import com.potatocake.everymoment.dto.request.DiaryAutoCreateRequest; @@ -112,6 +113,19 @@ public ResponseEntity> getMyDiary( .body(SuccessResponse.ok(response)); } + @GetMapping("/location/{diaryId}") + public ResponseEntity> getLocation( + @AuthenticationPrincipal MemberDetails memberDetails, + @PathVariable Long diaryId) { + Long memberId = memberDetails.getId(); + + LocationPoint response = diaryService.getDiaryLocation(memberId, diaryId); + + return ResponseEntity.ok() + .body(SuccessResponse.ok(response)); + } + + //일기 수정 @PatchMapping("/{diaryId}") public ResponseEntity> updateDiary( diff --git a/src/main/java/com/potatocake/everymoment/dto/LocationPoint.java b/src/main/java/com/potatocake/everymoment/dto/LocationPoint.java index 58baa90..6210f07 100644 --- a/src/main/java/com/potatocake/everymoment/dto/LocationPoint.java +++ b/src/main/java/com/potatocake/everymoment/dto/LocationPoint.java @@ -1,10 +1,12 @@ package com.potatocake.everymoment.dto; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; @AllArgsConstructor @Getter +@Builder public class LocationPoint { private double latitude; private double longitude; diff --git a/src/main/java/com/potatocake/everymoment/service/DiaryService.java b/src/main/java/com/potatocake/everymoment/service/DiaryService.java index 847730e..c6779fa 100644 --- a/src/main/java/com/potatocake/everymoment/service/DiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/DiaryService.java @@ -1,5 +1,6 @@ package com.potatocake.everymoment.service; +import com.potatocake.everymoment.dto.LocationPoint; import com.potatocake.everymoment.dto.request.CategoryRequest; import com.potatocake.everymoment.dto.request.DiaryAutoCreateRequest; import com.potatocake.everymoment.dto.request.DiaryFilterRequest; @@ -197,6 +198,17 @@ public MyDiaryResponse getMyDiary(Long memberId, Long diaryId) { return convertToMyDiaryResponseDto(diary); } + // 내 일기 위치 조회 + public LocationPoint getDiaryLocation(Long memberId, Long diaryId) { + Diary diary = getExistDiary(memberId, diaryId); + List locations = List.of(diary.getLocationPoint().split("/")); + + return LocationPoint.builder() + .latitude(Double.parseDouble(locations.get(0))) + .longitude(Double.parseDouble(locations.get(1))) + .build(); + } + // 내 일기 수정 public void updateDiary(Long memberId, Long diaryId, DiaryManualCreateRequest diaryManualCreateRequest) { Diary existingDiary = getExistDiary(memberId, diaryId); From 599c0a6a2290df63918a10d28d44a525ddc4b4a7 Mon Sep 17 00:00:00 2001 From: JunHyeongChoi Date: Fri, 11 Oct 2024 15:14:50 +0900 Subject: [PATCH 10/19] =?UTF-8?q?feat:=20Swagger=20API=20=EB=AC=B8?= =?UTF-8?q?=EC=84=9C=EC=97=90=20=EC=84=A4=EB=AA=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CategoryController.java | 40 +++++++-- .../controller/CommentController.java | 17 +++- .../controller/DiaryController.java | 89 ++++++++++++++++--- .../controller/FileController.java | 44 +++++++-- .../controller/FriendController.java | 46 +++++++--- .../controller/FriendRequestController.java | 45 ++++++++-- .../controller/LikeController.java | 24 ++++- .../controller/MemberController.java | 61 +++++++++---- .../controller/NotificationController.java | 21 ++++- 9 files changed, 317 insertions(+), 70 deletions(-) diff --git a/src/main/java/com/potatocake/everymoment/controller/CategoryController.java b/src/main/java/com/potatocake/everymoment/controller/CategoryController.java index 36a19fa..528c594 100644 --- a/src/main/java/com/potatocake/everymoment/controller/CategoryController.java +++ b/src/main/java/com/potatocake/everymoment/controller/CategoryController.java @@ -5,6 +5,12 @@ import com.potatocake.everymoment.dto.response.CategoryResponse; import com.potatocake.everymoment.security.MemberDetails; import com.potatocake.everymoment.service.CategoryService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import java.util.List; import lombok.RequiredArgsConstructor; @@ -19,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +@Tag(name = "Categories", description = "카테고리 관리 API") @RequiredArgsConstructor @RequestMapping("/api/categories") @RestController @@ -26,8 +33,11 @@ public class CategoryController { private final CategoryService categoryService; + @Operation(summary = "카테고리 목록 조회", description = "사용자의 카테고리 목록을 조회합니다.") + @ApiResponse(responseCode = "200", description = "카테고리 목록 조회 성공", content = @Content(schema = @Schema(implementation = CategoryResponse.class))) @GetMapping public ResponseEntity> getCategories( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails) { List categories = categoryService.getCategories(memberDetails.getId()); @@ -35,28 +45,44 @@ public ResponseEntity> getCategories( .body(SuccessResponse.ok(categories)); } + @Operation(summary = "카테고리 추가", description = "새로운 카테고리를 추가합니다.") + @ApiResponse(responseCode = "200", description = "카테고리 추가 성공") @PostMapping - public ResponseEntity addCategory(@RequestBody @Valid CategoryCreateRequest request, - @AuthenticationPrincipal MemberDetails memberDetails) { + public ResponseEntity addCategory( + @Parameter(description = "카테고리 생성 정보", required = true) + @RequestBody @Valid CategoryCreateRequest request, + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails) { categoryService.addCategory(memberDetails.getId(), request); return ResponseEntity.ok() .body(SuccessResponse.ok()); } + @Operation(summary = "카테고리 수정", description = "기존 카테고리를 수정합니다.") + @ApiResponse(responseCode = "200", description = "카테고리 수정 성공") @PatchMapping("/{categoryId}") - public ResponseEntity updateCategory(@PathVariable Long categoryId, - @RequestBody @Valid CategoryCreateRequest request, - @AuthenticationPrincipal MemberDetails memberDetails) { + public ResponseEntity updateCategory( + @Parameter(description = "수정할 카테고리 ID", required = true) + @PathVariable Long categoryId, + @Parameter(description = "카테고리 수정 정보", required = true) + @RequestBody @Valid CategoryCreateRequest request, + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails) { categoryService.updateCategory(categoryId, memberDetails.getId(), request); return ResponseEntity.ok() .body(SuccessResponse.ok()); } + @Operation(summary = "카테고리 삭제", description = "카테고리를 삭제합니다.") + @ApiResponse(responseCode = "200", description = "카테고리 삭제 성공") @DeleteMapping("/{categoryId}") - public ResponseEntity deleteCategory(@PathVariable Long categoryId, - @AuthenticationPrincipal MemberDetails memberDetails) { + public ResponseEntity deleteCategory( + @Parameter(description = "삭제할 카테고리 ID", required = true) + @PathVariable Long categoryId, + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails) { categoryService.deleteCategory(categoryId, memberDetails.getId()); return ResponseEntity.ok() diff --git a/src/main/java/com/potatocake/everymoment/controller/CommentController.java b/src/main/java/com/potatocake/everymoment/controller/CommentController.java index f462e1d..61a8295 100644 --- a/src/main/java/com/potatocake/everymoment/controller/CommentController.java +++ b/src/main/java/com/potatocake/everymoment/controller/CommentController.java @@ -4,8 +4,11 @@ import com.potatocake.everymoment.dto.request.CommentRequest; import com.potatocake.everymoment.security.MemberDetails; import com.potatocake.everymoment.service.CommentService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; @@ -15,6 +18,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +@Tag(name = "Comments", description = "댓글 관리 API") @RequiredArgsConstructor @RestController @RequestMapping("/api/comments") @@ -22,11 +26,15 @@ public class CommentController { private final CommentService commentService; - //댓글 수정 + @Operation(summary = "댓글 수정", description = "기존 댓글을 수정합니다.") + @ApiResponse(responseCode = "200", description = "댓글 수정 성공") @PatchMapping("/{commentId}") public ResponseEntity> updateComment( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "수정할 댓글 ID", required = true) @PathVariable Long commentId, + @Parameter(description = "댓글 수정 정보", required = true) @RequestBody CommentRequest commentRequest) { Long memberId = memberDetails.getId(); @@ -36,10 +44,13 @@ public ResponseEntity> updateComment( .body(SuccessResponse.ok()); } - //댓글 삭제 + @Operation(summary = "댓글 삭제", description = "댓글을 삭제합니다.") + @ApiResponse(responseCode = "200", description = "댓글 삭제 성공") @DeleteMapping("/{commentId}") public ResponseEntity> deleteComment( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "삭제할 댓글 ID", required = true) @PathVariable Long commentId) { Long memberId = memberDetails.getId(); diff --git a/src/main/java/com/potatocake/everymoment/controller/DiaryController.java b/src/main/java/com/potatocake/everymoment/controller/DiaryController.java index 66047a9..8d52071 100644 --- a/src/main/java/com/potatocake/everymoment/controller/DiaryController.java +++ b/src/main/java/com/potatocake/everymoment/controller/DiaryController.java @@ -8,7 +8,6 @@ import com.potatocake.everymoment.dto.response.CommentsResponse; import com.potatocake.everymoment.dto.response.FriendDiariesResponse; import com.potatocake.everymoment.dto.response.FriendDiaryResponse; -import com.potatocake.everymoment.dto.response.MemberDetailResponse; import com.potatocake.everymoment.dto.response.MyDiariesResponse; import com.potatocake.everymoment.dto.response.MyDiaryResponse; import com.potatocake.everymoment.dto.response.NotificationResponse; @@ -16,10 +15,15 @@ import com.potatocake.everymoment.service.CommentService; import com.potatocake.everymoment.service.DiaryService; import com.potatocake.everymoment.service.FriendDiaryService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import java.time.LocalDate; import lombok.RequiredArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; @@ -32,6 +36,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +@Tag(name = "Diaries", description = "일기 관리 API") @RequiredArgsConstructor @RestController @RequestMapping("/api/diaries") @@ -41,10 +46,13 @@ public class DiaryController { private final FriendDiaryService friendDiaryService; private final CommentService commentService; - //자동 일기 작성 + @Operation(summary = "자동 일기 작성", description = "자동으로 일기를 작성합니다.") + @ApiResponse(responseCode = "200", description = "자동 일기 작성 성공", content = @Content(schema = @Schema(implementation = NotificationResponse.class))) @PostMapping("/auto") public ResponseEntity> createDiaryAuto( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "자동 일기 작성 정보", required = true) @RequestBody DiaryAutoCreateRequest diaryAutoCreateRequest) { Long memberId = memberDetails.getId(); @@ -54,10 +62,13 @@ public ResponseEntity> createDiaryAuto( .body(SuccessResponse.ok(response)); } - //수기 일기 작성 + @Operation(summary = "수기 일기 작성", description = "수동으로 일기를 작성합니다.") + @ApiResponse(responseCode = "200", description = "수기 일기 작성 성공") @PostMapping("/manual") public ResponseEntity> createDiaryManual( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "수기 일기 작성 정보", required = true) @RequestBody DiaryManualCreateRequest diaryManualCreateRequest) { Long memberId = memberDetails.getId(); diaryService.createDiaryManual(memberId, diaryManualCreateRequest); @@ -66,18 +77,29 @@ public ResponseEntity> createDiaryManual( .body(SuccessResponse.ok()); } - //내 일기 전체 조회(타임라인) + @Operation(summary = "내 일기 전체 조회", description = "사용자의 모든 일기를 조회합니다. (타임라인)") + @ApiResponse(responseCode = "200", description = "내 일기 전체 조회 성공", content = @Content(schema = @Schema(implementation = MyDiariesResponse.class))) @GetMapping("/my") public ResponseEntity> getMyDiaries( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "검색 키워드") @RequestParam(required = false) String keyword, + @Parameter(description = "이모지 필터") @RequestParam(required = false) String emoji, + @Parameter(description = "카테고리 ID") @RequestParam(required = false) Long category, + @Parameter(description = "특정 날짜") @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date, + @Parameter(description = "시작 날짜") @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate from, + @Parameter(description = "종료 날짜") @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate until, + @Parameter(description = "북마크 여부") @RequestParam(required = false) Boolean bookmark, + @Parameter(description = "페이지 키") @RequestParam(defaultValue = "0") int key, + @Parameter(description = "페이지 크기") @RequestParam(defaultValue = "10") int size ) { Long memberId = memberDetails.getId(); @@ -99,10 +121,13 @@ public ResponseEntity> getMyDiaries( .body(SuccessResponse.ok(response)); } - //내 일기 상세 조회 + @Operation(summary = "내 일기 상세 조회", description = "특정 일기의 상세 내용을 조회합니다.") + @ApiResponse(responseCode = "200", description = "내 일기 상세 조회 성공", content = @Content(schema = @Schema(implementation = MyDiaryResponse.class))) @GetMapping("/my/{diaryId}") public ResponseEntity> getMyDiary( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "조회할 일기 ID", required = true) @PathVariable Long diaryId) { Long memberId = memberDetails.getId(); @@ -112,11 +137,15 @@ public ResponseEntity> getMyDiary( .body(SuccessResponse.ok(response)); } - //일기 수정 + @Operation(summary = "일기 수정", description = "기존 일기를 수정합니다.") + @ApiResponse(responseCode = "200", description = "일기 수정 성공") @PatchMapping("/{diaryId}") public ResponseEntity> updateDiary( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "수정할 일기 ID", required = true) @PathVariable Long diaryId, + @Parameter(description = "일기 수정 정보", required = true) @RequestBody DiaryManualCreateRequest diaryManualCreateRequest) { Long memberId = memberDetails.getId(); @@ -126,10 +155,13 @@ public ResponseEntity> updateDiary( .body(SuccessResponse.ok()); } - //일기 삭제 + @Operation(summary = "일기 삭제", description = "일기를 삭제합니다.") + @ApiResponse(responseCode = "200", description = "일기 삭제 성공") @DeleteMapping("/{diaryId}") public ResponseEntity> deleteDiary( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "삭제할 일기 ID", required = true) @PathVariable Long diaryId) { Long memberId = memberDetails.getId(); @@ -139,10 +171,13 @@ public ResponseEntity> deleteDiary( .body(SuccessResponse.ok()); } - //북마크 설정 토글 + @Operation(summary = "북마크 설정 토글", description = "일기의 북마크 상태를 토글합니다.") + @ApiResponse(responseCode = "200", description = "북마크 설정 토글 성공") @PatchMapping("/{diaryId}/bookmark") public ResponseEntity> toggleBookmark( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "토글할 일기 ID", required = true) @PathVariable Long diaryId) { Long memberId = memberDetails.getId(); @@ -152,10 +187,13 @@ public ResponseEntity> toggleBookmark( .body(SuccessResponse.ok()); } - //공개 설정 토글 + @Operation(summary = "공개 설정 토글", description = "일기의 공개 상태를 토글합니다.") + @ApiResponse(responseCode = "200", description = "공개 설정 토글 성공") @PatchMapping("/{diaryId}/privacy") public ResponseEntity> togglePrivacy( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "토글할 일기 ID", required = true) @PathVariable Long diaryId) { Long memberId = memberDetails.getId(); @@ -165,18 +203,29 @@ public ResponseEntity> togglePrivacy( .body(SuccessResponse.ok()); } - //전체 친구 일기 조회 + @Operation(summary = "전체 친구 일기 조회", description = "사용자 친구들의 모든 일기를 조회합니다.") + @ApiResponse(responseCode = "200", description = "친구 일기 전체 조회 성공", content = @Content(schema = @Schema(implementation = FriendDiariesResponse.class))) @GetMapping("/friend") public ResponseEntity> getFriendDiaries( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "검색 키워드") @RequestParam(required = false) String keyword, + @Parameter(description = "이모지 필터") @RequestParam(required = false) String emoji, + @Parameter(description = "카테고리 ID") @RequestParam(required = false) Long category, + @Parameter(description = "특정 날짜") @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date, + @Parameter(description = "시작 날짜") @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate from, + @Parameter(description = "종료 날짜") @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate until, + @Parameter(description = "북마크 여부") @RequestParam(required = false) Boolean bookmark, + @Parameter(description = "페이지 키") @RequestParam(defaultValue = "0") int key, + @Parameter(description = "페이지 크기") @RequestParam(defaultValue = "10") int size ) { Long memberId = memberDetails.getId(); @@ -198,10 +247,13 @@ public ResponseEntity> getFriendDiaries( .body(SuccessResponse.ok(response)); } - //친구 일기 상제 조회 + @Operation(summary = "친구 일기 상세 조회", description = "특정 친구 일기의 상세 내용을 조회합니다.") + @ApiResponse(responseCode = "200", description = "친구 일기 상세 조회 성공", content = @Content(schema = @Schema(implementation = FriendDiaryResponse.class))) @GetMapping("/friend/{diaryId}") public ResponseEntity> getFriendDiary( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "조회할 친구 일기 ID", required = true) @PathVariable Long diaryId) { Long memberId = memberDetails.getId(); @@ -211,11 +263,15 @@ public ResponseEntity> getFriendDiary( .body(SuccessResponse.ok(response)); } - //댓글 조회 + @Operation(summary = "댓글 조회", description = "특정 일기의 댓글을 조회합니다.") + @ApiResponse(responseCode = "200", description = "댓글 조회 성공", content = @Content(schema = @Schema(implementation = CommentsResponse.class))) @GetMapping("/{diaryId}/comments") public ResponseEntity> getComments( + @Parameter(description = "댓글을 조회할 일기 ID", required = true) @PathVariable Long diaryId, + @Parameter(description = "페이지 키") @RequestParam(defaultValue = "0") int key, + @Parameter(description = "페이지 크기") @RequestParam(defaultValue = "10") int size ) { CommentsResponse response = commentService.getComments(diaryId, key, size); @@ -224,11 +280,15 @@ public ResponseEntity> getComments( .body(SuccessResponse.ok(response)); } - //댓글 작성 + @Operation(summary = "댓글 작성", description = "특정 일기에 댓글을 작성합니다.") + @ApiResponse(responseCode = "200", description = "댓글 작성 성공") @PostMapping("/{diaryId}/comments") public ResponseEntity> createComment( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "댓글을 작성할 일기 ID", required = true) @PathVariable Long diaryId, + @Parameter(description = "댓글 작성 정보", required = true) @RequestBody CommentRequest commentRequest) { Long memberId = memberDetails.getId(); @@ -237,4 +297,5 @@ public ResponseEntity> createComment( return ResponseEntity.ok() .body(SuccessResponse.ok()); } + } diff --git a/src/main/java/com/potatocake/everymoment/controller/FileController.java b/src/main/java/com/potatocake/everymoment/controller/FileController.java index e17bd70..cb62468 100644 --- a/src/main/java/com/potatocake/everymoment/controller/FileController.java +++ b/src/main/java/com/potatocake/everymoment/controller/FileController.java @@ -5,6 +5,12 @@ import com.potatocake.everymoment.dto.response.FileResponse; import com.potatocake.everymoment.security.MemberDetails; import com.potatocake.everymoment.service.FileService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; @@ -19,6 +25,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; +@Tag(name = "Files", description = "파일 관리 API") @RequiredArgsConstructor @RequestMapping("/api/diaries/{diaryId}/files") @RestController @@ -26,30 +33,49 @@ public class FileController { private final FileService fileService; + @Operation(summary = "파일 목록 조회", description = "특정 일기의 파일 목록을 조회합니다.") + @ApiResponse(responseCode = "200", description = "파일 목록 조회 성공", content = @Content(schema = @Schema(implementation = FileResponse.class))) @GetMapping - public ResponseEntity> getFiles(@PathVariable Long diaryId) { + public ResponseEntity> getFiles(@Parameter(description = "조회할 일기 ID", required = true) + @PathVariable Long diaryId) { List files = fileService.getFiles(diaryId); return ResponseEntity.ok() .body(SuccessResponse.ok(files)); } + @Operation(summary = "파일 업로드", description = "특정 일기에 파일을 업로드합니다.") + @ApiResponse(responseCode = "200", description = "파일 업로드 성공") @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public ResponseEntity uploadFiles(@PathVariable Long diaryId, - @AuthenticationPrincipal MemberDetails memberDetails, - @RequestPart List files, - @RequestPart List info) { + public ResponseEntity uploadFiles( + @Parameter(description = "파일을 업로드할 일기 ID", required = true) + @PathVariable Long diaryId, + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "업로드할 파일 목록", required = true) + @RequestPart List files, + @Parameter(description = "일기에 보일 파일 이름과 순서", required = true) + @RequestPart List info + ) { fileService.uploadFiles(diaryId, memberDetails.getId(), files, info); return ResponseEntity.ok() .body(SuccessResponse.ok()); } + @Operation(summary = "파일 수정", description = "특정 일기의 파일을 수정합니다.") + @ApiResponse(responseCode = "200", description = "파일 수정 성공") @PutMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public ResponseEntity updateFiles(@PathVariable Long diaryId, - @AuthenticationPrincipal MemberDetails memberDetails, - @RequestPart List files, - @RequestPart List info) { + public ResponseEntity updateFiles( + @Parameter(description = "파일을 수정할 일기 ID", required = true) + @PathVariable Long diaryId, + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "수정할 파일 목록", required = true) + @RequestPart List files, + @Parameter(description = "일기에 보일 파일 이름과 순서", required = true) + @RequestPart List info + ) { fileService.updateFiles(diaryId, memberDetails.getId(), files, info); return ResponseEntity.ok() diff --git a/src/main/java/com/potatocake/everymoment/controller/FriendController.java b/src/main/java/com/potatocake/everymoment/controller/FriendController.java index 79772c9..c1644dc 100644 --- a/src/main/java/com/potatocake/everymoment/controller/FriendController.java +++ b/src/main/java/com/potatocake/everymoment/controller/FriendController.java @@ -3,12 +3,16 @@ import com.potatocake.everymoment.dto.SuccessResponse; import com.potatocake.everymoment.dto.response.FriendListResponse; import com.potatocake.everymoment.dto.response.OneFriendDiariesResponse; -import com.potatocake.everymoment.entity.Member; import com.potatocake.everymoment.security.MemberDetails; import com.potatocake.everymoment.service.FriendService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import java.time.LocalDate; import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; @@ -19,6 +23,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +@Tag(name = "Friends", description = "친구 관리 API") @RestController @RequestMapping("/api/friends") public class FriendController { @@ -28,14 +33,21 @@ public FriendController(FriendService friendService) { this.friendService = friendService; } - //특정 친구 일기 전체 조회 + @Operation(summary = "특정 친구 일기 전체 조회", description = "특정 친구의 모든 일기를 조회합니다.") + @ApiResponse(responseCode = "200", description = "친구 일기 조회 성공", content = @Content(schema = @Schema(implementation = OneFriendDiariesResponse.class))) @GetMapping("/{friendId}/diaries") public ResponseEntity> getOneFriendDiaries( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "조회할 친구 ID", required = true) @PathVariable Long friendId, + @Parameter(description = "조회할 날짜") @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date, + @Parameter(description = "페이지 키") @RequestParam(defaultValue = "0") int key, - @RequestParam(defaultValue = "10") int size) { + @Parameter(description = "페이지 크기") + @RequestParam(defaultValue = "10") int size + ) { Long memberId = memberDetails.getId(); OneFriendDiariesResponse response = friendService.OneFriendDiariesResponse(memberId, friendId, date, key, size); @@ -44,13 +56,19 @@ public ResponseEntity> getOneFriendDia .body(SuccessResponse.ok(response)); } - //내 친구 목록 조회 + @Operation(summary = "내 친구 목록 조회", description = "사용자의 친구 목록을 조회합니다.") + @ApiResponse(responseCode = "200", description = "친구 목록 조회 성공", content = @Content(schema = @Schema(implementation = FriendListResponse.class))) @GetMapping("/friends") public ResponseEntity> getFriendList( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "검색할 친구 닉네임") @RequestParam(required = false) String nickname, + @Parameter(description = "페이지 키") @RequestParam(defaultValue = "0") int key, - @RequestParam(defaultValue = "10") int size) { + @Parameter(description = "페이지 크기") + @RequestParam(defaultValue = "10") int size + ) { Long memberId = memberDetails.getId(); FriendListResponse response = friendService.getFriendList(memberId, nickname, key, size); @@ -59,11 +77,15 @@ public ResponseEntity> getFriendList( .body(SuccessResponse.ok(response)); } - //내 친구 삭제 + @Operation(summary = "친구 삭제", description = "특정 친구를 삭제합니다.") + @ApiResponse(responseCode = "200", description = "친구 삭제 성공") @DeleteMapping("/{friendId}") public ResponseEntity> deleteFriend( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, - @PathVariable Long friendId) { + @Parameter(description = "삭제할 친구 ID", required = true) + @PathVariable Long friendId + ) { Long memberId = memberDetails.getId(); friendService.deleteFriend(memberId, friendId); @@ -72,11 +94,15 @@ public ResponseEntity> deleteFriend( .body(SuccessResponse.ok()); } - //친한 친구 설정 + @Operation(summary = "친한 친구 설정", description = "특정 친구를 친한 친구로 설정하거나 해제합니다.") + @ApiResponse(responseCode = "200", description = "친한 친구 설정 성공") @PatchMapping("/{friendId}/bookmark") public ResponseEntity> toggleCloseFriend( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, - @PathVariable Long friendId) { + @Parameter(description = "설정할 친구 ID", required = true) + @PathVariable Long friendId + ) { Long memberId = memberDetails.getId(); friendService.toggleCloseFriend(memberId, friendId); diff --git a/src/main/java/com/potatocake/everymoment/controller/FriendRequestController.java b/src/main/java/com/potatocake/everymoment/controller/FriendRequestController.java index f960fbc..407aafa 100644 --- a/src/main/java/com/potatocake/everymoment/controller/FriendRequestController.java +++ b/src/main/java/com/potatocake/everymoment/controller/FriendRequestController.java @@ -6,6 +6,12 @@ import com.potatocake.everymoment.exception.GlobalException; import com.potatocake.everymoment.security.MemberDetails; import com.potatocake.everymoment.service.FriendRequestService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; @@ -16,17 +22,24 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +@Tag(name = "Friend Requests", description = "친구 요청 관리 API") @RequiredArgsConstructor @RestController public class FriendRequestController { private final FriendRequestService friendRequestService; + @Operation(summary = "친구 요청 목록 조회", description = "사용자에게 온 친구 요청 목록을 조회합니다.") + @ApiResponse(responseCode = "200", description = "친구 요청 목록 조회 성공", content = @Content(schema = @Schema(implementation = FriendRequestPageRequest.class))) @GetMapping("/api/friend-requests") public ResponseEntity> getFriendRequests( + @Parameter(description = "페이지 키") @RequestParam(required = false) Long key, + @Parameter(description = "페이지 크기") @RequestParam(defaultValue = "10") int size, - @AuthenticationPrincipal MemberDetails memberDetails) { + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails + ) { FriendRequestPageRequest friendRequests = friendRequestService.getFriendRequests(key, size, memberDetails.getId()); @@ -34,9 +47,15 @@ public ResponseEntity> getFriendReques .body(SuccessResponse.ok(friendRequests)); } + @Operation(summary = "친구 요청 보내기", description = "특정 사용자에게 친구 요청을 보냅니다.") + @ApiResponse(responseCode = "200", description = "친구 요청 전송 성공") @PostMapping("/api/members/{memberId}/friend-requests") - public ResponseEntity sendFriendRequest(@PathVariable Long memberId, - @AuthenticationPrincipal MemberDetails memberDetails) { + public ResponseEntity sendFriendRequest( + @Parameter(description = "친구 요청을 받을 사용자 ID", required = true) + @PathVariable Long memberId, + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails + ) { if (memberDetails.getId().equals(memberId)) { throw new GlobalException(ErrorCode.SELF_FRIEND_REQUEST); } @@ -47,18 +66,30 @@ public ResponseEntity sendFriendRequest(@PathVariable Long memb .body(SuccessResponse.ok()); } + @Operation(summary = "친구 요청 수락", description = "받은 친구 요청을 수락합니다.") + @ApiResponse(responseCode = "200", description = "친구 요청 수락 성공") @PostMapping("/api/friend-requests/{requestId}/accept") - public ResponseEntity acceptFriendRequest(@PathVariable Long requestId, - @AuthenticationPrincipal MemberDetails memberDetails) { + public ResponseEntity acceptFriendRequest( + @Parameter(description = "수락할 친구 요청 ID", required = true) + @PathVariable Long requestId, + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails + ) { friendRequestService.acceptFriendRequest(requestId, memberDetails.getId()); return ResponseEntity.ok() .body(SuccessResponse.ok()); } + @Operation(summary = "친구 요청 거절", description = "받은 친구 요청을 거절합니다.") + @ApiResponse(responseCode = "200", description = "친구 요청 거절 성공") @DeleteMapping("/api/friend-requests/{requestId}/reject") - public ResponseEntity rejectFriendRequest(@PathVariable Long requestId, - @AuthenticationPrincipal MemberDetails memberDetails) { + public ResponseEntity rejectFriendRequest( + @Parameter(description = "거절할 친구 요청 ID", required = true) + @PathVariable Long requestId, + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails + ) { friendRequestService.rejectFriendRequest(requestId, memberDetails.getId()); return ResponseEntity.ok() diff --git a/src/main/java/com/potatocake/everymoment/controller/LikeController.java b/src/main/java/com/potatocake/everymoment/controller/LikeController.java index 229497e..c6729b3 100644 --- a/src/main/java/com/potatocake/everymoment/controller/LikeController.java +++ b/src/main/java/com/potatocake/everymoment/controller/LikeController.java @@ -4,6 +4,12 @@ import com.potatocake.everymoment.dto.response.LikeCountResponse; import com.potatocake.everymoment.security.MemberDetails; import com.potatocake.everymoment.service.LikeService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; @@ -13,6 +19,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +@Tag(name = "Likes", description = "좋아요 관리 API") @RequiredArgsConstructor @RequestMapping("/api/diaries/{diaryId}/likes") @RestController @@ -20,17 +27,28 @@ public class LikeController { private final LikeService likeService; + @Operation(summary = "좋아요 수 조회", description = "특정 일기의 좋아요 수를 조회합니다.") + @ApiResponse(responseCode = "200", description = "좋아요 수 조회 성공", content = @Content(schema = @Schema(implementation = LikeCountResponse.class))) @GetMapping - public ResponseEntity> getLikeCount(@PathVariable Long diaryId) { + public ResponseEntity> getLikeCount( + @Parameter(description = "조회할 일기 ID", required = true) + @PathVariable Long diaryId + ) { LikeCountResponse likeCount = likeService.getLikeCount(diaryId); return ResponseEntity.ok() .body(SuccessResponse.ok(likeCount)); } + @Operation(summary = "좋아요 토글", description = "특정 일기에 대한 좋아요를 추가하거나 취소합니다.") + @ApiResponse(responseCode = "200", description = "좋아요 토글 성공") @PostMapping - public ResponseEntity toggleLike(@PathVariable Long diaryId, - @AuthenticationPrincipal MemberDetails memberDetails) { + public ResponseEntity toggleLike( + @Parameter(description = "토글할 일기 ID", required = true) + @PathVariable Long diaryId, + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails + ) { likeService.toggleLike(memberDetails.getId(), diaryId); return ResponseEntity.ok() diff --git a/src/main/java/com/potatocake/everymoment/controller/MemberController.java b/src/main/java/com/potatocake/everymoment/controller/MemberController.java index b94885f..894c9d6 100644 --- a/src/main/java/com/potatocake/everymoment/controller/MemberController.java +++ b/src/main/java/com/potatocake/everymoment/controller/MemberController.java @@ -11,6 +11,11 @@ import com.potatocake.everymoment.security.MemberDetails; import com.potatocake.everymoment.service.MemberService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -26,6 +31,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; +@Tag(name = "Members", description = "회원 관리 API") @RequiredArgsConstructor @RequestMapping("/api/members") @RestController @@ -34,53 +40,73 @@ public class MemberController { private final MemberService memberService; @Operation(summary = "로그인", description = "회원 번호와 닉네임으로 로그인합니다.") -// @ApiResponses(value = { -// @ApiResponse(responseCode = "200", description = "로그인 성공", -// content = @Content(schema = @Schema(implementation = JwtResponse.class))), -// @ApiResponse(responseCode = "401", description = "로그인 실패", -// content = @Content(schema = @Schema(implementation = ErrorResponse.class))) -// }) + @ApiResponse(responseCode = "200", description = "로그인 성공", content = @Content(schema = @Schema(implementation = JwtResponse.class))) @PostMapping("/login") - public ResponseEntity> login(@RequestBody MemberLoginRequest request) { + public ResponseEntity> login( + @Parameter(description = "로그인 정보", required = true) + @RequestBody MemberLoginRequest request + ) { // 이 메서드는 실제로 호출되지 않습니다. Swagger 문서화를 위해서만 존재합니다. // 실제 로그인 처리는 LoginFilter에서 이루어집니다. return ResponseEntity.ok(SuccessResponse.ok(JwtResponse.of("token"))); } + @Operation(summary = "회원 검색", description = "닉네임으로 회원을 검색합니다.") + @ApiResponse(responseCode = "200", description = "회원 검색 성공", content = @Content(schema = @Schema(implementation = MemberSearchResponse.class))) @GetMapping public ResponseEntity> searchMembers( + @Parameter(description = "검색할 닉네임") @RequestParam(required = false) String nickname, + @Parameter(description = "페이지 키") @RequestParam(required = false) Long key, + @Parameter(description = "페이지 크기") @RequestParam(defaultValue = "10") int size, - @AuthenticationPrincipal MemberDetails memberDetails) { - + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails + ) { MemberSearchResponse response = memberService.searchMembers(nickname, key, size, memberDetails.getId()); return ResponseEntity.ok() .body(SuccessResponse.ok(response)); } + @Operation(summary = "내 정보 조회", description = "로그인한 회원의 상세 정보를 조회합니다.") + @ApiResponse(responseCode = "200", description = "내 정보 조회 성공", content = @Content(schema = @Schema(implementation = MemberDetailResponse.class))) @GetMapping("/me") public ResponseEntity> myInfo( - @AuthenticationPrincipal MemberDetails memberDetails) { + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails + ) { MemberDetailResponse response = memberService.getMyInfo(memberDetails.getId()); return ResponseEntity.ok() .body(SuccessResponse.ok(response)); } + @Operation(summary = "회원 정보 조회", description = "특정 회원의 정보를 조회합니다.") + @ApiResponse(responseCode = "200", description = "회원 정보 조회 성공", content = @Content(schema = @Schema(implementation = MemberMyResponse.class))) @GetMapping("/{memberId}") - public ResponseEntity> memberInfo(@PathVariable Long memberId) { + public ResponseEntity> memberInfo( + @Parameter(description = "조회할 회원 ID", required = true) + @PathVariable Long memberId + ) { MemberMyResponse response = memberService.getMemberInfo(memberId); return ResponseEntity.ok() .body(SuccessResponse.ok(response)); } + @Operation(summary = "회원 정보 수정", description = "로그인한 회원의 프로필 이미지와 닉네임을 수정합니다.") + @ApiResponse(responseCode = "200", description = "회원 정보 수정 성공") @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - public ResponseEntity> updateMemberInfo(@AuthenticationPrincipal MemberDetails memberDetails, - @RequestParam(required = false) MultipartFile profileImage, - @RequestParam(required = false) String nickname) { + public ResponseEntity> updateMemberInfo( + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "프로필 이미지 파일") + @RequestParam(required = false) MultipartFile profileImage, + @Parameter(description = "새로운 닉네임") + @RequestParam(required = false) String nickname + ) { validateProfileUpdate(profileImage, nickname); memberService.updateMemberInfo(memberDetails.getId(), profileImage, nickname); @@ -89,8 +115,13 @@ public ResponseEntity> updateMemberInfo(@AuthenticationPri .body(SuccessResponse.ok()); } + @Operation(summary = "회원 탈퇴", description = "로그인한 회원의 계정을 삭제합니다.") + @ApiResponse(responseCode = "200", description = "회원 탈퇴 성공") @DeleteMapping - public ResponseEntity> deleteMember(@AuthenticationPrincipal MemberDetails memberDetails) { + public ResponseEntity> deleteMember( + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails + ) { memberService.deleteMember(memberDetails.getId()); return ResponseEntity.ok() diff --git a/src/main/java/com/potatocake/everymoment/controller/NotificationController.java b/src/main/java/com/potatocake/everymoment/controller/NotificationController.java index e8ce3d9..ccd186f 100644 --- a/src/main/java/com/potatocake/everymoment/controller/NotificationController.java +++ b/src/main/java/com/potatocake/everymoment/controller/NotificationController.java @@ -4,6 +4,12 @@ import com.potatocake.everymoment.dto.response.NotificationListResponse; import com.potatocake.everymoment.security.MemberDetails; import com.potatocake.everymoment.service.NotificationService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -14,6 +20,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +@Tag(name = "Notifications", description = "알림 관리 API") @RequiredArgsConstructor @RestController @RequestMapping("/api/notifications") @@ -21,9 +28,13 @@ public class NotificationController { private final NotificationService notificationService; + @Operation(summary = "알림 목록 조회", description = "로그인한 사용자의 알림 목록을 조회합니다.") + @ApiResponse(responseCode = "200", description = "알림 목록 조회 성공", content = @Content(schema = @Schema(implementation = NotificationListResponse.class))) @GetMapping public ResponseEntity>> getNotifications( - @AuthenticationPrincipal MemberDetails memberDetails){ + @Parameter(description = "인증된 사용자 정보", hidden = true) + @AuthenticationPrincipal MemberDetails memberDetails + ) { Long memberId = memberDetails.getId(); List response = notificationService.getNotifications(memberId); @@ -32,10 +43,15 @@ public ResponseEntity>> getNotifi .body(SuccessResponse.ok(response)); } + @Operation(summary = "알림 읽음 처리", description = "특정 알림을 읽음 처리합니다.") + @ApiResponse(responseCode = "200", description = "알림 읽음 처리 성공") @PatchMapping("/{notificationId}") public ResponseEntity> updateNotification( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, - @PathVariable Long notificationId) { + @Parameter(description = "읽음 처리할 알림 ID", required = true) + @PathVariable Long notificationId + ) { Long memberId = memberDetails.getId(); notificationService.updateNotification(memberId, notificationId); @@ -43,4 +59,5 @@ public ResponseEntity> updateNotification( return ResponseEntity.ok() .body(SuccessResponse.ok()); } + } From 8c05137cfbf3b6f5a02d327235441856f307e2d1 Mon Sep 17 00:00:00 2001 From: JunHyeongChoi Date: Fri, 11 Oct 2024 15:20:51 +0900 Subject: [PATCH 11/19] =?UTF-8?q?feat:=20=ED=95=9C=EA=B5=AD=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=EB=8C=80=EB=A1=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/master_weekly_cicd.yml | 2 +- src/main/resources/application-prod.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/master_weekly_cicd.yml b/.github/workflows/master_weekly_cicd.yml index 1c4ad9e..1e8ae40 100644 --- a/.github/workflows/master_weekly_cicd.yml +++ b/.github/workflows/master_weekly_cicd.yml @@ -56,4 +56,4 @@ jobs: script: | cd ./project sudo fuser -k -n tcp 8080 || true - nohup java -jar app.jar > ./output.log 2>&1 & + nohup java -Duser.timezone=Asia/Seoul -jar app.jar > ./output.log 2>&1 & diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 3fc83ae..62053b5 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -8,6 +8,8 @@ spring: properties: hibernate: format_sql: true + jdbc: + time_zone: Asia/Seoul show-sql: true h2: From 534ea587f25994f5994f0d1f262cc237dd65b92c Mon Sep 17 00:00:00 2001 From: JunHyeongChoi Date: Fri, 11 Oct 2024 16:09:02 +0900 Subject: [PATCH 12/19] =?UTF-8?q?feat:=20RDS=20(MySQL)=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/master_weekly_cicd.yml | 3 +++ .github/workflows/pr_weekly_ci.yml | 3 +++ src/main/resources/application-prod.yml | 10 +++++----- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/master_weekly_cicd.yml b/.github/workflows/master_weekly_cicd.yml index 1e8ae40..3a04a2c 100644 --- a/.github/workflows/master_weekly_cicd.yml +++ b/.github/workflows/master_weekly_cicd.yml @@ -25,6 +25,9 @@ jobs: with: files: ./src/main/resources/application-prod.yml env: + spring.datasource.url: ${{ secrets.RDS_URL }} + spring.datasource.username: ${{ secrets.RDS_USERNAME }} + spring.datasource.password: ${{ secrets.RDS_PASSWORD }} aws.s3.bucket: ${{ secrets.AWS_S3_BUCKET }} aws.s3.accessKey: ${{ secrets.AWS_S3_ACCESS_KEY }} aws.s3.secretKey: ${{ secrets.AWS_S3_SECRET_KEY }} diff --git a/.github/workflows/pr_weekly_ci.yml b/.github/workflows/pr_weekly_ci.yml index d00ebe0..0acf431 100644 --- a/.github/workflows/pr_weekly_ci.yml +++ b/.github/workflows/pr_weekly_ci.yml @@ -28,6 +28,9 @@ jobs: with: files: ./src/main/resources/application-prod.yml env: + spring.datasource.url: ${{ secrets.RDS_URL }} + spring.datasource.username: ${{ secrets.RDS_USERNAME }} + spring.datasource.password: ${{ secrets.RDS_PASSWORD }} aws.s3.bucket: ${{ secrets.AWS_S3_BUCKET }} aws.s3.accessKey: ${{ secrets.AWS_S3_ACCESS_KEY }} aws.s3.secretKey: ${{ secrets.AWS_S3_SECRET_KEY }} diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 62053b5..3bf77ba 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -1,16 +1,16 @@ spring: datasource: - url: jdbc:h2:mem:testdb - username: sa - password: + url: ${RDS_URL} + username: ${RDS_USERNAME} + password: ${RDS_PASSWORD} jpa: properties: hibernate: - format_sql: true jdbc: time_zone: Asia/Seoul - show-sql: true + hibernate: + ddl-auto: update h2: console: From 3aa56d3e1d604c39cc62b24ce4df966898c0c4d9 Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Fri, 11 Oct 2024 16:19:04 +0900 Subject: [PATCH 13/19] =?UTF-8?q?feat:=20=EC=9D=BC=EA=B8=B0=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=EB=A7=81=20=EC=A1=B0=EA=B1=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/DiaryController.java | 10 +++-- .../dto/request/DiaryFilterRequest.java | 23 +++++++++- .../everymoment/service/DiaryService.java | 43 +++++++----------- .../service/DiarySpecification.java | 17 +++++-- .../service/FriendDiaryService.java | 45 +++++++------------ .../everymoment/service/FriendService.java | 2 +- 6 files changed, 73 insertions(+), 67 deletions(-) diff --git a/src/main/java/com/potatocake/everymoment/controller/DiaryController.java b/src/main/java/com/potatocake/everymoment/controller/DiaryController.java index 65a7d95..3d3e598 100644 --- a/src/main/java/com/potatocake/everymoment/controller/DiaryController.java +++ b/src/main/java/com/potatocake/everymoment/controller/DiaryController.java @@ -73,7 +73,7 @@ public ResponseEntity> getMyDiaries( @AuthenticationPrincipal MemberDetails memberDetails, @RequestParam(required = false) String keyword, @RequestParam(required = false) String emoji, - @RequestParam(required = false) Long category, + @RequestParam(required = false) String category, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate from, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate until, @@ -82,6 +82,7 @@ public ResponseEntity> getMyDiaries( @RequestParam(defaultValue = "10") int size ) { Long memberId = memberDetails.getId(); + DiaryFilterRequest diaryFilterRequest = DiaryFilterRequest.builder() .keyword(keyword) .emoji(emoji) @@ -89,7 +90,7 @@ public ResponseEntity> getMyDiaries( .date(date) .from(from) .until(until) - .bookmark(bookmark) + .isBookmark(bookmark) .key(key) .size(size) .build(); @@ -185,7 +186,7 @@ public ResponseEntity> getFriendDiaries( @AuthenticationPrincipal MemberDetails memberDetails, @RequestParam(required = false) String keyword, @RequestParam(required = false) String emoji, - @RequestParam(required = false) Long category, + @RequestParam(required = false) String category, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate from, @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate until, @@ -194,6 +195,7 @@ public ResponseEntity> getFriendDiaries( @RequestParam(defaultValue = "10") int size ) { Long memberId = memberDetails.getId(); + DiaryFilterRequest diaryFilterRequest = DiaryFilterRequest.builder() .keyword(keyword) .emoji(emoji) @@ -201,7 +203,7 @@ public ResponseEntity> getFriendDiaries( .date(date) .from(from) .until(until) - .bookmark(bookmark) + .isBookmark(bookmark) .key(key) .size(size) .build(); diff --git a/src/main/java/com/potatocake/everymoment/dto/request/DiaryFilterRequest.java b/src/main/java/com/potatocake/everymoment/dto/request/DiaryFilterRequest.java index 7675f25..720a07e 100644 --- a/src/main/java/com/potatocake/everymoment/dto/request/DiaryFilterRequest.java +++ b/src/main/java/com/potatocake/everymoment/dto/request/DiaryFilterRequest.java @@ -1,6 +1,10 @@ package com.potatocake.everymoment.dto.request; import java.time.LocalDate; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; import lombok.Builder; import lombok.Getter; @@ -9,11 +13,26 @@ public class DiaryFilterRequest { private String keyword; private String emoji; - private Long category; + private String category; private LocalDate date; private LocalDate from; private LocalDate until; - private Boolean bookmark; + private Boolean isBookmark; private int key; private int size; + + public List getEmojis() { + return (emoji != null && !emoji.isEmpty()) + ? Arrays.asList(emoji.split(",")) + : Collections.emptyList(); + } + + public List getCategories() { + return (category != null && !category.isEmpty()) + ? Arrays.stream(category.split(",")) + .map(Long::parseLong) + .collect(Collectors.toList()) + : Collections.emptyList(); + } + } diff --git a/src/main/java/com/potatocake/everymoment/service/DiaryService.java b/src/main/java/com/potatocake/everymoment/service/DiaryService.java index c6779fa..b32e6a4 100644 --- a/src/main/java/com/potatocake/everymoment/service/DiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/DiaryService.java @@ -146,38 +146,27 @@ public void createDiaryManual(Long memberId, DiaryManualCreateRequest diaryManua // 내 일기 전체 조회 (타임라인) @Transactional(readOnly = true) public MyDiariesResponse getMyDiaries(Long memberId, DiaryFilterRequest diaryFilterRequest) { - //member 가져옴 + // member 가져옴 Member currentMember = memberRepository.findById(memberId) .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); Page diaryPage; - if (diaryFilterRequest.getCategory() == null) { - // category가 null인 경우 - Specification spec = DiarySpecification.filterDiaries(diaryFilterRequest.getKeyword(), - diaryFilterRequest.getEmoji(), diaryFilterRequest.getDate(), diaryFilterRequest.getFrom(), - diaryFilterRequest.getUntil(), diaryFilterRequest.getBookmark()) - .and((root, query, builder) -> builder.equal(root.get("memberId"), currentMember)); - - diaryPage = diaryRepository.findAll(spec, - PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); - } else { - // category가 있는 경우 - DiaryCategory에서 category 같은 것 찾음 - List diaryCategoryList = diaryCategoryRepository.findByCategoryId( - diaryFilterRequest.getCategory()); - - // Diary 중에 memberId같은 것 가져옴 - List DiaryIdList = diaryCategoryList.stream() - .filter(diaryCategory -> diaryCategory.getDiary().getMember() - .equals(currentMember)) // memberId가 일치하는 경우 필터링 - .map(diaryCategory -> diaryCategory.getDiary().getId()) - .collect(Collectors.toList()); - - // 가져온 DiaryId로 일기 찾음 - Specification spec = (root, query, builder) -> root.get("id").in(DiaryIdList); - diaryPage = diaryRepository.findAll(spec, - PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); - } + List categoryIds = diaryFilterRequest.getCategories(); + List emojis = diaryFilterRequest.getEmojis(); + + Specification spec = DiarySpecification.filterDiaries( + diaryFilterRequest.getKeyword(), + emojis, + categoryIds, + diaryFilterRequest.getDate(), + diaryFilterRequest.getFrom(), + diaryFilterRequest.getUntil(), + diaryFilterRequest.getIsBookmark()) + .and((root, query, builder) -> builder.equal(root.get("member"), currentMember)); + + diaryPage = diaryRepository.findAll(spec, PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); + List diaryDTOs = diaryPage.getContent().stream() .map(this::convertToMyDiarySimpleResponseDto) diff --git a/src/main/java/com/potatocake/everymoment/service/DiarySpecification.java b/src/main/java/com/potatocake/everymoment/service/DiarySpecification.java index 7554307..3a9826d 100644 --- a/src/main/java/com/potatocake/everymoment/service/DiarySpecification.java +++ b/src/main/java/com/potatocake/everymoment/service/DiarySpecification.java @@ -2,28 +2,37 @@ import com.potatocake.everymoment.entity.Diary; +import com.potatocake.everymoment.entity.DiaryCategory; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Join; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; +import java.util.List; import org.springframework.data.jpa.domain.Specification; import java.time.LocalDate; public class DiarySpecification { - public static Specification filterDiaries(String keyword, String emoji, LocalDate date, LocalDate from, LocalDate until, Boolean isBookmark) { + public static Specification filterDiaries( + String keyword, List emojis, List categories, + LocalDate date, LocalDate from, LocalDate until, Boolean isBookmark) { return (Root root, CriteriaQuery query, CriteriaBuilder builder) -> { Predicate predicate = builder.conjunction(); if (keyword != null) { predicate = builder.and(predicate, builder.like(root.get("content"), "%" + keyword + "%")); } - if (emoji != null) { - predicate = builder.and(predicate, builder.equal(root.get("emoji"), emoji)); + if (emojis != null && !emojis.isEmpty()) { + predicate = builder.and(predicate, root.get("emoji").in(emojis)); + } + + if (categories != null && !categories.isEmpty()) { + Join diaryCategoryJoin = root.join("diaryCategories"); + predicate = builder.and(predicate, diaryCategoryJoin.get("category").get("id").in(categories)); } - // 날짜 필터링 (null일 경우 오늘 날짜로 기본값 설정) LocalDate filterDate = (date != null) ? date : LocalDate.now(); predicate = builder.and(predicate, builder.equal(root.get("createAt").as(LocalDate.class), filterDate)); diff --git a/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java b/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java index 9284931..2df6e97 100644 --- a/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java @@ -51,32 +51,21 @@ public FriendDiariesResponse getFriendDiaries(Long memberId, DiaryFilterRequest Page diaryPage; - if (diaryFilterRequest.getCategory() == null) { - // category가 null인 경우 - Specification spec = DiarySpecification.filterDiaries(diaryFilterRequest.getKeyword(), - diaryFilterRequest.getEmoji(), diaryFilterRequest.getDate(), diaryFilterRequest.getFrom(), - diaryFilterRequest.getUntil(), diaryFilterRequest.getBookmark()) - .and((root, query, builder) -> root.get("member").in(friendIdList)); // memberIds 목록에서 검색 - - diaryPage = diaryRepository.findAll(spec, - PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); - } else { - // category가 있는 경우 - DiaryCategory에서 category 같은 것 찾음 - List diaryCategories = diaryCategoryRepository.findByCategoryId( - diaryFilterRequest.getCategory()); - - // Diary중에 memberId같은 것 가져옴 - List filteredDiaryIds = diaryCategories.stream() - .filter(diaryCategory -> friendIdList.contains( - diaryCategory.getDiary().getMember())) // memberIds 목록에서 필터링 - .map(diaryCategory -> diaryCategory.getDiary().getId()) - .collect(Collectors.toList()); - - // 가져온 diaryId로 일기 찾음 - Specification spec = (root, query, builder) -> root.get("id").in(filteredDiaryIds); - diaryPage = diaryRepository.findAll(spec, - PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); - } + // 카테고리와 이모지가 여러 개 전달될 수 있으므로 이를 리스트로 변환 + List categoryIds = diaryFilterRequest.getCategories(); + List emojis = diaryFilterRequest.getEmojis(); + + Specification spec = DiarySpecification.filterDiaries( + diaryFilterRequest.getKeyword(), + emojis, + categoryIds, + diaryFilterRequest.getDate(), + diaryFilterRequest.getFrom(), + diaryFilterRequest.getUntil(), + diaryFilterRequest.getIsBookmark()) + .and((root, query, builder) -> root.get("member").in(friendIdList)); + + diaryPage = diaryRepository.findAll(spec, PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); List friendDiarySimpleResponseList = diaryPage.getContent().stream() .map(this::convertToFriendDiariesResponseDTO) @@ -84,12 +73,10 @@ public FriendDiariesResponse getFriendDiaries(Long memberId, DiaryFilterRequest Integer nextPage = diaryPage.hasNext() ? diaryFilterRequest.getKey() + 1 : null; - FriendDiariesResponse friendDiariesResponse = FriendDiariesResponse.builder() + return FriendDiariesResponse.builder() .diaries(friendDiarySimpleResponseList) .next(nextPage) .build(); - - return friendDiariesResponse; } // 친구 다이어리 하나 조회 diff --git a/src/main/java/com/potatocake/everymoment/service/FriendService.java b/src/main/java/com/potatocake/everymoment/service/FriendService.java index d134bae..fe2e327 100644 --- a/src/main/java/com/potatocake/everymoment/service/FriendService.java +++ b/src/main/java/com/potatocake/everymoment/service/FriendService.java @@ -52,7 +52,7 @@ public OneFriendDiariesResponse OneFriendDiariesResponse(Long memberid, Long fri Pageable pageable = PageRequest.of(key, size); Page diaries = diaryRepository.findAll( - DiarySpecification.filterDiaries(null, null, date, null, null, null) + DiarySpecification.filterDiaries(null, null, null, date, null, null, null) .and((root, query, builder) -> builder.equal(root.get("member").get("id"), friendId)), pageable); From 6e9832c0693925c5691dcd2cea7c12f73186a171 Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Tue, 15 Oct 2024 23:53:50 +0900 Subject: [PATCH 14/19] =?UTF-8?q?chore:=20GIS=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 2d19b2c..8b03ef5 100644 --- a/build.gradle +++ b/build.gradle @@ -38,6 +38,7 @@ dependencies { compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' + implementation 'org.hibernate:hibernate-spatial:6.6.1.Final' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' From fca491f1954989d3cd0286b0b2557bb9049796b9 Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Tue, 15 Oct 2024 23:55:16 +0900 Subject: [PATCH 15/19] =?UTF-8?q?refactor:=20=EC=9C=84=EA=B2=BD=EB=8F=84?= =?UTF-8?q?=20Point=ED=83=80=EC=9E=85=EC=9C=BC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../everymoment/config/GeometryConfig.java | 14 ++++++++ .../controller/DiaryController.java | 9 ++++- .../everymoment/dto/LocationPoint.java | 5 --- .../potatocake/everymoment/entity/Diary.java | 9 ++--- .../everymoment/service/DiaryService.java | 36 +++++++++++++++---- 5 files changed, 56 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/potatocake/everymoment/config/GeometryConfig.java diff --git a/src/main/java/com/potatocake/everymoment/config/GeometryConfig.java b/src/main/java/com/potatocake/everymoment/config/GeometryConfig.java new file mode 100644 index 0000000..d9b6d39 --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/config/GeometryConfig.java @@ -0,0 +1,14 @@ +package com.potatocake.everymoment.config; + +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.PrecisionModel; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class GeometryConfig { + @Bean + public GeometryFactory geometryFactory() { + return new GeometryFactory(new PrecisionModel(), 4326); + } +} diff --git a/src/main/java/com/potatocake/everymoment/controller/DiaryController.java b/src/main/java/com/potatocake/everymoment/controller/DiaryController.java index 3d3e598..bf0f7d2 100644 --- a/src/main/java/com/potatocake/everymoment/controller/DiaryController.java +++ b/src/main/java/com/potatocake/everymoment/controller/DiaryController.java @@ -17,6 +17,9 @@ import com.potatocake.everymoment.service.CommentService; import com.potatocake.everymoment.service.DiaryService; import com.potatocake.everymoment.service.FriendDiaryService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import java.time.LocalDate; import lombok.RequiredArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; @@ -114,9 +117,13 @@ public ResponseEntity> getMyDiary( .body(SuccessResponse.ok(response)); } - @GetMapping("/location/{diaryId}") + @Operation(summary = "특정 일기 위경도 조회", description = "특정 일기에 있는 위경도를 조회합니다.") + @ApiResponse(responseCode = "200", description = "위경도 조회 성공") + @GetMapping("/{diaryId}/location") public ResponseEntity> getLocation( + @Parameter(description = "인증된 사용자 정보", hidden = true) @AuthenticationPrincipal MemberDetails memberDetails, + @Parameter(description = "조회할 일기 ID", required = true) @PathVariable Long diaryId) { Long memberId = memberDetails.getId(); diff --git a/src/main/java/com/potatocake/everymoment/dto/LocationPoint.java b/src/main/java/com/potatocake/everymoment/dto/LocationPoint.java index 6210f07..a9ab297 100644 --- a/src/main/java/com/potatocake/everymoment/dto/LocationPoint.java +++ b/src/main/java/com/potatocake/everymoment/dto/LocationPoint.java @@ -10,9 +10,4 @@ public class LocationPoint { private double latitude; private double longitude; - - @Override - public String toString() { - return latitude + "/" + longitude; - } } diff --git a/src/main/java/com/potatocake/everymoment/entity/Diary.java b/src/main/java/com/potatocake/everymoment/entity/Diary.java index a8abca1..50dc3fa 100644 --- a/src/main/java/com/potatocake/everymoment/entity/Diary.java +++ b/src/main/java/com/potatocake/everymoment/entity/Diary.java @@ -1,5 +1,6 @@ package com.potatocake.everymoment.entity; +import com.potatocake.everymoment.dto.LocationPoint; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -14,6 +15,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import org.locationtech.jts.geom.Point; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -32,9 +34,8 @@ public class Diary extends BaseTimeEntity { @Lob private String content; - //point는 mysql연결 뒤에 - @Column(length = 250, nullable = false) - private String locationPoint; // Java에서는 문자열로 처리 + @Column(nullable = false) + private Point locationPoint; @Column(length = 50, nullable = false) private String locationName; @@ -59,7 +60,7 @@ public void updateContent(String content) { } } - public void updateLocationPoint(String locationPoint) { + public void updateLocationPoint(Point locationPoint) { if (locationPoint != null) { this.locationPoint = locationPoint; } diff --git a/src/main/java/com/potatocake/everymoment/service/DiaryService.java b/src/main/java/com/potatocake/everymoment/service/DiaryService.java index b32e6a4..b44f006 100644 --- a/src/main/java/com/potatocake/everymoment/service/DiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/DiaryService.java @@ -32,6 +32,8 @@ import java.util.Objects; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.GeometryFactory; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.domain.Specification; @@ -40,6 +42,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.locationtech.jts.geom.Point; @RequiredArgsConstructor @Transactional @@ -52,6 +55,7 @@ public class DiaryService { private final MemberRepository memberRepository; private final CategoryRepository categoryRepository; private final FileRepository fileRepository; + private final GeometryFactory geometryFactory; // 자동 일기 저장 (LocationPoint, Name, Adress 만 저장) public NotificationResponse createDiaryAuto(Long memberId, DiaryAutoCreateRequest diaryAutoCreateRequest) { @@ -59,9 +63,14 @@ public NotificationResponse createDiaryAuto(Long memberId, DiaryAutoCreateReques Member currentMember = memberRepository.findById(memberId) .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); + double longitude = diaryAutoCreateRequest.getLocationPoint().getLongitude(); + double latitude = diaryAutoCreateRequest.getLocationPoint().getLatitude(); + + Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude)); + Diary diary = Diary.builder() .member(currentMember) - .locationPoint(diaryAutoCreateRequest.getLocationPoint().toString()) + .locationPoint(point) .locationName(diaryAutoCreateRequest.getLocationName()) .address(diaryAutoCreateRequest.getAddress()) .build(); @@ -98,10 +107,16 @@ public void createDiaryManual(Long memberId, DiaryManualCreateRequest diaryManua Member currentMember = memberRepository.findById(memberId) .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); + + double longitude = diaryManualCreateRequest.getLocationPoint().getLongitude(); + double latitude = diaryManualCreateRequest.getLocationPoint().getLatitude(); + + Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude)); + Diary diary = Diary.builder() .member(currentMember) .content(diaryManualCreateRequest.getContent()) - .locationPoint(diaryManualCreateRequest.getLocationPoint().toString()) + .locationPoint(point) .locationName(diaryManualCreateRequest.getLocationName()) .address(diaryManualCreateRequest.getAddress()) .emoji(diaryManualCreateRequest.getEmoji()) @@ -190,11 +205,11 @@ public MyDiaryResponse getMyDiary(Long memberId, Long diaryId) { // 내 일기 위치 조회 public LocationPoint getDiaryLocation(Long memberId, Long diaryId) { Diary diary = getExistDiary(memberId, diaryId); - List locations = List.of(diary.getLocationPoint().split("/")); + Point point = diary.getLocationPoint(); return LocationPoint.builder() - .latitude(Double.parseDouble(locations.get(0))) - .longitude(Double.parseDouble(locations.get(1))) + .latitude(point.getX()) + .longitude(point.getY()) .build(); } @@ -240,10 +255,17 @@ public void updateDiary(Long memberId, Long diaryId, DiaryManualCreateRequest di } } + if (diaryManualCreateRequest.getLocationPoint() != null) { + double longitude = diaryManualCreateRequest.getLocationPoint().getLongitude(); + double latitude = diaryManualCreateRequest.getLocationPoint().getLatitude(); + + Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude)); + + existingDiary.updateLocationPoint(point); + } + //다이어리 업데이트 existingDiary.updateContent(diaryManualCreateRequest.getContent()); - existingDiary.updateLocationPoint(diaryManualCreateRequest.getLocationPoint() != null - ? diaryManualCreateRequest.getLocationPoint().toString() : null); existingDiary.updateLocationName(diaryManualCreateRequest.getLocationName()); existingDiary.updateAddress(diaryManualCreateRequest.getAddress()); existingDiary.updateEmoji(diaryManualCreateRequest.getEmoji()); From 51b64fafce2c9eb34a72a8dbd7b06686be768c78 Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Wed, 16 Oct 2024 00:00:55 +0900 Subject: [PATCH 16/19] =?UTF-8?q?refactor:=20like=EB=8D=94=EB=AF=B8=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=EC=97=90=EC=84=9C=20=EC=8B=A4?= =?UTF-8?q?=EC=A0=9C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../everymoment/dto/response/FriendDiaryResponse.java | 2 +- .../everymoment/service/FriendDiaryService.java | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/potatocake/everymoment/dto/response/FriendDiaryResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/FriendDiaryResponse.java index b442af3..6372ed5 100644 --- a/src/main/java/com/potatocake/everymoment/dto/response/FriendDiaryResponse.java +++ b/src/main/java/com/potatocake/everymoment/dto/response/FriendDiaryResponse.java @@ -18,6 +18,6 @@ public class FriendDiaryResponse { private String emoji; private List file; private String content; - private Integer likeCount; + private LikeCountResponse likeCount; private LocalDateTime createAt; } diff --git a/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java b/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java index 2df6e97..0a5792f 100644 --- a/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java @@ -6,6 +6,7 @@ import com.potatocake.everymoment.dto.response.FriendDiariesResponse; import com.potatocake.everymoment.dto.response.FriendDiaryResponse; import com.potatocake.everymoment.dto.response.FriendDiarySimpleResponse; +import com.potatocake.everymoment.dto.response.LikeCountResponse; import com.potatocake.everymoment.dto.response.ThumbnailResponse; import com.potatocake.everymoment.entity.Diary; import com.potatocake.everymoment.entity.DiaryCategory; @@ -18,6 +19,7 @@ import com.potatocake.everymoment.repository.DiaryRepository; import com.potatocake.everymoment.repository.FileRepository; import com.potatocake.everymoment.repository.FriendRepository; +import com.potatocake.everymoment.repository.LikeRepository; import com.potatocake.everymoment.repository.MemberRepository; import java.util.ArrayList; import java.util.List; @@ -38,6 +40,7 @@ public class FriendDiaryService { private final FriendRepository friendRepository; private final MemberRepository memberRepository; private final FileRepository fileRepository; + private final LikeRepository likeRepository; //친구 일기 조회 public FriendDiariesResponse getFriendDiaries(Long memberId, DiaryFilterRequest diaryFilterRequest) { @@ -117,7 +120,11 @@ public FriendDiaryResponse getFriendDiary(Long memberId, Long diaryId) { .collect(Collectors.toList()); //like 갯수 반환 - Integer likeCount = 11; + Long likeCount = likeRepository.countByDiary(diary); + + LikeCountResponse count = LikeCountResponse.builder() + .likeCount(likeCount) + .build(); FriendDiaryResponse diaryResponseDTO = FriendDiaryResponse.builder() .id(diary.getId()) @@ -126,7 +133,7 @@ public FriendDiaryResponse getFriendDiary(Long memberId, Long diaryId) { .emoji(diary.getEmoji()) .file(fileResponseList) .content(diary.getContent()) - .likeCount(likeCount) + .likeCount(count) .createAt(diary.getCreateAt()) .build(); From 3199f019d9473bccd6ad3c7bea0b1e5e5c0b1d76 Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Wed, 16 Oct 2024 00:08:40 +0900 Subject: [PATCH 17/19] =?UTF-8?q?feat:=20=EB=8B=A4=EC=9D=B4=EC=96=B4?= =?UTF-8?q?=EB=A6=AC=20=EC=A0=80=EC=9E=A5,=20=EC=A1=B0=ED=9A=8C=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=ED=8C=8C=EC=9D=BC=20=EB=B6=80=EB=B6=84=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - thumbnail은 남겨둠 --- .../dto/response/FriendDiaryResponse.java | 1 - .../dto/response/MyDiaryResponse.java | 1 - .../everymoment/service/DiaryService.java | 38 ------------------- .../service/FriendDiaryService.java | 11 ------ 4 files changed, 51 deletions(-) diff --git a/src/main/java/com/potatocake/everymoment/dto/response/FriendDiaryResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/FriendDiaryResponse.java index 6372ed5..47ea8da 100644 --- a/src/main/java/com/potatocake/everymoment/dto/response/FriendDiaryResponse.java +++ b/src/main/java/com/potatocake/everymoment/dto/response/FriendDiaryResponse.java @@ -16,7 +16,6 @@ public class FriendDiaryResponse { private List categories; private String locationName; private String emoji; - private List file; private String content; private LikeCountResponse likeCount; private LocalDateTime createAt; diff --git a/src/main/java/com/potatocake/everymoment/dto/response/MyDiaryResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/MyDiaryResponse.java index 2b98a84..a92bc41 100644 --- a/src/main/java/com/potatocake/everymoment/dto/response/MyDiaryResponse.java +++ b/src/main/java/com/potatocake/everymoment/dto/response/MyDiaryResponse.java @@ -14,7 +14,6 @@ public class MyDiaryResponse { private String locationName; private boolean isBookmark; private String emoji; - private List file; private String content; private LocalDateTime createAt; } diff --git a/src/main/java/com/potatocake/everymoment/service/DiaryService.java b/src/main/java/com/potatocake/everymoment/service/DiaryService.java index b44f006..7b9218b 100644 --- a/src/main/java/com/potatocake/everymoment/service/DiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/DiaryService.java @@ -145,17 +145,6 @@ public void createDiaryManual(Long memberId, DiaryManualCreateRequest diaryManua diaryCategoryRepository.save(diaryCategory); } - //파일 저장 - List fileRequestList = diaryManualCreateRequest.getFile(); - for (FileRequest fileRequest : fileRequestList) { - File file = File.builder() - .diary(savedDiary) - .imageUrl(fileRequest.getImageUrl()) - .order(fileRequest.getOrder()) - .build(); - - fileRepository.save(file); - } } // 내 일기 전체 조회 (타임라인) @@ -239,22 +228,6 @@ public void updateDiary(Long memberId, Long diaryId, DiaryManualCreateRequest di } } - // 파일 업데이트 - List fileRequestList = diaryManualCreateRequest.getFile(); - if (fileRequestList != null && !fileRequestList.isEmpty()) { - fileRepository.deleteByDiary(existingDiary); - - for (FileRequest fileRequest : fileRequestList) { - File file = File.builder() - .diary(existingDiary) - .imageUrl(fileRequest.getImageUrl()) - .order(fileRequest.getOrder()) - .build(); - - fileRepository.save(file); - } - } - if (diaryManualCreateRequest.getLocationPoint() != null) { double longitude = diaryManualCreateRequest.getLocationPoint().getLongitude(); double latitude = diaryManualCreateRequest.getLocationPoint().getLatitude(); @@ -317,16 +290,6 @@ private MyDiaryResponse convertToMyDiaryResponseDto(Diary savedDiary) { .build()) .collect(Collectors.toList()); - // 파일 찾음 - List files = fileRepository.findByDiary(savedDiary); - List fileResponseList = files.stream() - .map(file -> FileResponse.builder() - .id(file.getId()) - .imageUrl(file.getImageUrl()) - .order(file.getOrder()) - .build()) - .collect(Collectors.toList()); - return MyDiaryResponse.builder() .id(savedDiary.getId()) .categories(categoryResponseList) @@ -334,7 +297,6 @@ private MyDiaryResponse convertToMyDiaryResponseDto(Diary savedDiary) { .locationName(savedDiary.getLocationName()) .isBookmark(savedDiary.isBookmark()) .emoji(savedDiary.getEmoji()) - .file(fileResponseList) .content(savedDiary.getContent()) .createAt(savedDiary.getCreateAt()) .build(); diff --git a/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java b/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java index 0a5792f..bb5d207 100644 --- a/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java @@ -109,16 +109,6 @@ public FriendDiaryResponse getFriendDiary(Long memberId, Long diaryId) { .build()) .collect(Collectors.toList()); - // 파일 찾음 - List files = fileRepository.findByDiary(diary); - List fileResponseList = files.stream() - .map(file -> FileResponse.builder() - .id(file.getId()) - .imageUrl(file.getImageUrl()) - .order(file.getOrder()) - .build()) - .collect(Collectors.toList()); - //like 갯수 반환 Long likeCount = likeRepository.countByDiary(diary); @@ -131,7 +121,6 @@ public FriendDiaryResponse getFriendDiary(Long memberId, Long diaryId) { .categories(categoryResponseList) .locationName(diary.getLocationName()) .emoji(diary.getEmoji()) - .file(fileResponseList) .content(diary.getContent()) .likeCount(count) .createAt(diary.getCreateAt()) From 2b9808ce423a54a4e9d0962d8760c4079796edcc Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Wed, 16 Oct 2024 00:12:21 +0900 Subject: [PATCH 18/19] =?UTF-8?q?refactor:=20imageUrl=20->=20filename?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=8B=A4=EC=8B=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/potatocake/everymoment/dto/request/FileRequest.java | 2 +- .../java/com/potatocake/everymoment/service/FileService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/potatocake/everymoment/dto/request/FileRequest.java b/src/main/java/com/potatocake/everymoment/dto/request/FileRequest.java index 8c2b494..9d22d27 100644 --- a/src/main/java/com/potatocake/everymoment/dto/request/FileRequest.java +++ b/src/main/java/com/potatocake/everymoment/dto/request/FileRequest.java @@ -4,6 +4,6 @@ @Getter public class FileRequest { - private String imageUrl; + private String filename; private int order; } diff --git a/src/main/java/com/potatocake/everymoment/service/FileService.java b/src/main/java/com/potatocake/everymoment/service/FileService.java index 5ab7bb6..771129e 100644 --- a/src/main/java/com/potatocake/everymoment/service/FileService.java +++ b/src/main/java/com/potatocake/everymoment/service/FileService.java @@ -46,7 +46,7 @@ public void uploadFiles(Long diaryId, Long memberId, List files, List fileEntities = new ArrayList<>(); for (FileRequest info : infos) { - MultipartFile file = fileMap.get(info.getImageUrl()); + MultipartFile file = fileMap.get(info.getFilename()); if (file == null) { throw new GlobalException(ErrorCode.FILE_NOT_FOUND); } From 69fe67facaa502a9811a2aa9abc35bd2df12ae5a Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Wed, 16 Oct 2024 00:33:30 +0900 Subject: [PATCH 19/19] style: --- .../everymoment/controller/CommentController.java | 1 - .../everymoment/controller/DiaryController.java | 2 -- .../everymoment/controller/FriendController.java | 2 -- .../java/com/potatocake/everymoment/entity/Diary.java | 1 - .../potatocake/everymoment/exception/ErrorResponse.java | 6 +++--- .../potatocake/everymoment/security/MemberDetails.java | 2 +- .../everymoment/security/filter/LoginFilter.java | 2 +- .../potatocake/everymoment/service/CommentService.java | 3 --- .../com/potatocake/everymoment/service/DiaryService.java | 9 +-------- .../everymoment/service/FriendDiaryService.java | 2 -- 10 files changed, 6 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/potatocake/everymoment/controller/CommentController.java b/src/main/java/com/potatocake/everymoment/controller/CommentController.java index f462e1d..cb86c22 100644 --- a/src/main/java/com/potatocake/everymoment/controller/CommentController.java +++ b/src/main/java/com/potatocake/everymoment/controller/CommentController.java @@ -5,7 +5,6 @@ import com.potatocake.everymoment.security.MemberDetails; import com.potatocake.everymoment.service.CommentService; import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; diff --git a/src/main/java/com/potatocake/everymoment/controller/DiaryController.java b/src/main/java/com/potatocake/everymoment/controller/DiaryController.java index bf0f7d2..48bfedf 100644 --- a/src/main/java/com/potatocake/everymoment/controller/DiaryController.java +++ b/src/main/java/com/potatocake/everymoment/controller/DiaryController.java @@ -9,7 +9,6 @@ import com.potatocake.everymoment.dto.response.CommentsResponse; import com.potatocake.everymoment.dto.response.FriendDiariesResponse; import com.potatocake.everymoment.dto.response.FriendDiaryResponse; -import com.potatocake.everymoment.dto.response.MemberDetailResponse; import com.potatocake.everymoment.dto.response.MyDiariesResponse; import com.potatocake.everymoment.dto.response.MyDiaryResponse; import com.potatocake.everymoment.dto.response.NotificationResponse; @@ -23,7 +22,6 @@ import java.time.LocalDate; import lombok.RequiredArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; diff --git a/src/main/java/com/potatocake/everymoment/controller/FriendController.java b/src/main/java/com/potatocake/everymoment/controller/FriendController.java index 79772c9..35c80ba 100644 --- a/src/main/java/com/potatocake/everymoment/controller/FriendController.java +++ b/src/main/java/com/potatocake/everymoment/controller/FriendController.java @@ -3,12 +3,10 @@ import com.potatocake.everymoment.dto.SuccessResponse; import com.potatocake.everymoment.dto.response.FriendListResponse; import com.potatocake.everymoment.dto.response.OneFriendDiariesResponse; -import com.potatocake.everymoment.entity.Member; import com.potatocake.everymoment.security.MemberDetails; import com.potatocake.everymoment.service.FriendService; import java.time.LocalDate; import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.DeleteMapping; diff --git a/src/main/java/com/potatocake/everymoment/entity/Diary.java b/src/main/java/com/potatocake/everymoment/entity/Diary.java index 50dc3fa..23d7583 100644 --- a/src/main/java/com/potatocake/everymoment/entity/Diary.java +++ b/src/main/java/com/potatocake/everymoment/entity/Diary.java @@ -1,6 +1,5 @@ package com.potatocake.everymoment.entity; -import com.potatocake.everymoment.dto.LocationPoint; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; diff --git a/src/main/java/com/potatocake/everymoment/exception/ErrorResponse.java b/src/main/java/com/potatocake/everymoment/exception/ErrorResponse.java index 54b7db8..0358ebf 100644 --- a/src/main/java/com/potatocake/everymoment/exception/ErrorResponse.java +++ b/src/main/java/com/potatocake/everymoment/exception/ErrorResponse.java @@ -11,9 +11,9 @@ @JsonInclude(Include.NON_NULL) public class ErrorResponse { - private int code; - private String message; - private Map validation; + private final int code; + private final String message; + private final Map validation; @Builder public ErrorResponse(int code, String message) { diff --git a/src/main/java/com/potatocake/everymoment/security/MemberDetails.java b/src/main/java/com/potatocake/everymoment/security/MemberDetails.java index b4fedca..3a5dd31 100644 --- a/src/main/java/com/potatocake/everymoment/security/MemberDetails.java +++ b/src/main/java/com/potatocake/everymoment/security/MemberDetails.java @@ -17,7 +17,7 @@ public class MemberDetails implements UserDetails { private final Member member; - private PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); @Override public Collection getAuthorities() { diff --git a/src/main/java/com/potatocake/everymoment/security/filter/LoginFilter.java b/src/main/java/com/potatocake/everymoment/security/filter/LoginFilter.java index 53a2951..63c7d5a 100644 --- a/src/main/java/com/potatocake/everymoment/security/filter/LoginFilter.java +++ b/src/main/java/com/potatocake/everymoment/security/filter/LoginFilter.java @@ -33,7 +33,7 @@ public class LoginFilter extends UsernamePasswordAuthenticationFilter { private final AuthenticationManager authenticationManager; private final MemberRepository memberRepository; - private boolean postOnly = true; + private final boolean postOnly = true; public LoginFilter(String filterProcessesUrl, ObjectMapper objectMapper, JwtUtil jwtUtil, MemberRepository memberRepository, AuthenticationManager authenticationManager) { diff --git a/src/main/java/com/potatocake/everymoment/service/CommentService.java b/src/main/java/com/potatocake/everymoment/service/CommentService.java index b0d7663..085ed0c 100644 --- a/src/main/java/com/potatocake/everymoment/service/CommentService.java +++ b/src/main/java/com/potatocake/everymoment/service/CommentService.java @@ -12,7 +12,6 @@ import com.potatocake.everymoment.repository.CommentRepository; import com.potatocake.everymoment.repository.DiaryRepository; import com.potatocake.everymoment.repository.MemberRepository; -import com.potatocake.everymoment.security.MemberDetails; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -20,8 +19,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/com/potatocake/everymoment/service/DiaryService.java b/src/main/java/com/potatocake/everymoment/service/DiaryService.java index 7b9218b..8293530 100644 --- a/src/main/java/com/potatocake/everymoment/service/DiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/DiaryService.java @@ -5,9 +5,7 @@ import com.potatocake.everymoment.dto.request.DiaryAutoCreateRequest; import com.potatocake.everymoment.dto.request.DiaryFilterRequest; import com.potatocake.everymoment.dto.request.DiaryManualCreateRequest; -import com.potatocake.everymoment.dto.request.FileRequest; import com.potatocake.everymoment.dto.response.CategoryResponse; -import com.potatocake.everymoment.dto.response.FileResponse; import com.potatocake.everymoment.dto.response.MyDiariesResponse; import com.potatocake.everymoment.dto.response.MyDiaryResponse; import com.potatocake.everymoment.dto.response.MyDiarySimpleResponse; @@ -26,23 +24,18 @@ import com.potatocake.everymoment.repository.FileRepository; import com.potatocake.everymoment.repository.MemberRepository; import com.potatocake.everymoment.repository.NotificationRepository; -import com.potatocake.everymoment.security.MemberDetails; -import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.Point; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.domain.Specification; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.locationtech.jts.geom.Point; @RequiredArgsConstructor @Transactional diff --git a/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java b/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java index bb5d207..fb83595 100644 --- a/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java @@ -2,7 +2,6 @@ import com.potatocake.everymoment.dto.request.DiaryFilterRequest; import com.potatocake.everymoment.dto.response.CategoryResponse; -import com.potatocake.everymoment.dto.response.FileResponse; import com.potatocake.everymoment.dto.response.FriendDiariesResponse; import com.potatocake.everymoment.dto.response.FriendDiaryResponse; import com.potatocake.everymoment.dto.response.FriendDiarySimpleResponse; @@ -21,7 +20,6 @@ import com.potatocake.everymoment.repository.FriendRepository; import com.potatocake.everymoment.repository.LikeRepository; import com.potatocake.everymoment.repository.MemberRepository; -import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor;