Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public enum ResponseCode {
IMAGE_NOT_FOUND("IMG-001", "There's no image onb request."),
COMMENT_NOT_FOUND("CMT-001", "No such comment exist."),
COMMENT_WRITER_DIFFERENCE("CMT-002", "User and author are different"),
LIKE_NOT_FOUND("LKE-001", "Like count not found."),
LIKE_DUPLICATE("LKE-002", "Like is duplicate.")
;

private final String responseCode;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.develop_mouse.gummy_dang.like.controller;

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.develop_mouse.gummy_dang.common.domain.response.Response;
import com.develop_mouse.gummy_dang.like.domain.LikeCount;
import com.develop_mouse.gummy_dang.like.domain.LikeResponse;
import com.develop_mouse.gummy_dang.like.service.LikeServiceV2;

import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class LikeControllerV2 {

private final LikeServiceV2 likeService;

/**
* 좋아요 누르기
* @param postId : 누르고자 하는 게시글 id
*/
@PostMapping("/post/{postId}/like")
public Response<LikeResponse> createLike(@PathVariable Long postId) {
return likeService.createLike(postId);
}

/**
* 좋아요 취소
* @param postId : 취소하고자 하는 게시글 id
*/
@DeleteMapping("/post/{postId}/like")
public Response<Void> deleteLike(@PathVariable Long postId) {
return likeService.deleteLike(postId);
}

/**
* 게시글의 총 좋아요 수 가져오기
* @param postId : 조회하고자 하는 게시글 id
*/
@GetMapping("/post/{postId}/like-count")
public Response<LikeCount> getLikeCount(@PathVariable Long postId) {
return likeService.getLikeCount(postId);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.develop_mouse.gummy_dang.like.domain;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@AllArgsConstructor
@NoArgsConstructor
public class LikeCount {

private Integer likeCount;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.develop_mouse.gummy_dang.like.domain;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@AllArgsConstructor
@NoArgsConstructor
public class LikeResponse {

private Long likeId;
private Long postId;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.develop_mouse.gummy_dang.like.repository;

import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;

import com.develop_mouse.gummy_dang.like.domain.entity.Like;
import com.develop_mouse.gummy_dang.member.domain.entity.Member;
import com.develop_mouse.gummy_dang.post.domain.entity.Post;

public interface LikeRepository extends JpaRepository<Like, Long> {

Optional<Like> findByMemberAndPost(Member member, Post post);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.develop_mouse.gummy_dang.like.service;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.develop_mouse.gummy_dang.authentication.util.SecurityContextUtil;
import com.develop_mouse.gummy_dang.common.Exception.BusinessException;
import com.develop_mouse.gummy_dang.common.domain.ResponseCode;
import com.develop_mouse.gummy_dang.common.domain.response.Response;
import com.develop_mouse.gummy_dang.like.domain.LikeCount;
import com.develop_mouse.gummy_dang.like.domain.LikeResponse;
import com.develop_mouse.gummy_dang.like.domain.entity.Like;
import com.develop_mouse.gummy_dang.like.repository.LikeRepository;
import com.develop_mouse.gummy_dang.member.domain.entity.Member;
import com.develop_mouse.gummy_dang.member.repository.MemberRepository;
import com.develop_mouse.gummy_dang.post.domain.entity.Post;
import com.develop_mouse.gummy_dang.post.repository.PostRepository;

import lombok.RequiredArgsConstructor;

@Service
@Transactional
@RequiredArgsConstructor
public class LikeServiceV2 {

private final LikeRepository likeRepository;
private final PostRepository postRepository;
private final SecurityContextUtil securityContextUtil;
private final MemberRepository memberRepository;

public Response<LikeResponse> createLike(Long postId) {
// Member 정보 조회
Member member = memberRepository.findById(securityContextUtil.getContextMemberInfo().getMemberId())
.stream()
.findAny()
.orElseThrow(() -> new BusinessException(ResponseCode.MEMBER_NOT_FOUND));

// Post 정보 조회
Post post = postRepository.findById(postId).stream()
.findAny()
.orElseThrow(() -> new BusinessException(ResponseCode.POST_NOT_FOUND));

likeRepository.findByMemberAndPost(member, post).ifPresent(like -> {
throw new BusinessException(ResponseCode.LIKE_DUPLICATE);
});

Like like = Like.builder()
.member(member)
.post(post)
.build();

Like savedLike = likeRepository.save(like);

return Response.ok(new LikeResponse(savedLike.getId(), post.getId()));
}

public Response<Void> deleteLike(Long postId) {
// Member 정보 조회
Member member = memberRepository.findById(securityContextUtil.getContextMemberInfo().getMemberId())
.stream()
.findAny()
.orElseThrow(() -> new BusinessException(ResponseCode.MEMBER_NOT_FOUND));

// Post 정보 조회
Post post = postRepository.findById(postId).stream()
.findAny()
.orElseThrow(() -> new BusinessException(ResponseCode.POST_NOT_FOUND));

Like like = likeRepository.findByMemberAndPost(member, post).stream()
.findAny()
.orElseThrow(() -> new BusinessException(ResponseCode.LIKE_NOT_FOUND));

if (like.getMember() != member) {
throw new BusinessException(ResponseCode.MEMBER_UNAUTHORIZED);
}

likeRepository.delete(like);

return Response.ok();
}

public Response<LikeCount> getLikeCount(Long postId) {
Post post = postRepository.findByIdIs(postId).stream()
.findAny()
.orElseThrow(() -> new BusinessException(ResponseCode.POST_NOT_FOUND));

return Response.ok(new LikeCount(post.getLike().size()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public class PostResponse {
private String description;
private String imageUrl;
private LocalDate createdAt;
@Builder.Default
private Boolean liked = false;

private List<PostCoordinateDTO> postCoordinates;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
package com.develop_mouse.gummy_dang.post.repository;

import java.util.List;
import java.util.Optional;

import com.develop_mouse.gummy_dang.post.domain.entity.Post;

import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;


public interface PostRepository extends JpaRepository<Post, Long>{

@EntityGraph(attributePaths = {"like"})
Optional<Post> findByIdIs(Long postId);

@EntityGraph(attributePaths = {"member"})
List<Post> findAll();
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import com.develop_mouse.gummy_dang.common.Exception.BusinessException;
import com.develop_mouse.gummy_dang.common.domain.ResponseCode;
import com.develop_mouse.gummy_dang.common.domain.response.Response;
import com.develop_mouse.gummy_dang.like.repository.LikeRepository;
import com.develop_mouse.gummy_dang.member.domain.entity.Member;
import com.develop_mouse.gummy_dang.member.repository.MemberRepository;
import com.develop_mouse.gummy_dang.post.DTO.PostCoordinateDTO;
import com.develop_mouse.gummy_dang.post.DTO.PostDTO;
import com.develop_mouse.gummy_dang.post.domain.entity.Post;
import com.develop_mouse.gummy_dang.post.domain.entity.PostCoordinate;
import com.develop_mouse.gummy_dang.post.domain.request.PostRequest;
Expand Down Expand Up @@ -43,6 +43,7 @@ public class PostServiceImpl implements PostService{
private final MemberRepository memberRepository;
private final SecurityContextUtil securityContextUtil; // 현 사용자 불러오기 위해 주입
private final PostCoordinateRepository postCoordinateRepository;
private final LikeRepository likeRepository;

// +) 이미지에서 사용
private ServletContext servletContext; // ServletContext 주입
Expand Down Expand Up @@ -189,6 +190,7 @@ public Response<Void> deletePost(Long id) {
// 글 하나 보기
@Override
public Response<PostResponse> detailPost(Long id) {
Optional<Member> member = memberRepository.findById(securityContextUtil.getContextMemberInfo().getMemberId());
Post post = postRepository.findById(id).stream()
.findAny()
.orElseThrow(() -> new BusinessException(ResponseCode.POST_NOT_FOUND));
Expand All @@ -198,6 +200,7 @@ public Response<PostResponse> detailPost(Long id) {
.title(post.getTitle())
.description(post.getDescription())
.imageUrl(post.getImageUrl())
.liked(member.isPresent() && likeRepository.findByMemberAndPost(member.get(), post).isPresent())
.postCoordinates(post.getPostCoordinates().stream()
.map(PostCoordinateDTO::fromEntity)
.toList())
Expand All @@ -210,6 +213,7 @@ public Response<PostResponse> detailPost(Long id) {
// 글 목록
@Override
public Response<List<PostResponse>> postList() {
Optional<Member> member = memberRepository.findById(securityContextUtil.getContextMemberInfo().getMemberId());
List<Post> posts = postRepository.findAll();

List<PostResponse> postResponses = posts.stream()
Expand All @@ -218,9 +222,11 @@ public Response<List<PostResponse>> postList() {
.title(post.getTitle())
.description(post.getDescription())
.imageUrl(post.getImageUrl())
.liked(member.isPresent() && likeRepository.findByMemberAndPost(member.get(), post).isPresent())
.postCoordinates(post.getPostCoordinates().stream()
.map(PostCoordinateDTO::fromEntity)
.toList())
.createdAt(post.getCreatedAt().toLocalDate())
.build())
.toList();

Expand Down