From 4ff6fc6d37486bdf949bd2d6aaea7d30b24c5293 Mon Sep 17 00:00:00 2001 From: kwchoi11 Date: Tue, 10 Oct 2023 10:41:18 +0900 Subject: [PATCH 01/14] =?UTF-8?q?feat:=20controller,=20service=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20#14?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/exception/GlobalException.java | 1 - .../notice/controller/NoticeController.java | 82 +++++++++++++++++ .../server/notice/dto/NoticeArticleDto.java | 35 ++++++++ .../server/notice/dto/NoticeContentDto.java | 27 ++++++ .../NoticeArticleNotFoundException.java | 13 +++ .../notice/exception/NoticeException.java | 24 +++++ .../repository/NoticeArticleRepository.java | 3 +- .../repository/NoticeContentRepository.java | 1 - .../server/service/NoticeService.java | 90 +++++++++++++++++++ 9 files changed, 273 insertions(+), 3 deletions(-) create mode 100644 src/main/java/HookKiller/server/notice/controller/NoticeController.java create mode 100644 src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java create mode 100644 src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java create mode 100644 src/main/java/HookKiller/server/notice/exception/NoticeArticleNotFoundException.java create mode 100644 src/main/java/HookKiller/server/notice/exception/NoticeException.java create mode 100644 src/main/java/HookKiller/server/service/NoticeService.java diff --git a/src/main/java/HookKiller/server/common/exception/GlobalException.java b/src/main/java/HookKiller/server/common/exception/GlobalException.java index 67bd4f7..07f151b 100644 --- a/src/main/java/HookKiller/server/common/exception/GlobalException.java +++ b/src/main/java/HookKiller/server/common/exception/GlobalException.java @@ -15,7 +15,6 @@ public enum GlobalException implements BaseErrorCode{ BAD_REQUEST.value(), "400-1", "메서드 인자가 유효하지 않거나 @Valid를 통과하지 못하여 발생하는 예외입니다."), INTERNAL_SERVER_ERRORS(INTERNAL_SERVER_ERROR.value(), "500-1", "서버 내부 오류입니다."); - private final Integer statusCode; private final String errorCode; private final String reason; diff --git a/src/main/java/HookKiller/server/notice/controller/NoticeController.java b/src/main/java/HookKiller/server/notice/controller/NoticeController.java new file mode 100644 index 0000000..032d5c1 --- /dev/null +++ b/src/main/java/HookKiller/server/notice/controller/NoticeController.java @@ -0,0 +1,82 @@ +package HookKiller.server.notice.controller; + +import HookKiller.server.common.type.LanguageType; +import HookKiller.server.notice.dto.NoticeArticleDto; +import HookKiller.server.notice.dto.NoticeContentDto; +import HookKiller.server.notice.entity.NoticeArticle; +import HookKiller.server.repository.NoticeArticleRepository; +import HookKiller.server.repository.NoticeContentRepository; +import HookKiller.server.service.NoticeService; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Optional; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/notice") +public class NoticeController { + + private final NoticeService noticeService; + private final NoticeArticleRepository articleRepository; + private final NoticeContentRepository contentRepository; + + /** + * 단건 조회 + * @param noticeArticleId + * @param request + * @param languageType + * @return + */ + @GetMapping("{/noticeArticleId}") + public NoticeArticleDto getNoticeArticle(@PathVariable Long noticeArticleId, HttpServletRequest request, LanguageType languageType) { + request.getHeader("languageType"); + return noticeService.getNoticeArticleByArticleId(noticeArticleId, languageType); + } + + /** + * 리스트 조회 + * @param request + * @param languageType + * @param requestData + * @return + */ + @GetMapping + public List getNoticeArticleList(HttpServletRequest request, LanguageType languageType, NoticeArticleDto requestData) { + request.getHeader("id"); + Long id = requestData.getId(); + List articleDto = noticeService.getNoticeArticleList(id, languageType); + return articleDto; + } + + /** + * 공지사항 등록 + */ + @PostMapping + public void addNotice(@RequestBody @Valid NoticeArticleDto articleRequest, NoticeContentDto contentRequest) { + noticeService.saveNotice(articleRequest, contentRequest); + } + + /** + * 공지사항 수정 + */ + @PutMapping("/{id}") + public void updateNotice(@PathVariable Long id, + @RequestBody @Valid NoticeArticleDto articleDto, NoticeContentDto contentDto) { + noticeService.update(id, articleDto); + Optional findNotice = articleRepository.findById(id); + } + + /** + * 공지사항 삭제 + */ + @DeleteMapping("/{noticeArticleId}") + public void deleteNotice(@PathVariable Long noticeArticleId) { + noticeService.deleteNotice(noticeArticleId); + } + +} + diff --git a/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java b/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java new file mode 100644 index 0000000..1e31f7a --- /dev/null +++ b/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java @@ -0,0 +1,35 @@ +package HookKiller.server.notice.dto; + +import HookKiller.server.common.type.LanguageType; +import HookKiller.server.common.type.NoticeArticleStatus; +import HookKiller.server.notice.entity.NoticeArticle; +import HookKiller.server.notice.entity.NoticeContent; +import lombok.Builder; +import lombok.Getter; + +import java.sql.Timestamp; + +@Getter +@Builder +public class NoticeArticleDto { + + private Long id; + private LanguageType language; + private NoticeArticleStatus status; + private Timestamp createdAt; + private Long createdUser; + private Timestamp updatedAt; + private Long updatedUser; + + public static NoticeArticleDto of(NoticeArticle noticeArticle, NoticeContent noticeContent) { + return NoticeArticleDto.builder() + .id(noticeArticle.getId()) + .language(noticeArticle.getLanguage()) + .status(noticeArticle.getStatus()) + .createdAt(noticeArticle.getCreatedAt()) + .createdUser(noticeArticle.getCreatedUser()) + .updatedAt(noticeArticle.getUpdatedAt()) + .updatedUser(noticeArticle.getUpdatedUser()) + .build(); + } +} diff --git a/src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java b/src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java new file mode 100644 index 0000000..1834c17 --- /dev/null +++ b/src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java @@ -0,0 +1,27 @@ +package HookKiller.server.notice.dto; + +import HookKiller.server.common.type.LanguageType; +import HookKiller.server.notice.entity.NoticeArticle; +import HookKiller.server.notice.entity.NoticeContent; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class NoticeContentDto { + + private Long id; + private LanguageType language; + private String title; + private String content; + + public NoticeContentDto of(NoticeArticle noticeArticle, NoticeContent noticeContent) { + + return NoticeContentDto.builder() + .id(noticeContent.getId()) + .language(noticeContent.getLanguage()) + .title(noticeContent.getTitle()) + .content(noticeContent.getContent()) + .build(); + } +} diff --git a/src/main/java/HookKiller/server/notice/exception/NoticeArticleNotFoundException.java b/src/main/java/HookKiller/server/notice/exception/NoticeArticleNotFoundException.java new file mode 100644 index 0000000..fc4bd75 --- /dev/null +++ b/src/main/java/HookKiller/server/notice/exception/NoticeArticleNotFoundException.java @@ -0,0 +1,13 @@ +package HookKiller.server.notice.exception; + +import HookKiller.server.common.exception.BaseException; + +import static HookKiller.server.notice.exception.NoticeException.NOTICE_ARTICLE_NOT_FOUND_EXCEPTION; + +public class NoticeArticleNotFoundException extends BaseException { + public static final BaseException EXCEPTION = new NoticeArticleNotFoundException(); + + private NoticeArticleNotFoundException() { + super(NOTICE_ARTICLE_NOT_FOUND_EXCEPTION); + } +} diff --git a/src/main/java/HookKiller/server/notice/exception/NoticeException.java b/src/main/java/HookKiller/server/notice/exception/NoticeException.java new file mode 100644 index 0000000..ddec89b --- /dev/null +++ b/src/main/java/HookKiller/server/notice/exception/NoticeException.java @@ -0,0 +1,24 @@ +package HookKiller.server.notice.exception; + +import HookKiller.server.common.dto.ErrorDetail; +import HookKiller.server.common.exception.BaseErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +import static org.springframework.http.HttpStatus.NOT_FOUND; + +@Getter +@AllArgsConstructor +public enum NoticeException implements BaseErrorCode { + NOTICE_ARTICLE_NOT_FOUND_EXCEPTION(NOT_FOUND.value(), "404-1", "공지사항 게시물이 존재하지 않습니다."); + + private final Integer statusCode; + private final String errorCode; + private final String reason; + + @Override + public ErrorDetail getErrorDetail() { + return ErrorDetail.of(statusCode, errorCode, reason); + } +} diff --git a/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java b/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java index 5dc2cb3..af5fba7 100644 --- a/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java +++ b/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java @@ -6,6 +6,7 @@ @Repository public interface NoticeArticleRepository extends JpaRepository { - NoticeArticle findAllById(NoticeArticle noticeArticle); + NoticeArticle findAll(NoticeArticle noticeArticle); + NoticeArticle getById(Long id); } diff --git a/src/main/java/HookKiller/server/repository/NoticeContentRepository.java b/src/main/java/HookKiller/server/repository/NoticeContentRepository.java index 64ccbd4..75cbe89 100644 --- a/src/main/java/HookKiller/server/repository/NoticeContentRepository.java +++ b/src/main/java/HookKiller/server/repository/NoticeContentRepository.java @@ -4,7 +4,6 @@ import HookKiller.server.notice.entity.NoticeArticle; import HookKiller.server.notice.entity.NoticeContent; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; import java.util.Optional; diff --git a/src/main/java/HookKiller/server/service/NoticeService.java b/src/main/java/HookKiller/server/service/NoticeService.java new file mode 100644 index 0000000..fb212b3 --- /dev/null +++ b/src/main/java/HookKiller/server/service/NoticeService.java @@ -0,0 +1,90 @@ +package HookKiller.server.service; + +import HookKiller.server.common.type.LanguageType; +import HookKiller.server.notice.dto.NoticeArticleDto; +import HookKiller.server.notice.dto.NoticeContentDto; +import HookKiller.server.notice.entity.NoticeArticle; +import HookKiller.server.notice.entity.NoticeContent; +import HookKiller.server.notice.exception.NoticeArticleNotFoundException; +import HookKiller.server.repository.NoticeArticleRepository; +import HookKiller.server.repository.NoticeContentRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class NoticeService { + + private final NoticeArticleRepository noticeArticleRepository; + private final NoticeContentRepository noticeContentRepository; + + @Transactional + public void saveNotice(NoticeArticleDto articleDto, NoticeContentDto contentDto) { + NoticeArticle noticeArticle = NoticeArticle.builder() + .id(articleDto.getId()) + .build(); + NoticeContent noticeContent = NoticeContent.builder() + .id(contentDto.getId()) + .build(); + noticeArticleRepository.save(noticeArticle); + noticeContentRepository.save(noticeContent); + } + + @Transactional(readOnly = true) + public List getNoticeList() { + + List all = noticeArticleRepository.findAll(); + List noticeArticleDtoList = new ArrayList<>(); + + for (NoticeArticle noticeArticle : all) { + NoticeArticleDto articleDto = NoticeArticleDto.builder() + .id(noticeArticle.getId()) + .language(noticeArticle.getLanguage()) + .status(noticeArticle.getStatus()) + .createdAt(noticeArticle.getCreatedAt()) + .createdUser(noticeArticle.getCreatedUser()) + .updatedAt(noticeArticle.getUpdatedAt()) + .updatedUser(noticeArticle.getUpdatedUser()) + .build(); + noticeArticleDtoList.add(articleDto); + } + return noticeArticleDtoList; + } + + @Transactional + public NoticeContentDto getNotice(Long id) { + NoticeContent noticeContent = noticeContentRepository.findById(id).orElseThrow(() -> NoticeArticleNotFoundException.EXCEPTION); + + return NoticeContentDto.builder() + .id(noticeContent.getId()) + .language(noticeContent.getLanguage()) + .title(noticeContent.getTitle()) + .content(noticeContent.getContent()) + .build(); + } + + @Transactional + public void deleteNotice(Long id) { + noticeArticleRepository.deleteById(id); + } + + @Transactional + public void update(Long id, NoticeArticleDto articleDto) { + Optional byId = noticeArticleRepository.findById(id); + // TODO : 수정 받고 다시 작업 예정 + } + + public NoticeArticleDto getNoticeArticleByArticleId(Long noticeArticleId, LanguageType languageType) { + return null; + } + + public List getNoticeArticleList(Long noticeArticleId, LanguageType languageType) { + return null; + } + +} From 19bc2ee0250c449256aa670b904f5ecf87b134f0 Mon Sep 17 00:00:00 2001 From: kwchoi11 Date: Tue, 10 Oct 2023 19:47:32 +0900 Subject: [PATCH 02/14] =?UTF-8?q?Feat:=20controller,=20service,=20dto,=20e?= =?UTF-8?q?xception,=20repository=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notice/controller/NoticeController.java | 25 ++-- .../server/notice/dto/NoticeArticleDto.java | 13 +- .../server/notice/dto/NoticeContentDto.java | 19 +++ .../server/notice/entity/NoticeArticle.java | 4 +- .../NoticeContentNotFoundException.java | 14 +++ .../notice/exception/NoticeException.java | 3 +- .../repository/NoticeArticleRepository.java | 12 +- .../server/service/NoticeService.java | 111 ++++++++++-------- 8 files changed, 126 insertions(+), 75 deletions(-) create mode 100644 src/main/java/HookKiller/server/notice/exception/NoticeContentNotFoundException.java diff --git a/src/main/java/HookKiller/server/notice/controller/NoticeController.java b/src/main/java/HookKiller/server/notice/controller/NoticeController.java index 032d5c1..effcfd0 100644 --- a/src/main/java/HookKiller/server/notice/controller/NoticeController.java +++ b/src/main/java/HookKiller/server/notice/controller/NoticeController.java @@ -4,6 +4,7 @@ import HookKiller.server.notice.dto.NoticeArticleDto; import HookKiller.server.notice.dto.NoticeContentDto; import HookKiller.server.notice.entity.NoticeArticle; +import HookKiller.server.notice.entity.NoticeContent; import HookKiller.server.repository.NoticeArticleRepository; import HookKiller.server.repository.NoticeContentRepository; import HookKiller.server.service.NoticeService; @@ -31,7 +32,7 @@ public class NoticeController { * @param languageType * @return */ - @GetMapping("{/noticeArticleId}") + @GetMapping("/{noticeArticleId}") public NoticeArticleDto getNoticeArticle(@PathVariable Long noticeArticleId, HttpServletRequest request, LanguageType languageType) { request.getHeader("languageType"); return noticeService.getNoticeArticleByArticleId(noticeArticleId, languageType); @@ -41,33 +42,29 @@ public NoticeArticleDto getNoticeArticle(@PathVariable Long noticeArticleId, Htt * 리스트 조회 * @param request * @param languageType - * @param requestData * @return */ - @GetMapping - public List getNoticeArticleList(HttpServletRequest request, LanguageType languageType, NoticeArticleDto requestData) { - request.getHeader("id"); - Long id = requestData.getId(); - List articleDto = noticeService.getNoticeArticleList(id, languageType); - return articleDto; + @GetMapping("/list") + public List getNoticeArticleList(HttpServletRequest request, LanguageType languageType) { + + return noticeService.getNoticeList(languageType); } /** * 공지사항 등록 */ @PostMapping - public void addNotice(@RequestBody @Valid NoticeArticleDto articleRequest, NoticeContentDto contentRequest) { + public void addNotice(@RequestBody NoticeArticleDto articleRequest, @Valid NoticeContentDto contentRequest) { noticeService.saveNotice(articleRequest, contentRequest); } /** * 공지사항 수정 */ - @PutMapping("/{id}") - public void updateNotice(@PathVariable Long id, - @RequestBody @Valid NoticeArticleDto articleDto, NoticeContentDto contentDto) { - noticeService.update(id, articleDto); - Optional findNotice = articleRepository.findById(id); + @PutMapping + public void updateNotice(@RequestBody NoticeArticleDto articleDto, @Valid NoticeContentDto contentDto, Long id) { + noticeService.update(id, contentDto); + Optional findNotice = contentRepository.findById(id); } /** diff --git a/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java b/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java index 1e31f7a..644c225 100644 --- a/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java +++ b/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java @@ -1,5 +1,6 @@ package HookKiller.server.notice.dto; +import HookKiller.server.common.AbstractTimeStamp; import HookKiller.server.common.type.LanguageType; import HookKiller.server.common.type.NoticeArticleStatus; import HookKiller.server.notice.entity.NoticeArticle; @@ -7,29 +8,27 @@ import lombok.Builder; import lombok.Getter; -import java.sql.Timestamp; - @Getter @Builder -public class NoticeArticleDto { +public class NoticeArticleDto extends AbstractTimeStamp { private Long id; private LanguageType language; private NoticeArticleStatus status; - private Timestamp createdAt; private Long createdUser; - private Timestamp updatedAt; private Long updatedUser; + private String content; + private String title; public static NoticeArticleDto of(NoticeArticle noticeArticle, NoticeContent noticeContent) { return NoticeArticleDto.builder() .id(noticeArticle.getId()) .language(noticeArticle.getLanguage()) .status(noticeArticle.getStatus()) - .createdAt(noticeArticle.getCreatedAt()) .createdUser(noticeArticle.getCreatedUser()) - .updatedAt(noticeArticle.getUpdatedAt()) .updatedUser(noticeArticle.getUpdatedUser()) + .content(noticeContent.getContent()) + .title(noticeContent.getTitle()) .build(); } } diff --git a/src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java b/src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java index 1834c17..3c81ed4 100644 --- a/src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java +++ b/src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java @@ -3,6 +3,7 @@ import HookKiller.server.common.type.LanguageType; import HookKiller.server.notice.entity.NoticeArticle; import HookKiller.server.notice.entity.NoticeContent; +import jakarta.validation.constraints.NotEmpty; import lombok.Builder; import lombok.Getter; @@ -12,9 +13,23 @@ public class NoticeContentDto { private Long id; private LanguageType language; + + @NotEmpty(message = "제목을 입력해주세요.") private String title; + + @NotEmpty(message = "내용을 입력해주세요.") private String content; + public static NoticeContentDto from(NoticeContent noticeContent) { + + return NoticeContentDto.builder() + .id(noticeContent.getId()) + .language(noticeContent.getLanguage()) + .title(noticeContent.getTitle()) + .content(noticeContent.getContent()) + .build(); + } + public NoticeContentDto of(NoticeArticle noticeArticle, NoticeContent noticeContent) { return NoticeContentDto.builder() @@ -24,4 +39,8 @@ public NoticeContentDto of(NoticeArticle noticeArticle, NoticeContent noticeCont .content(noticeContent.getContent()) .build(); } + + + + } diff --git a/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java b/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java index 410bb4b..39e0b3f 100644 --- a/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java +++ b/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java @@ -45,8 +45,8 @@ public class NoticeArticle { private Long updatedUser; @Builder - public NoticeArticle(Long id, List content, LanguageType language, - NoticeArticleStatus noticeArticleStatus, Timestamp createdAt, Long createdUser, Timestamp updatedAt, Long updatedUser) { + public NoticeArticle(Long id, List content, LanguageType language, NoticeArticleStatus noticeArticleStatus, + Timestamp createdAt, Long createdUser, Timestamp updatedAt, Long updatedUser) { this.id = id; this.content = content; this.language = language; diff --git a/src/main/java/HookKiller/server/notice/exception/NoticeContentNotFoundException.java b/src/main/java/HookKiller/server/notice/exception/NoticeContentNotFoundException.java new file mode 100644 index 0000000..f6aeda7 --- /dev/null +++ b/src/main/java/HookKiller/server/notice/exception/NoticeContentNotFoundException.java @@ -0,0 +1,14 @@ +package HookKiller.server.notice.exception; + +import HookKiller.server.common.exception.BaseException; + +import static HookKiller.server.notice.exception.NoticeException.NOTICE_ARTICLE_NOT_FOUND_EXCEPTION; +import static HookKiller.server.notice.exception.NoticeException.NOTICE_CONTENT_NOT_FOUND_EXCEPTION; + +public class NoticeContentNotFoundException extends BaseException { + public static final BaseException EXCEPTION = new NoticeContentNotFoundException(); + + private NoticeContentNotFoundException() { + super(NOTICE_CONTENT_NOT_FOUND_EXCEPTION); + } +} diff --git a/src/main/java/HookKiller/server/notice/exception/NoticeException.java b/src/main/java/HookKiller/server/notice/exception/NoticeException.java index ddec89b..477a118 100644 --- a/src/main/java/HookKiller/server/notice/exception/NoticeException.java +++ b/src/main/java/HookKiller/server/notice/exception/NoticeException.java @@ -11,7 +11,8 @@ @Getter @AllArgsConstructor public enum NoticeException implements BaseErrorCode { - NOTICE_ARTICLE_NOT_FOUND_EXCEPTION(NOT_FOUND.value(), "404-1", "공지사항 게시물이 존재하지 않습니다."); + NOTICE_ARTICLE_NOT_FOUND_EXCEPTION(NOT_FOUND.value(), "404-1", "공지사항 게시물이 존재하지 않습니다."), + NOTICE_CONTENT_NOT_FOUND_EXCEPTION(NOT_FOUND.value(), "404-2", "게시글이 존재하지 않습니다."); private final Integer statusCode; private final String errorCode; diff --git a/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java b/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java index af5fba7..b09d803 100644 --- a/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java +++ b/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java @@ -1,12 +1,16 @@ package HookKiller.server.repository; +import HookKiller.server.common.type.LanguageType; +import HookKiller.server.common.type.NoticeArticleStatus; import HookKiller.server.notice.entity.NoticeArticle; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -@Repository +import java.util.List; +import java.util.Optional; + public interface NoticeArticleRepository extends JpaRepository { - NoticeArticle findAll(NoticeArticle noticeArticle); - NoticeArticle getById(Long id); + + Optional findByLanguage(LanguageType languageType); + List findByStatus(NoticeArticleStatus status); } diff --git a/src/main/java/HookKiller/server/service/NoticeService.java b/src/main/java/HookKiller/server/service/NoticeService.java index fb212b3..bc1a2bd 100644 --- a/src/main/java/HookKiller/server/service/NoticeService.java +++ b/src/main/java/HookKiller/server/service/NoticeService.java @@ -6,13 +6,13 @@ import HookKiller.server.notice.entity.NoticeArticle; import HookKiller.server.notice.entity.NoticeContent; import HookKiller.server.notice.exception.NoticeArticleNotFoundException; +import HookKiller.server.notice.exception.NoticeContentNotFoundException; import HookKiller.server.repository.NoticeArticleRepository; import HookKiller.server.repository.NoticeContentRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -23,68 +23,85 @@ public class NoticeService { private final NoticeArticleRepository noticeArticleRepository; private final NoticeContentRepository noticeContentRepository; + /** + * 단건 조회 + * + * @param noticeArticleId + * @param languageType + * @return + */ + public NoticeArticleDto getNoticeArticleByArticleId(Long noticeArticleId, LanguageType languageType) { + NoticeArticle article = noticeArticleRepository.findById(noticeArticleId) + .orElseThrow(() -> NoticeArticleNotFoundException.EXCEPTION); + NoticeContent content = noticeContentRepository.findByNoticeArticleAndLanguage(article, languageType) + .orElseThrow(() -> NoticeContentNotFoundException.EXCEPTION); + return NoticeArticleDto.of(article, content); + } + + /** + * 리스트 조회 + * + * @return + */ + @Transactional(readOnly = true) + public List getNoticeList(LanguageType languageType) { + return noticeArticleRepository.findAll() + .stream().map(data -> + NoticeArticleDto.builder() + .id(data.getId()) + .language(data.getLanguage()) + .status(data.getStatus()) + .createdUser(data.getCreatedUser()) + .updatedUser(data.getUpdatedUser()) + .build()) + .toList(); + } + + /** + * 등록 + * + * @param articleDto + * @param contentDto + */ @Transactional public void saveNotice(NoticeArticleDto articleDto, NoticeContentDto contentDto) { NoticeArticle noticeArticle = NoticeArticle.builder() .id(articleDto.getId()) + .language(articleDto.getLanguage()) + .noticeArticleStatus(articleDto.getStatus()) + .createdUser(articleDto.getCreatedUser()) + .updatedUser(articleDto.getUpdatedUser()) .build(); NoticeContent noticeContent = NoticeContent.builder() - .id(contentDto.getId()) - .build(); + .id(contentDto.getId()) + .language((contentDto.getLanguage())) + .title(contentDto.getTitle()) + .content(contentDto.getContent()) + .build(); noticeArticleRepository.save(noticeArticle); noticeContentRepository.save(noticeContent); } - @Transactional(readOnly = true) - public List getNoticeList() { - - List all = noticeArticleRepository.findAll(); - List noticeArticleDtoList = new ArrayList<>(); - - for (NoticeArticle noticeArticle : all) { - NoticeArticleDto articleDto = NoticeArticleDto.builder() - .id(noticeArticle.getId()) - .language(noticeArticle.getLanguage()) - .status(noticeArticle.getStatus()) - .createdAt(noticeArticle.getCreatedAt()) - .createdUser(noticeArticle.getCreatedUser()) - .updatedAt(noticeArticle.getUpdatedAt()) - .updatedUser(noticeArticle.getUpdatedUser()) - .build(); - noticeArticleDtoList.add(articleDto); - } - return noticeArticleDtoList; - } - + /** + * 수정 + * + * @param id + * @param contentDto + */ @Transactional - public NoticeContentDto getNotice(Long id) { - NoticeContent noticeContent = noticeContentRepository.findById(id).orElseThrow(() -> NoticeArticleNotFoundException.EXCEPTION); - - return NoticeContentDto.builder() - .id(noticeContent.getId()) - .language(noticeContent.getLanguage()) - .title(noticeContent.getTitle()) - .content(noticeContent.getContent()) - .build(); + public void update(Long id, NoticeContentDto contentDto) { + Optional byId = noticeContentRepository.findById(id); + // TODO : 수정 받고 다시 작업 예정 } + /** + * 삭제 + * + * @param id + */ @Transactional public void deleteNotice(Long id) { noticeArticleRepository.deleteById(id); } - @Transactional - public void update(Long id, NoticeArticleDto articleDto) { - Optional byId = noticeArticleRepository.findById(id); - // TODO : 수정 받고 다시 작업 예정 - } - - public NoticeArticleDto getNoticeArticleByArticleId(Long noticeArticleId, LanguageType languageType) { - return null; - } - - public List getNoticeArticleList(Long noticeArticleId, LanguageType languageType) { - return null; - } - } From dee92963eee52baf9e1d7c9a80de9f798d1bd1cd Mon Sep 17 00:00:00 2001 From: kwchoi11 Date: Tue, 10 Oct 2023 21:24:02 +0900 Subject: [PATCH 03/14] =?UTF-8?q?Fix:=20NoticeArticle=20Timestamp=EB=A1=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HookKiller/server/notice/controller/NoticeController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/HookKiller/server/notice/controller/NoticeController.java b/src/main/java/HookKiller/server/notice/controller/NoticeController.java index 42846f7..16dc965 100644 --- a/src/main/java/HookKiller/server/notice/controller/NoticeController.java +++ b/src/main/java/HookKiller/server/notice/controller/NoticeController.java @@ -37,7 +37,6 @@ public class NoticeController { */ @GetMapping("/{noticeArticleId}") public NoticeArticleDto getNoticeArticle(@PathVariable Long noticeArticleId, HttpServletRequest request) { - LanguageType.findTypeByRequest(null); return noticeService.getNoticeArticleByArticleId(noticeArticleId, LanguageType.findTypeByRequest(request)); } From 1fa15e4e4364bf5b9d979ba660ccc508a86dc7c3 Mon Sep 17 00:00:00 2001 From: kwchoi11 Date: Wed, 11 Oct 2023 21:41:00 +0900 Subject: [PATCH 04/14] =?UTF-8?q?Feat:=20=EA=B3=B5=EC=A7=80=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20CRUD=EA=B5=AC=ED=98=84.(=EB=B2=88=EC=97=AD=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=9E=91=EC=97=85=20=EC=A7=84=ED=96=89=20?= =?UTF-8?q?=EC=98=88=EC=A0=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...eArticleStatus.java => ArticleStatus.java} | 2 +- .../server/common/type/LanguageType.java | 4 +- .../config/security/SecurityConfig.java | 2 +- .../notice/controller/NoticeController.java | 21 +- .../server/notice/dto/AddNoticeRequest.java | 24 +++ .../server/notice/dto/EditNoticeRequest.java | 27 +++ .../server/notice/dto/NoticeArticleDto.java | 9 +- .../server/notice/dto/NoticeContentDto.java | 3 - .../server/notice/entity/NoticeArticle.java | 35 +-- .../server/notice/entity/NoticeContent.java | 8 +- .../repository/NoticeArticleRepository.java | 4 +- .../repository/NoticeContentRepository.java | 3 + .../server/service/NoticeService.java | 103 ++++++--- src/main/resources/application-local.yml | 4 +- src/main/resources/data.sql | 202 +++++++++++++++++- 15 files changed, 381 insertions(+), 70 deletions(-) rename src/main/java/HookKiller/server/common/type/{NoticeArticleStatus.java => ArticleStatus.java} (73%) create mode 100644 src/main/java/HookKiller/server/notice/dto/AddNoticeRequest.java create mode 100644 src/main/java/HookKiller/server/notice/dto/EditNoticeRequest.java diff --git a/src/main/java/HookKiller/server/common/type/NoticeArticleStatus.java b/src/main/java/HookKiller/server/common/type/ArticleStatus.java similarity index 73% rename from src/main/java/HookKiller/server/common/type/NoticeArticleStatus.java rename to src/main/java/HookKiller/server/common/type/ArticleStatus.java index 568f192..bdc0ba2 100644 --- a/src/main/java/HookKiller/server/common/type/NoticeArticleStatus.java +++ b/src/main/java/HookKiller/server/common/type/ArticleStatus.java @@ -3,6 +3,6 @@ import lombok.Getter; @Getter -public enum NoticeArticleStatus { +public enum ArticleStatus { PUBLIC, DELETE; } diff --git a/src/main/java/HookKiller/server/common/type/LanguageType.java b/src/main/java/HookKiller/server/common/type/LanguageType.java index f297a6f..b00c3c5 100644 --- a/src/main/java/HookKiller/server/common/type/LanguageType.java +++ b/src/main/java/HookKiller/server/common/type/LanguageType.java @@ -10,10 +10,10 @@ public enum LanguageType { KO, EN, CN, JP; - public static LanguageType findType(String value) { if (value == null || value.isEmpty()) { - throw IllegalArgumentException.EXCEPTION; + return KO; +// throw IllegalArgumentException.EXCEPTION; } return Arrays.stream(LanguageType.values()) .filter(type -> type.name().equals(value.toUpperCase())) diff --git a/src/main/java/HookKiller/server/config/security/SecurityConfig.java b/src/main/java/HookKiller/server/config/security/SecurityConfig.java index 3ec5144..0961e29 100644 --- a/src/main/java/HookKiller/server/config/security/SecurityConfig.java +++ b/src/main/java/HookKiller/server/config/security/SecurityConfig.java @@ -43,7 +43,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .authorizeHttpRequests(authorization -> authorization .requestMatchers( "/login", - "/register", "/health").permitAll() + "/register", "/health", "/notice/**").permitAll() .requestMatchers("/user/**").authenticated() // 인증이 되면 들어갈 수 있음 .requestMatchers("/admin/**").hasAuthority("ADMIN") // 관리자 권한만 들어갈 수 있음 ) diff --git a/src/main/java/HookKiller/server/notice/controller/NoticeController.java b/src/main/java/HookKiller/server/notice/controller/NoticeController.java index 16dc965..588cf09 100644 --- a/src/main/java/HookKiller/server/notice/controller/NoticeController.java +++ b/src/main/java/HookKiller/server/notice/controller/NoticeController.java @@ -1,10 +1,10 @@ package HookKiller.server.notice.controller; import HookKiller.server.common.type.LanguageType; -import HookKiller.server.common.type.RequestHeaderConstants; +import HookKiller.server.notice.dto.AddNoticeRequest; +import HookKiller.server.notice.dto.EditNoticeRequest; import HookKiller.server.notice.dto.NoticeArticleDto; import HookKiller.server.notice.dto.NoticeContentDto; -import HookKiller.server.notice.entity.NoticeArticle; import HookKiller.server.notice.entity.NoticeContent; import HookKiller.server.repository.NoticeArticleRepository; import HookKiller.server.repository.NoticeContentRepository; @@ -12,14 +12,13 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -import org.apache.commons.codec.language.bm.Lang; -import org.apache.logging.log4j.message.LoggerNameAwareMessage; -import org.springframework.ui.Model; +import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.Optional; +@Slf4j @RestController @RequiredArgsConstructor @RequestMapping("/notice") @@ -37,6 +36,7 @@ public class NoticeController { */ @GetMapping("/{noticeArticleId}") public NoticeArticleDto getNoticeArticle(@PathVariable Long noticeArticleId, HttpServletRequest request) { + log.error("공지사항 단건 조회 >>> {}", noticeArticleId); return noticeService.getNoticeArticleByArticleId(noticeArticleId, LanguageType.findTypeByRequest(request)); } @@ -54,17 +54,16 @@ public List getNoticeArticleList(HttpServletRequest request) { * 공지사항 등록 */ @PostMapping - public void addNotice(@RequestBody NoticeArticleDto articleRequest, @Valid NoticeContentDto contentRequest) { - noticeService.saveNotice(articleRequest, contentRequest); + public void addNotice(@RequestBody @Valid AddNoticeRequest request) { + noticeService.saveNotice(request); } /** * 공지사항 수정 */ @PutMapping - public void updateNotice(@RequestBody NoticeArticleDto articleDto, @Valid NoticeContentDto contentDto, Long id) { - noticeService.update(id, contentDto); - Optional findNotice = contentRepository.findById(id); + public void updateNotice(@RequestBody @Valid EditNoticeRequest request) { + noticeService.updateNotice(request); } /** @@ -75,7 +74,5 @@ public void deleteNotice(@PathVariable Long noticeArticleId) { noticeService.deleteNotice(noticeArticleId); } - - } diff --git a/src/main/java/HookKiller/server/notice/dto/AddNoticeRequest.java b/src/main/java/HookKiller/server/notice/dto/AddNoticeRequest.java new file mode 100644 index 0000000..99ffb16 --- /dev/null +++ b/src/main/java/HookKiller/server/notice/dto/AddNoticeRequest.java @@ -0,0 +1,24 @@ +package HookKiller.server.notice.dto; + +import HookKiller.server.common.type.LanguageType; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +/** + * 공지사항 추가 요청 DTO + */ +@Getter +@Setter +public class AddNoticeRequest { + @NotNull(message = "언어 타입을 선택해야 합니다.") + private LanguageType language; + + @NotEmpty(message = "내용을 입력해주세요.") + private String title; + + @NotEmpty(message = "제목을 입력해주세요.") + private String content; + +} diff --git a/src/main/java/HookKiller/server/notice/dto/EditNoticeRequest.java b/src/main/java/HookKiller/server/notice/dto/EditNoticeRequest.java new file mode 100644 index 0000000..a496252 --- /dev/null +++ b/src/main/java/HookKiller/server/notice/dto/EditNoticeRequest.java @@ -0,0 +1,27 @@ +package HookKiller.server.notice.dto; + +import HookKiller.server.common.type.LanguageType; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +/** + * 공지사항 수정 요청 DTO + */ +@Getter +@Setter +public class EditNoticeRequest { + @NotNull(message = "공지사항 게시물 ID가 입력되지 않았습니다.") + private Long noticeArticleId; + + @NotNull(message = "언어 타입을 선택해야 합니다.") + private LanguageType language; + + private String orgTitle; + private String newTitle; + + + private String orgContent; + private String newContent; +} diff --git a/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java b/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java index 644c225..cc5f759 100644 --- a/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java +++ b/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java @@ -2,9 +2,10 @@ import HookKiller.server.common.AbstractTimeStamp; import HookKiller.server.common.type.LanguageType; -import HookKiller.server.common.type.NoticeArticleStatus; +import HookKiller.server.common.type.ArticleStatus; import HookKiller.server.notice.entity.NoticeArticle; import HookKiller.server.notice.entity.NoticeContent; +import HookKiller.server.user.entity.User; import lombok.Builder; import lombok.Getter; @@ -14,9 +15,9 @@ public class NoticeArticleDto extends AbstractTimeStamp { private Long id; private LanguageType language; - private NoticeArticleStatus status; - private Long createdUser; - private Long updatedUser; + private ArticleStatus status; + private User createdUser; + private User updatedUser; private String content; private String title; diff --git a/src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java b/src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java index 3c81ed4..98e5d9b 100644 --- a/src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java +++ b/src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java @@ -40,7 +40,4 @@ public NoticeContentDto of(NoticeArticle noticeArticle, NoticeContent noticeCont .build(); } - - - } diff --git a/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java b/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java index 39e0b3f..4b9bd14 100644 --- a/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java +++ b/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java @@ -1,12 +1,11 @@ package HookKiller.server.notice.entity; +import HookKiller.server.common.AbstractTimeStamp; import HookKiller.server.common.type.LanguageType; -import HookKiller.server.common.type.NoticeArticleStatus; +import HookKiller.server.common.type.ArticleStatus; +import HookKiller.server.user.entity.User; import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import java.sql.Timestamp; import java.util.List; @@ -22,9 +21,10 @@ @Entity @Getter +@Setter @Table(name = "tbl_notice_article") @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class NoticeArticle { +public class NoticeArticle extends AbstractTimeStamp { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -37,23 +37,26 @@ public class NoticeArticle { private LanguageType language; @Enumerated(EnumType.STRING) - private NoticeArticleStatus status; + private ArticleStatus status; - private Timestamp createdAt; - private Long createdUser; - private Timestamp updatedAt; - private Long updatedUser; + @ManyToOne(fetch = FetchType.LAZY) + private User createdUser; + + @ManyToOne(fetch = FetchType.LAZY) + private User updatedUser; @Builder - public NoticeArticle(Long id, List content, LanguageType language, NoticeArticleStatus noticeArticleStatus, - Timestamp createdAt, Long createdUser, Timestamp updatedAt, Long updatedUser) { + public NoticeArticle(Long id, List content, LanguageType language, ArticleStatus status, + User createdUser,User updatedUser) { this.id = id; this.content = content; this.language = language; - this.status = noticeArticleStatus; - this.createdAt = createdAt; + this.status = status; this.createdUser = createdUser; - this.updatedAt = updatedAt; this.updatedUser = updatedUser; } + + public void updateStatus(ArticleStatus status) { + this.status = status; + } } diff --git a/src/main/java/HookKiller/server/notice/entity/NoticeContent.java b/src/main/java/HookKiller/server/notice/entity/NoticeContent.java index 994646f..57fc084 100644 --- a/src/main/java/HookKiller/server/notice/entity/NoticeContent.java +++ b/src/main/java/HookKiller/server/notice/entity/NoticeContent.java @@ -1,6 +1,7 @@ package HookKiller.server.notice.entity; import HookKiller.server.common.type.LanguageType; +import HookKiller.server.notice.dto.NoticeContentDto; import jakarta.persistence.*; import lombok.*; @@ -12,6 +13,7 @@ @Entity @Getter +@Setter @Table(name = "tbl_notice_content") @NoArgsConstructor(access = AccessLevel.PROTECTED) public class NoticeContent { @@ -29,7 +31,6 @@ public class NoticeContent { private String title; - @Column @Lob private String content; @@ -41,4 +42,9 @@ public NoticeContent(Long id, NoticeArticle noticeArticle, this.title = title; this.content = content; } + + public void update(NoticeContentDto contentDto) { + this.title = contentDto.getTitle(); + this.content = contentDto.getContent(); + } } diff --git a/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java b/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java index b09d803..829a974 100644 --- a/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java +++ b/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java @@ -1,7 +1,7 @@ package HookKiller.server.repository; import HookKiller.server.common.type.LanguageType; -import HookKiller.server.common.type.NoticeArticleStatus; +import HookKiller.server.common.type.ArticleStatus; import HookKiller.server.notice.entity.NoticeArticle; import org.springframework.data.jpa.repository.JpaRepository; @@ -11,6 +11,6 @@ public interface NoticeArticleRepository extends JpaRepository { Optional findByLanguage(LanguageType languageType); - List findByStatus(NoticeArticleStatus status); + List findAllByStatus(ArticleStatus status); } diff --git a/src/main/java/HookKiller/server/repository/NoticeContentRepository.java b/src/main/java/HookKiller/server/repository/NoticeContentRepository.java index 75cbe89..2c97d7e 100644 --- a/src/main/java/HookKiller/server/repository/NoticeContentRepository.java +++ b/src/main/java/HookKiller/server/repository/NoticeContentRepository.java @@ -5,8 +5,11 @@ import HookKiller.server.notice.entity.NoticeContent; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; import java.util.Optional; public interface NoticeContentRepository extends JpaRepository { Optional findByNoticeArticleAndLanguage(NoticeArticle noticeArticle, LanguageType languageType); + + List findAllByNoticeArticle(NoticeArticle noticeArticle); } diff --git a/src/main/java/HookKiller/server/service/NoticeService.java b/src/main/java/HookKiller/server/service/NoticeService.java index b525ec5..7f68218 100644 --- a/src/main/java/HookKiller/server/service/NoticeService.java +++ b/src/main/java/HookKiller/server/service/NoticeService.java @@ -1,6 +1,10 @@ package HookKiller.server.service; +import HookKiller.server.common.type.ArticleStatus; import HookKiller.server.common.type.LanguageType; +import HookKiller.server.common.util.UserUtils; +import HookKiller.server.notice.dto.AddNoticeRequest; +import HookKiller.server.notice.dto.EditNoticeRequest; import HookKiller.server.notice.dto.NoticeArticleDto; import HookKiller.server.notice.dto.NoticeContentDto; import HookKiller.server.notice.entity.NoticeArticle; @@ -9,19 +13,25 @@ import HookKiller.server.notice.exception.NoticeContentNotFoundException; import HookKiller.server.repository.NoticeArticleRepository; import HookKiller.server.repository.NoticeContentRepository; +import HookKiller.server.user.entity.User; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; import java.util.List; import java.util.Optional; +import static HookKiller.server.common.type.ArticleStatus.DELETE; +import static HookKiller.server.common.type.ArticleStatus.PUBLIC; + @Service @RequiredArgsConstructor public class NoticeService { private final NoticeArticleRepository noticeArticleRepository; private final NoticeContentRepository noticeContentRepository; + private final UserUtils userUtils; /** * 단건 조회 @@ -48,6 +58,8 @@ public NoticeArticleDto getNoticeArticleByArticleId(Long noticeArticleId, Langua */ @Transactional(readOnly = true) public List getNoticeList(LanguageType languageType) { + List articleList = noticeArticleRepository.findAllByStatus(PUBLIC); + return noticeArticleRepository.findAll() .stream().map(data -> NoticeArticleDto.builder() @@ -63,38 +75,78 @@ public List getNoticeList(LanguageType languageType) { /** * 등록 * - * @param articleDto - * @param contentDto */ @Transactional - public void saveNotice(NoticeArticleDto articleDto, NoticeContentDto contentDto) { - NoticeArticle noticeArticle = NoticeArticle.builder() - .id(articleDto.getId()) - .language(articleDto.getLanguage()) - .noticeArticleStatus(articleDto.getStatus()) - .createdUser(articleDto.getCreatedUser()) - .updatedUser(articleDto.getUpdatedUser()) - .build(); - NoticeContent noticeContent = NoticeContent.builder() - .id(contentDto.getId()) - .language((contentDto.getLanguage())) - .title(contentDto.getTitle()) - .content(contentDto.getContent()) - .build(); - noticeArticleRepository.save(noticeArticle); - noticeContentRepository.save(noticeContent); + public void saveNotice(AddNoticeRequest addNoticeRequest) { + User loginUser = userUtils.getUser(); + + NoticeArticle noticeArticle = noticeArticleRepository.save( + NoticeArticle.builder() + .language(addNoticeRequest.getLanguage()) + .status(PUBLIC) + .createdUser(loginUser) + .updatedUser(loginUser) + .build() + ); + + List contentsList = new ArrayList<>(); + contentsList.add( + NoticeContent.builder() + .noticeArticle(noticeArticle) + .language(addNoticeRequest.getLanguage()) + .title(addNoticeRequest.getTitle()) + .content(addNoticeRequest.getContent()) + .build() + ); + // TODO : getLanguage에 들어있는 언어에서 다른 언어 번역한 결과 역시 NoticeContent로 제작해서 Save + noticeContentRepository.saveAll(contentsList); } /** * 수정 - * - * @param id - * @param contentDto */ @Transactional - public void update(Long id, NoticeContentDto contentDto) { - Optional byId = noticeContentRepository.findById(id); - // TODO : 수정 받고 다시 작업 예정 + public void updateNotice(EditNoticeRequest request) { + //로그인한 사용자 획득 + User user = userUtils.getUser(); + boolean chgTitle = false; + boolean chgContent = false; + + NoticeArticle article = noticeArticleRepository.findById(request.getNoticeArticleId()) + .orElseThrow(() -> NoticeArticleNotFoundException.EXCEPTION); + List contents = noticeContentRepository.findAllByNoticeArticle(article); + + article.setUpdatedUser(user); + //다른경우 변경 + if (!request.getLanguage().equals(article.getLanguage())) + article.setLanguage(request.getLanguage()); + + NoticeContent choiceContent = contents.stream() + .filter(content -> request.getLanguage().equals(content.getLanguage())) + .findFirst().orElseThrow(() -> NoticeContentNotFoundException.EXCEPTION); + + if(request.getNewTitle() != null && !request.getNewTitle().equals(request.getOrgTitle())) { + chgTitle = true; + choiceContent.setTitle(request.getNewTitle()); + } + if(request.getNewContent() != null && !request.getNewContent().equals(request.getOrgContent())){ + chgContent = true; + choiceContent.setContent(request.getNewContent()); + } + + if(chgTitle || chgContent) { + final boolean finalChgTitle = chgTitle; + final boolean finalChgContent = chgContent; + contents.stream().filter(content-> choiceContent != content).forEach(content-> { + if(finalChgTitle){ + // TODO : request의 언어를 원본으로 해서 content의 언어로 타겟잡아 번역후 title변환 + } + if(finalChgContent){ + // TODO : request의 언어를 원본으로 해서 content의 언어로 타겟잡아 번역후 content변환 + } + }); + } + } /** @@ -104,7 +156,8 @@ public void update(Long id, NoticeContentDto contentDto) { */ @Transactional public void deleteNotice(Long id) { - noticeArticleRepository.deleteById(id); + noticeArticleRepository.findById(id).orElseThrow(() -> + NoticeArticleNotFoundException.EXCEPTION).updateStatus(DELETE); } } diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index 999de09..2183428 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -2,12 +2,12 @@ hook: db: url: db-it7f7-kr.vpc-pub-cdb.ntruss.com - database: jw + database: kw username: hooklocal password: hooklocal1234! port: 3306 -# Test용 (Mr.재운DB) +# Test용 (Mr.근우DB) spring: diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 24496ed..a862577 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -9,6 +9,206 @@ select 1 from dual; insert into tbl_user (email, password, nick_name, role) values ("admin@test.com", "1111", "관리자", "ADMIN"); - insert into tbl_user (email, password, nick_name, role) values ("user@test.com", "1111", "사용자", "USER"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-20 10:00:00", 123, "2023-09-21 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (1, "KO", "title1", "content1"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-21 10:00:00", 123, "2023-09-22 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (2, "KO", "title2", "content2"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-22 10:00:00", 123, "2023-09-23 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (3, "KO", "title3", "content3"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-23 10:00:00", 123, "2023-09-24 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (4, "KO", "title4", "content4"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-24 10:00:00", 123, "2023-09-25 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (5, "KO", "title5", "content5"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-25 10:00:00", 123, "2023-09-26 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (6, "KO", "title6", "content6"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-26 10:00:00", 123, "2023-09-27 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (7, "KO", "title7", "content7"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-27 10:00:00", 123, "2023-09-28 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (8, "KO", "title8", "content8"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-28 10:00:00", 123, "2023-09-28 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (9, "KO", "title9", "content9"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-29 10:00:00", 123, "2023-09-30 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (10, "KO", "title10", "content10"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-01 10:00:00", 123, "2023-10-02 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (11, "KO", "title11", "content11"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-02 10:00:00", 123, "2023-10-03 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (12, "KO", "title12", "content12"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-03 10:00:00", 123, "2023-10-04 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (13, "KO", "title13", "content13"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-04 10:00:00", 123, "2023-10-05 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (14, "KO", "title14", "content14"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-05 10:00:00", 123, "2023-10-06 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (15, "KO", "title15", "content15"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-06 10:00:00", 123, "2023-10-07 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (16, "KO", "title16", "content16"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-08 10:00:00", 123, "2023-10-09 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (17, "KO", "title17", "content17"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-10 10:00:00", 123, "2023-10-11 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (18, "KO", "title18", "content18"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-12 10:00:00", 123, "2023-10-13 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (19, "KO", "title19", "content19"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-13 10:00:00", 123, "2023-10-14 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (20, "KO", "title20", "content20"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-15 10:00:00", 123, "2023-10-16 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (21, "KO", "title21", "content21"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-17 10:00:00", 123, "2023-10-18 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (22, "KO", "title22", "content22"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-19 10:00:00", 123, "2023-10-20 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (23, "KO", "title23", "content23"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-21 10:00:00", 123, "2023-10-22 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (24, "KO", "title24", "content24"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-23 10:00:00", 123, "2023-10-24 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (25, "KO", "title25", "content25"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-25 10:00:00", 123, "2023-10-26 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (26, "KO", "title26", "content26"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-27 10:00:00", 123, "2023-10-28 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (27, "KO", "title27", "content27"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-29 10:00:00", 123, "2023-10-30 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (28, "KO", "title28", "content28"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-31 10:00:00", 123, "2023-11-01 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (29, "KO", "title29", "content29"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-02 10:00:00", 123, "2023-11-03 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (30, "KO", "title30", "content30"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-04 10:00:00", 123, "2023-11-05 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (31, "KO", "title31", "content31"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-06 10:00:00", 123, "2023-11-07 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (32, "KO", "title32", "content32"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-08 10:00:00", 123, "2023-11-09 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (33, "KO", "title33", "content33"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-10 10:00:00", 123, "2023-11-11 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (34, "KO", "title34", "content34"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-12 10:00:00", 123, "2023-11-13 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (35, "KO", "title35", "content35"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-14 10:00:00", 123, "2023-11-15 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (36, "KO", "title36", "content36"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-16 10:00:00", 123, "2023-11-17 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (37, "KO", "title37", "content37"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-18 10:00:00", 123, "2023-11-19 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (38, "KO", "title38", "content38"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-20 10:00:00", 123, "2023-11-21 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (39, "KO", "title39", "content39"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-22 10:00:00", 123, "2023-11-23 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (40, "KO", "title40", "content40"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-24 10:00:00", 123, "2023-11-25 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (41, "KO", "title41", "content41"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-26 10:00:00", 123, "2023-11-27 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (42, "KO", "title42", "content42"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-28 10:00:00", 123, "2023-11-29 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (43, "KO", "title43", "content43"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-12-01 10:00:00", 123, "2023-12-02 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (44, "KO", "title44", "content44"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-12-02 10:00:00", 123, "2023-12-03 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (45, "KO", "title45", "content45"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-12-04 10:00:00", 123, "2023-12-05 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (46, "KO", "title46", "content46"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-12-06 10:00:00", 123, "2023-12-07 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (47, "KO", "title47", "content47"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-12-08 10:00:00", 123, "2023-12-09 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (48, "KO", "title48", "content48"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-12-10 10:00:00", 123, "2023-12-11 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (49, "KO", "title49", "content49"); + +insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-12-12 10:00:00", 123, "2023-12-13 10:00:00", 123); + +insert into tbl_notice_content (notice_id, language, title, content) values (50, "KO", "title50", "content50"); + From a11145cc2903cb19607ebd6ee57bd50cfb9840da Mon Sep 17 00:00:00 2001 From: kwchoi11 Date: Thu, 12 Oct 2023 14:11:22 +0900 Subject: [PATCH 05/14] =?UTF-8?q?Feat:=20=EA=B3=B5=EC=A7=80=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20CRUD=EA=B5=AC=ED=98=84.(=EB=B2=88=EC=97=AD=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=9E=91=EC=97=85=20=EC=A7=84=ED=96=89=20?= =?UTF-8?q?=EC=98=88=EC=A0=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/HookKiller/server/common/type/LanguageType.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/HookKiller/server/common/type/LanguageType.java b/src/main/java/HookKiller/server/common/type/LanguageType.java index b00c3c5..b2ae407 100644 --- a/src/main/java/HookKiller/server/common/type/LanguageType.java +++ b/src/main/java/HookKiller/server/common/type/LanguageType.java @@ -23,7 +23,8 @@ public static LanguageType findType(String value) { public static LanguageType findTypeByRequest(HttpServletRequest request) { if(request == null) - throw IllegalArgumentException.EXCEPTION; + return KO; +// throw IllegalArgumentException.EXCEPTION; return findType(request.getHeader(RequestHeaderConstants.KEY_LANGUAGE)); } } From ecd9e875c27a54d4c110fce6da3d5e5183f86c51 Mon Sep 17 00:00:00 2001 From: kwchoi11 Date: Thu, 12 Oct 2023 14:16:17 +0900 Subject: [PATCH 06/14] =?UTF-8?q?Fix:=20SecurityConfig=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/HookKiller/server/config/security/SecurityConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/HookKiller/server/config/security/SecurityConfig.java b/src/main/java/HookKiller/server/config/security/SecurityConfig.java index 0961e29..3ec5144 100644 --- a/src/main/java/HookKiller/server/config/security/SecurityConfig.java +++ b/src/main/java/HookKiller/server/config/security/SecurityConfig.java @@ -43,7 +43,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .authorizeHttpRequests(authorization -> authorization .requestMatchers( "/login", - "/register", "/health", "/notice/**").permitAll() + "/register", "/health").permitAll() .requestMatchers("/user/**").authenticated() // 인증이 되면 들어갈 수 있음 .requestMatchers("/admin/**").hasAuthority("ADMIN") // 관리자 권한만 들어갈 수 있음 ) From 9da9053351f6af8739a6e8c7587c8e83e659d654 Mon Sep 17 00:00:00 2001 From: donsonioc2010 Date: Thu, 12 Oct 2023 15:10:55 +0900 Subject: [PATCH 07/14] =?UTF-8?q?fix=20:=20=EA=B7=BC=EC=9A=B0=EB=A5=BC=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/common/AbstractTimeStamp.java | 8 ++-- .../server/common/type/LanguageType.java | 18 +++----- .../common/type/RequestHeaderConstants.java | 5 --- .../notice/controller/NoticeController.java | 20 +++++---- .../server/notice/dto/NoticeArticleDto.java | 3 ++ .../server/notice/dto/NoticeContentDto.java | 43 ------------------- .../server/notice/entity/NoticeArticle.java | 28 ++++++++---- .../server/notice/entity/NoticeContent.java | 27 +++++++----- .../NoticeArticleNotFoundException.java | 13 ------ .../NoticeContentNotFoundException.java | 14 ------ .../notice/exception/NoticeException.java | 3 +- .../exception/NoticeNotFoundException.java | 13 ++++++ .../repository/NoticeArticleRepository.java | 3 -- .../server/service/NoticeService.java | 26 +++++------ 14 files changed, 86 insertions(+), 138 deletions(-) delete mode 100644 src/main/java/HookKiller/server/common/type/RequestHeaderConstants.java delete mode 100644 src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java delete mode 100644 src/main/java/HookKiller/server/notice/exception/NoticeArticleNotFoundException.java delete mode 100644 src/main/java/HookKiller/server/notice/exception/NoticeContentNotFoundException.java create mode 100644 src/main/java/HookKiller/server/notice/exception/NoticeNotFoundException.java diff --git a/src/main/java/HookKiller/server/common/AbstractTimeStamp.java b/src/main/java/HookKiller/server/common/AbstractTimeStamp.java index 8ac865f..79e677d 100644 --- a/src/main/java/HookKiller/server/common/AbstractTimeStamp.java +++ b/src/main/java/HookKiller/server/common/AbstractTimeStamp.java @@ -5,6 +5,7 @@ import jakarta.persistence.EntityListeners; import jakarta.persistence.MappedSuperclass; import lombok.Getter; +import lombok.Setter; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; @@ -12,6 +13,7 @@ import java.sql.Timestamp; @Getter +@Setter @MappedSuperclass @EntityListeners(value = {AuditingEntityListener.class}) public abstract class AbstractTimeStamp { @@ -20,9 +22,9 @@ public abstract class AbstractTimeStamp { nullable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP") @CreatedDate - @JsonFormat( - shape = JsonFormat.Shape.STRING, - pattern = "yyyy-MM-dd hh:mm:ss") + @JsonFormat( + shape = JsonFormat.Shape.STRING, + pattern = "yyyy-MM-dd hh:mm:ss") private Timestamp createAt; @Column( diff --git a/src/main/java/HookKiller/server/common/type/LanguageType.java b/src/main/java/HookKiller/server/common/type/LanguageType.java index b2ae407..9c24f09 100644 --- a/src/main/java/HookKiller/server/common/type/LanguageType.java +++ b/src/main/java/HookKiller/server/common/type/LanguageType.java @@ -1,6 +1,5 @@ package HookKiller.server.common.type; -import HookKiller.server.common.exception.IllegalArgumentException; import jakarta.servlet.http.HttpServletRequest; import lombok.Getter; @@ -10,21 +9,16 @@ public enum LanguageType { KO, EN, CN, JP; + private static final String HTTP_REQUEST_HEADER_KEY_LANGUAGE = "language"; + public static LanguageType findType(String value) { - if (value == null || value.isEmpty()) { - return KO; -// throw IllegalArgumentException.EXCEPTION; - } - return Arrays.stream(LanguageType.values()) + return (value == null || value.isEmpty()) ? + KO : Arrays.stream(LanguageType.values()) .filter(type -> type.name().equals(value.toUpperCase())) - .findFirst() - .orElseThrow(() -> IllegalArgumentException.EXCEPTION); + .findFirst().orElse(KO); } public static LanguageType findTypeByRequest(HttpServletRequest request) { - if(request == null) - return KO; -// throw IllegalArgumentException.EXCEPTION; - return findType(request.getHeader(RequestHeaderConstants.KEY_LANGUAGE)); + return request == null ? KO : findType(request.getHeader(HTTP_REQUEST_HEADER_KEY_LANGUAGE)); } } diff --git a/src/main/java/HookKiller/server/common/type/RequestHeaderConstants.java b/src/main/java/HookKiller/server/common/type/RequestHeaderConstants.java deleted file mode 100644 index ff037ce..0000000 --- a/src/main/java/HookKiller/server/common/type/RequestHeaderConstants.java +++ /dev/null @@ -1,5 +0,0 @@ -package HookKiller.server.common.type; - -public class RequestHeaderConstants { - public static String KEY_LANGUAGE = "language"; -} diff --git a/src/main/java/HookKiller/server/notice/controller/NoticeController.java b/src/main/java/HookKiller/server/notice/controller/NoticeController.java index 588cf09..4d6e8ef 100644 --- a/src/main/java/HookKiller/server/notice/controller/NoticeController.java +++ b/src/main/java/HookKiller/server/notice/controller/NoticeController.java @@ -4,19 +4,21 @@ import HookKiller.server.notice.dto.AddNoticeRequest; import HookKiller.server.notice.dto.EditNoticeRequest; import HookKiller.server.notice.dto.NoticeArticleDto; -import HookKiller.server.notice.dto.NoticeContentDto; -import HookKiller.server.notice.entity.NoticeContent; -import HookKiller.server.repository.NoticeArticleRepository; -import HookKiller.server.repository.NoticeContentRepository; import HookKiller.server.service.NoticeService; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -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.PutMapping; +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; -import java.util.Optional; @Slf4j @RestController @@ -25,11 +27,10 @@ public class NoticeController { private final NoticeService noticeService; - private final NoticeArticleRepository articleRepository; - private final NoticeContentRepository contentRepository; /** - * 단건 조회 + * 단건 조회 + * * @param noticeArticleId * @param request * @return @@ -42,6 +43,7 @@ public NoticeArticleDto getNoticeArticle(@PathVariable Long noticeArticleId, Htt /** * 리스트 조회 + * * @param request * @return */ diff --git a/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java b/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java index cc5f759..1c50253 100644 --- a/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java +++ b/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java @@ -21,6 +21,9 @@ public class NoticeArticleDto extends AbstractTimeStamp { private String content; private String title; + // TODO : 생성일자 , 수정일자 필요한지 없는지 생각해보기 + // TODO : NoticeArticle의 status인지 NoticeContent의 language인지 생각해보기 + // TODO : NoticeArticle 한개로도 끝날 수 있는거 아닌지 생각해보기 public static NoticeArticleDto of(NoticeArticle noticeArticle, NoticeContent noticeContent) { return NoticeArticleDto.builder() .id(noticeArticle.getId()) diff --git a/src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java b/src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java deleted file mode 100644 index 98e5d9b..0000000 --- a/src/main/java/HookKiller/server/notice/dto/NoticeContentDto.java +++ /dev/null @@ -1,43 +0,0 @@ -package HookKiller.server.notice.dto; - -import HookKiller.server.common.type.LanguageType; -import HookKiller.server.notice.entity.NoticeArticle; -import HookKiller.server.notice.entity.NoticeContent; -import jakarta.validation.constraints.NotEmpty; -import lombok.Builder; -import lombok.Getter; - -@Getter -@Builder -public class NoticeContentDto { - - private Long id; - private LanguageType language; - - @NotEmpty(message = "제목을 입력해주세요.") - private String title; - - @NotEmpty(message = "내용을 입력해주세요.") - private String content; - - public static NoticeContentDto from(NoticeContent noticeContent) { - - return NoticeContentDto.builder() - .id(noticeContent.getId()) - .language(noticeContent.getLanguage()) - .title(noticeContent.getTitle()) - .content(noticeContent.getContent()) - .build(); - } - - public NoticeContentDto of(NoticeArticle noticeArticle, NoticeContent noticeContent) { - - return NoticeContentDto.builder() - .id(noticeContent.getId()) - .language(noticeContent.getLanguage()) - .title(noticeContent.getTitle()) - .content(noticeContent.getContent()) - .build(); - } - -} diff --git a/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java b/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java index 4b9bd14..23f8583 100644 --- a/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java +++ b/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java @@ -1,13 +1,26 @@ package HookKiller.server.notice.entity; import HookKiller.server.common.AbstractTimeStamp; -import HookKiller.server.common.type.LanguageType; import HookKiller.server.common.type.ArticleStatus; +import HookKiller.server.common.type.LanguageType; import HookKiller.server.user.entity.User; -import jakarta.persistence.*; -import lombok.*; +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.ManyToOne; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; -import java.sql.Timestamp; +import java.util.ArrayList; import java.util.List; /** @@ -18,7 +31,6 @@ * updatedAt : 공지글 정보 업데이트 일자 * updatedUser : 마지막에 수정한 사용자 ID입력. */ - @Entity @Getter @Setter @@ -31,7 +43,7 @@ public class NoticeArticle extends AbstractTimeStamp { private Long id; @OneToMany - private List content; + private List content = new ArrayList<>(); @Enumerated(EnumType.STRING) private LanguageType language; @@ -46,10 +58,8 @@ public class NoticeArticle extends AbstractTimeStamp { private User updatedUser; @Builder - public NoticeArticle(Long id, List content, LanguageType language, ArticleStatus status, - User createdUser,User updatedUser) { + public NoticeArticle(Long id, LanguageType language, ArticleStatus status, User createdUser, User updatedUser) { this.id = id; - this.content = content; this.language = language; this.status = status; this.createdUser = createdUser; diff --git a/src/main/java/HookKiller/server/notice/entity/NoticeContent.java b/src/main/java/HookKiller/server/notice/entity/NoticeContent.java index 57fc084..c367bb4 100644 --- a/src/main/java/HookKiller/server/notice/entity/NoticeContent.java +++ b/src/main/java/HookKiller/server/notice/entity/NoticeContent.java @@ -1,9 +1,22 @@ package HookKiller.server.notice.entity; import HookKiller.server.common.type.LanguageType; -import HookKiller.server.notice.dto.NoticeContentDto; -import jakarta.persistence.*; -import lombok.*; +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 lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; /** * language : title, content가 적용된 언어 @@ -35,16 +48,10 @@ public class NoticeContent { private String content; @Builder - public NoticeContent(Long id, NoticeArticle noticeArticle, - LanguageType language, String title, String content) { + public NoticeContent(Long id, NoticeArticle noticeArticle,LanguageType language, String title, String content) { this.noticeArticle = noticeArticle; this.language = language; this.title = title; this.content = content; } - - public void update(NoticeContentDto contentDto) { - this.title = contentDto.getTitle(); - this.content = contentDto.getContent(); - } } diff --git a/src/main/java/HookKiller/server/notice/exception/NoticeArticleNotFoundException.java b/src/main/java/HookKiller/server/notice/exception/NoticeArticleNotFoundException.java deleted file mode 100644 index fc4bd75..0000000 --- a/src/main/java/HookKiller/server/notice/exception/NoticeArticleNotFoundException.java +++ /dev/null @@ -1,13 +0,0 @@ -package HookKiller.server.notice.exception; - -import HookKiller.server.common.exception.BaseException; - -import static HookKiller.server.notice.exception.NoticeException.NOTICE_ARTICLE_NOT_FOUND_EXCEPTION; - -public class NoticeArticleNotFoundException extends BaseException { - public static final BaseException EXCEPTION = new NoticeArticleNotFoundException(); - - private NoticeArticleNotFoundException() { - super(NOTICE_ARTICLE_NOT_FOUND_EXCEPTION); - } -} diff --git a/src/main/java/HookKiller/server/notice/exception/NoticeContentNotFoundException.java b/src/main/java/HookKiller/server/notice/exception/NoticeContentNotFoundException.java deleted file mode 100644 index f6aeda7..0000000 --- a/src/main/java/HookKiller/server/notice/exception/NoticeContentNotFoundException.java +++ /dev/null @@ -1,14 +0,0 @@ -package HookKiller.server.notice.exception; - -import HookKiller.server.common.exception.BaseException; - -import static HookKiller.server.notice.exception.NoticeException.NOTICE_ARTICLE_NOT_FOUND_EXCEPTION; -import static HookKiller.server.notice.exception.NoticeException.NOTICE_CONTENT_NOT_FOUND_EXCEPTION; - -public class NoticeContentNotFoundException extends BaseException { - public static final BaseException EXCEPTION = new NoticeContentNotFoundException(); - - private NoticeContentNotFoundException() { - super(NOTICE_CONTENT_NOT_FOUND_EXCEPTION); - } -} diff --git a/src/main/java/HookKiller/server/notice/exception/NoticeException.java b/src/main/java/HookKiller/server/notice/exception/NoticeException.java index 477a118..d2d196b 100644 --- a/src/main/java/HookKiller/server/notice/exception/NoticeException.java +++ b/src/main/java/HookKiller/server/notice/exception/NoticeException.java @@ -11,8 +11,7 @@ @Getter @AllArgsConstructor public enum NoticeException implements BaseErrorCode { - NOTICE_ARTICLE_NOT_FOUND_EXCEPTION(NOT_FOUND.value(), "404-1", "공지사항 게시물이 존재하지 않습니다."), - NOTICE_CONTENT_NOT_FOUND_EXCEPTION(NOT_FOUND.value(), "404-2", "게시글이 존재하지 않습니다."); + NOTICE_NOT_FOUND(NOT_FOUND.value(), "404-1", "요청한 공지사항 게시물이 존재하지 않습니다."); private final Integer statusCode; private final String errorCode; diff --git a/src/main/java/HookKiller/server/notice/exception/NoticeNotFoundException.java b/src/main/java/HookKiller/server/notice/exception/NoticeNotFoundException.java new file mode 100644 index 0000000..cd29776 --- /dev/null +++ b/src/main/java/HookKiller/server/notice/exception/NoticeNotFoundException.java @@ -0,0 +1,13 @@ +package HookKiller.server.notice.exception; + +import HookKiller.server.common.exception.BaseException; + +import static HookKiller.server.notice.exception.NoticeException.NOTICE_NOT_FOUND; + +public class NoticeNotFoundException extends BaseException { + public static final BaseException EXCEPTION = new NoticeNotFoundException(); + + private NoticeNotFoundException() { + super(NOTICE_NOT_FOUND); + } +} diff --git a/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java b/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java index 829a974..c46d84d 100644 --- a/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java +++ b/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java @@ -1,16 +1,13 @@ package HookKiller.server.repository; -import HookKiller.server.common.type.LanguageType; import HookKiller.server.common.type.ArticleStatus; import HookKiller.server.notice.entity.NoticeArticle; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; -import java.util.Optional; public interface NoticeArticleRepository extends JpaRepository { - Optional findByLanguage(LanguageType languageType); List findAllByStatus(ArticleStatus status); } diff --git a/src/main/java/HookKiller/server/service/NoticeService.java b/src/main/java/HookKiller/server/service/NoticeService.java index 7f68218..355b2da 100644 --- a/src/main/java/HookKiller/server/service/NoticeService.java +++ b/src/main/java/HookKiller/server/service/NoticeService.java @@ -1,16 +1,13 @@ package HookKiller.server.service; -import HookKiller.server.common.type.ArticleStatus; import HookKiller.server.common.type.LanguageType; import HookKiller.server.common.util.UserUtils; import HookKiller.server.notice.dto.AddNoticeRequest; import HookKiller.server.notice.dto.EditNoticeRequest; import HookKiller.server.notice.dto.NoticeArticleDto; -import HookKiller.server.notice.dto.NoticeContentDto; import HookKiller.server.notice.entity.NoticeArticle; import HookKiller.server.notice.entity.NoticeContent; -import HookKiller.server.notice.exception.NoticeArticleNotFoundException; -import HookKiller.server.notice.exception.NoticeContentNotFoundException; +import HookKiller.server.notice.exception.NoticeNotFoundException; import HookKiller.server.repository.NoticeArticleRepository; import HookKiller.server.repository.NoticeContentRepository; import HookKiller.server.user.entity.User; @@ -20,7 +17,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Optional; import static HookKiller.server.common.type.ArticleStatus.DELETE; import static HookKiller.server.common.type.ArticleStatus.PUBLIC; @@ -40,14 +36,13 @@ public class NoticeService { * @param languageType * @return */ + @Transactional(readOnly = true) public NoticeArticleDto getNoticeArticleByArticleId(Long noticeArticleId, LanguageType languageType) { - + // TODO : 삭제처리된 게시물도 조회가 가능한것인가? NoticeArticle article = noticeArticleRepository.findById(noticeArticleId) - .orElseThrow(() -> NoticeArticleNotFoundException.EXCEPTION); - + .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); NoticeContent content = noticeContentRepository.findByNoticeArticleAndLanguage(article, languageType) - .orElseThrow(() -> NoticeContentNotFoundException.EXCEPTION); - + .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); return NoticeArticleDto.of(article, content); } @@ -59,7 +54,7 @@ public NoticeArticleDto getNoticeArticleByArticleId(Long noticeArticleId, Langua @Transactional(readOnly = true) public List getNoticeList(LanguageType languageType) { List articleList = noticeArticleRepository.findAllByStatus(PUBLIC); - + // TODO : NoticeArticle의 정보가 아니라, NoticeArticle이 PUBLIC상태인 게시물의 Content를 파라미터로 받은 languageType의 Content로 리스트를 반환해야 함. return noticeArticleRepository.findAll() .stream().map(data -> NoticeArticleDto.builder() @@ -68,7 +63,8 @@ public List getNoticeList(LanguageType languageType) { .status(data.getStatus()) .createdUser(data.getCreatedUser()) .updatedUser(data.getUpdatedUser()) - .build()) + .build() + ) .toList(); } @@ -113,7 +109,7 @@ public void updateNotice(EditNoticeRequest request) { boolean chgContent = false; NoticeArticle article = noticeArticleRepository.findById(request.getNoticeArticleId()) - .orElseThrow(() -> NoticeArticleNotFoundException.EXCEPTION); + .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); List contents = noticeContentRepository.findAllByNoticeArticle(article); article.setUpdatedUser(user); @@ -123,7 +119,7 @@ public void updateNotice(EditNoticeRequest request) { NoticeContent choiceContent = contents.stream() .filter(content -> request.getLanguage().equals(content.getLanguage())) - .findFirst().orElseThrow(() -> NoticeContentNotFoundException.EXCEPTION); + .findFirst().orElseThrow(() -> NoticeNotFoundException.EXCEPTION); if(request.getNewTitle() != null && !request.getNewTitle().equals(request.getOrgTitle())) { chgTitle = true; @@ -157,7 +153,7 @@ public void updateNotice(EditNoticeRequest request) { @Transactional public void deleteNotice(Long id) { noticeArticleRepository.findById(id).orElseThrow(() -> - NoticeArticleNotFoundException.EXCEPTION).updateStatus(DELETE); + NoticeNotFoundException.EXCEPTION).updateStatus(DELETE); } } From f55ac6db59580cdb82463f4fc1e90f89cab9b554 Mon Sep 17 00:00:00 2001 From: kwchoi11 Date: Thu, 12 Oct 2023 18:08:48 +0900 Subject: [PATCH 08/14] =?UTF-8?q?Fix:=20SecurityConfig=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/notice/dto/EditNoticeRequest.java | 1 - .../server/notice/dto/NoticeArticleDto.java | 10 ++++++++-- .../server/notice/entity/NoticeArticle.java | 13 ++++--------- .../server/notice/entity/NoticeContent.java | 6 ------ .../server/notice/exception/NoticeException.java | 1 - .../server/repository/NoticeArticleRepository.java | 2 ++ .../server/repository/NoticeContentRepository.java | 1 + .../HookKiller/server/service/NoticeService.java | 7 +++++-- 8 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/main/java/HookKiller/server/notice/dto/EditNoticeRequest.java b/src/main/java/HookKiller/server/notice/dto/EditNoticeRequest.java index a496252..6335a08 100644 --- a/src/main/java/HookKiller/server/notice/dto/EditNoticeRequest.java +++ b/src/main/java/HookKiller/server/notice/dto/EditNoticeRequest.java @@ -1,7 +1,6 @@ package HookKiller.server.notice.dto; import HookKiller.server.common.type.LanguageType; -import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java b/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java index 1c50253..725a536 100644 --- a/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java +++ b/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java @@ -9,6 +9,8 @@ import lombok.Builder; import lombok.Getter; +import java.sql.Timestamp; + @Getter @Builder public class NoticeArticleDto extends AbstractTimeStamp { @@ -20,19 +22,23 @@ public class NoticeArticleDto extends AbstractTimeStamp { private User updatedUser; private String content; private String title; + private Timestamp createAt; + private Timestamp updateAt; - // TODO : 생성일자 , 수정일자 필요한지 없는지 생각해보기 + // TODO : 생성일자, 수정일자 필요한지 없는지 생각해보기 // TODO : NoticeArticle의 status인지 NoticeContent의 language인지 생각해보기 // TODO : NoticeArticle 한개로도 끝날 수 있는거 아닌지 생각해보기 public static NoticeArticleDto of(NoticeArticle noticeArticle, NoticeContent noticeContent) { return NoticeArticleDto.builder() .id(noticeArticle.getId()) - .language(noticeArticle.getLanguage()) + .language(noticeContent.getLanguage()) .status(noticeArticle.getStatus()) .createdUser(noticeArticle.getCreatedUser()) .updatedUser(noticeArticle.getUpdatedUser()) .content(noticeContent.getContent()) .title(noticeContent.getTitle()) + .createAt(noticeArticle.getCreateAt()) + .updateAt(noticeArticle.getUpdateAt()) .build(); } } diff --git a/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java b/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java index 23f8583..9b010bd 100644 --- a/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java +++ b/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java @@ -20,17 +20,10 @@ import lombok.NoArgsConstructor; import lombok.Setter; +import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; -/** - * orgArticleLanguage : 원본으로 작성된 언어 타입. KOR:한국어, ENG:영어, CHI:중국어, JPN:일본어 - * status : 공지글 상태. PUBLIC:공개상태, DELETE:삭제처리 - * createdAt : 공지글 생성일 - * createdUser : 공지글 작성 사용자 ID입력. - * updatedAt : 공지글 정보 업데이트 일자 - * updatedUser : 마지막에 수정한 사용자 ID입력. - */ @Entity @Getter @Setter @@ -58,12 +51,14 @@ public class NoticeArticle extends AbstractTimeStamp { private User updatedUser; @Builder - public NoticeArticle(Long id, LanguageType language, ArticleStatus status, User createdUser, User updatedUser) { + public NoticeArticle(Long id, LanguageType language, ArticleStatus status, User createdUser, + User updatedUser, String title) { this.id = id; this.language = language; this.status = status; this.createdUser = createdUser; this.updatedUser = updatedUser; + this.title = title; } public void updateStatus(ArticleStatus status) { diff --git a/src/main/java/HookKiller/server/notice/entity/NoticeContent.java b/src/main/java/HookKiller/server/notice/entity/NoticeContent.java index c367bb4..54e7fe1 100644 --- a/src/main/java/HookKiller/server/notice/entity/NoticeContent.java +++ b/src/main/java/HookKiller/server/notice/entity/NoticeContent.java @@ -18,12 +18,6 @@ import lombok.NoArgsConstructor; import lombok.Setter; -/** - * language : title, content가 적용된 언어 - * title : 공지사항 제목 - * content : 공지사항 내용 - */ - @Entity @Getter @Setter diff --git a/src/main/java/HookKiller/server/notice/exception/NoticeException.java b/src/main/java/HookKiller/server/notice/exception/NoticeException.java index d2d196b..e21b5ed 100644 --- a/src/main/java/HookKiller/server/notice/exception/NoticeException.java +++ b/src/main/java/HookKiller/server/notice/exception/NoticeException.java @@ -4,7 +4,6 @@ import HookKiller.server.common.exception.BaseErrorCode; import lombok.AllArgsConstructor; import lombok.Getter; -import org.springframework.http.HttpStatus; import static org.springframework.http.HttpStatus.NOT_FOUND; diff --git a/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java b/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java index c46d84d..dca38e8 100644 --- a/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java +++ b/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java @@ -5,9 +5,11 @@ import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; +import java.util.Optional; public interface NoticeArticleRepository extends JpaRepository { List findAllByStatus(ArticleStatus status); + Optional findByIdAndStatus(Long id, ArticleStatus status); } diff --git a/src/main/java/HookKiller/server/repository/NoticeContentRepository.java b/src/main/java/HookKiller/server/repository/NoticeContentRepository.java index 2c97d7e..d7335e2 100644 --- a/src/main/java/HookKiller/server/repository/NoticeContentRepository.java +++ b/src/main/java/HookKiller/server/repository/NoticeContentRepository.java @@ -1,5 +1,6 @@ package HookKiller.server.repository; +import HookKiller.server.common.type.ArticleStatus; import HookKiller.server.common.type.LanguageType; import HookKiller.server.notice.entity.NoticeArticle; import HookKiller.server.notice.entity.NoticeContent; diff --git a/src/main/java/HookKiller/server/service/NoticeService.java b/src/main/java/HookKiller/server/service/NoticeService.java index 355b2da..f0194b3 100644 --- a/src/main/java/HookKiller/server/service/NoticeService.java +++ b/src/main/java/HookKiller/server/service/NoticeService.java @@ -39,7 +39,7 @@ public class NoticeService { @Transactional(readOnly = true) public NoticeArticleDto getNoticeArticleByArticleId(Long noticeArticleId, LanguageType languageType) { // TODO : 삭제처리된 게시물도 조회가 가능한것인가? - NoticeArticle article = noticeArticleRepository.findById(noticeArticleId) + NoticeArticle article = noticeArticleRepository.findByIdAndStatus(noticeArticleId, PUBLIC) .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); NoticeContent content = noticeContentRepository.findByNoticeArticleAndLanguage(article, languageType) .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); @@ -55,7 +55,7 @@ public NoticeArticleDto getNoticeArticleByArticleId(Long noticeArticleId, Langua public List getNoticeList(LanguageType languageType) { List articleList = noticeArticleRepository.findAllByStatus(PUBLIC); // TODO : NoticeArticle의 정보가 아니라, NoticeArticle이 PUBLIC상태인 게시물의 Content를 파라미터로 받은 languageType의 Content로 리스트를 반환해야 함. - return noticeArticleRepository.findAll() + return noticeArticleRepository.findAllByStatus(PUBLIC) .stream().map(data -> NoticeArticleDto.builder() .id(data.getId()) @@ -63,6 +63,9 @@ public List getNoticeList(LanguageType languageType) { .status(data.getStatus()) .createdUser(data.getCreatedUser()) .updatedUser(data.getUpdatedUser()) + .createAt(data.getCreateAt()) + .updateAt(data.getUpdateAt()) + .title(data.getContent().get(0).getTitle()) .build() ) .toList(); From b71334dd9770dd73fca9749d388497ca69f7c162 Mon Sep 17 00:00:00 2001 From: kwchoi11 Date: Thu, 12 Oct 2023 18:09:40 +0900 Subject: [PATCH 09/14] =?UTF-8?q?Fix:=20SecurityConfig=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/HookKiller/server/notice/entity/NoticeArticle.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java b/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java index 9b010bd..891dc64 100644 --- a/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java +++ b/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java @@ -52,13 +52,12 @@ public class NoticeArticle extends AbstractTimeStamp { @Builder public NoticeArticle(Long id, LanguageType language, ArticleStatus status, User createdUser, - User updatedUser, String title) { + User updatedUser) { this.id = id; this.language = language; this.status = status; this.createdUser = createdUser; this.updatedUser = updatedUser; - this.title = title; } public void updateStatus(ArticleStatus status) { From 57ee438725b63e56686bf8bc10a90fa77e7d9362 Mon Sep 17 00:00:00 2001 From: kwchoi11 Date: Fri, 13 Oct 2023 10:59:45 +0900 Subject: [PATCH 10/14] =?UTF-8?q?Feat:=20=EA=B3=B5=EC=A7=80=EC=82=AC?= =?UTF-8?q?=ED=95=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/common/type/LanguageType.java | 1 + .../notice/controller/NoticeController.java | 8 +- .../server/notice/entity/NoticeArticle.java | 7 +- .../server/notice/entity/NoticeContent.java | 2 + .../repository/NoticeArticleRepository.java | 16 ++ .../repository/NoticeContentRepository.java | 15 ++ .../server/notice/service/NoticeService.java | 164 ++++++++++++++++++ 7 files changed, 206 insertions(+), 7 deletions(-) create mode 100644 src/main/java/HookKiller/server/notice/repository/NoticeArticleRepository.java create mode 100644 src/main/java/HookKiller/server/notice/repository/NoticeContentRepository.java create mode 100644 src/main/java/HookKiller/server/notice/service/NoticeService.java diff --git a/src/main/java/HookKiller/server/common/type/LanguageType.java b/src/main/java/HookKiller/server/common/type/LanguageType.java index 9c24f09..81dd156 100644 --- a/src/main/java/HookKiller/server/common/type/LanguageType.java +++ b/src/main/java/HookKiller/server/common/type/LanguageType.java @@ -3,6 +3,7 @@ import jakarta.servlet.http.HttpServletRequest; import lombok.Getter; +import java.awt.print.Pageable; import java.util.Arrays; @Getter diff --git a/src/main/java/HookKiller/server/notice/controller/NoticeController.java b/src/main/java/HookKiller/server/notice/controller/NoticeController.java index 4d6e8ef..f5d75bf 100644 --- a/src/main/java/HookKiller/server/notice/controller/NoticeController.java +++ b/src/main/java/HookKiller/server/notice/controller/NoticeController.java @@ -4,7 +4,7 @@ import HookKiller.server.notice.dto.AddNoticeRequest; import HookKiller.server.notice.dto.EditNoticeRequest; import HookKiller.server.notice.dto.NoticeArticleDto; -import HookKiller.server.service.NoticeService; +import HookKiller.server.notice.service.NoticeService; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.awt.print.Pageable; import java.util.List; @Slf4j @@ -37,7 +38,7 @@ public class NoticeController { */ @GetMapping("/{noticeArticleId}") public NoticeArticleDto getNoticeArticle(@PathVariable Long noticeArticleId, HttpServletRequest request) { - log.error("공지사항 단건 조회 >>> {}", noticeArticleId); + log.info("공지사항 단건 조회 >>> {}", noticeArticleId); return noticeService.getNoticeArticleByArticleId(noticeArticleId, LanguageType.findTypeByRequest(request)); } @@ -47,8 +48,9 @@ public NoticeArticleDto getNoticeArticle(@PathVariable Long noticeArticleId, Htt * @param request * @return */ - @GetMapping + @GetMapping("/") public List getNoticeArticleList(HttpServletRequest request) { + log.info("공지사항 리스트 조회"); return noticeService.getNoticeList(LanguageType.findTypeByRequest(request)); } diff --git a/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java b/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java index 891dc64..e055356 100644 --- a/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java +++ b/src/main/java/HookKiller/server/notice/entity/NoticeArticle.java @@ -20,7 +20,6 @@ import lombok.NoArgsConstructor; import lombok.Setter; -import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; @@ -35,7 +34,7 @@ public class NoticeArticle extends AbstractTimeStamp { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @OneToMany + @OneToMany(mappedBy = "noticeArticle", fetch = FetchType.LAZY) private List content = new ArrayList<>(); @Enumerated(EnumType.STRING) @@ -44,10 +43,10 @@ public class NoticeArticle extends AbstractTimeStamp { @Enumerated(EnumType.STRING) private ArticleStatus status; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.EAGER) private User createdUser; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.EAGER) private User updatedUser; @Builder diff --git a/src/main/java/HookKiller/server/notice/entity/NoticeContent.java b/src/main/java/HookKiller/server/notice/entity/NoticeContent.java index 54e7fe1..f88ff7b 100644 --- a/src/main/java/HookKiller/server/notice/entity/NoticeContent.java +++ b/src/main/java/HookKiller/server/notice/entity/NoticeContent.java @@ -17,10 +17,12 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import lombok.ToString; @Entity @Getter @Setter +@ToString @Table(name = "tbl_notice_content") @NoArgsConstructor(access = AccessLevel.PROTECTED) public class NoticeContent { diff --git a/src/main/java/HookKiller/server/notice/repository/NoticeArticleRepository.java b/src/main/java/HookKiller/server/notice/repository/NoticeArticleRepository.java new file mode 100644 index 0000000..8893b72 --- /dev/null +++ b/src/main/java/HookKiller/server/notice/repository/NoticeArticleRepository.java @@ -0,0 +1,16 @@ +package HookKiller.server.notice.repository; + +import HookKiller.server.common.type.ArticleStatus; +import HookKiller.server.notice.entity.NoticeArticle; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; + +public interface NoticeArticleRepository extends JpaRepository { + + List findAllByStatus(ArticleStatus status); + + Optional findByIdAndStatus(Long id, ArticleStatus status); + +} diff --git a/src/main/java/HookKiller/server/notice/repository/NoticeContentRepository.java b/src/main/java/HookKiller/server/notice/repository/NoticeContentRepository.java new file mode 100644 index 0000000..7875ad4 --- /dev/null +++ b/src/main/java/HookKiller/server/notice/repository/NoticeContentRepository.java @@ -0,0 +1,15 @@ +package HookKiller.server.notice.repository; + +import HookKiller.server.common.type.LanguageType; +import HookKiller.server.notice.entity.NoticeArticle; +import HookKiller.server.notice.entity.NoticeContent; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; + +public interface NoticeContentRepository extends JpaRepository { + Optional findByNoticeArticleAndLanguage(NoticeArticle noticeArticle, LanguageType languageType); + + List findAllByNoticeArticle(NoticeArticle noticeArticle); +} diff --git a/src/main/java/HookKiller/server/notice/service/NoticeService.java b/src/main/java/HookKiller/server/notice/service/NoticeService.java new file mode 100644 index 0000000..e4a4124 --- /dev/null +++ b/src/main/java/HookKiller/server/notice/service/NoticeService.java @@ -0,0 +1,164 @@ +package HookKiller.server.notice.service; + +import HookKiller.server.common.type.LanguageType; +import HookKiller.server.common.util.UserUtils; +import HookKiller.server.notice.dto.AddNoticeRequest; +import HookKiller.server.notice.dto.EditNoticeRequest; +import HookKiller.server.notice.dto.NoticeArticleDto; +import HookKiller.server.notice.entity.NoticeArticle; +import HookKiller.server.notice.entity.NoticeContent; +import HookKiller.server.notice.exception.NoticeNotFoundException; +import HookKiller.server.notice.repository.NoticeArticleRepository; +import HookKiller.server.notice.repository.NoticeContentRepository; +import HookKiller.server.user.entity.User; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +import static HookKiller.server.common.type.ArticleStatus.DELETE; +import static HookKiller.server.common.type.ArticleStatus.PUBLIC; + +@Slf4j +@Service +@RequiredArgsConstructor +public class NoticeService { + + private final NoticeArticleRepository noticeArticleRepository; + private final NoticeContentRepository noticeContentRepository; + private final UserUtils userUtils; + + /** + * 단건 조회 + * + * @param noticeArticleId + * @param languageType + * @return + */ + @Transactional(readOnly = true) + public NoticeArticleDto getNoticeArticleByArticleId(Long noticeArticleId, LanguageType languageType) { + // TODO : 삭제처리된 게시물도 조회가 가능한것인가? + NoticeArticle article = noticeArticleRepository.findByIdAndStatus(noticeArticleId, PUBLIC) + .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); + NoticeContent content = noticeContentRepository.findByNoticeArticleAndLanguage(article, languageType) + .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); + return NoticeArticleDto.of(article, content); + } + + /** + * 리스트 조회 + * + * @return + */ + @Transactional(readOnly = true) + public List getNoticeList(LanguageType languageType) { + List articleList = noticeArticleRepository.findAllByStatus(PUBLIC); + // TODO : NoticeArticle의 정보가 아니라, NoticeArticle이 PUBLIC상태인 게시물의 Content를 파라미터로 받은 languageType의 Content로 리스트를 반환해야 함. + return noticeArticleRepository.findAllByStatus(PUBLIC) + .stream() + .map(data -> NoticeArticleDto.builder() + .id(data.getId()) + .language(data.getLanguage()) + .status(data.getStatus()) + .createdUser(data.getCreatedUser()) + .updatedUser(data.getUpdatedUser()) + .createAt(data.getCreateAt()) + .updateAt(data.getUpdateAt()) + .title(data.getContent().get(0).getTitle()) + .build() + ).toList(); + + } + + /** + * 등록 + * + */ + @Transactional + public void saveNotice(AddNoticeRequest addNoticeRequest) { + User loginUser = userUtils.getUser(); + + NoticeArticle noticeArticle = noticeArticleRepository.save( + NoticeArticle.builder() + .language(addNoticeRequest.getLanguage()) + .status(PUBLIC) + .createdUser(loginUser) + .updatedUser(loginUser) + .build() + ); + + List contentsList = new ArrayList<>(); + contentsList.add( + NoticeContent.builder() + .noticeArticle(noticeArticle) + .language(addNoticeRequest.getLanguage()) + .title(addNoticeRequest.getTitle()) + .content(addNoticeRequest.getContent()) + .build() + ); + // TODO : getLanguage에 들어있는 언어에서 다른 언어 번역한 결과 역시 NoticeContent로 제작해서 Save + noticeContentRepository.saveAll(contentsList); + } + + /** + * 수정 + */ + @Transactional + public void updateNotice(EditNoticeRequest request) { + //로그인한 사용자 획득 + User user = userUtils.getUser(); + boolean chgTitle = false; + boolean chgContent = false; + + NoticeArticle article = noticeArticleRepository.findById(request.getNoticeArticleId()) + .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); + List contents = noticeContentRepository.findAllByNoticeArticle(article); + + article.setUpdatedUser(user); + //다른경우 변경 + if (!request.getLanguage().equals(article.getLanguage())) + article.setLanguage(request.getLanguage()); + + NoticeContent choiceContent = contents.stream() + .filter(content -> request.getLanguage().equals(content.getLanguage())) + .findFirst().orElseThrow(() -> NoticeNotFoundException.EXCEPTION); + + if(request.getNewTitle() != null && !request.getNewTitle().equals(request.getOrgTitle())) { + chgTitle = true; + choiceContent.setTitle(request.getNewTitle()); + } + if(request.getNewContent() != null && !request.getNewContent().equals(request.getOrgContent())){ + chgContent = true; + choiceContent.setContent(request.getNewContent()); + } + + if(chgTitle || chgContent) { + final boolean finalChgTitle = chgTitle; + final boolean finalChgContent = chgContent; + contents.stream().filter(content-> choiceContent != content).forEach(content-> { + if(finalChgTitle){ + // TODO : request의 언어를 원본으로 해서 content의 언어로 타겟잡아 번역후 title변환 + } + if(finalChgContent){ + // TODO : request의 언어를 원본으로 해서 content의 언어로 타겟잡아 번역후 content변환 + } + }); + } + + } + + /** + * 삭제 + * + * @param id + */ + @Transactional + public void deleteNotice(Long id) { + noticeArticleRepository.findById(id).orElseThrow(() -> + NoticeNotFoundException.EXCEPTION).updateStatus(DELETE); + } + +} From f900859c8f3eff5c90cfd213960352923329c89a Mon Sep 17 00:00:00 2001 From: kwchoi11 Date: Fri, 13 Oct 2023 11:33:21 +0900 Subject: [PATCH 11/14] =?UTF-8?q?Feat:=20=EA=B3=B5=EC=A7=80=EC=82=AC?= =?UTF-8?q?=ED=95=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../HookKiller/server/notice/controller/NoticeController.java | 1 - .../java/HookKiller/server/notice/dto/NoticeArticleDto.java | 3 --- .../java/HookKiller/server/notice/service/NoticeService.java | 2 -- 3 files changed, 6 deletions(-) diff --git a/src/main/java/HookKiller/server/notice/controller/NoticeController.java b/src/main/java/HookKiller/server/notice/controller/NoticeController.java index f5d75bf..f41eec3 100644 --- a/src/main/java/HookKiller/server/notice/controller/NoticeController.java +++ b/src/main/java/HookKiller/server/notice/controller/NoticeController.java @@ -18,7 +18,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.awt.print.Pageable; import java.util.List; @Slf4j diff --git a/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java b/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java index 725a536..6b2c341 100644 --- a/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java +++ b/src/main/java/HookKiller/server/notice/dto/NoticeArticleDto.java @@ -25,9 +25,6 @@ public class NoticeArticleDto extends AbstractTimeStamp { private Timestamp createAt; private Timestamp updateAt; - // TODO : 생성일자, 수정일자 필요한지 없는지 생각해보기 - // TODO : NoticeArticle의 status인지 NoticeContent의 language인지 생각해보기 - // TODO : NoticeArticle 한개로도 끝날 수 있는거 아닌지 생각해보기 public static NoticeArticleDto of(NoticeArticle noticeArticle, NoticeContent noticeContent) { return NoticeArticleDto.builder() .id(noticeArticle.getId()) diff --git a/src/main/java/HookKiller/server/notice/service/NoticeService.java b/src/main/java/HookKiller/server/notice/service/NoticeService.java index e4a4124..3c8fe83 100644 --- a/src/main/java/HookKiller/server/notice/service/NoticeService.java +++ b/src/main/java/HookKiller/server/notice/service/NoticeService.java @@ -40,7 +40,6 @@ public class NoticeService { */ @Transactional(readOnly = true) public NoticeArticleDto getNoticeArticleByArticleId(Long noticeArticleId, LanguageType languageType) { - // TODO : 삭제처리된 게시물도 조회가 가능한것인가? NoticeArticle article = noticeArticleRepository.findByIdAndStatus(noticeArticleId, PUBLIC) .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); NoticeContent content = noticeContentRepository.findByNoticeArticleAndLanguage(article, languageType) @@ -56,7 +55,6 @@ public NoticeArticleDto getNoticeArticleByArticleId(Long noticeArticleId, Langua @Transactional(readOnly = true) public List getNoticeList(LanguageType languageType) { List articleList = noticeArticleRepository.findAllByStatus(PUBLIC); - // TODO : NoticeArticle의 정보가 아니라, NoticeArticle이 PUBLIC상태인 게시물의 Content를 파라미터로 받은 languageType의 Content로 리스트를 반환해야 함. return noticeArticleRepository.findAllByStatus(PUBLIC) .stream() .map(data -> NoticeArticleDto.builder() From 215421d0a88ff64b77ab697c1c7d25d27e861f2c Mon Sep 17 00:00:00 2001 From: kwchoi11 Date: Fri, 13 Oct 2023 13:53:03 +0900 Subject: [PATCH 12/14] Merge Dev Branch --- .gitignore | 3 +- build.gradle | 1 - .../board/controller/ArticleController.java | 72 ++++++++ .../server/board/dto/ArticleRequestDto.java | 47 +++++ .../board/dto/PostArticleRequestDto.java | 33 ++++ .../server/board/entity/Article.java | 94 ++++++++++ .../server/board/entity/ArticleContent.java | 67 ++++++++ .../server/board/entity/ArticleLike.java | 39 +++++ .../HookKiller/server/board/entity/Board.java | 49 ++++++ .../HookKiller/server/board/entity/Reply.java | 51 ++++++ .../server/board/entity/ReplyContent.java | 45 +++++ .../ArticleContentNotFoundException.java | 13 ++ .../board/exception/BoardException.java | 26 +++ .../exception/BoardNotFoundException.java | 13 ++ .../repository/ArticleContentRepository.java | 17 ++ .../board/repository/ArticleRepository.java | 15 ++ .../board/repository/BoardRepository.java | 14 ++ .../repository/ReplyContentRepository.java | 7 + .../board/repository/ReplyRepository.java | 7 + .../board/service/ArticleContentService.java | 85 +++++++++ .../server/board/service/ArticleService.java | 89 ++++++++++ .../server/board/type/ArticleStatus.java | 13 ++ .../server/board/type/BoardType.java | 14 ++ .../controller/HealthCheckController.java | 5 - .../controller/PapagoSampleController.java | 29 ++++ .../server/common/dto/PapagoHtmlRequest.java | 20 +++ .../server/common/dto/PapagoHtmlResponse.java | 18 ++ .../server/common/dto/PapagoTextRequest.java | 24 +++ .../server/common/dto/PapagoTextResponse.java | 35 ++++ .../common/dto/TranslateResponseDto.java | 29 ++++ .../common/exception/GlobalException.java | 1 + .../common/exception/NaverErrorException.java | 14 ++ .../common/service/TranslateService.java | 85 +++++++++ .../config/ConfigurationProperties.java | 4 +- .../NaverObjectStorageProperties.java | 1 + .../server/properties/PapagoProperties.java | 19 ++ .../server/service/NoticeService.java | 162 ------------------ src/main/resources/application-papago.yml | 3 + src/main/resources/application.yml | 1 + 39 files changed, 1094 insertions(+), 170 deletions(-) create mode 100644 src/main/java/HookKiller/server/board/controller/ArticleController.java create mode 100644 src/main/java/HookKiller/server/board/dto/ArticleRequestDto.java create mode 100644 src/main/java/HookKiller/server/board/dto/PostArticleRequestDto.java create mode 100644 src/main/java/HookKiller/server/board/entity/Article.java create mode 100644 src/main/java/HookKiller/server/board/entity/ArticleContent.java create mode 100644 src/main/java/HookKiller/server/board/entity/ArticleLike.java create mode 100644 src/main/java/HookKiller/server/board/entity/Board.java create mode 100644 src/main/java/HookKiller/server/board/entity/Reply.java create mode 100644 src/main/java/HookKiller/server/board/entity/ReplyContent.java create mode 100644 src/main/java/HookKiller/server/board/exception/ArticleContentNotFoundException.java create mode 100644 src/main/java/HookKiller/server/board/exception/BoardException.java create mode 100644 src/main/java/HookKiller/server/board/exception/BoardNotFoundException.java create mode 100644 src/main/java/HookKiller/server/board/repository/ArticleContentRepository.java create mode 100644 src/main/java/HookKiller/server/board/repository/ArticleRepository.java create mode 100644 src/main/java/HookKiller/server/board/repository/BoardRepository.java create mode 100644 src/main/java/HookKiller/server/board/repository/ReplyContentRepository.java create mode 100644 src/main/java/HookKiller/server/board/repository/ReplyRepository.java create mode 100644 src/main/java/HookKiller/server/board/service/ArticleContentService.java create mode 100644 src/main/java/HookKiller/server/board/service/ArticleService.java create mode 100644 src/main/java/HookKiller/server/board/type/ArticleStatus.java create mode 100644 src/main/java/HookKiller/server/board/type/BoardType.java create mode 100644 src/main/java/HookKiller/server/common/controller/PapagoSampleController.java create mode 100644 src/main/java/HookKiller/server/common/dto/PapagoHtmlRequest.java create mode 100644 src/main/java/HookKiller/server/common/dto/PapagoHtmlResponse.java create mode 100644 src/main/java/HookKiller/server/common/dto/PapagoTextRequest.java create mode 100644 src/main/java/HookKiller/server/common/dto/PapagoTextResponse.java create mode 100644 src/main/java/HookKiller/server/common/dto/TranslateResponseDto.java create mode 100644 src/main/java/HookKiller/server/common/exception/NaverErrorException.java create mode 100644 src/main/java/HookKiller/server/common/service/TranslateService.java create mode 100644 src/main/java/HookKiller/server/properties/PapagoProperties.java delete mode 100644 src/main/java/HookKiller/server/service/NoticeService.java create mode 100644 src/main/resources/application-papago.yml diff --git a/.gitignore b/.gitignore index 2bff8a4..154b7c4 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,5 @@ out/ ### VS Code ### .vscode/ -.DS_Store \ No newline at end of file +.DS_Store + diff --git a/build.gradle b/build.gradle index e350f7f..a4f3487 100644 --- a/build.gradle +++ b/build.gradle @@ -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' diff --git a/src/main/java/HookKiller/server/board/controller/ArticleController.java b/src/main/java/HookKiller/server/board/controller/ArticleController.java new file mode 100644 index 0000000..67c4933 --- /dev/null +++ b/src/main/java/HookKiller/server/board/controller/ArticleController.java @@ -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.*; + +import java.util.List; + +@Slf4j +@RestController +@RequestMapping("/article") +@RequiredArgsConstructor +public class ArticleController { + + private final ArticleService articleService; + private final ArticleContentService articleContentService; + + /** + * 게시글 조회 + */ + @GetMapping("/{boardId}") + public List 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 createArticle(@RequestBody PostArticleRequestDto requestDto) { + articleContentService.createContent( + requestDto, articleService.createArticle(requestDto) + ); + return ResponseEntity.ok("Article Create Success"); + } + + /** + * 게시물 수정 + */ + @PutMapping + public ResponseEntity updateArticle(@RequestBody PostArticleRequestDto requestDto) { + articleContentService.updateContent(requestDto, articleService.updateArticle(requestDto)); + return ResponseEntity.ok("Article Create Success"); + } + + + /** + * 게시물 삭제 + */ + @DeleteMapping("/{articleId}") + public ResponseEntity deleteArticle(@PathVariable Long articleId) { + articleService.deleteArticle(articleId); + return ResponseEntity.ok("삭제처리가 완료되었습니다."); + } + +} diff --git a/src/main/java/HookKiller/server/board/dto/ArticleRequestDto.java b/src/main/java/HookKiller/server/board/dto/ArticleRequestDto.java new file mode 100644 index 0000000..6108a86 --- /dev/null +++ b/src/main/java/HookKiller/server/board/dto/ArticleRequestDto.java @@ -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(); + } + +} diff --git a/src/main/java/HookKiller/server/board/dto/PostArticleRequestDto.java b/src/main/java/HookKiller/server/board/dto/PostArticleRequestDto.java new file mode 100644 index 0000000..3638bb5 --- /dev/null +++ b/src/main/java/HookKiller/server/board/dto/PostArticleRequestDto.java @@ -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; +} diff --git a/src/main/java/HookKiller/server/board/entity/Article.java b/src/main/java/HookKiller/server/board/entity/Article.java new file mode 100644 index 0000000..0dea218 --- /dev/null +++ b/src/main/java/HookKiller/server/board/entity/Article.java @@ -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 = new ArrayList<>(); + + @OneToMany(mappedBy = "article", fetch = FetchType.LAZY) + private List articleContent = new ArrayList<>(); + + @OneToMany(mappedBy = "article", fetch = FetchType.LAZY) + private List 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; + } + +} diff --git a/src/main/java/HookKiller/server/board/entity/ArticleContent.java b/src/main/java/HookKiller/server/board/entity/ArticleContent.java new file mode 100644 index 0000000..16b5eb5 --- /dev/null +++ b/src/main/java/HookKiller/server/board/entity/ArticleContent.java @@ -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; + } +} diff --git a/src/main/java/HookKiller/server/board/entity/ArticleLike.java b/src/main/java/HookKiller/server/board/entity/ArticleLike.java new file mode 100644 index 0000000..76843f0 --- /dev/null +++ b/src/main/java/HookKiller/server/board/entity/ArticleLike.java @@ -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; +} diff --git a/src/main/java/HookKiller/server/board/entity/Board.java b/src/main/java/HookKiller/server/board/entity/Board.java new file mode 100644 index 0000000..b359dfd --- /dev/null +++ b/src/main/java/HookKiller/server/board/entity/Board.java @@ -0,0 +1,49 @@ +package HookKiller.server.board.entity; + +import HookKiller.server.board.type.BoardType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import jakarta.validation.constraints.NotNull; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * id : PK + * name :게시판 명 + * boardType : 게시판 종류 + * description : 게시판 사용 용도 + */ + +@Entity +@Getter +@Table(name = "tbl_board") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Board { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name="board_id") + private Long id; + + @OneToMany(mappedBy = "board") + private List
article; + + @NotNull + private String name; + + @Enumerated(EnumType.STRING) + private BoardType boardType; + + @NotNull + private String description; + +} \ No newline at end of file diff --git a/src/main/java/HookKiller/server/board/entity/Reply.java b/src/main/java/HookKiller/server/board/entity/Reply.java new file mode 100644 index 0000000..a1b657f --- /dev/null +++ b/src/main/java/HookKiller/server/board/entity/Reply.java @@ -0,0 +1,51 @@ +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.OneToMany; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * id : PK + * article : 게시글 정보 + * replyContent : 댓글 내용 + * orgReplyLanguage : 원본으로 작성된 언어 타입 + * isDeleted : 댓글 삭제 여부 + * createdAt : 댓글 생성일 + * createdUser : 댓글 작성 사용자 ID + * updatedAt : 댓글 정보 업데이트 + * updatedUser : 마지막에 수정한 사용자 ID + */ + +@Entity +@Getter +@Table(name = "tbl_reply") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Reply extends AbstractTimeStamp { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="article_id") + private Article article; + + @OneToMany(mappedBy = "reply") + private List replyContent; + + private String orgReplyLanguage; + private boolean isDeleted; + private Long createdUserId; + private Long updatedUserId; +} diff --git a/src/main/java/HookKiller/server/board/entity/ReplyContent.java b/src/main/java/HookKiller/server/board/entity/ReplyContent.java new file mode 100644 index 0000000..f4f2266 --- /dev/null +++ b/src/main/java/HookKiller/server/board/entity/ReplyContent.java @@ -0,0 +1,45 @@ +package HookKiller.server.board.entity; + +import HookKiller.server.common.type.LanguageType; +import jakarta.persistence.Column; +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.Lob; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.validation.constraints.NotNull; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * language : content가 적용된 언어 타입. + * content : 댓글 내용. + */ + +@Entity +@Getter +@Table(name = "tbl_reply_content") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ReplyContent { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="reply_id") + private Reply reply; + + @NotNull + private LanguageType language; + + @Column + @Lob + private String content; + + +} diff --git a/src/main/java/HookKiller/server/board/exception/ArticleContentNotFoundException.java b/src/main/java/HookKiller/server/board/exception/ArticleContentNotFoundException.java new file mode 100644 index 0000000..af2dd5d --- /dev/null +++ b/src/main/java/HookKiller/server/board/exception/ArticleContentNotFoundException.java @@ -0,0 +1,13 @@ +package HookKiller.server.board.exception; + +import HookKiller.server.common.exception.BaseException; + +public class ArticleContentNotFoundException extends BaseException { + + public static final BaseException EXCEPTION = new ArticleContentNotFoundException(); + + private ArticleContentNotFoundException() { + super(BoardException.ARTICLE_CONTENT_NOT_FOUND_ERROR); + } + +} diff --git a/src/main/java/HookKiller/server/board/exception/BoardException.java b/src/main/java/HookKiller/server/board/exception/BoardException.java new file mode 100644 index 0000000..92c0e27 --- /dev/null +++ b/src/main/java/HookKiller/server/board/exception/BoardException.java @@ -0,0 +1,26 @@ +package HookKiller.server.board.exception; + + +import HookKiller.server.common.dto.ErrorDetail; +import HookKiller.server.common.exception.BaseErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import static org.springframework.http.HttpStatus.*; + +@Getter +@AllArgsConstructor +public enum BoardException implements BaseErrorCode { + + BOARD_NOT_FOUND_ERROR(NOT_FOUND.value(), "Board_404_1", "해당 게시판을 찾을 수 없습니다."), + ARTICLE_CONTENT_NOT_FOUND_ERROR(NOT_FOUND.value(), "ArticleContent_404_1", "해당 게시글을 찾을 수 없습니다."); + + private final Integer statusCode; + private final String errorCode; + private final String reason; + + @Override + public ErrorDetail getErrorDetail() { + return ErrorDetail.of(statusCode, errorCode, reason); + } +} diff --git a/src/main/java/HookKiller/server/board/exception/BoardNotFoundException.java b/src/main/java/HookKiller/server/board/exception/BoardNotFoundException.java new file mode 100644 index 0000000..f5f0d86 --- /dev/null +++ b/src/main/java/HookKiller/server/board/exception/BoardNotFoundException.java @@ -0,0 +1,13 @@ +package HookKiller.server.board.exception; + +import HookKiller.server.common.exception.BaseException; + +public class BoardNotFoundException extends BaseException { + + public static final BaseException EXCEPTION = new BoardNotFoundException(); + + private BoardNotFoundException() { + super(BoardException.BOARD_NOT_FOUND_ERROR); + } + +} diff --git a/src/main/java/HookKiller/server/board/repository/ArticleContentRepository.java b/src/main/java/HookKiller/server/board/repository/ArticleContentRepository.java new file mode 100644 index 0000000..83d5801 --- /dev/null +++ b/src/main/java/HookKiller/server/board/repository/ArticleContentRepository.java @@ -0,0 +1,17 @@ +package HookKiller.server.board.repository; + +import HookKiller.server.board.entity.Article; +import HookKiller.server.board.entity.ArticleContent; +import HookKiller.server.common.type.LanguageType; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; + +public interface ArticleContentRepository extends JpaRepository { + + Optional findByArticleAndLanguage(Article article, LanguageType language); + + List findAllByArticle(Article article); + +} diff --git a/src/main/java/HookKiller/server/board/repository/ArticleRepository.java b/src/main/java/HookKiller/server/board/repository/ArticleRepository.java new file mode 100644 index 0000000..f0de7a9 --- /dev/null +++ b/src/main/java/HookKiller/server/board/repository/ArticleRepository.java @@ -0,0 +1,15 @@ +package HookKiller.server.board.repository; + +import HookKiller.server.board.entity.Article; +import HookKiller.server.board.entity.Board; +import HookKiller.server.board.type.ArticleStatus; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + + +public interface ArticleRepository extends JpaRepository { + + List
findAllByBoardAndArticleStatus(Board board, ArticleStatus status); + +} diff --git a/src/main/java/HookKiller/server/board/repository/BoardRepository.java b/src/main/java/HookKiller/server/board/repository/BoardRepository.java new file mode 100644 index 0000000..a66803f --- /dev/null +++ b/src/main/java/HookKiller/server/board/repository/BoardRepository.java @@ -0,0 +1,14 @@ +package HookKiller.server.board.repository; + +import HookKiller.server.board.entity.Board; +import org.springframework.data.jpa.repository.JpaRepository; + + +/** + * BoardRepository: BoardRepository 인터페이스는 Board 엔터티를 데이터베이스에 + * 저장, 조회, 수정 및 삭제하기 위한 메서드를 제공합니다. + * Spring Data JPA를 사용하여 기본 CRUD 작업을 자동으로 처리합니다. + */ + +public interface BoardRepository extends JpaRepository { +} diff --git a/src/main/java/HookKiller/server/board/repository/ReplyContentRepository.java b/src/main/java/HookKiller/server/board/repository/ReplyContentRepository.java new file mode 100644 index 0000000..2ed9d65 --- /dev/null +++ b/src/main/java/HookKiller/server/board/repository/ReplyContentRepository.java @@ -0,0 +1,7 @@ +package HookKiller.server.board.repository; + +import HookKiller.server.board.entity.ReplyContent; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ReplyContentRepository extends JpaRepository { +} diff --git a/src/main/java/HookKiller/server/board/repository/ReplyRepository.java b/src/main/java/HookKiller/server/board/repository/ReplyRepository.java new file mode 100644 index 0000000..0a42bfb --- /dev/null +++ b/src/main/java/HookKiller/server/board/repository/ReplyRepository.java @@ -0,0 +1,7 @@ +package HookKiller.server.board.repository; + +import HookKiller.server.board.entity.Reply; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ReplyRepository extends JpaRepository { +} diff --git a/src/main/java/HookKiller/server/board/service/ArticleContentService.java b/src/main/java/HookKiller/server/board/service/ArticleContentService.java new file mode 100644 index 0000000..ada76df --- /dev/null +++ b/src/main/java/HookKiller/server/board/service/ArticleContentService.java @@ -0,0 +1,85 @@ +package HookKiller.server.board.service; + +import HookKiller.server.board.dto.PostArticleRequestDto; +import HookKiller.server.board.entity.Article; +import HookKiller.server.board.entity.ArticleContent; +import HookKiller.server.board.repository.ArticleContentRepository; +import HookKiller.server.common.type.LanguageType; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@Slf4j +@Service +@RequiredArgsConstructor +public class ArticleContentService { + private final ArticleContentRepository articleContentRepository; + + public void createContent(PostArticleRequestDto requestDto, Article article) { + + List targetLanguageList = Arrays.stream(LanguageType.values()) + .filter(languageType -> !languageType.equals(requestDto.getOrgArticleLanguage())) + .toList(); + + List articleContentList = new ArrayList<>( + targetLanguageList.stream().map( + languageType -> ArticleContent.builder() + .article(article) + .language(languageType) + // .title(getTranslatePapagoTextArticleContent(requestDto.getOrgArticleLanguage().getLanguageCode(), languageType.getLanguageCode(), requestDto.getTitle())) + // .content(getTranslatePapagoHTMLArticleContent(requestDto.getOrgArticleLanguage().getLanguageCode(), languageType.getLanguageCode(), requestDto.getContent())) + .build() + ).toList() + ); + articleContentList.add( + ArticleContent.builder() + .article(article) + .language(requestDto.getOrgArticleLanguage()) + .title(requestDto.getTitle()) + .content(requestDto.getContent()) + .build() + ); + articleContentRepository.saveAll(articleContentList); + } + + public void updateContent(PostArticleRequestDto requestDto, Article article) { + // 게시물의 모든 내용을 찾습니다. + List existingContents = articleContentRepository.findAllByArticle(article); + + // 원본 언어의 내용을 업데이트합니다. + existingContents.stream() + .filter(content -> content.getLanguage().equals(requestDto.getOrgArticleLanguage())) + .forEach(content -> { + content.articleUpdate(requestDto.getTitle(), requestDto.getContent()); + }); + + // 다른 언어로 번역된 내용들을 업데이트합니다. + for (LanguageType languageType : LanguageType.values()) { + if (!languageType.equals(requestDto.getOrgArticleLanguage())) { + existingContents.stream() + .filter(content -> content.getLanguage().equals(languageType)) + .forEach(content -> { + // content.articleUpdate(getTranslatePapagoTextArticleContent(requestDto.getOrgArticleLanguage().getLanguageCode(), languageType.getLanguageCode(), requestDto.getTitle()), + // getTranslatePapagoHTMLArticleContent(requestDto.getOrgArticleLanguage().getLanguageCode(), languageType.getLanguageCode(), requestDto.getContent())); + }); + } + } + + articleContentRepository.saveAll(existingContents); + } + + + + protected String getTranslatePapagoTextArticleContent(String source, String target, String content) { + return null; + } + + protected String getTranslatePapagoHTMLArticleContent(String source, String target, String content) { + return null; + } + +} diff --git a/src/main/java/HookKiller/server/board/service/ArticleService.java b/src/main/java/HookKiller/server/board/service/ArticleService.java new file mode 100644 index 0000000..c3551e5 --- /dev/null +++ b/src/main/java/HookKiller/server/board/service/ArticleService.java @@ -0,0 +1,89 @@ +package HookKiller.server.board.service; + +import HookKiller.server.board.dto.ArticleRequestDto; +import HookKiller.server.board.dto.PostArticleRequestDto; +import HookKiller.server.board.entity.Article; +import HookKiller.server.board.entity.Board; +import HookKiller.server.board.exception.ArticleContentNotFoundException; +import HookKiller.server.board.exception.BoardNotFoundException; +import HookKiller.server.board.repository.ArticleContentRepository; +import HookKiller.server.board.repository.ArticleRepository; +import HookKiller.server.board.repository.BoardRepository; +import HookKiller.server.board.type.ArticleStatus; +import HookKiller.server.common.type.LanguageType; +import HookKiller.server.common.util.UserUtils; +import HookKiller.server.user.entity.User; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Service +@RequiredArgsConstructor +public class ArticleService { + + private final UserUtils userUtils; + private final ArticleContentService articleContentService; + private final BoardRepository boardRepository; + private final ArticleRepository articleRepository; + private final ArticleContentRepository articleContentRepository; + + public List getArticleList(Long boardId, LanguageType language) { + // boardId로 board에 해당하는 Article들을 모두 뽑아온다 + Board board = boardRepository.findById(boardId).orElseThrow(()-> BoardNotFoundException.EXCEPTION); + List
articleList = articleRepository.findAllByBoardAndArticleStatus(board, ArticleStatus.PUBLIC); + + return articleList.stream() + .map(article -> + ArticleRequestDto.of(article, articleContentRepository + .findByArticleAndLanguage(article, language) + .orElseThrow(()-> ArticleContentNotFoundException.EXCEPTION))) + .toList(); + } + + public Article createArticle(PostArticleRequestDto postArticleRequestDto) { + Board board = boardRepository.findById(postArticleRequestDto.getBoardId()) + .orElseThrow(() -> BoardNotFoundException.EXCEPTION); + + User requestUser = userUtils.getUser(); + return articleRepository.save(Article.builder() + .board(board) + .articleStatus(ArticleStatus.PUBLIC) + .orgArticleLanguage(postArticleRequestDto.getOrgArticleLanguage()) + .createdUser(requestUser) + .updatedUser(requestUser) + .build() + ); + } + + @Transactional + public Article updateArticle(PostArticleRequestDto postArticleRequestDto) { + + Article article = articleRepository.findById(postArticleRequestDto.getArticleId()) + .orElseThrow(() -> ArticleContentNotFoundException.EXCEPTION); + + User requestUser = userUtils.getUser(); + + article.setOrgArticleLanguage(postArticleRequestDto.getOrgArticleLanguage()); + article.setUpdatedUser(requestUser); + + // 게시물 내용 업데이트 + articleContentService.updateContent(postArticleRequestDto, article); + + return articleRepository.save(article); + } + + + + @Transactional + public void deleteArticle(Long articleId) { + articleRepository + .findById(articleId) + .orElseThrow(() -> ArticleContentNotFoundException.EXCEPTION) + .updateStatus(ArticleStatus.DELETE); + } +} diff --git a/src/main/java/HookKiller/server/board/type/ArticleStatus.java b/src/main/java/HookKiller/server/board/type/ArticleStatus.java new file mode 100644 index 0000000..853cd00 --- /dev/null +++ b/src/main/java/HookKiller/server/board/type/ArticleStatus.java @@ -0,0 +1,13 @@ +package HookKiller.server.board.type; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum ArticleStatus { + PUBLIC("공개상태"), + DELETE("삭제처리"); + + private final String typeName; +} diff --git a/src/main/java/HookKiller/server/board/type/BoardType.java b/src/main/java/HookKiller/server/board/type/BoardType.java new file mode 100644 index 0000000..b5ef078 --- /dev/null +++ b/src/main/java/HookKiller/server/board/type/BoardType.java @@ -0,0 +1,14 @@ +package HookKiller.server.board.type; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum BoardType { + KOREA("한국 게시판"), + JAPAN("일본 게시판"), + CHINA("중국 게시판"); + + private final String typeName; +} diff --git a/src/main/java/HookKiller/server/common/controller/HealthCheckController.java b/src/main/java/HookKiller/server/common/controller/HealthCheckController.java index 9768fc5..6bc7534 100644 --- a/src/main/java/HookKiller/server/common/controller/HealthCheckController.java +++ b/src/main/java/HookKiller/server/common/controller/HealthCheckController.java @@ -2,9 +2,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -12,11 +10,8 @@ @RestController @RequiredArgsConstructor public class HealthCheckController { - @GetMapping("/health") public ResponseEntity healthCheck(){ - log.error("authentication : {}", SecurityContextHolder.getContext().getAuthentication().getName()); - return ResponseEntity.ok().build(); } diff --git a/src/main/java/HookKiller/server/common/controller/PapagoSampleController.java b/src/main/java/HookKiller/server/common/controller/PapagoSampleController.java new file mode 100644 index 0000000..69a5b80 --- /dev/null +++ b/src/main/java/HookKiller/server/common/controller/PapagoSampleController.java @@ -0,0 +1,29 @@ +package HookKiller.server.common.controller; + +import HookKiller.server.common.service.TranslateService; +import HookKiller.server.common.type.LanguageType; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import java.util.ArrayList; +import java.util.List; + +// TODO : 추후 삭제 필요 예정, 해당 클래스통해 번역의뢰 하는거 아니고 서비스 사용방법 기록하려 한거에요, 여기 추가하지마세요. by.Jong1 +@Slf4j +@RequiredArgsConstructor +@RequestMapping("/papago") +public class PapagoSampleController { + private final TranslateService translateService; + + @GetMapping("/test") + public ResponseEntity> testSample() { + + return ResponseEntity.ok(new ArrayList<>() {{ + add(translateService.naverPapagoTextTranslate(LanguageType.KO, LanguageType.JP, "안녕하세요~~")); + add(translateService.naverPapagoHtmlTranslate(LanguageType.KO, LanguageType.JP, "
안녕하세요. 파파고입니다.
")); + }}); + } +} diff --git a/src/main/java/HookKiller/server/common/dto/PapagoHtmlRequest.java b/src/main/java/HookKiller/server/common/dto/PapagoHtmlRequest.java new file mode 100644 index 0000000..6949585 --- /dev/null +++ b/src/main/java/HookKiller/server/common/dto/PapagoHtmlRequest.java @@ -0,0 +1,20 @@ +package HookKiller.server.common.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +public class PapagoHtmlRequest { + private String source; + private String target; + private String html; +} diff --git a/src/main/java/HookKiller/server/common/dto/PapagoHtmlResponse.java b/src/main/java/HookKiller/server/common/dto/PapagoHtmlResponse.java new file mode 100644 index 0000000..366ab6c --- /dev/null +++ b/src/main/java/HookKiller/server/common/dto/PapagoHtmlResponse.java @@ -0,0 +1,18 @@ +package HookKiller.server.common.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Getter +@Builder +@ToString +@AllArgsConstructor +@NoArgsConstructor +public class PapagoHtmlResponse { + + private String result; + +} diff --git a/src/main/java/HookKiller/server/common/dto/PapagoTextRequest.java b/src/main/java/HookKiller/server/common/dto/PapagoTextRequest.java new file mode 100644 index 0000000..762fe88 --- /dev/null +++ b/src/main/java/HookKiller/server/common/dto/PapagoTextRequest.java @@ -0,0 +1,24 @@ +package HookKiller.server.common.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +public class PapagoTextRequest { + private String source; + private String target; + private String text; + private String html; + private String glossaryKey; + private String replaceInfo; + private Boolean honorific; +} diff --git a/src/main/java/HookKiller/server/common/dto/PapagoTextResponse.java b/src/main/java/HookKiller/server/common/dto/PapagoTextResponse.java new file mode 100644 index 0000000..af4664c --- /dev/null +++ b/src/main/java/HookKiller/server/common/dto/PapagoTextResponse.java @@ -0,0 +1,35 @@ +package HookKiller.server.common.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Builder +@ToString +@NoArgsConstructor +@AllArgsConstructor +@JsonInclude(JsonInclude.Include.ALWAYS) +public class PapagoTextResponse { + + private PapagoMessage message; + @Getter + @Setter + public static class PapagoMessage{ + private PapagoResult result; + } + + @Getter + @Setter + @ToString + public static class PapagoResult { + private String srcLangType; + private String tarLangType; + private String translatedText; + } +} + diff --git a/src/main/java/HookKiller/server/common/dto/TranslateResponseDto.java b/src/main/java/HookKiller/server/common/dto/TranslateResponseDto.java new file mode 100644 index 0000000..31ab6b2 --- /dev/null +++ b/src/main/java/HookKiller/server/common/dto/TranslateResponseDto.java @@ -0,0 +1,29 @@ +package HookKiller.server.common.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class TranslateResponseDto { + + private Message message; + + @AllArgsConstructor + @Getter + @NoArgsConstructor + public static class Message { + private Result result; + } + + @AllArgsConstructor + @Getter + @NoArgsConstructor + public static class Result { + private String srcLangType; + private String tarLangType; + private String translatedText; + } +} diff --git a/src/main/java/HookKiller/server/common/exception/GlobalException.java b/src/main/java/HookKiller/server/common/exception/GlobalException.java index 1d0b496..a81a141 100644 --- a/src/main/java/HookKiller/server/common/exception/GlobalException.java +++ b/src/main/java/HookKiller/server/common/exception/GlobalException.java @@ -24,6 +24,7 @@ public enum GlobalException implements BaseErrorCode{ FILE_DELETE_ERROR(INTERNAL_SERVER_ERROR.value(), "500-11", "파일 삭제 중 오류가 발생하였습니다"), FILE_IO_ERROR(INTERNAL_SERVER_ERROR.value(), "500-12","파일 변환 중 오류가 발생하였습니다"), MAIL_SEND_ERROR(INTERNAL_SERVER_ERROR.value(), "500-20", "메일 발송중 오류가 발생하였습니다"), + NAVER_ERROR(INTERNAL_SERVER_ERROR.value(), "500-30", "네이버 번역 도중 오류가 발생하였습니다") ; private final Integer statusCode; diff --git a/src/main/java/HookKiller/server/common/exception/NaverErrorException.java b/src/main/java/HookKiller/server/common/exception/NaverErrorException.java new file mode 100644 index 0000000..aec83f0 --- /dev/null +++ b/src/main/java/HookKiller/server/common/exception/NaverErrorException.java @@ -0,0 +1,14 @@ +package HookKiller.server.common.exception; + + +import static HookKiller.server.common.exception.GlobalException.NAVER_ERROR; + +public class NaverErrorException extends BaseException { + + public static final BaseException EXCEPTION = new NaverErrorException(); + + private NaverErrorException() { + super(NAVER_ERROR); + } + +} \ No newline at end of file diff --git a/src/main/java/HookKiller/server/common/service/TranslateService.java b/src/main/java/HookKiller/server/common/service/TranslateService.java new file mode 100644 index 0000000..18eb9a0 --- /dev/null +++ b/src/main/java/HookKiller/server/common/service/TranslateService.java @@ -0,0 +1,85 @@ +package HookKiller.server.common.service; + +import HookKiller.server.common.dto.*; +import HookKiller.server.common.exception.NaverErrorException; +import HookKiller.server.common.type.LanguageType; +import HookKiller.server.properties.PapagoProperties; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.*; +import org.springframework.http.converter.FormHttpMessageConverter; +import org.springframework.stereotype.Service; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@Service +@RequiredArgsConstructor +public class TranslateService { + + private final PapagoProperties papagoProperties; + private final ObjectMapper objectMapper; + + public String naverPapagoHtmlTranslate(LanguageType source, LanguageType target, String html) { + RestTemplate restTemplate = new RestTemplate(); + + MultiValueMap papagoRequestBody = new LinkedMultiValueMap<>(); + papagoRequestBody.add("source", source.getLanguageCode()); + papagoRequestBody.add("target", target.getLanguageCode()); + papagoRequestBody.add("html", html); + +// Map papagoRequestBody = objectMapper.convertValue(PapagoHtmlRequest.builder() +// .source(source.getLanguageCode()) +// .target(target.getLanguageCode()) +// .html(html) +// .build(), Map.class); + +// HttpEntity request = new HttpEntity<>(papagoRequestBody, papagoRequestHeaders); + + HttpHeaders papagoRequestHeaders = new HttpHeaders(); + papagoRequestHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + papagoProperties.getHeader().forEach(papagoRequestHeaders::set); + + HttpEntity> request = new HttpEntity<>(papagoRequestBody, papagoRequestHeaders); + + ResponseEntity response = + restTemplate.postForEntity(URI.create(papagoProperties.getHtmlRequestUrl()), request, String.class); + if (response.getStatusCode().equals(HttpStatus.OK)) { + log.info("result >>> {}", response.getBody()); + return response.getBody(); + } + throw NaverErrorException.EXCEPTION; + } + + public String naverPapagoTextTranslate(LanguageType source, LanguageType target, String content) { + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders papagoRequestHeaders = new HttpHeaders(); + papagoRequestHeaders.setContentType(MediaType.APPLICATION_JSON); + papagoProperties.getHeader().forEach(papagoRequestHeaders::set); + + Map papagoRequestBody = objectMapper.convertValue(PapagoTextRequest.builder() + .source(source.getLanguageCode()) + .target(target.getLanguageCode()) + .text(content) + .build(), Map.class); + + HttpEntity request = new HttpEntity<>(papagoRequestBody, papagoRequestHeaders); + + ResponseEntity response = + restTemplate.postForEntity(URI.create(papagoProperties.getTextRequestUrl()), request, PapagoTextResponse.class); + + if (response.getStatusCode().equals(HttpStatus.OK)) { + log.info("result >>> {}", response.getBody().getMessage().getResult().toString()); + return response.getBody().getMessage().getResult().getTranslatedText(); + } + throw NaverErrorException.EXCEPTION; + } + +} + diff --git a/src/main/java/HookKiller/server/config/ConfigurationProperties.java b/src/main/java/HookKiller/server/config/ConfigurationProperties.java index 4dc9057..92aa3cf 100644 --- a/src/main/java/HookKiller/server/config/ConfigurationProperties.java +++ b/src/main/java/HookKiller/server/config/ConfigurationProperties.java @@ -4,6 +4,7 @@ import HookKiller.server.properties.CorsProperties; import HookKiller.server.properties.JwtProperties; import HookKiller.server.properties.NaverObjectStorageProperties; +import HookKiller.server.properties.PapagoProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; @@ -11,7 +12,8 @@ { JwtProperties.class, CorsProperties.class, - NaverObjectStorageProperties.class + NaverObjectStorageProperties.class, + PapagoProperties.class } ) @Configuration diff --git a/src/main/java/HookKiller/server/properties/NaverObjectStorageProperties.java b/src/main/java/HookKiller/server/properties/NaverObjectStorageProperties.java index ad9724d..e2d7726 100644 --- a/src/main/java/HookKiller/server/properties/NaverObjectStorageProperties.java +++ b/src/main/java/HookKiller/server/properties/NaverObjectStorageProperties.java @@ -17,3 +17,4 @@ public class NaverObjectStorageProperties { private String secretKey; private String bucketName; } + diff --git a/src/main/java/HookKiller/server/properties/PapagoProperties.java b/src/main/java/HookKiller/server/properties/PapagoProperties.java new file mode 100644 index 0000000..36a5883 --- /dev/null +++ b/src/main/java/HookKiller/server/properties/PapagoProperties.java @@ -0,0 +1,19 @@ +package HookKiller.server.properties; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.ToString; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.util.Map; + +@Getter +@ToString +@AllArgsConstructor +@ConfigurationProperties(prefix = "papago") +public class PapagoProperties { + private String textRequestUrl; + private String htmlRequestUrl; + private Map header; +} diff --git a/src/main/java/HookKiller/server/service/NoticeService.java b/src/main/java/HookKiller/server/service/NoticeService.java deleted file mode 100644 index f0194b3..0000000 --- a/src/main/java/HookKiller/server/service/NoticeService.java +++ /dev/null @@ -1,162 +0,0 @@ -package HookKiller.server.service; - -import HookKiller.server.common.type.LanguageType; -import HookKiller.server.common.util.UserUtils; -import HookKiller.server.notice.dto.AddNoticeRequest; -import HookKiller.server.notice.dto.EditNoticeRequest; -import HookKiller.server.notice.dto.NoticeArticleDto; -import HookKiller.server.notice.entity.NoticeArticle; -import HookKiller.server.notice.entity.NoticeContent; -import HookKiller.server.notice.exception.NoticeNotFoundException; -import HookKiller.server.repository.NoticeArticleRepository; -import HookKiller.server.repository.NoticeContentRepository; -import HookKiller.server.user.entity.User; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.ArrayList; -import java.util.List; - -import static HookKiller.server.common.type.ArticleStatus.DELETE; -import static HookKiller.server.common.type.ArticleStatus.PUBLIC; - -@Service -@RequiredArgsConstructor -public class NoticeService { - - private final NoticeArticleRepository noticeArticleRepository; - private final NoticeContentRepository noticeContentRepository; - private final UserUtils userUtils; - - /** - * 단건 조회 - * - * @param noticeArticleId - * @param languageType - * @return - */ - @Transactional(readOnly = true) - public NoticeArticleDto getNoticeArticleByArticleId(Long noticeArticleId, LanguageType languageType) { - // TODO : 삭제처리된 게시물도 조회가 가능한것인가? - NoticeArticle article = noticeArticleRepository.findByIdAndStatus(noticeArticleId, PUBLIC) - .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); - NoticeContent content = noticeContentRepository.findByNoticeArticleAndLanguage(article, languageType) - .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); - return NoticeArticleDto.of(article, content); - } - - /** - * 리스트 조회 - * - * @return - */ - @Transactional(readOnly = true) - public List getNoticeList(LanguageType languageType) { - List articleList = noticeArticleRepository.findAllByStatus(PUBLIC); - // TODO : NoticeArticle의 정보가 아니라, NoticeArticle이 PUBLIC상태인 게시물의 Content를 파라미터로 받은 languageType의 Content로 리스트를 반환해야 함. - return noticeArticleRepository.findAllByStatus(PUBLIC) - .stream().map(data -> - NoticeArticleDto.builder() - .id(data.getId()) - .language(data.getLanguage()) - .status(data.getStatus()) - .createdUser(data.getCreatedUser()) - .updatedUser(data.getUpdatedUser()) - .createAt(data.getCreateAt()) - .updateAt(data.getUpdateAt()) - .title(data.getContent().get(0).getTitle()) - .build() - ) - .toList(); - } - - /** - * 등록 - * - */ - @Transactional - public void saveNotice(AddNoticeRequest addNoticeRequest) { - User loginUser = userUtils.getUser(); - - NoticeArticle noticeArticle = noticeArticleRepository.save( - NoticeArticle.builder() - .language(addNoticeRequest.getLanguage()) - .status(PUBLIC) - .createdUser(loginUser) - .updatedUser(loginUser) - .build() - ); - - List contentsList = new ArrayList<>(); - contentsList.add( - NoticeContent.builder() - .noticeArticle(noticeArticle) - .language(addNoticeRequest.getLanguage()) - .title(addNoticeRequest.getTitle()) - .content(addNoticeRequest.getContent()) - .build() - ); - // TODO : getLanguage에 들어있는 언어에서 다른 언어 번역한 결과 역시 NoticeContent로 제작해서 Save - noticeContentRepository.saveAll(contentsList); - } - - /** - * 수정 - */ - @Transactional - public void updateNotice(EditNoticeRequest request) { - //로그인한 사용자 획득 - User user = userUtils.getUser(); - boolean chgTitle = false; - boolean chgContent = false; - - NoticeArticle article = noticeArticleRepository.findById(request.getNoticeArticleId()) - .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); - List contents = noticeContentRepository.findAllByNoticeArticle(article); - - article.setUpdatedUser(user); - //다른경우 변경 - if (!request.getLanguage().equals(article.getLanguage())) - article.setLanguage(request.getLanguage()); - - NoticeContent choiceContent = contents.stream() - .filter(content -> request.getLanguage().equals(content.getLanguage())) - .findFirst().orElseThrow(() -> NoticeNotFoundException.EXCEPTION); - - if(request.getNewTitle() != null && !request.getNewTitle().equals(request.getOrgTitle())) { - chgTitle = true; - choiceContent.setTitle(request.getNewTitle()); - } - if(request.getNewContent() != null && !request.getNewContent().equals(request.getOrgContent())){ - chgContent = true; - choiceContent.setContent(request.getNewContent()); - } - - if(chgTitle || chgContent) { - final boolean finalChgTitle = chgTitle; - final boolean finalChgContent = chgContent; - contents.stream().filter(content-> choiceContent != content).forEach(content-> { - if(finalChgTitle){ - // TODO : request의 언어를 원본으로 해서 content의 언어로 타겟잡아 번역후 title변환 - } - if(finalChgContent){ - // TODO : request의 언어를 원본으로 해서 content의 언어로 타겟잡아 번역후 content변환 - } - }); - } - - } - - /** - * 삭제 - * - * @param id - */ - @Transactional - public void deleteNotice(Long id) { - noticeArticleRepository.findById(id).orElseThrow(() -> - NoticeNotFoundException.EXCEPTION).updateStatus(DELETE); - } - -} diff --git a/src/main/resources/application-papago.yml b/src/main/resources/application-papago.yml new file mode 100644 index 0000000..eacec33 --- /dev/null +++ b/src/main/resources/application-papago.yml @@ -0,0 +1,3 @@ +papago: + text-request-url: https://naveropenapi.apigw.ntruss.com/nmt/v1/translation + html-request-url: https://naveropenapi.apigw.ntruss.com/web-trans/v1/translate \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index b31fc07..f9b4372 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,6 +4,7 @@ spring: include: - db - auth + - papago mail: From c84fca76cbe6e60c7419e657598f3a94503e2c2e Mon Sep 17 00:00:00 2001 From: kwchoi11 Date: Fri, 13 Oct 2023 13:54:44 +0900 Subject: [PATCH 13/14] =?UTF-8?q?Feat:=20=EA=B3=B5=EC=A7=80=EC=82=AC?= =?UTF-8?q?=ED=95=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/notice/controller/NoticeController.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/HookKiller/server/notice/controller/NoticeController.java b/src/main/java/HookKiller/server/notice/controller/NoticeController.java index f41eec3..ac45781 100644 --- a/src/main/java/HookKiller/server/notice/controller/NoticeController.java +++ b/src/main/java/HookKiller/server/notice/controller/NoticeController.java @@ -56,16 +56,18 @@ public List getNoticeArticleList(HttpServletRequest request) { /** * 공지사항 등록 */ - @PostMapping + @PostMapping("/") public void addNotice(@RequestBody @Valid AddNoticeRequest request) { + log.info("공지사항 등록"); noticeService.saveNotice(request); } /** * 공지사항 수정 */ - @PutMapping + @PutMapping("/") public void updateNotice(@RequestBody @Valid EditNoticeRequest request) { + log.info("공지사항 수정"); noticeService.updateNotice(request); } From d24822779a836a81c6a442d102c279c9cda268a7 Mon Sep 17 00:00:00 2001 From: donsonioc2010 Date: Fri, 13 Oct 2023 18:16:39 +0900 Subject: [PATCH 14/14] =?UTF-8?q?feat=20:=20=EA=B3=B5=EC=A7=80=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EA=B0=9C=EB=B0=9C=20-=20=EA=B3=B5=EC=A7=80?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20(=ED=8E=98=EC=9D=B4=EC=A7=95)=20-=20Exception?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20-=20=EA=B3=B5=EC=A7=80=EC=82=AC=ED=95=AD?= =?UTF-8?q?=20=EA=B2=8C=EC=8B=9C=EB=AC=BC=EC=9D=98=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=20=20-=20=EA=B4=80=EB=A6=AC=EC=9E=90=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=20=20-=20=EA=B2=8C=EC=8B=9C=EB=AC=BC=20=EB=B2=88=EC=97=AD=20?= =?UTF-8?q?=20=20-=20=EC=8B=A4=ED=8C=A8=EC=8B=9C=20=EB=A1=A4=EB=B0=B1=20-?= =?UTF-8?q?=20=EA=B3=B5=EC=A7=80=EC=82=AC=ED=95=AD=20=EA=B2=8C=EC=8B=9C?= =?UTF-8?q?=EB=AC=BC=EC=9D=98=20=EC=88=98=EC=A0=95=20=20=20-=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=EC=9E=90=20=EA=B2=80=EC=A6=9D=20=20=20-=20=EA=B2=8C?= =?UTF-8?q?=EC=8B=9C=EB=AC=BC=20=EC=83=81=ED=83=9C=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=20=20-=20=EB=B2=88=EC=97=AD=EC=8B=A4=ED=8C=A8=EC=8B=9C=20?= =?UTF-8?q?=EB=A1=A4=EB=B0=B1=20-=20=EA=B3=B5=EC=A7=80=EC=82=AC=ED=95=AD?= =?UTF-8?q?=20=EA=B2=8C=EC=8B=9C=EB=AC=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 동일 명칭 Repository --- .../server/common/type/LanguageType.java | 8 + .../notice/controller/NoticeController.java | 15 +- .../notice/exception/NoticeException.java | 4 +- .../NoticeNotAdminForbiddenException.java | 13 ++ .../repository/NoticeArticleRepository.java | 5 +- .../server/notice/service/NoticeService.java | 149 +++++++++++++----- .../repository/NoticeArticleRepository.java | 15 -- .../repository/NoticeContentRepository.java | 16 -- src/main/resources/data.sql | 100 ++++++------ 9 files changed, 200 insertions(+), 125 deletions(-) create mode 100644 src/main/java/HookKiller/server/notice/exception/NoticeNotAdminForbiddenException.java delete mode 100644 src/main/java/HookKiller/server/repository/NoticeArticleRepository.java delete mode 100644 src/main/java/HookKiller/server/repository/NoticeContentRepository.java diff --git a/src/main/java/HookKiller/server/common/type/LanguageType.java b/src/main/java/HookKiller/server/common/type/LanguageType.java index 1a76479..e633155 100644 --- a/src/main/java/HookKiller/server/common/type/LanguageType.java +++ b/src/main/java/HookKiller/server/common/type/LanguageType.java @@ -5,6 +5,8 @@ import lombok.Getter; import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; @Getter @AllArgsConstructor @@ -25,4 +27,10 @@ public static LanguageType findType(String value) { public static LanguageType findTypeByRequest(HttpServletRequest request) { return request == null ? KO : findType(request.getHeader(HTTP_REQUEST_HEADER_KEY_LANGUAGE)); } + + public Set getTranslateTargetLanguage() { + return Arrays.stream(LanguageType.values()) + .filter(languageType -> !languageType.equals(this)) + .collect(Collectors.toSet()); + } } diff --git a/src/main/java/HookKiller/server/notice/controller/NoticeController.java b/src/main/java/HookKiller/server/notice/controller/NoticeController.java index ac45781..21eef9c 100644 --- a/src/main/java/HookKiller/server/notice/controller/NoticeController.java +++ b/src/main/java/HookKiller/server/notice/controller/NoticeController.java @@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.List; @@ -47,16 +48,20 @@ public NoticeArticleDto getNoticeArticle(@PathVariable Long noticeArticleId, Htt * @param request * @return */ - @GetMapping("/") - public List getNoticeArticleList(HttpServletRequest request) { + @GetMapping + public List getNoticeArticleList( + @RequestParam(defaultValue = "0", required = false) int page, + @RequestParam(defaultValue = "10", required = false) int articleLimit, + HttpServletRequest request + ) { log.info("공지사항 리스트 조회"); - return noticeService.getNoticeList(LanguageType.findTypeByRequest(request)); + return noticeService.getNoticeList(page, articleLimit, LanguageType.findTypeByRequest(request)); } /** * 공지사항 등록 */ - @PostMapping("/") + @PostMapping public void addNotice(@RequestBody @Valid AddNoticeRequest request) { log.info("공지사항 등록"); noticeService.saveNotice(request); @@ -65,7 +70,7 @@ public void addNotice(@RequestBody @Valid AddNoticeRequest request) { /** * 공지사항 수정 */ - @PutMapping("/") + @PutMapping public void updateNotice(@RequestBody @Valid EditNoticeRequest request) { log.info("공지사항 수정"); noticeService.updateNotice(request); diff --git a/src/main/java/HookKiller/server/notice/exception/NoticeException.java b/src/main/java/HookKiller/server/notice/exception/NoticeException.java index e21b5ed..30b56e5 100644 --- a/src/main/java/HookKiller/server/notice/exception/NoticeException.java +++ b/src/main/java/HookKiller/server/notice/exception/NoticeException.java @@ -5,12 +5,14 @@ import lombok.AllArgsConstructor; import lombok.Getter; +import static org.springframework.http.HttpStatus.FORBIDDEN; import static org.springframework.http.HttpStatus.NOT_FOUND; @Getter @AllArgsConstructor public enum NoticeException implements BaseErrorCode { - NOTICE_NOT_FOUND(NOT_FOUND.value(), "404-1", "요청한 공지사항 게시물이 존재하지 않습니다."); + NOTICE_NOT_FOUND(NOT_FOUND.value(), "404-1", "요청한 공지사항 게시물이 존재하지 않습니다."), + NOTICE_NOT_AUTH(FORBIDDEN.value(), "404-2", "권한이 없습니다."); private final Integer statusCode; private final String errorCode; diff --git a/src/main/java/HookKiller/server/notice/exception/NoticeNotAdminForbiddenException.java b/src/main/java/HookKiller/server/notice/exception/NoticeNotAdminForbiddenException.java new file mode 100644 index 0000000..fbf7060 --- /dev/null +++ b/src/main/java/HookKiller/server/notice/exception/NoticeNotAdminForbiddenException.java @@ -0,0 +1,13 @@ +package HookKiller.server.notice.exception; + +import HookKiller.server.common.exception.BaseException; + +import static HookKiller.server.notice.exception.NoticeException.NOTICE_NOT_AUTH; + +public class NoticeNotAdminForbiddenException extends BaseException { + public static final BaseException EXCEPTION = new NoticeNotAdminForbiddenException(); + + private NoticeNotAdminForbiddenException() { + super(NOTICE_NOT_AUTH); + } +} diff --git a/src/main/java/HookKiller/server/notice/repository/NoticeArticleRepository.java b/src/main/java/HookKiller/server/notice/repository/NoticeArticleRepository.java index 8893b72..276f93a 100644 --- a/src/main/java/HookKiller/server/notice/repository/NoticeArticleRepository.java +++ b/src/main/java/HookKiller/server/notice/repository/NoticeArticleRepository.java @@ -2,6 +2,8 @@ import HookKiller.server.common.type.ArticleStatus; import HookKiller.server.notice.entity.NoticeArticle; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; @@ -9,8 +11,9 @@ public interface NoticeArticleRepository extends JpaRepository { - List findAllByStatus(ArticleStatus status); + List findAllByStatusOrderByCreateAtDesc(ArticleStatus status); Optional findByIdAndStatus(Long id, ArticleStatus status); + Page findAllByStatusOrderByCreateAtDesc(ArticleStatus status, Pageable pageable); } diff --git a/src/main/java/HookKiller/server/notice/service/NoticeService.java b/src/main/java/HookKiller/server/notice/service/NoticeService.java index 3c8fe83..6a1c8f0 100644 --- a/src/main/java/HookKiller/server/notice/service/NoticeService.java +++ b/src/main/java/HookKiller/server/notice/service/NoticeService.java @@ -1,5 +1,6 @@ package HookKiller.server.notice.service; +import HookKiller.server.common.service.TranslateService; import HookKiller.server.common.type.LanguageType; import HookKiller.server.common.util.UserUtils; import HookKiller.server.notice.dto.AddNoticeRequest; @@ -7,12 +8,16 @@ import HookKiller.server.notice.dto.NoticeArticleDto; import HookKiller.server.notice.entity.NoticeArticle; import HookKiller.server.notice.entity.NoticeContent; +import HookKiller.server.notice.exception.NoticeNotAdminForbiddenException; import HookKiller.server.notice.exception.NoticeNotFoundException; import HookKiller.server.notice.repository.NoticeArticleRepository; import HookKiller.server.notice.repository.NoticeContentRepository; import HookKiller.server.user.entity.User; +import HookKiller.server.user.type.UserRole; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -26,7 +31,7 @@ @Service @RequiredArgsConstructor public class NoticeService { - + private final TranslateService translateService; private final NoticeArticleRepository noticeArticleRepository; private final NoticeContentRepository noticeContentRepository; private final UserUtils userUtils; @@ -48,43 +53,61 @@ public NoticeArticleDto getNoticeArticleByArticleId(Long noticeArticleId, Langua } /** - * 리스트 조회 + * 리스트 조회 - 사용자가 요청한 languageType에 맞춰서 List조회 + * 1. ArticleStatus가 공개중(PUBLIC)인 상태 + * 2. 생성일이 최신 순서로 + * 3. Content에서 선택한 언어로 번역된 데이터가 존재하는 경우 + * TODO : 페이지네이션 * * @return */ @Transactional(readOnly = true) - public List getNoticeList(LanguageType languageType) { - List articleList = noticeArticleRepository.findAllByStatus(PUBLIC); - return noticeArticleRepository.findAllByStatus(PUBLIC) + public List getNoticeList(int page, int articleLimit, LanguageType languageType) { + return noticeArticleRepository.findAllByStatusOrderByCreateAtDesc(PUBLIC, PageRequest.of(page, articleLimit)) .stream() - .map(data -> NoticeArticleDto.builder() - .id(data.getId()) - .language(data.getLanguage()) - .status(data.getStatus()) - .createdUser(data.getCreatedUser()) - .updatedUser(data.getUpdatedUser()) - .createAt(data.getCreateAt()) - .updateAt(data.getUpdateAt()) - .title(data.getContent().get(0).getTitle()) - .build() - ).toList(); - + .filter(noticeArticle -> noticeArticle.getContent().stream().anyMatch(noticeContent -> noticeContent.getLanguage().equals(languageType))) + .map(noticeArticle -> { + //그래봐야 Filter로 존재하는 애들만 걸러져서 의미없음 + NoticeContent noticeContent = noticeArticle.getContent() + .stream() + .filter(content -> content.getLanguage().equals(languageType)) + .findFirst() + .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); + return NoticeArticleDto.builder() + .id(noticeArticle.getId()) + .language(noticeArticle.getLanguage()) + .status(noticeArticle.getStatus()) + .createdUser(noticeArticle.getCreatedUser()) + .updatedUser(noticeArticle.getUpdatedUser()) + .title(noticeContent.getTitle()) + .build(); + }) + .toList(); } /** - * 등록 + * 공지사항 게시물 등록 + * 1. 사용자가 로그인을 하지 않은 경우 → UserNotFoundException이 발생한다. + * 2. 사용자가 로그인을 하였지만 관리자가 아닌 경우 → NoticeNotAdminForbiddenException이 발생한다. + * 3. 번역이 실패한 경우 → NaverErrorException이 발생한다. * + * @param addNoticeRequest */ @Transactional public void saveNotice(AddNoticeRequest addNoticeRequest) { - User loginUser = userUtils.getUser(); + //로그인한 사용자 획득 + User user = userUtils.getUser(); + + //관리자 권한 확인 + if(user.getRole().equals(UserRole.ADMIN)) + throw NoticeNotAdminForbiddenException.EXCEPTION; NoticeArticle noticeArticle = noticeArticleRepository.save( NoticeArticle.builder() .language(addNoticeRequest.getLanguage()) .status(PUBLIC) - .createdUser(loginUser) - .updatedUser(loginUser) + .createdUser(user) + .updatedUser(user) .build() ); @@ -97,24 +120,62 @@ public void saveNotice(AddNoticeRequest addNoticeRequest) { .content(addNoticeRequest.getContent()) .build() ); - // TODO : getLanguage에 들어있는 언어에서 다른 언어 번역한 결과 역시 NoticeContent로 제작해서 Save + + addNoticeRequest + .getLanguage() + .getTranslateTargetLanguage() + .forEach(targetLanguage -> + contentsList.add( + NoticeContent + .builder() + .noticeArticle(noticeArticle) + .language(targetLanguage) + .title( + translateService.naverPapagoTextTranslate( + addNoticeRequest.getLanguage(), targetLanguage, addNoticeRequest.getTitle() + ) + ).content( + translateService.naverPapagoHtmlTranslate( + addNoticeRequest.getLanguage(), targetLanguage, addNoticeRequest.getContent() + ) + ).build() + ) + ); + noticeContentRepository.saveAll(contentsList); } /** - * 수정 + * 게시물 수정 + * 1. 사용자가 로그인을 하지 않은 경우 → UserNotFoundException이 발생한다. + * 2. 사용자가 로그인을 하였지만 관리자가 아닌 경우 → NoticeNotAdminForbiddenException이 발생한다. + * 3. 공지사항 게시물이 NoticeArticleId와 공개상태인지로 조회시 존재하지 않는 경우 → NoticeNotFoundException이 발생한다. + * 4. 요청한 언어가 DB에 없는 경우 → NoticeNotFoundException이 발생한다 + * 5. 번역이 실패한 경우 → NaverErrorException이 발생한다. + * + * 어떤 경우도 Exception이 발생하면 수정이 적용되지 않고 Rollback된다. + * + * @param request */ @Transactional public void updateNotice(EditNoticeRequest request) { //로그인한 사용자 획득 User user = userUtils.getUser(); + + //관리자 권한 확인 + if(user.getRole().equals(UserRole.ADMIN)) + throw NoticeNotAdminForbiddenException.EXCEPTION; + + // 변경여부 확인을 위한 변수 boolean chgTitle = false; boolean chgContent = false; - NoticeArticle article = noticeArticleRepository.findById(request.getNoticeArticleId()) + //게시물이 공개중이어야 수정가능함 + NoticeArticle article = noticeArticleRepository.findByIdAndStatus(request.getNoticeArticleId(), PUBLIC) .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); List contents = noticeContentRepository.findAllByNoticeArticle(article); + article.setUpdatedUser(user); //다른경우 변경 if (!request.getLanguage().equals(article.getLanguage())) @@ -122,39 +183,53 @@ public void updateNotice(EditNoticeRequest request) { NoticeContent choiceContent = contents.stream() .filter(content -> request.getLanguage().equals(content.getLanguage())) - .findFirst().orElseThrow(() -> NoticeNotFoundException.EXCEPTION); + .findFirst() + .orElseThrow(() -> NoticeNotFoundException.EXCEPTION); - if(request.getNewTitle() != null && !request.getNewTitle().equals(request.getOrgTitle())) { + if (request.getNewTitle() != null && !request.getNewTitle().equals(request.getOrgTitle())) { chgTitle = true; choiceContent.setTitle(request.getNewTitle()); } - if(request.getNewContent() != null && !request.getNewContent().equals(request.getOrgContent())){ + if (request.getNewContent() != null && !request.getNewContent().equals(request.getOrgContent())) { chgContent = true; choiceContent.setContent(request.getNewContent()); } - if(chgTitle || chgContent) { + if (chgTitle || chgContent) { + //Lambda에서 활용하기 위한 final변수 변환 final boolean finalChgTitle = chgTitle; final boolean finalChgContent = chgContent; - contents.stream().filter(content-> choiceContent != content).forEach(content-> { - if(finalChgTitle){ - // TODO : request의 언어를 원본으로 해서 content의 언어로 타겟잡아 번역후 title변환 - } - if(finalChgContent){ - // TODO : request의 언어를 원본으로 해서 content의 언어로 타겟잡아 번역후 content변환 - } - }); + contents.stream() + .filter(content -> choiceContent != content) + .forEach(content -> { + if (finalChgTitle) { + translateService.naverPapagoTextTranslate(choiceContent.getLanguage(), content.getLanguage(), choiceContent.getTitle()); + } + if (finalChgContent) { + translateService.naverPapagoHtmlTranslate(choiceContent.getLanguage(), content.getLanguage(), choiceContent.getContent()); + } + } + ); } } /** - * 삭제 + * 공지사항 게시물 삭제 + * 1. 사용자가 로그인을 하지 않은 경우 → UserNotFoundException이 발생한다. + * 2. 사용자가 로그인을 하였지만 관리자가 아닌 경우 → NoticeNotAdminForbiddenException이 발생한다. * * @param id */ @Transactional public void deleteNotice(Long id) { + //로그인한 사용자 획득 + User user = userUtils.getUser(); + + //관리자 권한 확인 + if(user.getRole().equals(UserRole.ADMIN)) + throw NoticeNotAdminForbiddenException.EXCEPTION; + noticeArticleRepository.findById(id).orElseThrow(() -> NoticeNotFoundException.EXCEPTION).updateStatus(DELETE); } diff --git a/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java b/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java deleted file mode 100644 index dca38e8..0000000 --- a/src/main/java/HookKiller/server/repository/NoticeArticleRepository.java +++ /dev/null @@ -1,15 +0,0 @@ -package HookKiller.server.repository; - -import HookKiller.server.common.type.ArticleStatus; -import HookKiller.server.notice.entity.NoticeArticle; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; -import java.util.Optional; - -public interface NoticeArticleRepository extends JpaRepository { - - List findAllByStatus(ArticleStatus status); - - Optional findByIdAndStatus(Long id, ArticleStatus status); -} diff --git a/src/main/java/HookKiller/server/repository/NoticeContentRepository.java b/src/main/java/HookKiller/server/repository/NoticeContentRepository.java deleted file mode 100644 index d7335e2..0000000 --- a/src/main/java/HookKiller/server/repository/NoticeContentRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package HookKiller.server.repository; - -import HookKiller.server.common.type.ArticleStatus; -import HookKiller.server.common.type.LanguageType; -import HookKiller.server.notice.entity.NoticeArticle; -import HookKiller.server.notice.entity.NoticeContent; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.util.List; -import java.util.Optional; - -public interface NoticeContentRepository extends JpaRepository { - Optional findByNoticeArticleAndLanguage(NoticeArticle noticeArticle, LanguageType languageType); - - List findAllByNoticeArticle(NoticeArticle noticeArticle); -} diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index a862577..03e9625 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -12,203 +12,203 @@ insert into tbl_user (email, password, nick_name, role) values ("admin@test.com" insert into tbl_user (email, password, nick_name, role) values ("user@test.com", "1111", "사용자", "USER"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-20 10:00:00", 123, "2023-09-21 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-09-20 10:00:00", 1, "2023-09-21 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (1, "KO", "title1", "content1"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-21 10:00:00", 123, "2023-09-22 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-09-21 10:00:00", 1, "2023-09-22 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (2, "KO", "title2", "content2"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-22 10:00:00", 123, "2023-09-23 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-09-22 10:00:00", 1, "2023-09-23 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (3, "KO", "title3", "content3"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-23 10:00:00", 123, "2023-09-24 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-09-23 10:00:00", 1, "2023-09-24 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (4, "KO", "title4", "content4"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-24 10:00:00", 123, "2023-09-25 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-09-24 10:00:00", 1, "2023-09-25 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (5, "KO", "title5", "content5"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-25 10:00:00", 123, "2023-09-26 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-09-25 10:00:00", 1, "2023-09-26 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (6, "KO", "title6", "content6"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-26 10:00:00", 123, "2023-09-27 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-09-26 10:00:00", 1, "2023-09-27 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (7, "KO", "title7", "content7"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-27 10:00:00", 123, "2023-09-28 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-09-27 10:00:00", 1, "2023-09-28 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (8, "KO", "title8", "content8"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-28 10:00:00", 123, "2023-09-28 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-09-28 10:00:00", 1, "2023-09-28 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (9, "KO", "title9", "content9"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-09-29 10:00:00", 123, "2023-09-30 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-09-29 10:00:00", 1, "2023-09-30 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (10, "KO", "title10", "content10"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-01 10:00:00", 123, "2023-10-02 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-01 10:00:00", 1, "2023-10-02 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (11, "KO", "title11", "content11"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-02 10:00:00", 123, "2023-10-03 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-02 10:00:00", 1, "2023-10-03 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (12, "KO", "title12", "content12"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-03 10:00:00", 123, "2023-10-04 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-03 10:00:00", 1, "2023-10-04 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (13, "KO", "title13", "content13"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-04 10:00:00", 123, "2023-10-05 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-04 10:00:00", 1, "2023-10-05 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (14, "KO", "title14", "content14"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-05 10:00:00", 123, "2023-10-06 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-05 10:00:00", 1, "2023-10-06 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (15, "KO", "title15", "content15"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-06 10:00:00", 123, "2023-10-07 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-06 10:00:00", 1, "2023-10-07 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (16, "KO", "title16", "content16"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-08 10:00:00", 123, "2023-10-09 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-08 10:00:00", 1, "2023-10-09 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (17, "KO", "title17", "content17"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-10 10:00:00", 123, "2023-10-11 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-10 10:00:00", 1, "2023-10-11 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (18, "KO", "title18", "content18"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-12 10:00:00", 123, "2023-10-13 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-12 10:00:00", 1, "2023-10-13 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (19, "KO", "title19", "content19"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-13 10:00:00", 123, "2023-10-14 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-13 10:00:00", 1, "2023-10-14 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (20, "KO", "title20", "content20"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-15 10:00:00", 123, "2023-10-16 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-15 10:00:00", 1, "2023-10-16 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (21, "KO", "title21", "content21"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-17 10:00:00", 123, "2023-10-18 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-17 10:00:00", 1, "2023-10-18 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (22, "KO", "title22", "content22"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-19 10:00:00", 123, "2023-10-20 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-19 10:00:00", 1, "2023-10-20 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (23, "KO", "title23", "content23"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-21 10:00:00", 123, "2023-10-22 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-21 10:00:00", 1, "2023-10-22 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (24, "KO", "title24", "content24"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-23 10:00:00", 123, "2023-10-24 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-23 10:00:00", 1, "2023-10-24 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (25, "KO", "title25", "content25"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-25 10:00:00", 123, "2023-10-26 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-25 10:00:00", 1, "2023-10-26 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (26, "KO", "title26", "content26"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-27 10:00:00", 123, "2023-10-28 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-27 10:00:00", 1, "2023-10-28 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (27, "KO", "title27", "content27"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-29 10:00:00", 123, "2023-10-30 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-29 10:00:00", 1, "2023-10-30 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (28, "KO", "title28", "content28"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-10-31 10:00:00", 123, "2023-11-01 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-10-31 10:00:00", 1, "2023-11-01 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (29, "KO", "title29", "content29"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-02 10:00:00", 123, "2023-11-03 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-11-02 10:00:00", 1, "2023-11-03 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (30, "KO", "title30", "content30"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-04 10:00:00", 123, "2023-11-05 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-11-04 10:00:00", 1, "2023-11-05 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (31, "KO", "title31", "content31"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-06 10:00:00", 123, "2023-11-07 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-11-06 10:00:00", 1, "2023-11-07 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (32, "KO", "title32", "content32"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-08 10:00:00", 123, "2023-11-09 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-11-08 10:00:00", 1, "2023-11-09 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (33, "KO", "title33", "content33"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-10 10:00:00", 123, "2023-11-11 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-11-10 10:00:00", 1, "2023-11-11 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (34, "KO", "title34", "content34"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-12 10:00:00", 123, "2023-11-13 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-11-12 10:00:00", 1, "2023-11-13 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (35, "KO", "title35", "content35"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-14 10:00:00", 123, "2023-11-15 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-11-14 10:00:00", 1, "2023-11-15 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (36, "KO", "title36", "content36"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-16 10:00:00", 123, "2023-11-17 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-11-16 10:00:00", 1, "2023-11-17 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (37, "KO", "title37", "content37"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-18 10:00:00", 123, "2023-11-19 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-11-18 10:00:00", 1, "2023-11-19 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (38, "KO", "title38", "content38"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-20 10:00:00", 123, "2023-11-21 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-11-20 10:00:00", 1, "2023-11-21 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (39, "KO", "title39", "content39"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-22 10:00:00", 123, "2023-11-23 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-11-22 10:00:00", 1, "2023-11-23 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (40, "KO", "title40", "content40"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-24 10:00:00", 123, "2023-11-25 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-11-24 10:00:00", 1, "2023-11-25 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (41, "KO", "title41", "content41"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-26 10:00:00", 123, "2023-11-27 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-11-26 10:00:00", 1, "2023-11-27 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (42, "KO", "title42", "content42"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-11-28 10:00:00", 123, "2023-11-29 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-11-28 10:00:00", 1, "2023-11-29 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (43, "KO", "title43", "content43"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-12-01 10:00:00", 123, "2023-12-02 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-12-01 10:00:00", 1, "2023-12-02 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (44, "KO", "title44", "content44"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-12-02 10:00:00", 123, "2023-12-03 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-12-02 10:00:00", 1, "2023-12-03 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (45, "KO", "title45", "content45"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-12-04 10:00:00", 123, "2023-12-05 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-12-04 10:00:00", 1, "2023-12-05 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (46, "KO", "title46", "content46"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-12-06 10:00:00", 123, "2023-12-07 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-12-06 10:00:00", 1, "2023-12-07 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (47, "KO", "title47", "content47"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-12-08 10:00:00", 123, "2023-12-09 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-12-08 10:00:00", 1, "2023-12-09 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (48, "KO", "title48", "content48"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-12-10 10:00:00", 123, "2023-12-11 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-12-10 10:00:00", 1, "2023-12-11 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (49, "KO", "title49", "content49"); -insert into tbl_notice_article (language, status, created_at, created_user, updated_at, updated_user) values ("KO", "PUBLIC", "2023-12-12 10:00:00", 123, "2023-12-13 10:00:00", 123); +insert into tbl_notice_article (language, status, created_at, created_user_id, update_at, updated_user_id) values ("KO", "PUBLIC", "2023-12-12 10:00:00", 1, "2023-12-13 10:00:00", 1); insert into tbl_notice_content (notice_id, language, title, content) values (50, "KO", "title50", "content50");