Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ dependencies {

// Goolge OAuth2
implementation 'com.google.api-client:google-api-client:2.8.0'

// jsch 라이브러리, for ssh tunneling
implementation 'com.github.mwiede:jsch:0.2.15'
// application.yml의 환경 변수를 class에서 사용하기 위한 라이브러리
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'

// Apache Commons Lang
// implementation 'org.apache.commons:commons-lang3:3.12.0'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.ikdaman.domain.notice.controller;

import com.ikdaman.domain.notice.model.NoticeListRes;
import com.ikdaman.domain.notice.model.NoticeReq;
import com.ikdaman.domain.notice.model.NoticeRes;
import com.ikdaman.domain.notice.service.NoticeService;
import com.ikdaman.global.auth.model.AuthMember;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/notices")
@RequiredArgsConstructor
public class NoticeController {

private final NoticeService noticeService;

// 공지사항 등록
@PostMapping
public ResponseEntity<NoticeReq> addNotice(
@AuthenticationPrincipal AuthMember authMember,
@RequestBody NoticeReq request) {
noticeService.addNotice(request);
return ResponseEntity.status(HttpStatus.CREATED).build();
}

@GetMapping
public ResponseEntity<NoticeListRes> getNotices(
@AuthenticationPrincipal AuthMember authMember,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "9") Integer limit) {
return ResponseEntity.ok(noticeService.getNotices(page, limit));
}

// 공지사항 상세 조회
@GetMapping("/{notice_id}")
public ResponseEntity<NoticeRes> getNotice(
@AuthenticationPrincipal AuthMember authMember,
@PathVariable("notice_id") Long noticeId) {
return ResponseEntity.ok(noticeService.getNotice(noticeId));
}
}
49 changes: 49 additions & 0 deletions src/main/java/com/ikdaman/domain/notice/entity/Notice.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.ikdaman.domain.notice.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.validation.constraints.Size;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

import java.time.LocalDateTime;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@DynamicInsert
@DynamicUpdate
public class Notice {
@Id
@GeneratedValue
@Column(name = "notice_id", nullable = false, updatable = false)
private int noticeId;

@Column(length = 100)
@Size(min = 1, max = 100)
private String title;

@Column(name = "notice_writer", length = 10)
@Size(min = 1, max = 10)
private String noticeWriter;

@Column(columnDefinition = "TEXT")
private String content;

@Column(updatable = false, name = "uploaded_at")
private LocalDateTime uploadedAt;

@Builder
public Notice(String title, String noticeWriter, String content, LocalDateTime uploadedAt) {
this.title = title;
this.noticeWriter = noticeWriter;
this.content = content;
this.uploadedAt = uploadedAt;
}
}
24 changes: 24 additions & 0 deletions src/main/java/com/ikdaman/domain/notice/model/NoticeListRes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.ikdaman.domain.notice.model;

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.time.LocalDateTime;
import java.util.List;

@Getter
@AllArgsConstructor
public class NoticeListRes {
private List<NoticeListDTO> notices;
private boolean hasNext;
private Integer currentPage;
private Integer totalPages;

@Getter
@AllArgsConstructor
public static class NoticeListDTO {
private int noticeId;
private String title;
private LocalDateTime uploadedAt;
}
}
21 changes: 21 additions & 0 deletions src/main/java/com/ikdaman/domain/notice/model/NoticeReq.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.ikdaman.domain.notice.model;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class NoticeReq {
private String title;
private String noticeWriter;
private String content;

@Builder
public NoticeReq(String title, String noticeWriter, String content) {
this.title = title;
this.noticeWriter = noticeWriter;
this.content = content;
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/ikdaman/domain/notice/model/NoticeRes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.ikdaman.domain.notice.model;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Getter
@NoArgsConstructor
public class NoticeRes {
private int noticeId;
private String title;
private String content;
private LocalDateTime uploadedAt;
private String noticeWriter;

@Builder
public NoticeRes(int noticeId, String title, String content, LocalDateTime uploadedAt, String noticeWriter) {
this.noticeId = noticeId;
this.title = title;
this.content = content;
this.uploadedAt = uploadedAt;
this.noticeWriter = noticeWriter;
}
}
4 changes: 0 additions & 4 deletions src/main/java/com/ikdaman/domain/notice/notice/Notice.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.ikdaman.domain.notice.repository;

import com.ikdaman.domain.notice.entity.Notice;
import org.springframework.data.jpa.repository.JpaRepository;

public interface NoticeRepository extends JpaRepository<Notice, Long> {

}
11 changes: 11 additions & 0 deletions src/main/java/com/ikdaman/domain/notice/service/NoticeService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.ikdaman.domain.notice.service;

import com.ikdaman.domain.notice.model.NoticeListRes;
import com.ikdaman.domain.notice.model.NoticeReq;
import com.ikdaman.domain.notice.model.NoticeRes;

public interface NoticeService {
NoticeRes addNotice(NoticeReq noticeReq);
NoticeListRes getNotices(Integer page, Integer limit);
NoticeRes getNotice(Long noticeId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.ikdaman.domain.notice.service;

import com.ikdaman.domain.notice.entity.Notice;
import com.ikdaman.domain.notice.model.NoticeListRes;
import com.ikdaman.domain.notice.model.NoticeReq;
import com.ikdaman.domain.notice.model.NoticeRes;
import com.ikdaman.domain.notice.repository.NoticeRepository;
import com.ikdaman.global.exception.BaseException;
import com.ikdaman.global.exception.ErrorCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
@RequiredArgsConstructor
public class NoticeServiceImpl implements NoticeService {

private final NoticeRepository noticeRepository;

@Override
@Transactional
public NoticeRes addNotice(NoticeReq request) {
Notice notice = Notice.builder()
.title(request.getTitle())
.noticeWriter(
request.getNoticeWriter() == null || request.getNoticeWriter().isBlank()
? "관리자"
: request.getNoticeWriter())
.content(request.getContent())
.uploadedAt(LocalDateTime.now())
.build();

Notice savedNotice = noticeRepository.save(notice);

return NoticeRes.builder()
.noticeId(savedNotice.getNoticeId())
.title(savedNotice.getTitle())
.content(savedNotice.getContent())
.uploadedAt(savedNotice.getUploadedAt())
.noticeWriter(savedNotice.getNoticeWriter())
.build();
}

@Override
@Transactional(readOnly = true)
public NoticeListRes getNotices(Integer page, Integer limit) {
Pageable pageable = PageRequest.of(page - 1, limit, Sort.by(Sort.Direction.DESC, "uploadedAt"));

Page<Notice> noticePage = noticeRepository.findAll(pageable);

List<NoticeListRes.NoticeListDTO> noticeDTOs = noticePage.stream()
.map(notice -> new NoticeListRes.NoticeListDTO(
notice.getNoticeId(),
notice.getTitle(),
notice.getUploadedAt()
))
.toList();

return new NoticeListRes(
noticeDTOs,
noticePage.hasNext(),
noticePage.getNumber() + 1,
noticePage.getTotalPages() + 1
);
}

@Override
@Transactional(readOnly = true)
public NoticeRes getNotice(Long id) {
Notice notice = noticeRepository.findById(id)
.orElseThrow(() -> new BaseException(ErrorCode.NOT_FOUND_NOTICE));

return new NoticeRes(
notice.getNoticeId(),
notice.getTitle(),
notice.getContent(),
notice.getUploadedAt(),
notice.getNoticeWriter()
);
}
}
1 change: 1 addition & 0 deletions src/main/java/com/ikdaman/global/exception/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public enum ErrorCode {
EMPTY_IMPRESSION(HttpStatus.BAD_REQUEST.value(), 4040303, "첫인상을 입력해주세요."),

// Notice(04)
NOT_FOUND_NOTICE(HttpStatus.NOT_FOUND.value(), 4040301, "해당하는 공지사항이 존재하지 않습니다."),

/**
* 409 Conflict
Expand Down