From 7109400437bff8ce1be844a88b0f63b8b53032c5 Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Mon, 23 Sep 2024 21:27:06 +0900 Subject: [PATCH 1/7] =?UTF-8?q?refactor:=203=EC=A3=BC=EC=B0=A8=20=ED=94=BC?= =?UTF-8?q?=EB=93=9C=EB=B0=B1=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -서비스에 트렌젝션 추가 - 엔티티에서 업데이트하도록 변경 - 모든 다이어리 가져오기 쿼리DTO추가 - 오류코드 변경 - 레포지토리 어노테이션 제거 - RequiredArgsConstructor추가 - DTO 이름 변경 --- .../controller/DiaryController.java | 42 ++++-- ...quest.java => DiaryAutoCreateRequest.java} | 2 +- .../dto/request/DiaryFilterRequest.java | 19 +++ ...est.java => DiaryManualCreateRequest.java} | 2 +- .../dto/response/MyDiariesResponse.java | 2 +- .../potatocake/everymoment/entity/Diary.java | 46 ++++++ .../everymoment/exception/ErrorCode.java | 3 + .../repository/DiaryCategoryRepository.java | 5 +- .../repository/DiaryRepository.java | 2 - .../repository/NotificationRepository.java | 2 - .../everymoment/service/DiaryService.java | 139 +++++++----------- 11 files changed, 152 insertions(+), 112 deletions(-) rename src/main/java/com/potatocake/everymoment/dto/request/{DiaryAutoRequest.java => DiaryAutoCreateRequest.java} (86%) create mode 100644 src/main/java/com/potatocake/everymoment/dto/request/DiaryFilterRequest.java rename src/main/java/com/potatocake/everymoment/dto/request/{DiaryManualRequest.java => DiaryManualCreateRequest.java} (91%) diff --git a/src/main/java/com/potatocake/everymoment/controller/DiaryController.java b/src/main/java/com/potatocake/everymoment/controller/DiaryController.java index e2c961c..2dd59e2 100644 --- a/src/main/java/com/potatocake/everymoment/controller/DiaryController.java +++ b/src/main/java/com/potatocake/everymoment/controller/DiaryController.java @@ -1,13 +1,15 @@ package com.potatocake.everymoment.controller; import com.potatocake.everymoment.dto.SuccessResponse; -import com.potatocake.everymoment.dto.request.DiaryAutoRequest; -import com.potatocake.everymoment.dto.request.DiaryManualRequest; +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.response.MyDiariesResponse; import com.potatocake.everymoment.dto.response.MyDiaryResponse; import com.potatocake.everymoment.dto.response.NotificationResponse; import com.potatocake.everymoment.service.DiaryService; import java.time.LocalDate; +import lombok.RequiredArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -21,21 +23,18 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +@RequiredArgsConstructor @RestController -@RequestMapping("api/diaries") +@RequestMapping("/api/diaries") public class DiaryController { private final DiaryService diaryService; - public DiaryController(DiaryService diaryService) { - this.diaryService = diaryService; - } - //자동 일기 작성 @PostMapping("/auto") public ResponseEntity> createDiaryAuto( - @RequestBody DiaryAutoRequest diaryAutoRequest) { - NotificationResponse notificationResponse = diaryService.createDiaryAuto(diaryAutoRequest); + @RequestBody DiaryAutoCreateRequest diaryAutoCreateRequest) { + NotificationResponse notificationResponse = diaryService.createDiaryAuto(diaryAutoCreateRequest); SuccessResponse response = SuccessResponse.builder() .code(HttpStatus.OK.value()) .message("success") @@ -48,8 +47,8 @@ public ResponseEntity> createDiaryAuto( //수기 일기 작성 @PostMapping("/manual") public ResponseEntity> createDiaryManual( - @RequestBody DiaryManualRequest diaryManualRequest) { - diaryService.createDiaryManual(diaryManualRequest); + @RequestBody DiaryManualCreateRequest diaryManualCreateRequest) { + diaryService.createDiaryManual(diaryManualCreateRequest); SuccessResponse response = SuccessResponse.builder() .code(HttpStatus.OK.value()) .message("success") @@ -60,7 +59,7 @@ public ResponseEntity> createDiaryManual( } //내 일기 전체 조회(타임라인) - @GetMapping("my") + @GetMapping("/my") public ResponseEntity> getMyDiaries( @RequestParam(required = false) String keyword, @RequestParam(required = false) String emoji, @@ -72,8 +71,19 @@ public ResponseEntity> getMyDiaries( @RequestParam(defaultValue = "0") int key, @RequestParam(defaultValue = "10") int size ) { - MyDiariesResponse myDiariesResponse = diaryService.getMyDiaries(keyword, emoji, category, date, from, until, - bookmark, key, size); + DiaryFilterRequest diaryFilterRequest = DiaryFilterRequest.builder() + .keyword(keyword) + .emoji(emoji) + .category(category) + .date(date) + .from(from) + .until(until) + .bookmark(bookmark) + .key(key) + .size(size) + .build(); + + MyDiariesResponse myDiariesResponse = diaryService.getMyDiaries(diaryFilterRequest); SuccessResponse response = SuccessResponse.builder() .code(HttpStatus.OK.value()) .message("success") @@ -99,8 +109,8 @@ public ResponseEntity> getMyDiary(@PathVariable //일기 수정 @PatchMapping("/{id}") public ResponseEntity> updateDiary(@PathVariable Long id, - @RequestBody DiaryManualRequest diaryManualRequest) { - diaryService.updateDiary(id, diaryManualRequest); + @RequestBody DiaryManualCreateRequest diaryManualCreateRequest) { + diaryService.updateDiary(id, diaryManualCreateRequest); SuccessResponse response = SuccessResponse.builder() .code(HttpStatus.OK.value()) .message("success") diff --git a/src/main/java/com/potatocake/everymoment/dto/request/DiaryAutoRequest.java b/src/main/java/com/potatocake/everymoment/dto/request/DiaryAutoCreateRequest.java similarity index 86% rename from src/main/java/com/potatocake/everymoment/dto/request/DiaryAutoRequest.java rename to src/main/java/com/potatocake/everymoment/dto/request/DiaryAutoCreateRequest.java index 095cbf4..d1dbede 100644 --- a/src/main/java/com/potatocake/everymoment/dto/request/DiaryAutoRequest.java +++ b/src/main/java/com/potatocake/everymoment/dto/request/DiaryAutoCreateRequest.java @@ -4,7 +4,7 @@ import lombok.Getter; @Getter -public class DiaryAutoRequest { +public class DiaryAutoCreateRequest { private LocationPoint locationPoint; private String locationName; private String address; diff --git a/src/main/java/com/potatocake/everymoment/dto/request/DiaryFilterRequest.java b/src/main/java/com/potatocake/everymoment/dto/request/DiaryFilterRequest.java new file mode 100644 index 0000000..7675f25 --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/dto/request/DiaryFilterRequest.java @@ -0,0 +1,19 @@ +package com.potatocake.everymoment.dto.request; + +import java.time.LocalDate; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class DiaryFilterRequest { + private String keyword; + private String emoji; + private Long category; + private LocalDate date; + private LocalDate from; + private LocalDate until; + private Boolean bookmark; + private int key; + private int size; +} diff --git a/src/main/java/com/potatocake/everymoment/dto/request/DiaryManualRequest.java b/src/main/java/com/potatocake/everymoment/dto/request/DiaryManualCreateRequest.java similarity index 91% rename from src/main/java/com/potatocake/everymoment/dto/request/DiaryManualRequest.java rename to src/main/java/com/potatocake/everymoment/dto/request/DiaryManualCreateRequest.java index 78bde8b..849298a 100644 --- a/src/main/java/com/potatocake/everymoment/dto/request/DiaryManualRequest.java +++ b/src/main/java/com/potatocake/everymoment/dto/request/DiaryManualCreateRequest.java @@ -5,7 +5,7 @@ import lombok.Getter; @Getter -public class DiaryManualRequest { +public class DiaryManualCreateRequest { private List categories; private LocationPoint locationPoint; private String locationName; 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 208e5c3..48de888 100644 --- a/src/main/java/com/potatocake/everymoment/dto/response/MyDiariesResponse.java +++ b/src/main/java/com/potatocake/everymoment/dto/response/MyDiariesResponse.java @@ -8,5 +8,5 @@ @Builder public class MyDiariesResponse { private List diaries; - private Integer key; + private Integer next; } diff --git a/src/main/java/com/potatocake/everymoment/entity/Diary.java b/src/main/java/com/potatocake/everymoment/entity/Diary.java index 644dc82..ea22d24 100644 --- a/src/main/java/com/potatocake/everymoment/entity/Diary.java +++ b/src/main/java/com/potatocake/everymoment/entity/Diary.java @@ -50,4 +50,50 @@ public class Diary extends BaseTimeEntity { @Column(nullable = false) @Builder.Default private boolean isPublic = false; + + public void updateContent(String content) { + if (content != null) { + this.content = content; + } + } + + public void updateLocationPoint(String locationPoint) { + if (locationPoint != null) { + this.locationPoint = locationPoint; + } + } + + public void updateLocationName(String locationName) { + if (locationName != null) { + this.locationName = locationName; + } + } + + public void updateAddress(String address) { + if (address != null) { + this.address = address; + } + } + + public void updateEmoji(String emoji) { + if (emoji != null) { + this.emoji = emoji; + } + } + + public void updateBookmark(boolean isBookmark) { + this.isBookmark = isBookmark; + } + + public void updatePublic(boolean isPublic) { + this.isPublic = isPublic; + } + + public void toggleBookmark() { + this.isBookmark = !this.isBookmark; + } + + public void togglePublic() { + this.isPublic = !this.isPublic; + } } diff --git a/src/main/java/com/potatocake/everymoment/exception/ErrorCode.java b/src/main/java/com/potatocake/everymoment/exception/ErrorCode.java index 16df143..6d969ee 100644 --- a/src/main/java/com/potatocake/everymoment/exception/ErrorCode.java +++ b/src/main/java/com/potatocake/everymoment/exception/ErrorCode.java @@ -12,6 +12,9 @@ @Getter public enum ErrorCode { + /* Diary */ + DIARY_NOT_FOUND("존재하지 않는 일기입니다.", NOT_FOUND), + /* CategoryService */ ALREADY_EXISTS_CATEGORY("이미 존재하는 카테고리입니다.", CONFLICT), diff --git a/src/main/java/com/potatocake/everymoment/repository/DiaryCategoryRepository.java b/src/main/java/com/potatocake/everymoment/repository/DiaryCategoryRepository.java index 6770d22..2989173 100644 --- a/src/main/java/com/potatocake/everymoment/repository/DiaryCategoryRepository.java +++ b/src/main/java/com/potatocake/everymoment/repository/DiaryCategoryRepository.java @@ -1,12 +1,9 @@ package com.potatocake.everymoment.repository; import com.potatocake.everymoment.entity.DiaryCategory; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; -@Repository public interface DiaryCategoryRepository extends JpaRepository { List findByCategoryId(Long categoryId); } diff --git a/src/main/java/com/potatocake/everymoment/repository/DiaryRepository.java b/src/main/java/com/potatocake/everymoment/repository/DiaryRepository.java index 4e48c49..deff65c 100644 --- a/src/main/java/com/potatocake/everymoment/repository/DiaryRepository.java +++ b/src/main/java/com/potatocake/everymoment/repository/DiaryRepository.java @@ -3,8 +3,6 @@ import com.potatocake.everymoment.entity.Diary; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.stereotype.Repository; -@Repository public interface DiaryRepository extends JpaRepository, JpaSpecificationExecutor { } diff --git a/src/main/java/com/potatocake/everymoment/repository/NotificationRepository.java b/src/main/java/com/potatocake/everymoment/repository/NotificationRepository.java index c380eaf..a3a5974 100644 --- a/src/main/java/com/potatocake/everymoment/repository/NotificationRepository.java +++ b/src/main/java/com/potatocake/everymoment/repository/NotificationRepository.java @@ -2,8 +2,6 @@ import com.potatocake.everymoment.entity.Notification; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -@Repository public interface NotificationRepository extends JpaRepository { } diff --git a/src/main/java/com/potatocake/everymoment/service/DiaryService.java b/src/main/java/com/potatocake/everymoment/service/DiaryService.java index b0532e6..d9f9a72 100644 --- a/src/main/java/com/potatocake/everymoment/service/DiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/DiaryService.java @@ -1,7 +1,8 @@ package com.potatocake.everymoment.service; -import com.potatocake.everymoment.dto.request.DiaryAutoRequest; -import com.potatocake.everymoment.dto.request.DiaryManualRequest; +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.response.CategoryResponse; import com.potatocake.everymoment.dto.response.FileResponse; import com.potatocake.everymoment.dto.response.MyDiariesResponse; @@ -12,18 +13,23 @@ import com.potatocake.everymoment.entity.Diary; import com.potatocake.everymoment.entity.DiaryCategory; import com.potatocake.everymoment.entity.Notification; +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.NotificationRepository; -import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +@RequiredArgsConstructor +@Transactional @Service public class DiaryService { @@ -31,23 +37,16 @@ public class DiaryService { private final DiaryCategoryRepository diaryCategoryRepository; private final NotificationRepository notificationRepository; - public DiaryService(DiaryRepository diaryRepository, DiaryCategoryRepository diaryCategoryRepository, - NotificationRepository notificationRepository) { - this.diaryRepository = diaryRepository; - this.diaryCategoryRepository = diaryCategoryRepository; - this.notificationRepository = notificationRepository; - } - // 자동 일기 저장 (LocationPoint, Name, Adress 만 저장) - public NotificationResponse createDiaryAuto(DiaryAutoRequest diaryAutoRequest) { + public NotificationResponse createDiaryAuto(DiaryAutoCreateRequest diaryAutoCreateRequest) { // member Id 가져옴 Long memberId = 1L; Diary diary = Diary.builder() .memberId(memberId) - .locationPoint(diaryAutoRequest.getLocationPoint().toString()) - .locationName(diaryAutoRequest.getLocationName()) - .address(diaryAutoRequest.getAddress()) + .locationPoint(diaryAutoCreateRequest.getLocationPoint().toString()) + .locationName(diaryAutoCreateRequest.getLocationName()) + .address(diaryAutoCreateRequest.getAddress()) .build(); Diary savedDiary = diaryRepository.save(diary); @@ -77,19 +76,19 @@ public NotificationResponse createDiaryAuto(DiaryAutoRequest diaryAutoRequest) { } // 수동 일기 작성 - public void createDiaryManual(DiaryManualRequest diaryManualRequest) { + public void createDiaryManual(DiaryManualCreateRequest diaryManualCreateRequest) { // member Id 가져옴 Long memberId = 1L; Diary diary = Diary.builder() .memberId(memberId) - .content(diaryManualRequest.getContent()) - .locationPoint(diaryManualRequest.getLocationPoint().toString()) - .locationName(diaryManualRequest.getLocationName()) - .address(diaryManualRequest.getAddress()) - .emoji(diaryManualRequest.getEmoji()) - .isBookmark(diaryManualRequest.isBookmark()) - .isPublic(diaryManualRequest.isPublic()) + .content(diaryManualCreateRequest.getContent()) + .locationPoint(diaryManualCreateRequest.getLocationPoint().toString()) + .locationName(diaryManualCreateRequest.getLocationName()) + .address(diaryManualCreateRequest.getAddress()) + .emoji(diaryManualCreateRequest.getEmoji()) + .isBookmark(diaryManualCreateRequest.isBookmark()) + .isPublic(diaryManualCreateRequest.isPublic()) .build(); Diary savedDiary = diaryRepository.save(diary); @@ -100,23 +99,26 @@ public void createDiaryManual(DiaryManualRequest diaryManualRequest) { } // 내 일기 전체 조회 (타임라인) - public MyDiariesResponse getMyDiaries(String keyword, String emoji, Long category, - LocalDate date, LocalDate from, LocalDate until, - Boolean isBookmark, int key, int size) { + @Transactional(readOnly = true) + public MyDiariesResponse getMyDiaries(DiaryFilterRequest diaryFilterRequest) { //member id 가져옴 Long memberId = 1L; Page diaryPage; - if (category == null) { + if (diaryFilterRequest.getCategory() == null) { // category가 null인 경우 - Specification spec = DiarySpecification.filterDiaries(keyword, emoji, date, from, until, isBookmark) + 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"), memberId)); - diaryPage = diaryRepository.findAll(spec, PageRequest.of(key, size)); + diaryPage = diaryRepository.findAll(spec, + PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); } else { // category가 있는 경우 - DiaryCategory에서 category 같은 것 찾음 - List diaryCategoryList = diaryCategoryRepository.findByCategoryId(category); + List diaryCategoryList = diaryCategoryRepository.findByCategoryId( + diaryFilterRequest.getCategory()); // Diary 중에 memberId같은 것 가져옴 List DiaryIdList = diaryCategoryList.stream() @@ -127,57 +129,48 @@ public MyDiariesResponse getMyDiaries(String keyword, String emoji, Long categor // 가져온 DiaryId로 일기 찾음 Specification spec = (root, query, builder) -> root.get("id").in(DiaryIdList); - diaryPage = diaryRepository.findAll(spec, PageRequest.of(key, size)); + diaryPage = diaryRepository.findAll(spec, + PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); } List diaryDTOs = diaryPage.getContent().stream() .map(this::convertToMyDiarySimpleResponseDto) .collect(Collectors.toList()); - Integer nextPage = diaryPage.hasNext() ? key + 1 : null; + Integer nextPage = diaryPage.hasNext() ? diaryFilterRequest.getKey() + 1 : null; - MyDiariesResponse myDiariesResponse = MyDiariesResponse.builder() + return MyDiariesResponse.builder() .diaries(diaryDTOs) - .key(nextPage) + .next(nextPage) .build(); - - return myDiariesResponse; } // 내 일기 상세 조회 + @Transactional(readOnly = true) public MyDiaryResponse getMyDiary(Long id) { Diary diary = diaryRepository.findById(id) - .orElseThrow(() -> new IllegalArgumentException("Diary not found")); + .orElseThrow(() -> new GlobalException(ErrorCode.DIARY_NOT_FOUND)); return convertToMyDiaryResponseDto(diary); } // 내 일기 수정 - public void updateDiary(Long id, DiaryManualRequest diaryManualRequest) { + public void updateDiary(Long id, DiaryManualCreateRequest diaryManualCreateRequest) { Diary existingDiary = diaryRepository.findById(id) - .orElseThrow(() -> new IllegalArgumentException("Diary not found")); + .orElseThrow(() -> new GlobalException(ErrorCode.DIARY_NOT_FOUND)); //카테고리 업데이트 //파일 업데이트 //다이어리 업데이트 - Diary updatedDiary = Diary.builder() - .id(existingDiary.getId()) - .memberId(1L) - .content(diaryManualRequest.getContent() != null ? diaryManualRequest.getContent() - : existingDiary.getContent()) - .locationPoint( - diaryManualRequest.getLocationPoint() != null ? diaryManualRequest.getLocationPoint() - .toString() : existingDiary.getLocationPoint()) - .locationName(diaryManualRequest.getLocationName() != null ? diaryManualRequest.getLocationName() - : existingDiary.getLocationName()) - .address(diaryManualRequest.getAddress() != null ? diaryManualRequest.getAddress() - : existingDiary.getAddress()) - .emoji(diaryManualRequest.getEmoji() != null ? diaryManualRequest.getEmoji() - : existingDiary.getEmoji()) - .build(); - - diaryRepository.save(updatedDiary); + 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()); + existingDiary.updateBookmark(diaryManualCreateRequest.isBookmark()); + existingDiary.updatePublic(diaryManualCreateRequest.isPublic()); } // 내 일기 삭제 @@ -187,42 +180,18 @@ public void deleteDiary(Long id) { // 내 일기 북마크 설정 public void toggleBookmark(Long id) { - Diary diary = diaryRepository.findById(id) - .orElseThrow(() -> new IllegalArgumentException("Diary not found")); - - Diary updatedDiary = Diary.builder() - .id(diary.getId()) - .memberId(diary.getMemberId()) - .content(diary.getContent()) - .locationPoint(diary.getLocationPoint()) - .locationName(diary.getLocationName()) - .address(diary.getAddress()) - .emoji(diary.getEmoji()) - .isBookmark(!diary.isBookmark()) // 북마크 토글 - .isPublic(diary.isPublic()) - .build(); + Diary existingDiary = diaryRepository.findById(id) + .orElseThrow(() -> new GlobalException(ErrorCode.DIARY_NOT_FOUND)); - diaryRepository.save(updatedDiary); + existingDiary.toggleBookmark(); } // 내 일기 공개 설정 public void togglePrivacy(Long id) { - Diary diary = diaryRepository.findById(id) - .orElseThrow(() -> new IllegalArgumentException("Diary not found")); - - Diary updatedDiary = Diary.builder() - .id(diary.getId()) - .memberId(diary.getMemberId()) - .content(diary.getContent()) - .locationPoint(diary.getLocationPoint()) - .locationName(diary.getLocationName()) - .address(diary.getAddress()) - .emoji(diary.getEmoji()) - .isBookmark(diary.isBookmark()) - .isPublic(!diary.isPublic()) // 공개여부 토글 - .build(); + Diary existingDiary = diaryRepository.findById(id) + .orElseThrow(() -> new GlobalException(ErrorCode.DIARY_NOT_FOUND)); - diaryRepository.save(updatedDiary); + existingDiary.togglePublic(); } //상세 조회시 일기DTO 변환 From f3aa28c9314669bdb35fdf60ed188ce16225447f Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Mon, 23 Sep 2024 23:29:45 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=EB=82=B4=EC=9D=BC=EA=B8=B0=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=EB=A1=9C=EC=A7=81=20=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 엔티티 참조 관계 변경 - 자신의 일기인지 확인하는 로직 추가 --- .../potatocake/everymoment/entity/Diary.java | 11 +-- .../everymoment/entity/Notification.java | 11 +-- .../everymoment/service/DiaryService.java | 72 +++++++++++++------ 3 files changed, 64 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/potatocake/everymoment/entity/Diary.java b/src/main/java/com/potatocake/everymoment/entity/Diary.java index ea22d24..b0b85ee 100644 --- a/src/main/java/com/potatocake/everymoment/entity/Diary.java +++ b/src/main/java/com/potatocake/everymoment/entity/Diary.java @@ -2,10 +2,14 @@ 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; +import jakarta.persistence.JoinColumn; import jakarta.persistence.Lob; +import jakarta.persistence.ManyToOne; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; @@ -22,10 +26,9 @@ public class Diary extends BaseTimeEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - // @ManyToOne(fetch = FetchType.LAZY) -// @JoinColumn(name = "member_id", foreignKey = @ForeignKey(name = "fk_member_id"), nullable = false) - @Column(nullable = false) - private Long memberId; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(nullable = false) + private Member memberId; @Lob private String content; diff --git a/src/main/java/com/potatocake/everymoment/entity/Notification.java b/src/main/java/com/potatocake/everymoment/entity/Notification.java index b2fd360..7963a15 100644 --- a/src/main/java/com/potatocake/everymoment/entity/Notification.java +++ b/src/main/java/com/potatocake/everymoment/entity/Notification.java @@ -2,9 +2,13 @@ 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; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; @@ -21,10 +25,9 @@ public class Notification extends BaseTimeEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - // @ManyToOne(fetch = FetchType.LAZY) -// @JoinColumn(name = "member_id", foreignKey = @ForeignKey(name = "fk_member_id"), nullable = false) - @Column(nullable = false) - private Long memberId; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(nullable = false) + private Member memberId; @Column(nullable = false) private String content; diff --git a/src/main/java/com/potatocake/everymoment/service/DiaryService.java b/src/main/java/com/potatocake/everymoment/service/DiaryService.java index d9f9a72..2adb77d 100644 --- a/src/main/java/com/potatocake/everymoment/service/DiaryService.java +++ b/src/main/java/com/potatocake/everymoment/service/DiaryService.java @@ -5,6 +5,9 @@ import com.potatocake.everymoment.dto.request.DiaryManualCreateRequest; 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.FriendDiarySimpleResponse; +import com.potatocake.everymoment.dto.response.FriendDiaryResponse; import com.potatocake.everymoment.dto.response.MyDiariesResponse; import com.potatocake.everymoment.dto.response.MyDiaryResponse; import com.potatocake.everymoment.dto.response.MyDiarySimpleResponse; @@ -12,19 +15,28 @@ import com.potatocake.everymoment.dto.response.ThumbnailResponse; import com.potatocake.everymoment.entity.Diary; import com.potatocake.everymoment.entity.DiaryCategory; +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.DiaryCategoryRepository; 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 com.potatocake.everymoment.util.JwtUtil; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; 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; @@ -39,11 +51,13 @@ public class DiaryService { // 자동 일기 저장 (LocationPoint, Name, Adress 만 저장) public NotificationResponse createDiaryAuto(DiaryAutoCreateRequest diaryAutoCreateRequest) { - // member Id 가져옴 - Long memberId = 1L; + // member 가져옴 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + MemberDetails memberDetails = (MemberDetails) authentication.getPrincipal(); + Member currentMember = memberDetails.getMember(); Diary diary = Diary.builder() - .memberId(memberId) + .memberId(currentMember) .locationPoint(diaryAutoCreateRequest.getLocationPoint().toString()) .locationName(diaryAutoCreateRequest.getLocationName()) .address(diaryAutoCreateRequest.getAddress()) @@ -55,7 +69,7 @@ public NotificationResponse createDiaryAuto(DiaryAutoCreateRequest diaryAutoCrea String content = "현재 " + savedDiary.getLocationName() + "에 머무르고 있어요! 지금 기분은 어떠신가요?"; Notification notification = Notification.builder() - .memberId(memberId) + .memberId(currentMember) .content(content) .type("MOOD_CHECK") .targetId(savedDiary.getId()) @@ -77,11 +91,13 @@ public NotificationResponse createDiaryAuto(DiaryAutoCreateRequest diaryAutoCrea // 수동 일기 작성 public void createDiaryManual(DiaryManualCreateRequest diaryManualCreateRequest) { - // member Id 가져옴 - Long memberId = 1L; + // member Id + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + MemberDetails memberDetails = (MemberDetails) authentication.getPrincipal(); + Member currentMember = memberDetails.getMember(); Diary diary = Diary.builder() - .memberId(memberId) + .memberId(currentMember) .content(diaryManualCreateRequest.getContent()) .locationPoint(diaryManualCreateRequest.getLocationPoint().toString()) .locationName(diaryManualCreateRequest.getLocationName()) @@ -101,8 +117,10 @@ public void createDiaryManual(DiaryManualCreateRequest diaryManualCreateRequest) // 내 일기 전체 조회 (타임라인) @Transactional(readOnly = true) public MyDiariesResponse getMyDiaries(DiaryFilterRequest diaryFilterRequest) { - //member id 가져옴 - Long memberId = 1L; + //member 가져옴 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + MemberDetails memberDetails = (MemberDetails) authentication.getPrincipal(); + Member currentMember = memberDetails.getMember(); Page diaryPage; @@ -111,7 +129,7 @@ public MyDiariesResponse getMyDiaries(DiaryFilterRequest diaryFilterRequest) { 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"), memberId)); + .and((root, query, builder) -> builder.equal(root.get("memberId"), currentMember)); diaryPage = diaryRepository.findAll(spec, PageRequest.of(diaryFilterRequest.getKey(), diaryFilterRequest.getSize())); @@ -123,7 +141,7 @@ public MyDiariesResponse getMyDiaries(DiaryFilterRequest diaryFilterRequest) { // Diary 중에 memberId같은 것 가져옴 List DiaryIdList = diaryCategoryList.stream() .filter(diaryCategory -> diaryCategory.getDiary().getMemberId() - .equals(memberId)) // memberId가 일치하는 경우 필터링 + .equals(currentMember)) // memberId가 일치하는 경우 필터링 .map(diaryCategory -> diaryCategory.getDiary().getId()) .collect(Collectors.toList()); @@ -148,16 +166,13 @@ public MyDiariesResponse getMyDiaries(DiaryFilterRequest diaryFilterRequest) { // 내 일기 상세 조회 @Transactional(readOnly = true) public MyDiaryResponse getMyDiary(Long id) { - Diary diary = diaryRepository.findById(id) - .orElseThrow(() -> new GlobalException(ErrorCode.DIARY_NOT_FOUND)); - + Diary diary = getExistDiary(id); return convertToMyDiaryResponseDto(diary); } // 내 일기 수정 public void updateDiary(Long id, DiaryManualCreateRequest diaryManualCreateRequest) { - Diary existingDiary = diaryRepository.findById(id) - .orElseThrow(() -> new GlobalException(ErrorCode.DIARY_NOT_FOUND)); + Diary existingDiary = getExistDiary(id); //카테고리 업데이트 //파일 업데이트 @@ -175,23 +190,36 @@ public void updateDiary(Long id, DiaryManualCreateRequest diaryManualCreateReque // 내 일기 삭제 public void deleteDiary(Long id) { - diaryRepository.deleteById(id); + Diary existingDiary = getExistDiary(id); + diaryRepository.delete(existingDiary); } // 내 일기 북마크 설정 public void toggleBookmark(Long id) { - Diary existingDiary = diaryRepository.findById(id) - .orElseThrow(() -> new GlobalException(ErrorCode.DIARY_NOT_FOUND)); - + Diary existingDiary = getExistDiary(id); existingDiary.toggleBookmark(); } // 내 일기 공개 설정 public void togglePrivacy(Long id) { - Diary existingDiary = diaryRepository.findById(id) + Diary existingDiary = getExistDiary(id); + existingDiary.togglePublic(); + } + + // 로그인한 유저의 일기가 맞는지 확인 후 일기 반환 + private Diary getExistDiary(Long diaryId){ + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + MemberDetails memberDetails = (MemberDetails) authentication.getPrincipal(); + Member currentMember = memberDetails.getMember(); + + Diary diary = diaryRepository.findById(diaryId) .orElseThrow(() -> new GlobalException(ErrorCode.DIARY_NOT_FOUND)); - existingDiary.togglePublic(); + if(!Objects.equals(currentMember.getId(), diary.getMemberId().getId())){ + throw new GlobalException(ErrorCode.DIARY_NOT_FOUND); + } + + return diary; } //상세 조회시 일기DTO 변환 From e81a183e11a7f271717986c7d69f6c5a055b4841 Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Fri, 27 Sep 2024 12:42:01 +0900 Subject: [PATCH 3/7] =?UTF-8?q?fix:=20H2-console=20=EB=8C=80=EC=8B=9C?= =?UTF-8?q?=EB=B3=B4=EB=93=9C=20=EB=B3=B4=EC=9D=B4=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8A=94=20=EC=98=A4=EB=A5=98=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/config/SecurityConfig.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/potatocake/everymoment/config/SecurityConfig.java b/src/main/java/com/potatocake/everymoment/config/SecurityConfig.java index f479788..49ff12b 100644 --- a/src/main/java/com/potatocake/everymoment/config/SecurityConfig.java +++ b/src/main/java/com/potatocake/everymoment/config/SecurityConfig.java @@ -15,6 +15,7 @@ import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer.FrameOptionsConfig; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -39,6 +40,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .formLogin(auth -> auth.disable()) .httpBasic(auth -> auth.disable()); + http + .headers(header -> header.frameOptions(FrameOptionsConfig::sameOrigin)); + http .authorizeHttpRequests(auth -> auth .requestMatchers("/api/members/login", "/h2-console/**", "/error").permitAll() From 160a0e700ff29727c95c4f3efe88ce61fcab6595 Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Fri, 27 Sep 2024 16:07:01 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=EB=82=A0=EC=A7=9C=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=EB=A7=81=20=EB=94=94=ED=8F=B4=ED=8A=B8=20=EC=98=A4?= =?UTF-8?q?=EB=8A=98=20=EB=82=A0=EC=A7=9C=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../everymoment/service/DiarySpecification.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/potatocake/everymoment/service/DiarySpecification.java b/src/main/java/com/potatocake/everymoment/service/DiarySpecification.java index e5031a4..7554307 100644 --- a/src/main/java/com/potatocake/everymoment/service/DiarySpecification.java +++ b/src/main/java/com/potatocake/everymoment/service/DiarySpecification.java @@ -22,9 +22,11 @@ public static Specification filterDiaries(String keyword, String emoji, L if (emoji != null) { predicate = builder.and(predicate, builder.equal(root.get("emoji"), emoji)); } - if (date != null) { - predicate = builder.and(predicate, builder.equal(builder.function("DATE", LocalDate.class, root.get("createAt")), date)); - } + + // 날짜 필터링 (null일 경우 오늘 날짜로 기본값 설정) + LocalDate filterDate = (date != null) ? date : LocalDate.now(); + predicate = builder.and(predicate, builder.equal(root.get("createAt").as(LocalDate.class), filterDate)); + if (from != null && until != null) { predicate = builder.and(predicate, builder.between(root.get("createAt"), from.atStartOfDay(), until.plusDays(1).atStartOfDay())); } From 66bd22c70627f7793be6702b09a6a8d49c6cf063 Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Fri, 27 Sep 2024 16:14:11 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat:=20=EC=B9=9C=EA=B5=AC=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../potatocake/everymoment/entity/Friend.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/main/java/com/potatocake/everymoment/entity/Friend.java diff --git a/src/main/java/com/potatocake/everymoment/entity/Friend.java b/src/main/java/com/potatocake/everymoment/entity/Friend.java new file mode 100644 index 0000000..b6818cb --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/entity/Friend.java @@ -0,0 +1,43 @@ +package com.potatocake.everymoment.entity; + +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; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +@Getter +@Builder +public class Friend { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(nullable = false) + private Member memberId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(nullable = false) + private Member friendId; + + @Column(nullable = false) + @Builder.Default + private boolean isClose = false; + + public void toggleIsClose() { + this.isClose = !this.isClose; + } +} From 3cc63fa6151d67a93fbae0eb9a500fc749d76d62 Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Fri, 27 Sep 2024 16:42:18 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feat:=20=EC=B9=9C=EA=B5=ACAPI=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 - 특정 친구 일기 전체 조회 - 내 친구 목록 조회 - 내 친구 삭제 - 친한 친구 설정 --- .../controller/FriendController.java | 83 +++++++++ .../response/FriendDiarySimpleResponse.java | 23 +++ .../dto/response/FriendListResponse.java | 12 ++ .../dto/response/FriendProfileResponse.java | 13 ++ .../response/OneFriendDiariesResponse.java | 12 ++ .../everymoment/exception/ErrorCode.java | 6 + .../repository/FriendRepository.java | 14 ++ .../everymoment/service/FriendService.java | 159 ++++++++++++++++++ .../service/FriendSpecification.java | 32 ++++ 9 files changed, 354 insertions(+) create mode 100644 src/main/java/com/potatocake/everymoment/controller/FriendController.java create mode 100644 src/main/java/com/potatocake/everymoment/dto/response/FriendDiarySimpleResponse.java create mode 100644 src/main/java/com/potatocake/everymoment/dto/response/FriendListResponse.java create mode 100644 src/main/java/com/potatocake/everymoment/dto/response/FriendProfileResponse.java create mode 100644 src/main/java/com/potatocake/everymoment/dto/response/OneFriendDiariesResponse.java create mode 100644 src/main/java/com/potatocake/everymoment/repository/FriendRepository.java create mode 100644 src/main/java/com/potatocake/everymoment/service/FriendService.java create mode 100644 src/main/java/com/potatocake/everymoment/service/FriendSpecification.java diff --git a/src/main/java/com/potatocake/everymoment/controller/FriendController.java b/src/main/java/com/potatocake/everymoment/controller/FriendController.java new file mode 100644 index 0000000..d108739 --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/controller/FriendController.java @@ -0,0 +1,83 @@ +package com.potatocake.everymoment.controller; + +import com.potatocake.everymoment.dto.SuccessResponse; +import com.potatocake.everymoment.dto.response.FriendListResponse; +import com.potatocake.everymoment.dto.response.OneFriendDiariesResponse; +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.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("api/friends") +public class FriendController { + private final FriendService friendService; + + public FriendController(FriendService friendService) { + this.friendService = friendService; + } + + //특정 친구 일기 전체 조회 + @GetMapping("/{id}/diaries") + public ResponseEntity> getOneFriendDiaries( + @PathVariable Long id, + @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date, + @RequestParam(defaultValue = "0") int key, + @RequestParam(defaultValue = "10") int size) { + OneFriendDiariesResponse diaries = friendService.OneFriendDiariesResponse(id, date, key, size); + SuccessResponse response = SuccessResponse.builder() + .code(HttpStatus.OK.value()) + .message("success") + .info(diaries) + .build(); + return ResponseEntity.ok(response); + } + + //내 친구 목록 조회 + @GetMapping("/friends") + public ResponseEntity> getFriendList( + @RequestParam(required = false) String nickname, + @RequestParam(required = false) String email, + @RequestParam(defaultValue = "0") int key, + @RequestParam(defaultValue = "10") int size) { + FriendListResponse friendList = friendService.getFriendList(nickname, email, key, size); + SuccessResponse response = SuccessResponse.builder() + .code(HttpStatus.OK.value()) + .message("success") + .info(friendList) + .build(); + return ResponseEntity.ok(response); + } + + //내 친구 삭제 + @DeleteMapping("/{id}") + public ResponseEntity> deleteFriend(@PathVariable Long id) { + friendService.deleteFriend(id); + SuccessResponse response = SuccessResponse.builder() + .code(HttpStatus.OK.value()) + .message("success") + .info(null) + .build(); + return ResponseEntity.ok(response); + } + + //친한 친구 설정 + @PatchMapping("/{id}/bookmark") + public ResponseEntity> toggleCloseFriend(@PathVariable Long id) { + friendService.toggleCloseFriend(id); + SuccessResponse response = SuccessResponse.builder() + .code(HttpStatus.OK.value()) + .message("success") + .info(null) + .build(); + return ResponseEntity.ok(response); + } +} diff --git a/src/main/java/com/potatocake/everymoment/dto/response/FriendDiarySimpleResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/FriendDiarySimpleResponse.java new file mode 100644 index 0000000..d159936 --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/dto/response/FriendDiarySimpleResponse.java @@ -0,0 +1,23 @@ +package com.potatocake.everymoment.dto.response; + +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class FriendDiarySimpleResponse { + private Long id; + private String locationName; + private String address; + private boolean isBookmark; + private boolean isPublic; + private String emoji; + private ThumbnailResponse thumbnailResponse; + private String content; + private LocalDateTime createAt; +} diff --git a/src/main/java/com/potatocake/everymoment/dto/response/FriendListResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/FriendListResponse.java new file mode 100644 index 0000000..d5131e7 --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/dto/response/FriendListResponse.java @@ -0,0 +1,12 @@ +package com.potatocake.everymoment.dto.response; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class FriendListResponse { + private List friends; + private Integer next; +} diff --git a/src/main/java/com/potatocake/everymoment/dto/response/FriendProfileResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/FriendProfileResponse.java new file mode 100644 index 0000000..5e359dc --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/dto/response/FriendProfileResponse.java @@ -0,0 +1,13 @@ +package com.potatocake.everymoment.dto.response; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class FriendProfileResponse { + private Long id; + private String nickname; + private String profileImageUrl; + private boolean isClose; +} diff --git a/src/main/java/com/potatocake/everymoment/dto/response/OneFriendDiariesResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/OneFriendDiariesResponse.java new file mode 100644 index 0000000..31ae287 --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/dto/response/OneFriendDiariesResponse.java @@ -0,0 +1,12 @@ +package com.potatocake.everymoment.dto.response; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class OneFriendDiariesResponse { + private List diaries; + private Integer next; +} diff --git a/src/main/java/com/potatocake/everymoment/exception/ErrorCode.java b/src/main/java/com/potatocake/everymoment/exception/ErrorCode.java index 6d969ee..cd69820 100644 --- a/src/main/java/com/potatocake/everymoment/exception/ErrorCode.java +++ b/src/main/java/com/potatocake/everymoment/exception/ErrorCode.java @@ -15,6 +15,12 @@ public enum ErrorCode { /* Diary */ DIARY_NOT_FOUND("존재하지 않는 일기입니다.", NOT_FOUND), + /* Member */ + MEMBER_NOT_FOUND("존재하지 않는 회원입니다.", NOT_FOUND), + + /* Friend */ + FRIEND_NOT_FOUND("존재하지 않는 친구입니다.", NOT_FOUND), + /* CategoryService */ ALREADY_EXISTS_CATEGORY("이미 존재하는 카테고리입니다.", CONFLICT), diff --git a/src/main/java/com/potatocake/everymoment/repository/FriendRepository.java b/src/main/java/com/potatocake/everymoment/repository/FriendRepository.java new file mode 100644 index 0000000..5eb96f7 --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/repository/FriendRepository.java @@ -0,0 +1,14 @@ +package com.potatocake.everymoment.repository; + +import com.potatocake.everymoment.entity.Friend; +import com.potatocake.everymoment.entity.Member; +import java.util.List; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface FriendRepository extends JpaRepository, JpaSpecificationExecutor { + Optional findByMemberIdAndFriendId(Member member, Member friend); + + List findAllFriendIdsByMemberId(Member member); +} diff --git a/src/main/java/com/potatocake/everymoment/service/FriendService.java b/src/main/java/com/potatocake/everymoment/service/FriendService.java new file mode 100644 index 0000000..d252170 --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/service/FriendService.java @@ -0,0 +1,159 @@ +package com.potatocake.everymoment.service; + +import com.potatocake.everymoment.dto.response.FriendDiarySimpleResponse; +import com.potatocake.everymoment.dto.response.FriendListResponse; +import com.potatocake.everymoment.dto.response.FriendProfileResponse; +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.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.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; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +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; + +@RequiredArgsConstructor +@Transactional +@Service +public class FriendService { + + private final FriendRepository friendRepository; + private final MemberRepository memberRepository; + private final DiaryRepository diaryRepository; + + //특정 친구 일기 조회 + @Transactional(readOnly = true) + public OneFriendDiariesResponse OneFriendDiariesResponse(Long id, LocalDate date, int key, int size) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + MemberDetails memberDetails = (MemberDetails) authentication.getPrincipal(); + Member currentMember = memberDetails.getMember(); + + //친구인지 확인 + Member friend = memberRepository.findById(id) + .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); + friendRepository.findByMemberIdAndFriendId(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"), id)), pageable); + + List diaryList = diaries.getContent().stream() + .map(this::convertToFriendDiariesResponseDTO) + .collect(Collectors.toList()); + + Integer nextPage = diaries.hasNext() ? key + 1 : null; + + return OneFriendDiariesResponse.builder() + .diaries(diaryList) + .next(nextPage) + .build(); + } + + //내 친구 목록 조회 + @Transactional(readOnly = true) + public FriendListResponse getFriendList(String nickname, String email, int key, int size) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + MemberDetails memberDetails = (MemberDetails) authentication.getPrincipal(); + Member currentMember = memberDetails.getMember(); + Long memberId = currentMember.getId(); + + Pageable pageable = PageRequest.of(key, size); + + Specification spec = FriendSpecification.filterFriends(memberId, nickname, email) + .and((root, query, builder) -> builder.equal(root.get("memberId").get("id"), memberId)); + + Page friends = friendRepository.findAll(spec, pageable); + + List friendProfiles = friends.stream() + .map(this::convertToFriendProfileResponseDTO) + .collect(Collectors.toList()); + + Integer nextPage = friends.hasNext() ? key + 1 : null; + + return FriendListResponse.builder() + .friends(friendProfiles) + .next(nextPage) + .build(); + } + + // 친구 삭제 + public void deleteFriend(Long id) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + MemberDetails memberDetails = (MemberDetails) authentication.getPrincipal(); + Member currentMember = memberDetails.getMember(); + + Member friendMember = memberRepository.findById(id) + .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); + + Friend friendMine = friendRepository.findByMemberIdAndFriendId(currentMember, friendMember) + .orElseThrow(() -> new GlobalException(ErrorCode.FRIEND_NOT_FOUND)); + Friend friendFriends = friendRepository.findByMemberIdAndFriendId(friendMember, currentMember) + .orElseThrow(() -> new GlobalException(ErrorCode.FRIEND_NOT_FOUND)); + + friendRepository.delete(friendMine); + friendRepository.delete(friendFriends); + } + + // 친한 친구 설정(토글) + public void toggleCloseFriend(Long id) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + MemberDetails memberDetails = (MemberDetails) authentication.getPrincipal(); + Member currentMember = memberDetails.getMember(); + + Member friendMember = memberRepository.findById(id) + .orElseThrow(() -> new GlobalException(ErrorCode.MEMBER_NOT_FOUND)); + Friend friend = friendRepository.findByMemberIdAndFriendId(currentMember, friendMember) + .orElseThrow(() -> new GlobalException(ErrorCode.FRIEND_NOT_FOUND)); + + friend.toggleIsClose(); + } + + //다이어리 DTO 변환 + private FriendDiarySimpleResponse convertToFriendDiariesResponseDTO(Diary savedDiary) { + //파일 찾음 + ThumbnailResponse thumbnailResponse = ThumbnailResponse.builder() + .id(1L) + .imageUrl("image1.url") + .build(); + + return FriendDiarySimpleResponse.builder() + .id(savedDiary.getId()) + .address(savedDiary.getAddress()) + .locationName(savedDiary.getLocationName()) + .isBookmark(savedDiary.isBookmark()) + .isPublic(savedDiary.isPublic()) + .emoji(savedDiary.getEmoji()) + .thumbnailResponse(thumbnailResponse) + .content(savedDiary.getContent()) + .createAt(savedDiary.getCreateAt()) + .build(); + } + + //친구 프로필 DTO 변환 + private FriendProfileResponse convertToFriendProfileResponseDTO(Friend friend){ + Member friendMember = friend.getFriendId(); + return FriendProfileResponse.builder() + .id(friendMember.getId()) + .nickname(friendMember.getNickname()) + .profileImageUrl(friendMember.getProfileImageUrl()) + .isClose(friend.isClose()) + .build(); + } +} diff --git a/src/main/java/com/potatocake/everymoment/service/FriendSpecification.java b/src/main/java/com/potatocake/everymoment/service/FriendSpecification.java new file mode 100644 index 0000000..6d193f1 --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/service/FriendSpecification.java @@ -0,0 +1,32 @@ +package com.potatocake.everymoment.service; + +import com.potatocake.everymoment.entity.Friend; +import com.potatocake.everymoment.entity.Member; +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 org.springframework.data.jpa.domain.Specification; + +public class FriendSpecification { + public static Specification filterFriends(Long memberId, String nickname, String email) { + return (Root root, CriteriaQuery query, CriteriaBuilder builder) -> { + Predicate predicate = builder.conjunction(); + + predicate = builder.and(predicate, builder.equal(root.get("memberId").get("id"), memberId)); + + if (nickname != null) { + Join friendJoin = root.join("friendId"); + predicate = builder.and(predicate, builder.like(friendJoin.get("nickname"), "%" + nickname + "%")); + } + + if (email != null) { + Join friendJoin = root.join("friendId"); + predicate = builder.and(predicate, builder.like(friendJoin.get("email"), "%" + email + "%")); + } + + return predicate; + }; + } +} From ab55440e5db95783d6e0cfba286d363856f53ecd Mon Sep 17 00:00:00 2001 From: HyeJiJUN Date: Fri, 27 Sep 2024 16:51:14 +0900 Subject: [PATCH 7/7] =?UTF-8?q?feat:=20=EC=B9=9C=EA=B5=AC=20=EC=9D=BC?= =?UTF-8?q?=EA=B8=B0API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 전체 친구 일기 조회 - 친구 일기 상세 조회 --- .../controller/DiaryController.java | 54 +++++- .../dto/response/FriendDiariesResponse.java | 12 ++ .../dto/response/FriendDiaryResponse.java | 23 +++ .../service/FriendDiaryService.java | 161 ++++++++++++++++++ 4 files changed, 246 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/potatocake/everymoment/dto/response/FriendDiariesResponse.java create mode 100644 src/main/java/com/potatocake/everymoment/dto/response/FriendDiaryResponse.java create mode 100644 src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java diff --git a/src/main/java/com/potatocake/everymoment/controller/DiaryController.java b/src/main/java/com/potatocake/everymoment/controller/DiaryController.java index 2dd59e2..e149daa 100644 --- a/src/main/java/com/potatocake/everymoment/controller/DiaryController.java +++ b/src/main/java/com/potatocake/everymoment/controller/DiaryController.java @@ -4,10 +4,13 @@ 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.response.FriendDiariesResponse; +import com.potatocake.everymoment.dto.response.FriendDiaryResponse; import com.potatocake.everymoment.dto.response.MyDiariesResponse; import com.potatocake.everymoment.dto.response.MyDiaryResponse; import com.potatocake.everymoment.dto.response.NotificationResponse; import com.potatocake.everymoment.service.DiaryService; +import com.potatocake.everymoment.service.FriendDiaryService; import java.time.LocalDate; import lombok.RequiredArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; @@ -29,6 +32,7 @@ public class DiaryController { private final DiaryService diaryService; + private final FriendDiaryService friendDiaryService; //자동 일기 작성 @PostMapping("/auto") @@ -40,7 +44,6 @@ public ResponseEntity> createDiaryAuto( .message("success") .info(notificationResponse) .build(); - return ResponseEntity.ok(response); } @@ -54,7 +57,6 @@ public ResponseEntity> createDiaryManual( .message("success") .info(null) .build(); - return ResponseEntity.ok(response); } @@ -89,7 +91,6 @@ public ResponseEntity> getMyDiaries( .message("success") .info(myDiariesResponse) .build(); - return ResponseEntity.ok(response); } @@ -102,7 +103,6 @@ public ResponseEntity> getMyDiary(@PathVariable .message("success") .info(myDiaryResponse) .build(); - return ResponseEntity.ok(response); } @@ -154,4 +154,50 @@ public ResponseEntity> togglePrivacy(@PathVariable Long id .build(); return ResponseEntity.ok(response); } + + //전체 친구 일기 조회 + @GetMapping("/friend") + public ResponseEntity> getFriendDiaries( + @RequestParam(required = false) String keyword, + @RequestParam(required = false) String emoji, + @RequestParam(required = false) Long 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, + @RequestParam(required = false) Boolean bookmark, + @RequestParam(defaultValue = "0") int key, + @RequestParam(defaultValue = "10") int size + ) { + DiaryFilterRequest diaryFilterRequest = DiaryFilterRequest.builder() + .keyword(keyword) + .emoji(emoji) + .category(category) + .date(date) + .from(from) + .until(until) + .bookmark(bookmark) + .key(key) + .size(size) + .build(); + + FriendDiariesResponse diaries = friendDiaryService.getFriendDiaries(diaryFilterRequest); + SuccessResponse response = SuccessResponse.builder() + .code(HttpStatus.OK.value()) + .message("success") + .info(diaries) + .build(); + return ResponseEntity.ok(response); + } + + //친구 일기 상제 조회 + @GetMapping("/friend/{id}") + public ResponseEntity> getFriendDiary(@PathVariable Long id) { + FriendDiaryResponse diary = friendDiaryService.getFriendDiary(id); + SuccessResponse response = SuccessResponse.builder() + .code(HttpStatus.OK.value()) + .message("success") + .info(diary) + .build(); + return ResponseEntity.ok(response); + } } diff --git a/src/main/java/com/potatocake/everymoment/dto/response/FriendDiariesResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/FriendDiariesResponse.java new file mode 100644 index 0000000..f2f096f --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/dto/response/FriendDiariesResponse.java @@ -0,0 +1,12 @@ +package com.potatocake.everymoment.dto.response; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class FriendDiariesResponse { + private List diaries; + private Integer next; +} diff --git a/src/main/java/com/potatocake/everymoment/dto/response/FriendDiaryResponse.java b/src/main/java/com/potatocake/everymoment/dto/response/FriendDiaryResponse.java new file mode 100644 index 0000000..b442af3 --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/dto/response/FriendDiaryResponse.java @@ -0,0 +1,23 @@ +package com.potatocake.everymoment.dto.response; + +import java.time.LocalDateTime; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class FriendDiaryResponse { + private Long id; + private List categories; + private String locationName; + private String emoji; + private List file; + private String content; + private Integer 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 new file mode 100644 index 0000000..d6d4ee1 --- /dev/null +++ b/src/main/java/com/potatocake/everymoment/service/FriendDiaryService.java @@ -0,0 +1,161 @@ +package com.potatocake.everymoment.service; + +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; +import com.potatocake.everymoment.dto.response.ThumbnailResponse; +import com.potatocake.everymoment.entity.Diary; +import com.potatocake.everymoment.entity.DiaryCategory; +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.FriendRepository; +import com.potatocake.everymoment.security.MemberDetails; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +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; + +@RequiredArgsConstructor +@Transactional +@Service +public class FriendDiaryService { + private final DiaryRepository diaryRepository; + private final DiaryCategoryRepository diaryCategoryRepository; + private final FriendRepository friendRepository; + + //친구 일기 조회 + public FriendDiariesResponse getFriendDiaries(DiaryFilterRequest diaryFilterRequest) { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + MemberDetails memberDetails = (MemberDetails) authentication.getPrincipal(); + Member currentMember = memberDetails.getMember(); + + List friends = friendRepository.findAllFriendIdsByMemberId(currentMember); + List friendIdList = friends.stream() + .map(Member::getId) + .collect(Collectors.toList()); + + 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("memberId").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().getMemberId())) // 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 friendDiarySimpleResponseList = diaryPage.getContent().stream() + .map(this::convertToFriendDiariesResponseDTO) + .collect(Collectors.toList()); + + Integer nextPage = diaryPage.hasNext() ? diaryFilterRequest.getKey() + 1 : null; + + FriendDiariesResponse friendDiariesResponse = FriendDiariesResponse.builder() + .diaries(friendDiarySimpleResponseList) + .next(nextPage) + .build(); + + return friendDiariesResponse; + } + + // 친구 다이어리 하나 조회 + public FriendDiaryResponse getFriendDiary(Long id) { + Diary diary = diaryRepository.findById(id) + .orElseThrow(() -> new IllegalArgumentException("Diary not found")); + + //글쓴사람이 친구인지 확인 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + MemberDetails memberDetails = (MemberDetails) authentication.getPrincipal(); + Member currentMember = memberDetails.getMember(); + + List friends = friendRepository.findAllFriendIdsByMemberId(currentMember); + List friendIdList = friends.stream() + .map(Member::getId) + .collect(Collectors.toList()); + + if(!friendIdList.contains(diary.getMemberId())){ + 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); + + //like 갯수 반환 + Integer likeCount = 11; + + FriendDiaryResponse diaryResponseDTO = FriendDiaryResponse.builder() + .id(diary.getId()) + .categories(categoryResponseDTOList) + .locationName(diary.getLocationName()) + .emoji(diary.getEmoji()) + .file(fileResponseDTOList) + .content(diary.getContent()) + .likeCount(likeCount) + .createAt(diary.getCreateAt()) + .build(); + + return diaryResponseDTO; + } + + //친구 일기 DTO변환 + private FriendDiarySimpleResponse convertToFriendDiariesResponseDTO(Diary savedDiary) { + //파일 찾음 + ThumbnailResponse thumbnailResponse = ThumbnailResponse.builder() + .id(1L) + .imageUrl("image1.url") + .build(); + + return FriendDiarySimpleResponse.builder() + .id(savedDiary.getId()) + .address(savedDiary.getAddress()) + .locationName(savedDiary.getLocationName()) + .isBookmark(savedDiary.isBookmark()) + .isPublic(savedDiary.isPublic()) + .emoji(savedDiary.getEmoji()) + .thumbnailResponse(thumbnailResponse) + .content(savedDiary.getContent()) + .createAt(savedDiary.getCreateAt()) + .build(); + } +}