From 7cae21b6f9dddfb96dbf19c60d95e33a4ed9c274 Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 15:46:11 +0900 Subject: [PATCH 01/16] =?UTF-8?q?feat:=20=EB=89=B4=EC=8A=A4=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=84=A4=EA=B3=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/news/domain/entity/News.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 backend/src/main/java/org/example/backend/news/domain/entity/News.java diff --git a/backend/src/main/java/org/example/backend/news/domain/entity/News.java b/backend/src/main/java/org/example/backend/news/domain/entity/News.java new file mode 100644 index 00000000..b9a565cd --- /dev/null +++ b/backend/src/main/java/org/example/backend/news/domain/entity/News.java @@ -0,0 +1,67 @@ +package org.example.backend.news.domain.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.example.backend.news.domain.dto.NewsReqDto; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class News { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "news_id", nullable = false) + private Long id; + + @Column(name = "name") + private String title; + + @Column(name = "content") + private String content; + + @Column(name = "create_date") + private String createDate; + + @Column(name = "link") + private String link; + + @Column(name = "image") + private String image; + + + @Builder + private News(String title, String content, String createDate, String link, + String image) { + this.title = title; + this.content = content; + this.createDate = createDate; + this.link = link; + this.image = image; + } + + public static News of(NewsReqDto dto) { + return News.builder() + .title(dto.getTitle()) + .content(dto.getWriter()) + .createDate(dto.getPlace()) + .link(dto.getStartDate()) + .image(dto.getEndDate()) + .build(); + } + + public void update(NewsReqDto dto) { + this.title = dto.getTitle(); + this.content = dto.getWriter(); + this.createDate = dto.getPlace(); + this.link = dto.getStartDate(); + this.image = dto.getEndDate(); + } +} From ef9436a2abe9cd33c1491eddb7906a0fbf44a1d3 Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 15:48:35 +0900 Subject: [PATCH 02/16] =?UTF-8?q?feat:=20=EB=89=B4=EC=8A=A4=20dto=20?= =?UTF-8?q?=EC=84=A4=EA=B3=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/news/domain/dto/NewsReqDto.java | 37 +++++++++++++++ .../backend/news/domain/dto/NewsResDto.java | 46 +++++++++++++++++++ .../backend/news/domain/entity/News.java | 16 +++---- 3 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 backend/src/main/java/org/example/backend/news/domain/dto/NewsReqDto.java create mode 100644 backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java diff --git a/backend/src/main/java/org/example/backend/news/domain/dto/NewsReqDto.java b/backend/src/main/java/org/example/backend/news/domain/dto/NewsReqDto.java new file mode 100644 index 00000000..d917f6e3 --- /dev/null +++ b/backend/src/main/java/org/example/backend/news/domain/dto/NewsReqDto.java @@ -0,0 +1,37 @@ +package org.example.backend.news.domain.dto; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class NewsReqDto { + private String title; + private String content; + private String createDate; + private String link; + private String image; + + @Builder + private NewsReqDto(String title, String content, String createDate, + String link, String image) { + this.title = title; + this.content = content; + this.createDate = createDate; + this.link = link; + this.image = image; + } + + public static NewsReqDto of(String title, String content, String createDate, + String link, String image) { + return NewsReqDto.builder() + .title(title) + .content(content) + .createDate(createDate) + .link(link) + .image(image) + .build(); + } +} diff --git a/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java b/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java new file mode 100644 index 00000000..3d9447c5 --- /dev/null +++ b/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java @@ -0,0 +1,46 @@ +package org.example.backend.news.domain.dto; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.example.backend.news.domain.entity.News; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class NewsResDto { + private Long id; + private String title; + private String writer; + private String place; + private String startDate; + private String endDate; + private String speaker; + private String company; + + @Builder + private NewsResDto(Long id, String title, String writer, String place, + String startDate, String endDate, String speaker, String company) { + this.id = id; + this.title = title; + this.writer = writer; + this.place = place; + this.startDate = startDate; + this.endDate = endDate; + this.speaker = speaker; + this.company = company; + } + + public static NewsResDto of(News seminar) { + return NewsResDto.builder() + .id(seminar.getId()) + .title(seminar.getTitle()) + .writer(seminar.getWriter()) + .place(seminar.getPlace()) + .startDate(seminar.getStartDate()) + .endDate(seminar.getEndDate()) + .speaker(seminar.getSpeaker()) + .company(seminar.getCompany()) + .build(); + } +} \ No newline at end of file diff --git a/backend/src/main/java/org/example/backend/news/domain/entity/News.java b/backend/src/main/java/org/example/backend/news/domain/entity/News.java index b9a565cd..1831d832 100644 --- a/backend/src/main/java/org/example/backend/news/domain/entity/News.java +++ b/backend/src/main/java/org/example/backend/news/domain/entity/News.java @@ -50,18 +50,18 @@ private News(String title, String content, String createDate, String link, public static News of(NewsReqDto dto) { return News.builder() .title(dto.getTitle()) - .content(dto.getWriter()) - .createDate(dto.getPlace()) - .link(dto.getStartDate()) - .image(dto.getEndDate()) + .content(dto.getContent()) + .createDate(dto.getCreateDate()) + .link(dto.getLink()) + .image(dto.getImage()) .build(); } public void update(NewsReqDto dto) { this.title = dto.getTitle(); - this.content = dto.getWriter(); - this.createDate = dto.getPlace(); - this.link = dto.getStartDate(); - this.image = dto.getEndDate(); + this.content = dto.getContent(); + this.createDate = dto.getCreateDate(); + this.link = dto.getLink(); + this.image = dto.getImage(); } } From 4fb80cbaeb031d18b90f25742158b6c6c11b442f Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 15:50:15 +0900 Subject: [PATCH 03/16] =?UTF-8?q?feat:=20NewResDto=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/news/domain/dto/NewsResDto.java | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java b/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java index 3d9447c5..90fb5580 100644 --- a/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java +++ b/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java @@ -11,36 +11,30 @@ public class NewsResDto { private Long id; private String title; - private String writer; - private String place; - private String startDate; - private String endDate; - private String speaker; - private String company; + private String content; + private String createDate; + private String link; + private String image; @Builder - private NewsResDto(Long id, String title, String writer, String place, - String startDate, String endDate, String speaker, String company) { + private NewsResDto(Long id, String title, String content, String createDate, + String link, String image) { this.id = id; this.title = title; - this.writer = writer; - this.place = place; - this.startDate = startDate; - this.endDate = endDate; - this.speaker = speaker; - this.company = company; + this.content = content; + this.createDate = createDate; + this.link = link; + this.image = image; } public static NewsResDto of(News seminar) { return NewsResDto.builder() .id(seminar.getId()) .title(seminar.getTitle()) - .writer(seminar.getWriter()) - .place(seminar.getPlace()) - .startDate(seminar.getStartDate()) - .endDate(seminar.getEndDate()) - .speaker(seminar.getSpeaker()) - .company(seminar.getCompany()) + .content(seminar.getContent()) + .createDate(seminar.getCreateDate()) + .link(seminar.getLink()) + .image(seminar.getImage()) .build(); } } \ No newline at end of file From 9ff0d689e8df9a0662284f16e071c3c084c50cb3 Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 15:51:15 +0900 Subject: [PATCH 04/16] =?UTF-8?q?feat:=20=EB=89=B4=EC=8A=A4=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/news/exception/NewsException.java | 16 ++++++++++ .../news/exception/NewsExceptionType.java | 30 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 backend/src/main/java/org/example/backend/news/exception/NewsException.java create mode 100644 backend/src/main/java/org/example/backend/news/exception/NewsExceptionType.java diff --git a/backend/src/main/java/org/example/backend/news/exception/NewsException.java b/backend/src/main/java/org/example/backend/news/exception/NewsException.java new file mode 100644 index 00000000..e9116afd --- /dev/null +++ b/backend/src/main/java/org/example/backend/news/exception/NewsException.java @@ -0,0 +1,16 @@ +package org.example.backend.news.exception; + +import lombok.RequiredArgsConstructor; +import org.example.backend.common.exception.BaseException; +import org.example.backend.common.exception.BaseExceptionType; + +@RequiredArgsConstructor +public class NewsException extends BaseException { + + private final NewsExceptionType exceptionType; + + @Override + public BaseExceptionType exceptionType() { + return exceptionType; + } +} diff --git a/backend/src/main/java/org/example/backend/news/exception/NewsExceptionType.java b/backend/src/main/java/org/example/backend/news/exception/NewsExceptionType.java new file mode 100644 index 00000000..136bf22b --- /dev/null +++ b/backend/src/main/java/org/example/backend/news/exception/NewsExceptionType.java @@ -0,0 +1,30 @@ +package org.example.backend.news.exception; + +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.NOT_FOUND; + +import lombok.RequiredArgsConstructor; +import org.example.backend.common.exception.BaseExceptionType; +import org.springframework.http.HttpStatus; + +@RequiredArgsConstructor +public enum NewsExceptionType implements BaseExceptionType { + + NOT_FOUND_NEWS(NOT_FOUND, "뉴스를 찾을 수 없습니다"), + + REQUIRED_Title(BAD_REQUEST, "제목은 필수 입력값입니다."), + ; + + private final HttpStatus httpStatus; + private final String errorMessage; + + @Override + public HttpStatus httpStatus() { + return httpStatus; + } + + @Override + public String errorMessage() { + return errorMessage; + } +} From dc3b9bd170e55ebf5bec89a4983af97d835c57c2 Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 15:52:52 +0900 Subject: [PATCH 05/16] =?UTF-8?q?refactor:=20=ED=95=84=EB=93=9C=EB=AA=85?= =?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 --- .../org/example/backend/news/exception/NewsExceptionType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/org/example/backend/news/exception/NewsExceptionType.java b/backend/src/main/java/org/example/backend/news/exception/NewsExceptionType.java index 136bf22b..ca126a0a 100644 --- a/backend/src/main/java/org/example/backend/news/exception/NewsExceptionType.java +++ b/backend/src/main/java/org/example/backend/news/exception/NewsExceptionType.java @@ -12,7 +12,7 @@ public enum NewsExceptionType implements BaseExceptionType { NOT_FOUND_NEWS(NOT_FOUND, "뉴스를 찾을 수 없습니다"), - REQUIRED_Title(BAD_REQUEST, "제목은 필수 입력값입니다."), + REQUIRED_TITLE(BAD_REQUEST, "제목은 필수 입력값입니다."), ; private final HttpStatus httpStatus; From 9db49df2c7534348d87fc871b6fa80babc862654 Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 15:53:05 +0900 Subject: [PATCH 06/16] =?UTF-8?q?feat:=20=EB=89=B4=EC=8A=A4=20repository?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/backend/news/repository/NewsRepository.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 backend/src/main/java/org/example/backend/news/repository/NewsRepository.java diff --git a/backend/src/main/java/org/example/backend/news/repository/NewsRepository.java b/backend/src/main/java/org/example/backend/news/repository/NewsRepository.java new file mode 100644 index 00000000..2d98b2de --- /dev/null +++ b/backend/src/main/java/org/example/backend/news/repository/NewsRepository.java @@ -0,0 +1,7 @@ +package org.example.backend.news.repository; + +import org.example.backend.news.domain.entity.News; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface NewsRepository extends JpaRepository { +} From 4d33f396bd08f1e779bd08dae839f917a09e0c72 Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 15:53:30 +0900 Subject: [PATCH 07/16] =?UTF-8?q?feat:=20=EB=89=B4=EC=8A=A4=20service=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/news/service/NewsService.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 backend/src/main/java/org/example/backend/news/service/NewsService.java diff --git a/backend/src/main/java/org/example/backend/news/service/NewsService.java b/backend/src/main/java/org/example/backend/news/service/NewsService.java new file mode 100644 index 00000000..c2dd65a7 --- /dev/null +++ b/backend/src/main/java/org/example/backend/news/service/NewsService.java @@ -0,0 +1,63 @@ +package org.example.backend.news.service; + +import static org.example.backend.news.exception.NewsExceptionType.NOT_FOUND_NEWS; + +import lombok.RequiredArgsConstructor; +import org.example.backend.news.domain.dto.NewsReqDto; +import org.example.backend.news.domain.dto.NewsResDto; +import org.example.backend.news.domain.entity.News; +import org.example.backend.news.exception.NewsException; +import org.example.backend.news.exception.NewsExceptionType; +import org.example.backend.news.repository.NewsRepository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class NewsService { + private final NewsRepository newsRepository; + + @Transactional + public Long saveNews(NewsReqDto newsReqDto) { + validateUserRequiredFields(newsReqDto); + News news = News.of(newsReqDto); + News savedNews = newsRepository.save(news); + return savedNews.getId(); + } + + private void validateUserRequiredFields(NewsReqDto dto) { + if (dto.getTitle() == null || dto.getTitle().isEmpty()) { + throw new NewsException(NewsExceptionType.REQUIRED_TITLE); + } + } + + public NewsResDto getNews(Long newsId) { + News news = findNewsById(newsId); + return NewsResDto.of(news); + } + + @Transactional + public NewsResDto updateNews(Long newsId, NewsReqDto newsReqDto) { + News news = findNewsById(newsId); + news.update(newsReqDto); + return NewsResDto.of(news); + } + + public void deleteNews(Long newsId) { + News news = findNewsById(newsId); + newsRepository.delete(news); + } + + private News findNewsById(Long newsId) { + return newsRepository.findById(newsId) + .orElseThrow(() -> new NewsException(NOT_FOUND_NEWS)); + } + + public Page getAllNewss(Pageable pageable) { + return newsRepository.findAll(pageable) + .map(NewsResDto::of); + } +} \ No newline at end of file From f4bc3ded97d1a01cdd1c9868edb17ea900df14c7 Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 15:55:05 +0900 Subject: [PATCH 08/16] =?UTF-8?q?feat:=20=EB=89=B4=EC=8A=A4=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/example/backend/news/domain/dto/NewsReqDto.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/backend/src/main/java/org/example/backend/news/domain/dto/NewsReqDto.java b/backend/src/main/java/org/example/backend/news/domain/dto/NewsReqDto.java index d917f6e3..b5303460 100644 --- a/backend/src/main/java/org/example/backend/news/domain/dto/NewsReqDto.java +++ b/backend/src/main/java/org/example/backend/news/domain/dto/NewsReqDto.java @@ -1,5 +1,6 @@ package org.example.backend.news.domain.dto; +import jakarta.validation.constraints.NotBlank; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -8,7 +9,11 @@ @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class NewsReqDto { + + @NotBlank(message = "제목은 필수 입력값입니다.") private String title; + + @NotBlank(message = "내용은 필수 입력값입니다.") private String content; private String createDate; private String link; From c29db73c5fe0c546792690f5ad73c1ac4385f2ab Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 16:10:15 +0900 Subject: [PATCH 09/16] =?UTF-8?q?feat:=20=EB=89=B4=EC=8A=A4=20CRUD=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../news/controller/NewsController.java | 73 +++++++++++++++++++ .../backend/news/domain/dto/NewsReqDto.java | 8 ++ .../backend/news/service/NewsService.java | 18 ++++- 3 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 backend/src/main/java/org/example/backend/news/controller/NewsController.java diff --git a/backend/src/main/java/org/example/backend/news/controller/NewsController.java b/backend/src/main/java/org/example/backend/news/controller/NewsController.java new file mode 100644 index 00000000..d25772c5 --- /dev/null +++ b/backend/src/main/java/org/example/backend/news/controller/NewsController.java @@ -0,0 +1,73 @@ +package org.example.backend.news.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.example.backend.common.dto.PageRequestDto; +import org.example.backend.common.dto.ResponseDto; +import org.example.backend.news.domain.dto.NewsReqDto; +import org.example.backend.news.domain.dto.NewsResDto; +import org.example.backend.news.service.NewsService; +import org.springframework.data.domain.Page; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +@RestController +@RequiredArgsConstructor +@Tag(name = "뉴스", description = "뉴스 API") +@RequestMapping("/api/news") +public class NewsController { + private final NewsService newsService; + + @Operation(summary = "뉴스 생성 API", description = "뉴스 생성") + @PostMapping(consumes = "multipart/form-data") + public ResponseEntity createNews( + @RequestPart(value = "newsReqDto") @Valid NewsReqDto newsReqDto, + @RequestPart(value = "newsImage", required = false) MultipartFile multipartFile + ) { + Long newsId = newsService.saveNews(newsReqDto, multipartFile); + return new ResponseEntity<>(newsId, HttpStatus.OK); + } + + @Operation(summary = "모든 뉴스 조회 API", description = "모든 뉴스의 리스트 반환") + @GetMapping + public ResponseDto> getAllBoards(@Valid @ModelAttribute PageRequestDto pageRequest) { + + Page newsList = newsService.getAllNewss(pageRequest.toPageable()); + return ResponseDto.ok(newsList.getNumber(), newsList.getTotalPages(), newsList.getContent()); + } + + @Operation(summary = "단일 뉴스 조회 API", description = "단일 뉴스의 리스트 반환") + @GetMapping("/{newsId}") + public ResponseEntity getNews(@PathVariable(name = "newsId") Long newsId) { + NewsResDto newsResDto = newsService.getNews(newsId); + return new ResponseEntity<>(newsResDto, HttpStatus.OK); + } + + @Operation(summary = "뉴스 정보 업데이트 API", description = "뉴스 정보 업데이트") + @PostMapping("/{newsId}") + public ResponseEntity updateNews(@PathVariable(name = "newsId") Long newsId, + @RequestPart(value = "newsReqDto") NewsReqDto newsReqDto, + @RequestPart(value = "newsImage", required = false) MultipartFile multipartFile) { + NewsResDto newsResDto = newsService.updateNews(newsId, newsReqDto, multipartFile); + return new ResponseEntity<>(newsResDto, HttpStatus.OK); + } + + @Operation(summary = "뉴스 삭제 API", description = "뉴스 삭제") + @DeleteMapping("/{newsId}") + public ResponseEntity deleteNews(@PathVariable(name = "newsId") Long newsId) { + newsService.deleteNews(newsId); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/backend/src/main/java/org/example/backend/news/domain/dto/NewsReqDto.java b/backend/src/main/java/org/example/backend/news/domain/dto/NewsReqDto.java index b5303460..36a288d5 100644 --- a/backend/src/main/java/org/example/backend/news/domain/dto/NewsReqDto.java +++ b/backend/src/main/java/org/example/backend/news/domain/dto/NewsReqDto.java @@ -1,6 +1,7 @@ package org.example.backend.news.domain.dto; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -11,10 +12,13 @@ public class NewsReqDto { @NotBlank(message = "제목은 필수 입력값입니다.") + @Size(max = 200, message = "제목은 최대 200자 입력 가능합니다.") private String title; @NotBlank(message = "내용은 필수 입력값입니다.") + @Size(max = 5000, message = "내용은 최대 5000자까지 입력 가능합니다.") private String content; + private String createDate; private String link; private String image; @@ -39,4 +43,8 @@ public static NewsReqDto of(String title, String content, String createDate, .image(image) .build(); } + + public void setImage(String image) { + this.image = image; + } } diff --git a/backend/src/main/java/org/example/backend/news/service/NewsService.java b/backend/src/main/java/org/example/backend/news/service/NewsService.java index c2dd65a7..1dce5d6a 100644 --- a/backend/src/main/java/org/example/backend/news/service/NewsService.java +++ b/backend/src/main/java/org/example/backend/news/service/NewsService.java @@ -3,6 +3,7 @@ import static org.example.backend.news.exception.NewsExceptionType.NOT_FOUND_NEWS; import lombok.RequiredArgsConstructor; +import org.example.backend.global.config.aws.S3Uploader; import org.example.backend.news.domain.dto.NewsReqDto; import org.example.backend.news.domain.dto.NewsResDto; import org.example.backend.news.domain.entity.News; @@ -13,16 +14,24 @@ import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; @Service @RequiredArgsConstructor @Transactional(readOnly = true) public class NewsService { private final NewsRepository newsRepository; + private final S3Uploader s3Uploader; + private static final String dirName = "profile"; @Transactional - public Long saveNews(NewsReqDto newsReqDto) { + public Long saveNews(NewsReqDto newsReqDto, MultipartFile multipartFile) { validateUserRequiredFields(newsReqDto); + + if (multipartFile != null && !multipartFile.isEmpty()) { + String uploadImageUrl = s3Uploader.upload(multipartFile, dirName); + newsReqDto.setImage(uploadImageUrl); + } News news = News.of(newsReqDto); News savedNews = newsRepository.save(news); return savedNews.getId(); @@ -40,7 +49,12 @@ public NewsResDto getNews(Long newsId) { } @Transactional - public NewsResDto updateNews(Long newsId, NewsReqDto newsReqDto) { + public NewsResDto updateNews(Long newsId, NewsReqDto newsReqDto, MultipartFile multipartFile) { + if (multipartFile != null && !multipartFile.isEmpty()) { + String uploadImageUrl = s3Uploader.upload(multipartFile, dirName); + newsReqDto.setImage(uploadImageUrl); + } + News news = findNewsById(newsId); news.update(newsReqDto); return NewsResDto.of(news); From 05b19eb29c07721ae936ce05ccf6357e7715fcb7 Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 18:26:49 +0900 Subject: [PATCH 10/16] =?UTF-8?q?feat:=20=EC=A1=B0=ED=9A=8C=EC=88=98=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/news/domain/dto/NewsResDto.java | 19 +++++++++++-------- .../backend/news/domain/entity/News.java | 10 ++++++++-- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java b/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java index 90fb5580..dd252084 100644 --- a/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java +++ b/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java @@ -12,29 +12,32 @@ public class NewsResDto { private Long id; private String title; private String content; + private int view; private String createDate; private String link; private String image; @Builder - private NewsResDto(Long id, String title, String content, String createDate, + private NewsResDto(Long id, String title, int view, String content, String createDate, String link, String image) { this.id = id; this.title = title; this.content = content; + this.view = view; this.createDate = createDate; this.link = link; this.image = image; } - public static NewsResDto of(News seminar) { + public static NewsResDto of(News news) { return NewsResDto.builder() - .id(seminar.getId()) - .title(seminar.getTitle()) - .content(seminar.getContent()) - .createDate(seminar.getCreateDate()) - .link(seminar.getLink()) - .image(seminar.getImage()) + .id(news.getId()) + .title(news.getTitle()) + .content(news.getContent()) + .view(news.getView()) + .createDate(news.getCreateDate()) + .link(news.getLink()) + .image(news.getImage()) .build(); } } \ No newline at end of file diff --git a/backend/src/main/java/org/example/backend/news/domain/entity/News.java b/backend/src/main/java/org/example/backend/news/domain/entity/News.java index 1831d832..f401b589 100644 --- a/backend/src/main/java/org/example/backend/news/domain/entity/News.java +++ b/backend/src/main/java/org/example/backend/news/domain/entity/News.java @@ -9,12 +9,13 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import org.example.backend.common.domain.BaseEntity; import org.example.backend.news.domain.dto.NewsReqDto; @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class News { +public class News extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -27,6 +28,9 @@ public class News { @Column(name = "content") private String content; + @Column(name = "view") + private int view; + @Column(name = "create_date") private String createDate; @@ -38,10 +42,11 @@ public class News { @Builder - private News(String title, String content, String createDate, String link, + private News(String title, String content, int view, String createDate, String link, String image) { this.title = title; this.content = content; + this.view = view; this.createDate = createDate; this.link = link; this.image = image; @@ -51,6 +56,7 @@ public static News of(NewsReqDto dto) { return News.builder() .title(dto.getTitle()) .content(dto.getContent()) + .view(0) .createDate(dto.getCreateDate()) .link(dto.getLink()) .image(dto.getImage()) From 2e2069fe2730793ce5774fc75a6ebcd90bc7ed68 Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 19:02:40 +0900 Subject: [PATCH 11/16] =?UTF-8?q?feat:=20=EB=89=B4=EC=8A=A4=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=82=AC=EC=A7=84=20=EA=B8=B8=EC=9D=B4=20?= =?UTF-8?q?=EC=A0=9C=ED=95=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/example/backend/news/domain/entity/News.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/org/example/backend/news/domain/entity/News.java b/backend/src/main/java/org/example/backend/news/domain/entity/News.java index f401b589..eb994231 100644 --- a/backend/src/main/java/org/example/backend/news/domain/entity/News.java +++ b/backend/src/main/java/org/example/backend/news/domain/entity/News.java @@ -37,7 +37,7 @@ public class News extends BaseEntity { @Column(name = "link") private String link; - @Column(name = "image") + @Column(name = "image", length = 1000) private String image; From 26ce24fe76ee133bdb393199b8d0a80101a8debb Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 19:07:36 +0900 Subject: [PATCH 12/16] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/backend/news/exception/NewsExceptionType.java | 4 +--- .../java/org/example/backend/news/service/NewsService.java | 7 ------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/backend/src/main/java/org/example/backend/news/exception/NewsExceptionType.java b/backend/src/main/java/org/example/backend/news/exception/NewsExceptionType.java index ca126a0a..d65360e0 100644 --- a/backend/src/main/java/org/example/backend/news/exception/NewsExceptionType.java +++ b/backend/src/main/java/org/example/backend/news/exception/NewsExceptionType.java @@ -10,9 +10,7 @@ @RequiredArgsConstructor public enum NewsExceptionType implements BaseExceptionType { - NOT_FOUND_NEWS(NOT_FOUND, "뉴스를 찾을 수 없습니다"), - - REQUIRED_TITLE(BAD_REQUEST, "제목은 필수 입력값입니다."), + NOT_FOUND_NEWS(NOT_FOUND, "뉴스를 찾을 수 없습니다") ; private final HttpStatus httpStatus; diff --git a/backend/src/main/java/org/example/backend/news/service/NewsService.java b/backend/src/main/java/org/example/backend/news/service/NewsService.java index 1dce5d6a..5fe3d17b 100644 --- a/backend/src/main/java/org/example/backend/news/service/NewsService.java +++ b/backend/src/main/java/org/example/backend/news/service/NewsService.java @@ -26,7 +26,6 @@ public class NewsService { @Transactional public Long saveNews(NewsReqDto newsReqDto, MultipartFile multipartFile) { - validateUserRequiredFields(newsReqDto); if (multipartFile != null && !multipartFile.isEmpty()) { String uploadImageUrl = s3Uploader.upload(multipartFile, dirName); @@ -37,12 +36,6 @@ public Long saveNews(NewsReqDto newsReqDto, MultipartFile multipartFile) { return savedNews.getId(); } - private void validateUserRequiredFields(NewsReqDto dto) { - if (dto.getTitle() == null || dto.getTitle().isEmpty()) { - throw new NewsException(NewsExceptionType.REQUIRED_TITLE); - } - } - public NewsResDto getNews(Long newsId) { News news = findNewsById(newsId); return NewsResDto.of(news); From faa2b6568d741503d4dd23aa367673be96bda892 Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 19:08:44 +0900 Subject: [PATCH 13/16] =?UTF-8?q?refactor:=20dirName=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/example/backend/news/service/NewsService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/org/example/backend/news/service/NewsService.java b/backend/src/main/java/org/example/backend/news/service/NewsService.java index 5fe3d17b..bbc05acd 100644 --- a/backend/src/main/java/org/example/backend/news/service/NewsService.java +++ b/backend/src/main/java/org/example/backend/news/service/NewsService.java @@ -22,7 +22,7 @@ public class NewsService { private final NewsRepository newsRepository; private final S3Uploader s3Uploader; - private static final String dirName = "profile"; + private static final String dirName = "news"; @Transactional public Long saveNews(NewsReqDto newsReqDto, MultipartFile multipartFile) { From 90457625a977c3c45a61ec4031e503d071fbd24e Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 19:23:07 +0900 Subject: [PATCH 14/16] =?UTF-8?q?refactor:=20=EC=83=9D=EC=84=B1=EC=9D=BC?= =?UTF-8?q?=20=ED=8F=AC=EB=A9=A7=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/example/backend/news/domain/dto/NewsResDto.java | 3 ++- .../java/org/example/backend/news/domain/entity/News.java | 8 +------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java b/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java index dd252084..2a1ffe69 100644 --- a/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java +++ b/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java @@ -1,5 +1,6 @@ package org.example.backend.news.domain.dto; +정import java.time.format.DateTimeFormatter; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -35,7 +36,7 @@ public static NewsResDto of(News news) { .title(news.getTitle()) .content(news.getContent()) .view(news.getView()) - .createDate(news.getCreateDate()) + .createDate(news.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))) .link(news.getLink()) .image(news.getImage()) .build(); diff --git a/backend/src/main/java/org/example/backend/news/domain/entity/News.java b/backend/src/main/java/org/example/backend/news/domain/entity/News.java index eb994231..1ccb8b81 100644 --- a/backend/src/main/java/org/example/backend/news/domain/entity/News.java +++ b/backend/src/main/java/org/example/backend/news/domain/entity/News.java @@ -31,9 +31,6 @@ public class News extends BaseEntity { @Column(name = "view") private int view; - @Column(name = "create_date") - private String createDate; - @Column(name = "link") private String link; @@ -42,12 +39,11 @@ public class News extends BaseEntity { @Builder - private News(String title, String content, int view, String createDate, String link, + private News(String title, String content, int view, String link, String image) { this.title = title; this.content = content; this.view = view; - this.createDate = createDate; this.link = link; this.image = image; } @@ -57,7 +53,6 @@ public static News of(NewsReqDto dto) { .title(dto.getTitle()) .content(dto.getContent()) .view(0) - .createDate(dto.getCreateDate()) .link(dto.getLink()) .image(dto.getImage()) .build(); @@ -66,7 +61,6 @@ public static News of(NewsReqDto dto) { public void update(NewsReqDto dto) { this.title = dto.getTitle(); this.content = dto.getContent(); - this.createDate = dto.getCreateDate(); this.link = dto.getLink(); this.image = dto.getImage(); } From 64844a9a7306d1c5bd80a39095442b5cb2b1ac27 Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 19:23:48 +0900 Subject: [PATCH 15/16] =?UTF-8?q?refactor:=20=EC=9E=98=EB=AA=BB=EB=90=9C?= =?UTF-8?q?=20import=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/example/backend/news/domain/dto/NewsResDto.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java b/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java index 2a1ffe69..1e170008 100644 --- a/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java +++ b/backend/src/main/java/org/example/backend/news/domain/dto/NewsResDto.java @@ -1,6 +1,6 @@ package org.example.backend.news.domain.dto; -정import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatter; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; From c0cf1043620deda8d0e47b84d8c93a65e48c3442 Mon Sep 17 00:00:00 2001 From: "2jin2.1031" <2jin2.1031@gmail.com> Date: Fri, 3 Jan 2025 19:33:46 +0900 Subject: [PATCH 16/16] =?UTF-8?q?feat:=20=EB=89=B4=EC=8A=A4=20=EB=8D=94?= =?UTF-8?q?=EB=AF=B8=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/backup.sql | 15 +++++- backend/src/main/resources/data.sql | 76 ++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/backend/backup.sql b/backend/backup.sql index 0aad9380..1292edbc 100644 --- a/backend/backup.sql +++ b/backend/backup.sql @@ -28,6 +28,7 @@ DROP TABLE IF EXISTS `admin_SEQ`; DROP TABLE IF EXISTS `admin`; DROP TABLE IF EXISTS `UserEntity`; DROP TABLE IF EXISTS `professor_SEQ`; +DROP TABLE IF EXISTS `news`; -- Admin table CREATE TABLE `admin` ( @@ -119,4 +120,16 @@ CREATE TABLE `reservation` ( CONSTRAINT `FK_reservation_seminar_room` FOREIGN KEY (`seminar_room_id`) REFERENCES `seminar_room` (`seminar_room_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci; --- Continue for other tables like `thesis`, `board`, and `users` \ No newline at end of file +-- Continue for other tables like `thesis`, `board`, and `users` + +-- News 테이블 생성 +CREATE TABLE `news` ( + `news_id` BIGINT NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255), + `content` TEXT, + `view` INT DEFAULT 0, + `link` VARCHAR(255), + `image` VARCHAR(1000), + `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`news_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; \ No newline at end of file diff --git a/backend/src/main/resources/data.sql b/backend/src/main/resources/data.sql index e44c84bb..452805d1 100644 --- a/backend/src/main/resources/data.sql +++ b/backend/src/main/resources/data.sql @@ -16,6 +16,8 @@ DELETE FROM admin; DELETE FROM users; +DELETE +FROM news; -- Department 더미 데이터 (1개) @@ -313,4 +315,76 @@ VALUES ('2024-12-01 09:00:00', '2024-12-01 11:00:00', 'MEETING', '홍성무교 ('2024-12-06 10:30:00', '2024-12-06 12:30:00', 'MEETING', '김은희교수님 랩미팅', 1, 1, NOW(), NOW()), ('2024-12-07 13:30:00', '2024-12-07 15:30:00', 'MEETING', '김민수교수님 랩미팅', 1, 2, NOW(), NOW()), ('2024-12-08 11:00:00', '2024-12-08 13:00:00', 'MEETING', '전종훈교수님 랩미팅', 1, 1, NOW(), NOW()), - ('2024-12-09 16:00:00', '2024-12-09 18:00:00', 'MEETING', '서민석교수님 랩미팅', 1, 4, NOW(), NOW()); \ No newline at end of file + ('2024-12-09 16:00:00', '2024-12-09 18:00:00', 'MEETING', '서민석교수님 랩미팅', 1, 4, NOW(), NOW()); + +INSERT INTO news (name, content, view, link, image, created_at) +VALUES + ('세종대학교 바이오융합공학과, 혁신 연구 성과 발표', + '세종대학교 바이오융합공학과가 올해 혁신적인 연구 성과를 발표했습니다.', + 320, + 'https://example.com/news1', + 'https://dibb-bucket.s3.ap-northeast-2.amazonaws.com/news/image1.jpg', + NOW()), + + ('바이오융합공학과, 신입생 환영회 개최', + '세종대학교 바이오융합공학과가 신입생들을 위한 환영회를 열었습니다.', + 150, + 'https://example.com/news2', + 'https://dibb-bucket.s3.ap-northeast-2.amazonaws.com/news/image2.jpg', + NOW()), + + ('세종대, 바이오 분야 특화 교육 프로그램 개설', + '세종대학교가 바이오 분야를 중심으로 한 특화 교육 프로그램을 개설하였습니다.', + 200, + 'https://example.com/news3', + 'https://dibb-bucket.s3.ap-northeast-2.amazonaws.com/news/image3.jpg', + NOW()), + + ('바이오융합공학과 졸업생, 글로벌 기업 취업 성공', + '세종대학교 바이오융합공학과 졸업생이 글로벌 기업에 성공적으로 취업했습니다.', + 400, + 'https://example.com/news4', + 'https://dibb-bucket.s3.ap-northeast-2.amazonaws.com/news/image4.jpg', + NOW()), + + ('바이오융합공학과, 국제 학술대회 논문 발표', + '바이오융합공학과 교수진이 국제 학술대회에서 연구 논문을 발표했습니다.', + 280, + 'https://example.com/news5', + 'https://dibb-bucket.s3.ap-northeast-2.amazonaws.com/news/image5.jpg', + NOW()), + + ('세종대, 바이오 산업 연구 지원 강화', + '세종대학교는 바이오 산업 연구를 위한 지원을 강화하고 있습니다.', + 170, + 'https://example.com/news6', + 'https://dibb-bucket.s3.ap-northeast-2.amazonaws.com/news/image6.jpg', + NOW()), + + ('세종대 바이오융합공학과, 혁신적인 실험실 설립', + '세종대학교 바이오융합공학과가 혁신적인 실험실을 설립하였습니다.', + 310, + 'https://example.com/news7', + 'https://dibb-bucket.s3.ap-northeast-2.amazonaws.com/news/image7.jpg', + NOW()), + + ('세종대 바이오융합공학과, 신약 개발 프로젝트 시작', + '세종대학교 바이오융합공학과가 신약 개발 프로젝트를 시작했습니다.', + 250, + 'https://example.com/news8', + 'https://dibb-bucket.s3.ap-northeast-2.amazonaws.com/news/image8.jpg', + NOW()), + + ('세종대학교, 바이오융합공학과 신임 교수 임용', + '세종대학교는 바이오융합공학과에 새로운 교수님을 임용했습니다.', + 180, + 'https://example.com/news9', + 'https://dibb-bucket.s3.ap-northeast-2.amazonaws.com/news/image9.jpg', + NOW()), + + ('세종대 바이오융합공학과, 학술 논문 출판', + '바이오융합공학과 교수진이 학술 논문을 성공적으로 출판하였습니다.', + 210, + 'https://example.com/news10', + 'https://dibb-bucket.s3.ap-northeast-2.amazonaws.com/news/image10.jpg', + NOW()); \ No newline at end of file