Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/10 board - 게시판 entity , repo 작성 #20

Merged
merged 18 commits into from
Oct 13, 2023
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ out/
### VS Code ###
.vscode/

.DS_Store
.DS_Store

1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ dependencies {
// IAMPORT
implementation 'com.github.iamport:iamport-rest-client-java:0.2.23'


// Lombok And Annotation Processor
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package HookKiller.server.board.controller;

import HookKiller.server.board.dto.ArticleRequestDto;
import HookKiller.server.board.dto.PostArticleRequestDto;
import HookKiller.server.board.service.ArticleContentService;
import HookKiller.server.board.service.ArticleService;
import HookKiller.server.common.type.LanguageType;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import org.springframework.web.bind.annotation.*;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


import java.util.List;

@Slf4j
@RestController
@RequestMapping("/article")
@RequiredArgsConstructor
public class ArticleController {

private final ArticleService articleService;
private final ArticleContentService articleContentService;

/**
* 게시글 조회
*/
@GetMapping("/{boardId}")
public List<ArticleRequestDto> getArticleList(@PathVariable Long boardId, HttpServletRequest request) {
return articleService.getArticleList(boardId, LanguageType.findTypeByRequest(request));
}

/**
* 단건 조회
*/
// @GetMapping("/{boardId}/{articleId}")
// public ArticleRequestDto getArticle(@PathVariable Long articleId, HttpServletRequest request) {
// BoardType language = BoardType.valueOf(request.getHeader("language"));
// return articleService.getArticle(boardId, articleId, language);
// }

/**
* 게시글 등록
*/
@PostMapping
public ResponseEntity<String> createArticle(@RequestBody PostArticleRequestDto requestDto) {
articleContentService.createContent(
requestDto, articleService.createArticle(requestDto)
);
Comment on lines +47 to +49
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기는 깊게 생각해봤는데 두개를 한개의 메소드에서 작업하고 Transactional 처리를 해야 할 것 같습니다.

번역에 실패하면 롤백해야 하기 떄문입니다.

return ResponseEntity.ok("Article Create Success");
}

/**
* 게시물 수정
*/
@PutMapping
public ResponseEntity<String> updateArticle(@RequestBody PostArticleRequestDto requestDto) {
articleContentService.updateContent(requestDto, articleService.updateArticle(requestDto));
return ResponseEntity.ok("Article Create Success");
}


/**
* 게시물 삭제
*/
@DeleteMapping("/{articleId}")
public ResponseEntity<String> deleteArticle(@PathVariable Long articleId) {
articleService.deleteArticle(articleId);
return ResponseEntity.ok("삭제처리가 완료되었습니다.");
}

}
47 changes: 47 additions & 0 deletions src/main/java/HookKiller/server/board/dto/ArticleRequestDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package HookKiller.server.board.dto;

import HookKiller.server.board.entity.Article;
import HookKiller.server.board.entity.ArticleContent;
import HookKiller.server.board.type.ArticleStatus;
import HookKiller.server.common.AbstractTimeStamp;
import HookKiller.server.common.type.LanguageType;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Lob;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class ArticleRequestDto extends AbstractTimeStamp {

private Long boardId;

private Long articleId;

@Enumerated(EnumType.STRING)
private LanguageType orgArticleLanguage;

@Enumerated(EnumType.STRING)
private ArticleStatus status;

private int likeCount;

@Enumerated(EnumType.STRING)
private LanguageType contentLanguage;

private String title;

@Lob
private String content;

public static ArticleRequestDto of(Article article, ArticleContent articleContent) {
return ArticleRequestDto.builder()
.articleId(article.getId())
.title(articleContent.getTitle())
.content(articleContent.getContent())
.likeCount(article.getLikeCount())
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package HookKiller.server.board.dto;

import HookKiller.server.common.type.LanguageType;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Lob;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PostArticleRequestDto {
@NotNull(message = "게시판 ID는 필수 입니다.")
private Long boardId;

private Long articleId;

@NotNull(message = "원본 언어는 필수 선택 하셔야 합니다.")
@Enumerated(EnumType.STRING)
private LanguageType orgArticleLanguage;

@NotEmpty(message = "제목이 입력되지 않았습니다.")
private String title;

@NotEmpty(message = "내용이 입력되지 않았습니다.")
private String content;
}
94 changes: 94 additions & 0 deletions src/main/java/HookKiller/server/board/entity/Article.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package HookKiller.server.board.entity;

import HookKiller.server.board.type.ArticleStatus;
import HookKiller.server.common.AbstractTimeStamp;
import HookKiller.server.common.type.LanguageType;
import HookKiller.server.user.entity.User;
import jakarta.persistence.Entity;
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 jakarta.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

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

/**
* id : PK 키
* orgArticleLanguage : 원본으로 작성된 언어 타입. KOR:한국어, ENG:영어, CHI:중국어, JPN:일본어
* status: 게시물 상태. PUBLIC:공개, DELETE:삭제처리
* likeCount : 좋아요 갯수.
* isDeleted : 게시글 삭제 여부
* createdAt : 게시글 생성일
* createdUser : 게시글 작성 사용자 ID입력
* updatedUser : 마지막에 수정한 사용자 ID입력
*/

@Entity
@Getter
@Setter
@Table(name = "tbl_article")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Article extends AbstractTimeStamp {

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

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

@OneToMany(mappedBy = "article", fetch = FetchType.LAZY)
private List<ArticleLike> ArticleLike = new ArrayList<>();

@OneToMany(mappedBy = "article", fetch = FetchType.LAZY)
private List<ArticleContent> articleContent = new ArrayList<>();

@OneToMany(mappedBy = "article", fetch = FetchType.LAZY)
private List<Reply> reply = new ArrayList<>();

@NotNull
private LanguageType orgArticleLanguage;

@NotNull
@Enumerated(EnumType.STRING)
private ArticleStatus articleStatus;

private int likeCount;

@NotNull
@ManyToOne(fetch = FetchType.EAGER)
private User createdUser;

@NotNull
@ManyToOne(fetch = FetchType.EAGER)
private User updatedUser;

public void updateStatus(ArticleStatus status) {
articleStatus = status;
}

@Builder
public Article(Board board, Long id, LanguageType orgArticleLanguage, ArticleStatus articleStatus, User createdUser, User updatedUser) {
this.board = board;
this.id = id;
this.articleStatus = articleStatus;
this.orgArticleLanguage = orgArticleLanguage;
this.createdUser = createdUser;
this.updatedUser = updatedUser;
}

}
67 changes: 67 additions & 0 deletions src/main/java/HookKiller/server/board/entity/ArticleContent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package HookKiller.server.board.entity;


import HookKiller.server.common.type.LanguageType;
import jakarta.persistence.Entity;
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.Lob;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

/**
* id : PK
* article : 게시글 정보
* language : 적용된 언어 타입
* title : 게시글 제목
* content : 게시글 내용
*/

@Entity
@Getter
@Table(name = "tbl_article_content")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ArticleContent {

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

@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="article_id")
private Article article;

@Enumerated(EnumType.STRING)
private LanguageType language;

@NotNull
private String title;

@NotNull
@Lob
private String content;

@Builder
public ArticleContent(Article article, LanguageType language, String title, String content) {
this.article = article;
this.language = language;
this.title = title;
this.content = content;
}

public void articleUpdate(String title, String content) {
this.title = title;
this.content = content;
}
}
39 changes: 39 additions & 0 deletions src/main/java/HookKiller/server/board/entity/ArticleLike.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package HookKiller.server.board.entity;


import HookKiller.server.common.AbstractTimeStamp;
import jakarta.persistence.Entity;
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.Getter;
import lombok.NoArgsConstructor;

/**
* id : PK
* article : 게시물 정보
* userId : 좋아요를 누른 사용자의 userId
* createdAt : 게시물 좋아요를 클릭한 일자
*/

@Entity
@Getter
@Table(name = "tbl_article_like")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ArticleLike extends AbstractTimeStamp {

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

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="article_id")
private Article article;

private Long userId;
}
Loading