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(); + } +}