-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[Feat] #18 피드 CRUD 기능 구현
- Loading branch information
Showing
21 changed files
with
601 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,36 @@ | ||
package com.leets.X.domain.like.domain; | ||
package com.leets.X.domain.like.domain; | ||
|
||
import jakarta.persistence.*; | ||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.NoArgsConstructor; | ||
import com.leets.X.domain.post.domain.Post; | ||
import com.leets.X.domain.user.domain.User; | ||
import jakarta.persistence.*; | ||
import lombok.*; | ||
|
||
@Entity | ||
// mysql 예약어이기 때문에 별도 지정 | ||
@Table(name = "likes") | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor | ||
@Builder | ||
public class Like { | ||
@Entity | ||
// mysql 예약어이기 때문에 별도 지정 | ||
@Table(name = "likes") | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor | ||
@Builder | ||
@Getter | ||
public class Like { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "like_id") | ||
private Long id; | ||
} | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "like_id") | ||
private Long id; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "post_id") | ||
private Post post; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "user_id") | ||
private User user; | ||
|
||
// 게시물과 사용자 정보를 받는 생성자 추가 | ||
public Like(Post post, User user) { | ||
this.post = post; | ||
this.user = user; | ||
} | ||
|
||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/com/leets/X/domain/like/repository/LikeRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.leets.X.domain.like.repository; | ||
|
||
import com.leets.X.domain.like.domain.Like; | ||
import com.leets.X.domain.post.domain.Post; | ||
import com.leets.X.domain.user.domain.User; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface LikeRepository extends JpaRepository<Like, Long> { | ||
boolean existsByPostAndUser(Post post, User user); // 좋아요 여부 확인 | ||
void deleteByPostAndUser(Post post, User user); // 좋아요 삭제 | ||
long countByPost(Post post); // 특정 게시물의 좋아요 수 계산 | ||
} |
84 changes: 84 additions & 0 deletions
84
src/main/java/com/leets/X/domain/post/controller/PostController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package com.leets.X.domain.post.controller; | ||
|
||
import com.leets.X.domain.post.domain.Post; | ||
import com.leets.X.domain.post.dto.request.PostRequestDTO; | ||
import com.leets.X.domain.post.dto.response.PostResponseDto; | ||
import com.leets.X.domain.post.service.PostService; | ||
import com.leets.X.global.common.response.ResponseDto; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
//컨트롤러에서 ResponseDto만들게끔 | ||
@Tag(name = "POST") | ||
@RestController | ||
@RequestMapping("/api/v1/posts") | ||
@RequiredArgsConstructor | ||
public class PostController { | ||
|
||
private final PostService postService; | ||
|
||
|
||
@GetMapping("/{id}") | ||
@Operation(summary = "게시물 ID로 조회") | ||
public ResponseDto<PostResponseDto> getPost(@PathVariable Long id) { | ||
PostResponseDto postResponseDto = postService.getPostResponse(id); | ||
return ResponseDto.response(ResponseMessage.GET_POST_SUCCESS.getCode(), ResponseMessage.GET_POST_SUCCESS.getMessage(), postResponseDto); | ||
} | ||
|
||
|
||
@GetMapping("/likes") | ||
@Operation(summary = "좋아요 수로 정렬한 게시물 조회") | ||
public ResponseDto<List<PostResponseDto>> getPostsSortedByLikes() { | ||
List<PostResponseDto> posts = postService.getPostsSortedByLikes(); | ||
return ResponseDto.response(ResponseMessage.GET_SORTED_BY_LIKES_SUCCESS.getCode(), ResponseMessage.GET_SORTED_BY_LIKES_SUCCESS.getMessage(), posts); | ||
} | ||
|
||
|
||
@GetMapping("/latest") | ||
@Operation(summary = "최신 게시물 조회") | ||
public ResponseDto<List<PostResponseDto>> getLatestPosts() { | ||
List<PostResponseDto> posts = postService.getLatestPosts(); | ||
return ResponseDto.response(ResponseMessage.GET_LATEST_POST_SUCCESS.getCode(), ResponseMessage.GET_LATEST_POST_SUCCESS.getMessage(), posts); | ||
} | ||
|
||
|
||
@PostMapping("/post") | ||
@Operation(summary = "글 생성") | ||
public ResponseDto<PostResponseDto> createPost(@RequestBody PostRequestDTO postRequestDTO, @AuthenticationPrincipal String email) { | ||
// 인증된 사용자의 이메일을 `@AuthenticationPrincipal`을 통해 주입받음 | ||
PostResponseDto postResponseDto = postService.createPost(postRequestDTO, email); | ||
return ResponseDto.response(ResponseMessage.POST_SUCCESS.getCode(), ResponseMessage.POST_SUCCESS.getMessage(), postResponseDto); | ||
} | ||
|
||
@PostMapping("/{postId}/like") | ||
@Operation(summary = "게시물에 좋아요 추가") | ||
public ResponseDto<String> addLike(@PathVariable Long postId, @AuthenticationPrincipal String email) { | ||
String responseMessage = postService.addLike(postId, email); | ||
return ResponseDto.response(ResponseMessage.ADD_LIKE_SUCCESS.getCode(), responseMessage); | ||
} | ||
|
||
|
||
@DeleteMapping("/{postId}") | ||
@Operation(summary = "게시물 삭제") | ||
public ResponseDto<String> deletePost(@PathVariable Long postId, @AuthenticationPrincipal String email) { | ||
String responseMessage = postService.deletePost(postId, email); | ||
return ResponseDto.response(ResponseMessage.POST_DELETED_SUCCESS.getCode(), responseMessage); | ||
} | ||
|
||
|
||
@DeleteMapping("/{postId}/like") | ||
@Operation(summary = "좋아요 취소") | ||
public ResponseDto<String> cancelLike(@PathVariable Long postId, @AuthenticationPrincipal String email) { | ||
String responseMessage = postService.cancelLike(postId, email); | ||
return ResponseDto.response(ResponseMessage.LIKE_CANCEL_SUCCESS.getCode(), responseMessage); | ||
} | ||
|
||
|
||
|
||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/com/leets/X/domain/post/controller/ResponseMessage.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.leets.X.domain.post.controller; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@AllArgsConstructor | ||
public enum ResponseMessage { | ||
|
||
POST_SUCCESS(201, "게시물이 성공적으로 생성되었습니다."), | ||
GET_POST_SUCCESS(200, "게시물 조회에 성공했습니다."), | ||
GET_SORTED_BY_LIKES_SUCCESS(200, "좋아요 순으로 게시물 조회에 성공했습니다."), | ||
GET_LATEST_POST_SUCCESS(200, "최신 게시물 조회에 성공했습니다."), | ||
ADD_LIKE_SUCCESS(201, "좋아요가 추가되었습니다."), | ||
POST_DELETED_SUCCESS(200, "게시물이 성공적으로 삭제되었습니다."), | ||
LIKE_CANCEL_SUCCESS(200, "좋아요가 성공적으로 취소되었습니다."); | ||
|
||
private final int code; | ||
private final String message; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,94 @@ | ||
package com.leets.X.domain.post.domain; | ||
|
||
import com.leets.X.domain.comment.domain.Comment; | ||
import com.leets.X.domain.image.domain.Image; | ||
import com.leets.X.domain.like.domain.Like; | ||
import com.leets.X.domain.post.domain.enums.IsDeleted; | ||
import com.leets.X.domain.user.domain.User; | ||
import com.leets.X.global.common.domain.BaseTimeEntity; | ||
import jakarta.persistence.*; | ||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.NoArgsConstructor; | ||
import lombok.*; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
@Entity | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor | ||
@Builder | ||
@Getter | ||
public class Post extends BaseTimeEntity { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
@Column(name = "post_id") | ||
private Long id; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "user_id") | ||
private User user; | ||
|
||
@OneToMany(mappedBy = "post", cascade = CascadeType.REMOVE, orphanRemoval = true) | ||
private List<Like> likes = new ArrayList<>(); | ||
|
||
@OneToMany(mappedBy = "post", cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY) | ||
private List<Image> images = new ArrayList<>(); | ||
|
||
|
||
@Column(columnDefinition = "TEXT") | ||
private String content; | ||
|
||
private Integer views; | ||
|
||
private Boolean isDeleted; | ||
private IsDeleted isDeleted; | ||
|
||
private LocalDateTime deletedAt; | ||
|
||
@OneToMany(mappedBy = "post") | ||
private List<Comment> commentList; | ||
// 좋아요 수를 관리하기 위한 필드 | ||
|
||
@Column(name = "like_count") | ||
private Long likeCount = 0L; // 기본값을 0L로 초기화하여 null을 방지 | ||
|
||
public void incrementLikeCount() { | ||
if (this.likeCount == null) { | ||
this.likeCount = 1L; // null인 경우 1로 초기화 | ||
} else { | ||
this.likeCount++; | ||
} | ||
} | ||
|
||
// private List<Image> imageList; | ||
public void decrementLikeCount() { | ||
if (this.likeCount == null || this.likeCount == 0) { | ||
this.likeCount = 0L; // null이거나 0일 경우 0으로 유지 | ||
} else { | ||
this.likeCount--; | ||
} | ||
} | ||
|
||
public long getLikesCount() { | ||
return likeCount != null ? likeCount : 0; // null일 경우 0 반환 | ||
} | ||
|
||
|
||
|
||
// 서비스에서 글의 상태를 삭제 상태로 바꾸기 위한 메서드 | ||
public void delete() { | ||
if (this.isDeleted == IsDeleted.ACTIVE) { // 이미 삭제 상태가 아닐 때만 변경 | ||
this.isDeleted = IsDeleted.DELETED; | ||
} | ||
} | ||
|
||
// 정적 메서드로 글 생성 | ||
public static Post create(User user, String content) { | ||
return Post.builder() | ||
.user(user) | ||
.content(content) | ||
.views(0) // 기본 조회 수 | ||
.likeCount(0L) // 좋아요 갯수 추가 | ||
.isDeleted(IsDeleted.ACTIVE) // 기본값 ACTIVE로 설정 | ||
.images(new ArrayList<>()) // 빈 리스트로 초기화 | ||
.build(); | ||
} | ||
} | ||
|
6 changes: 6 additions & 0 deletions
6
src/main/java/com/leets/X/domain/post/domain/enums/IsDeleted.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.leets.X.domain.post.domain.enums; | ||
|
||
public enum IsDeleted { | ||
ACTIVE, //게시물이 활성화된 상태 | ||
DELETED // 게시물이 삭제된 상태 | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/com/leets/X/domain/post/dto/request/PostRequestDTO.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.leets.X.domain.post.dto.request; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
|
||
public record PostRequestDTO(@NotBlank(message = "Content cannot be empty") String content) { | ||
|
||
public static PostRequestDTO from(String content) { | ||
return new PostRequestDTO(content); | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
src/main/java/com/leets/X/domain/post/dto/response/CommentResponseDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.leets.X.domain.post.dto.response; | ||
|
||
import com.leets.X.domain.comment.domain.Comment; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public class CommentResponseDto { | ||
private Long commentId; | ||
private String content; | ||
|
||
public static CommentResponseDto from(Comment comment) { | ||
return new CommentResponseDto(comment.getId(), comment.getContent()); | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/com/leets/X/domain/post/dto/response/ImageResponseDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package com.leets.X.domain.post.dto.response; | ||
|
||
import com.leets.X.domain.image.domain.Image; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public class ImageResponseDto { | ||
|
||
private Long imageId; | ||
private String url; | ||
|
||
public static ImageResponseDto from(Image image) { | ||
return new ImageResponseDto(image.getId(), image.getUrl()); | ||
} | ||
} |
Oops, something went wrong.