Skip to content

Commit

Permalink
Merge pull request #7 from UMC-ON/feat/boardnpost
Browse files Browse the repository at this point in the history
[feature]게시글 기능 구현 - PostController 및 DTO
  • Loading branch information
sanggae4133 authored Aug 10, 2024
2 parents 43647d8 + 830f7a5 commit 543322d
Show file tree
Hide file tree
Showing 20 changed files with 370 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/main/java/com/on/server/domain/board/domain/Board.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.on.server.domain.board.domain;

import com.on.server.domain.post.domain.Post;
import com.on.server.global.domain.BaseEntity;
import jakarta.persistence.*;
import lombok.*;

import java.util.ArrayList;
import java.util.List;

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Table(name = "board")
public class Board extends BaseEntity {

@Enumerated(EnumType.STRING)
@Column(name = "type", nullable = false, unique = true)
private BoardType type;

@OneToMany(mappedBy = "board", cascade = CascadeType.ALL)
private List<Post> posts = new ArrayList<>();

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.on.server.domain.board.domain;

public enum BoardType {
INFO, // 정보게시판
FREE // 자유게시판
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.on.server.domain.board.domain.repository;

import com.on.server.domain.board.domain.Board;
import com.on.server.domain.board.domain.BoardType;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface BoardRepository extends JpaRepository<Board, Long> {
Optional<Board> findByType(BoardType type);
}
16 changes: 16 additions & 0 deletions src/main/java/com/on/server/domain/board/dto/BoardDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.on.server.domain.board.dto;

import com.on.server.domain.board.domain.BoardType;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class BoardDTO {

// 게시판 ID
private Long boardId;

// 게시판 타입
private BoardType type;
}
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
110 changes: 110 additions & 0 deletions src/main/java/com/on/server/domain/post/application/PostService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package com.on.server.domain.post.application;

import com.on.server.domain.board.domain.Board;
import com.on.server.domain.board.domain.BoardType;
import com.on.server.domain.board.domain.repository.BoardRepository;
import com.on.server.domain.post.domain.Post;
import com.on.server.domain.post.domain.repository.PostRepository;
import com.on.server.domain.post.dto.PostRequestDTO;
import com.on.server.domain.post.dto.PostResponseDTO;
import com.on.server.domain.user.domain.User;
import com.on.server.domain.user.domain.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Transactional
public class PostService {

private final PostRepository postRepository;
private final UserRepository userRepository;
private final BoardRepository boardRepository;

// 1. 특정 게시판의 모든 게시글 조회
@Transactional(readOnly = true)
public List<PostResponseDTO> getAllPostsByBoardType(BoardType boardType) {
Board board = boardRepository.findByType(boardType)
.orElseThrow(() -> new RuntimeException("게시판을 찾을 수 없습니다."));
return board.getPosts().stream()
.map(this::mapToPostResponseDTO)
.collect(Collectors.toList());
}

// 2. 특정 게시판에 새로운 게시글 작성
public PostResponseDTO createPost(BoardType boardType, PostRequestDTO postRequestDTO) {
User user = userRepository.findById(postRequestDTO.getUserId())
.orElseThrow(() -> new RuntimeException("사용자를 찾을 수 없습니다."));
Board board = boardRepository.findByType(boardType)
.orElseThrow(() -> new RuntimeException("게시판을 찾을 수 없습니다."));

Post post = Post.builder()
.title(postRequestDTO.getTitle())
.content(postRequestDTO.getContent())
.isAnonymous(postRequestDTO.isAnonymous())
.isAnonymousUniv(postRequestDTO.isAnonymousUniv())
.board(board)
.user(user)
.build();

postRepository.save(post);

return mapToPostResponseDTO(post);
}

// 3. 특정 게시글 조회
@Transactional(readOnly = true)
public PostResponseDTO getPostById(BoardType boardType, Long postId) {
Post post = postRepository.findById(postId)
.orElseThrow(() -> new RuntimeException("게시글을 찾을 수 없습니다."));
if (!post.getBoard().getType().equals(boardType)) {
throw new RuntimeException("해당 게시판에 게시글이 존재하지 않습니다.");
}
return mapToPostResponseDTO(post);
}

// 4. 특정 사용자가 특정 게시판에 작성한 모든 게시글 조회
@Transactional(readOnly = true)
public List<PostResponseDTO> getPostsByUserIdAndBoardType(Long userId, BoardType boardType) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("사용자를 찾을 수 없습니다."));
Board board = boardRepository.findByType(boardType)
.orElseThrow(() -> new RuntimeException("게시판을 찾을 수 없습니다."));

List<Post> posts = postRepository.findByUserAndBoard(user, board);
return posts.stream()
.map(this::mapToPostResponseDTO)
.collect(Collectors.toList());
}

// 5. 특정 게시글 삭제
public void deletePost(Long userId, BoardType boardType, Long postId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("사용자를 찾을 수 없습니다."));
Post post = postRepository.findById(postId)
.orElseThrow(() -> new RuntimeException("게시글을 찾을 수 없습니다."));

if (!post.getUser().getId().equals(userId) || !post.getBoard().getType().equals(boardType)) {
throw new RuntimeException("해당 게시판에 게시글이 존재하지 않습니다.");
}

postRepository.delete(post);
}

// Post 엔티티를 PostResponseDTO로 매핑하는 메서드
private PostResponseDTO mapToPostResponseDTO(Post post) {
return PostResponseDTO.builder()
.postId(post.getId())
.boardType(post.getBoard().getType())
.userId(post.getUser().getId())
.title(post.getTitle())
.content(post.getContent())
.isAnonymous(post.getIsAnonymous())
.isAnonymousUniv(post.getIsAnonymousUniv())
.build();
}
}
43 changes: 43 additions & 0 deletions src/main/java/com/on/server/domain/post/domain/Post.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.on.server.domain.post.domain;

import com.on.server.domain.board.domain.Board;
import com.on.server.domain.user.domain.User;
import com.on.server.global.domain.BaseEntity;
import jakarta.persistence.*;
import lombok.*;


@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
@Table(name = "post")
public class Post extends BaseEntity {

@Column(name = "title", nullable = false)
private String title;

@Column(name = "content")
private String content;

@Column(name = "is_anonymous", nullable = false)
private Boolean isAnonymous;

@Column(name = "is_anonymous_univ", nullable = false)
private Boolean isAnonymousUniv;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "board_id", nullable = false)
private Board board;

// @OneToMany(mappedBy = "post", cascade = CascadeType.ALL)
// private List<Comment> comments = new ArrayList<>();

// @OneToMany(mappedBy = "post", cascade = CascadeType.ALL)
// private List<Image> images = new ArrayList<>();

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.on.server.domain.post.domain.repository;

import com.on.server.domain.board.domain.Board;
import com.on.server.domain.post.domain.Post;
import com.on.server.domain.user.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface PostRepository extends JpaRepository<Post, Long> {

List<Post> findByUserAndBoard(User user, Board board);
}
29 changes: 29 additions & 0 deletions src/main/java/com/on/server/domain/post/dto/PostRequestDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.on.server.domain.post.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@Getter
@NoArgsConstructor
public class PostRequestDTO {

// 작성자 ID
private Long userId;

// 게시글 제목
private String title;

// 게시글 내용
private String content;

// 익명 여부
private boolean isAnonymous;

// 파견교 공개 여부
private boolean isAnonymousUniv;

// 이미지 ID 리스트
private List<Long> imageIdList;
}
40 changes: 40 additions & 0 deletions src/main/java/com/on/server/domain/post/dto/PostResponseDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.on.server.domain.post.dto;

import com.on.server.domain.board.domain.BoardType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PostResponseDTO {

// 게시판 타입
private BoardType boardType;

// 게시글 ID
private Long postId;

// 작성자 ID
private Long userId;

// 게시글 제목
private String title;

// 게시글 내용
private String content;

// 익명 여부
private boolean isAnonymous;

// 파견교 공개 여부
private boolean isAnonymousUniv;

// 이미지 ID 리스트
private List<Long> imageIdList;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.on.server.domain.post.presentation;

import com.on.server.domain.post.application.PostService;
import com.on.server.domain.post.dto.PostRequestDTO;
import com.on.server.domain.post.dto.PostResponseDTO;
import com.on.server.domain.board.domain.BoardType;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Tag(name = "게시글 작성")
@RestController
@RequiredArgsConstructor
@RequestMapping("/posts")
public class PostController {

private final PostService postService;

// 1. 특정 게시판(boardType)의 모든 게시글을 조회
@Operation(summary = "특정 게시판의 모든 게시글 조회")
@GetMapping("/{boardType}")
public ResponseEntity<List<PostResponseDTO>> getAllPostsByBoardType(@PathVariable BoardType boardType) {
// PostService를 호출하여 특정 boardType에 해당하는 게시글 목록을 가져옴
List<PostResponseDTO> posts = postService.getAllPostsByBoardType(boardType);

// 조회된 게시글 목록을 응답 본문에 담아 HTTP 200 OK 상태와 함께 반환
return ResponseEntity.ok(posts);
}

// 2. 특정 게시판(boardType)에 새로운 게시글을 작성
@Operation(summary = "특정 게시판에 새로운 게시글 작성")
@PostMapping("/{boardType}")
public ResponseEntity<PostResponseDTO> createPost(@PathVariable BoardType boardType, @RequestBody PostRequestDTO postRequestDTO) {
// PostService를 호출하여 새로운 게시글을 생성
PostResponseDTO createdPost = postService.createPost(boardType, postRequestDTO);

// 생성된 게시글을 응답 본문에 담아 HTTP 201 Created 상태와 함께 반환
return ResponseEntity.status(HttpStatus.CREATED).body(createdPost);
}

// 3. 특정 게시판(boardType) 내의 특정 게시글(postId)을 조회
@Operation(summary = "특정 게시판 내의 특정 게시글 조회")
@GetMapping("/{boardType}/{postId}")
public ResponseEntity<PostResponseDTO> getPostById(@PathVariable BoardType boardType, @PathVariable Long postId) {
// PostService를 호출하여 특정 boardType과 postId에 해당하는 게시글을 가져옴
PostResponseDTO post = postService.getPostById(boardType, postId);

// 조회된 게시글을 응답 본문에 담아 HTTP 200 OK 상태와 함께 반환
return ResponseEntity.ok(post);
}

// 4. 자기가 특정 게시판에 작성한 모든 게시글 조회
@Operation(summary = "사용자가 특정 게시판에 작성한 모든 게시글 조회")
@GetMapping("/user/{userId}/{boardType}")
public ResponseEntity<List<PostResponseDTO>> getPostsByUserIdAndBoardType(@PathVariable Long userId, @PathVariable BoardType boardType) {
List<PostResponseDTO> posts = postService.getPostsByUserIdAndBoardType(userId, boardType);
return ResponseEntity.ok(posts);
}

// 5. 자기가 특정 게시판에 작성한 특정 게시글(postId)을 삭제
@Operation(summary = "사용자가 특정 게시판에 작성한 특정 게시글 삭제")
@DeleteMapping("/user/{userId}/{boardType}/{postId}")
public ResponseEntity<Void> deletePost(@PathVariable Long userId, @PathVariable BoardType boardType, @PathVariable Long postId) {
// PostService를 호출하여 특정 boardType, postId 및 userId에 해당하는 게시글을 삭제
postService.deletePost(userId, boardType, postId);

// HTTP 204 No Content 상태를 반환하여 성공적으로 삭제되었음을 알림
return ResponseEntity.noContent().build();
}
}

0 comments on commit 543322d

Please sign in to comment.