Skip to content
Merged
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
39 changes: 39 additions & 0 deletions src/main/java/com/back/domain/post/category/entity/Category.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.back.domain.post.category.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

@Entity
@Getter
@Setter
@Table(name = "category")
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class Category {
// 각 게시글 카테고리을 구분하는 유일한 번호
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

// 카테고리 이름
@Column(name = "name", nullable = false, unique = true, length = 50)
private String name;

// 카테고리 설명
@Column(name = "description", length = 200)
private String description;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.back.domain.post.category.repository;

import com.back.domain.post.category.entity.Category;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CategoryRepository extends JpaRepository<Category, Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.back.domain.post.post.controller;

import com.back.domain.post.post.dto.request.PostRequestDto;
import com.back.domain.post.post.dto.response.PostResponseDto;
import com.back.domain.post.post.entity.Post;
import com.back.domain.post.post.service.PostService;
import com.back.global.rsData.RsData;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

private final PostService postService;

/**
* 게시글 작성 API
* @param postRequestDto 게시글 작성 요청 DTO
* @return 작성된 게시글 정보
*/
@PostMapping
public RsData<PostResponseDto> createPost(
@RequestBody PostRequestDto postRequestDto
) {
return RsData.successOf(postService.createPost(postRequestDto)); // code=200, message="success"
}

/**
* 게시글 다건 조회 API
* @return 모든 게시글 리스트
*/
@GetMapping
public RsData<List<Post>> getAllPosts() {
List<Post> posts = postService.getAllPosts();
return RsData.successOf(posts); // code=200, message="success"
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.back.domain.post.post.dto.request;

import java.util.List;

public record PostRequestDto(
Long categoryId,
String title,
String content,
String userNickName,
String imageUrl,
List<String> tags
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.back.domain.post.post.dto.response;

import com.back.domain.post.post.entity.Post;
import com.back.domain.post.post.enums.PostStatus;
import java.time.LocalDateTime;
import java.util.List;

public record PostResponseDto(
Long postId,
String categoryName,
String userNickName,
LocalDateTime createdAt,
LocalDateTime updatedAt,
PostStatus status,
String title,
String content,
String imageUrl,
List<String> tags,
Integer likeCount,
Integer commentCount,
Integer viewCount
) {

public PostResponseDto(Post post) {
this(
post.getId(),
post.getCategory().getName(),
post.getUser().getNickname(),
post.getCreatedAt(),
post.getUpdatedAt(),
post.getStatus(),
post.getTitle(),
post.getContent(),
post.getImageUrl(),
post.getPostTags().stream()
.map(postTag -> postTag.getTag().getName())
.toList(),
post.getLikeCount(),
post.getCommentCount(),
post.getViewCount()
);
}
}
104 changes: 104 additions & 0 deletions src/main/java/com/back/domain/post/post/entity/Post.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package com.back.domain.post.post.entity;

import com.back.domain.post.category.entity.Category;
import com.back.domain.post.post.enums.PostStatus;
import com.back.domain.user.entity.User;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

@Entity
@Getter
@Setter
@Table(name = "post")
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class Post {

// 각 게시글을 구분하는 유일한 번호
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

// 해당 게시글의 카테고리 고유 식별자
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_id")
private Category category;

// 해당 게시글을 작성한 유저의 고유 식별자
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

// 게시글 작성 날짜
@CreatedDate
private LocalDateTime createdAt;

// 게시글 수정 날짜
@LastModifiedDate
private LocalDateTime updatedAt;

// 게시글 게시 상태 (기본값: 공개)
@Builder.Default
@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = false)
private PostStatus status = PostStatus.PUBLIC;

// 게시글 제목
@Column(name = "title", nullable = false, length = 100)
private String title;

// 게시글 내용
@Column(name = "content", nullable = false, columnDefinition = "TEXT")
private String content;

// 게시글 이미지 URL
@Column(name = "image_url")
private String imageUrl;

@OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
private List<PostTag> postTags = new ArrayList<>();

// 게시글 추천 수 (기본값: 0)
@Builder.Default
@Column(name = "like_count", nullable = false)
private Integer likeCount = 0;

// 게시글 댓글 수
@Column(name = "comment_count")
private Integer commentCount;

// 게시글 조회 수
@Column(name = "view_count")
private Integer viewCount;

public void addTag(Tag tag) {
PostTag postTag = PostTag.create(this, tag);
this.postTags.add(postTag);
}
}
52 changes: 52 additions & 0 deletions src/main/java/com/back/domain/post/post/entity/PostTag.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.back.domain.post.post.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

@Entity
@Getter
@Table(name = "post_tag")
@EntityListeners(AuditingEntityListener.class)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class PostTag {

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

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

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "tag_id")
private Tag tag;

@Builder
public PostTag(Post post, Tag tag) {
this.post = post;
this.tag = tag;
}

// 정적 팩토리 메서드
public static PostTag create(Post post, Tag tag) {
return PostTag.builder()
.post(post)
.tag(tag)
.build();
}
}
29 changes: 29 additions & 0 deletions src/main/java/com/back/domain/post/post/entity/Tag.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.back.domain.post.post.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@Table(name = "tag")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class Tag { // Tag는 Post와 직접적인 관계를 맺지 않습니다.

@Id
@GeneratedValue
@Column(name = "id")
private Long id;

@Column(unique = true, nullable = false)
private String name;
}
15 changes: 15 additions & 0 deletions src/main/java/com/back/domain/post/post/enums/PostStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.back.domain.post.post.enums;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum PostStatus {
PUBLIC("공개", "모든 사용자가 볼 수 있는 상태"),
PRIVATE("비공개", "작성자만 볼 수 있는 상태"),
DELETED("삭제됨", "삭제 처리된 게시글 상태");

private final String title;
private final String description;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.back.domain.post.post.repository;

import com.back.domain.post.post.entity.Post;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.back.domain.post.post.repository;

import com.back.domain.post.post.entity.Tag;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface TagRepository extends JpaRepository<Tag, Long> {
// 태그 이름으로 Tag 엔티티를 찾기 위한 메서드
Optional<Tag> findByName(String name);
}
Loading