코딩과 결혼합니다

230828 - 스크랩 기능 본문

코딩과 매일매일♥/Seoulvival

230828 - 스크랩 기능

코딩러버 2023. 8. 29. 12:31
728x90

스크랩은 좋아요와 거의 비슷한 기능이라 생각했다. 다만 차이점이 있다면 내가 스크랩한 포스트글을 조회할 수 있다는 점?

 

Post Scrap

ScrapController

@RestController
@RequiredArgsConstructor
public class ScrapController {
    private final PostScrapService postScrapService;

    //포스트 스크랩
    @PostMapping("/posts/{postId}/scrap")
    public MessageResponseDto postScrap(@PathVariable Long postId,
                                       @AuthenticationPrincipal UserDetailsImpl userDetails){
        User user = userDetails.getUser();
        return postScrapService.postScrap(postId,user);
    }
}

좋아요와 똑같이 postId 와 유저 정보를 가져온다.

 

 PostScrapService
 
@Service
@RequiredArgsConstructor
public class PostScrapService {
    private final PostScrapRepository postScrapRepository;
    private final PostRepository postRepository;

    //post 스크랩
    public MessageResponseDto postScrap(Long postId, User user){
        Post post = postRepository.findById(postId).orElseThrow(
                ()-> new IllegalArgumentException("해당 게시글은 존재하지 않습니다.")
        );

        if (!postScrapRepository.existsScrapByPostAndUser(post, user)){
            LocalDateTime scrapedAt = LocalDateTime.now(); // 현재 시간을 스크랩 시간으로 설정
            PostScrap scrap = new PostScrap(post, user) ;
            postScrapRepository.save(scrap);
            return new MessageResponseDto("스크랩");
        }

        PostScrap scrap = postScrapRepository.findByPostAndUser(post, user).orElseThrow(
                ()-> new IllegalArgumentException("스크랩에 대한 정보가 존재하지 않습니다."));
        postScrapRepository.delete(scrap);
        return new MessageResponseDto("스크랩 취소");
    }
}

사용자가 게시글을 스크랩했는지 안했는지에 따라서 스크랩을 한 이력이 없다면 저장시키고 "스크랩" 메세지를 반환하고, 있다면 해당 스크랩 정보를 삭제하고 "스크랩 취소" 메세지를 반환한다.

 

PostScrap

@Entity
@Getter
@NoArgsConstructor
@Table(name = "post_scrap")
public class PostScrap {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "post_scrap_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "post_id")
    private Post post;

    @Column
    @Temporal(TemporalType.TIMESTAMP)
    private LocalDateTime scrapedAt; // 스크랩한 시간을 저장할 필드

    public PostScrap(Post post, User user, LocalDateTime scrapedAt) {
        this.post = post;
        this.user = user;
        this.scrapedAt = scrapedAt;
    }
}



Post Entity 와도 양방향 연관관계 걸어줌

    @JsonManagedReference
    @OneToMany(mappedBy = "post", cascade = {CascadeType.REMOVE})
    private List<PostScrap> scraps = new ArrayList<>();

내가 스크랩한 글 조회하기


    post controller

    //내가 스크랩한 글 조회
    @GetMapping("/myscrap")
    public PostListResponse getMyScrap(@RequestParam int page,
                                       @RequestParam int size,
                                       @AuthenticationPrincipal UserDetailsImpl userDetails){
        User user = userDetails.getUser();
        return postService.getMyScrap(page-1, size, user);
    }

페이징 처리를 해주었고, 프런트 쪽에서 size를 정할 수 있게 하였다. 이번 프로젝트에서는 페이징 처리 부분을 모두 이렇게 하여 프런트가 상황에 맞게 쓰기 편하게 함! 자잘 자잘하게 변경되는 부분들이 자주 있었기 때문이다.

 

 

  post service
  
    // 사용자가 스크랩한 글 조회
    public PostListResponse getMyScrap(int page, int size, User user) {
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "scrapedAt"));
        Page<PostScrap> scrapPages = postScrapRepository.findAllByUser(user, pageable);

        // 스크랩한 글을 가져와서 리스트로 변환
        List<Post> myScrapPosts = scrapPages.getContent().stream()
                .map(PostScrap::getPost)
                .collect(Collectors.toList());

        // 가져온 글을 PostResultDto로 매핑하여 리스트로 변환
        List<PostResultDto> postResultDtos = myScrapPosts.stream()
                .map(post -> mapToPostResultDto(post, user))
                .collect(Collectors.toList());

        return new PostListResponse("스크랩한 글 조회 성공", scrapPages.getTotalPages(), scrapPages.getTotalElements(), size, postResultDtos);
    }

 

페이징 처리를 해주며 스크랩한 시간을 기준으로 내림차순한다. (제일 최근에 스크랩한 글이 제일 상단에 위치하도록)


결과


왼 - 스크랩 한 번 눌렀을 때 / 오 - 스크랩 한 번 더 눌렀을 때

 

스크랩한 글 조회 성공!