From daac7654c3f1b1ab27b64ef7e763e6a183c5a021 Mon Sep 17 00:00:00 2001 From: AlreadyBold Date: Fri, 30 Aug 2024 03:30:28 +0900 Subject: [PATCH] feat : calender CRUD --- .../calendar/controller/EventController.java | 107 +++++++++++++----- .../calendar/dto/EventResponseInterface.java | 24 ++++ .../page/domain/calendar/entity/Event.java | 21 ++-- .../domain/calendar/entity/Participant.java | 10 +- ...ndarException.java => EventException.java} | 2 +- .../repoAndService/EventRepository.java | 20 ++++ .../calendar/repoAndService/EventService.java | 18 +-- .../repoAndService/ParticipantRepository.java | 9 ++ .../repoAndService/impl/EventServiceImpl.java | 75 ++++++++---- .../exception/GlobalExceptionHandler.java | 6 +- 10 files changed, 216 insertions(+), 76 deletions(-) create mode 100644 src/main/java/KKSC/page/domain/calendar/dto/EventResponseInterface.java rename src/main/java/KKSC/page/domain/calendar/exception/{CalendarException.java => EventException.java} (79%) create mode 100644 src/main/java/KKSC/page/domain/calendar/repoAndService/ParticipantRepository.java diff --git a/src/main/java/KKSC/page/domain/calendar/controller/EventController.java b/src/main/java/KKSC/page/domain/calendar/controller/EventController.java index 176fbd3..515b178 100644 --- a/src/main/java/KKSC/page/domain/calendar/controller/EventController.java +++ b/src/main/java/KKSC/page/domain/calendar/controller/EventController.java @@ -2,65 +2,116 @@ import KKSC.page.domain.calendar.dto.EventRequest; import KKSC.page.domain.calendar.dto.EventResponse; -import KKSC.page.domain.calendar.exception.CalendarException; +import KKSC.page.domain.calendar.dto.EventResponseInterface; +import KKSC.page.domain.calendar.exception.EventException; import KKSC.page.domain.calendar.repoAndService.EventService; import KKSC.page.global.auth.service.JwtService; import KKSC.page.global.exception.ErrorCode; +import KKSC.page.global.exception.dto.ErrorResponseVO; import KKSC.page.global.exception.dto.ResponseVO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + import org.springframework.web.bind.annotation.*; import java.util.List; +@Tag(name = "Event", description = "일정관리 API") @RestController @RequiredArgsConstructor -@RequestMapping("/calendar") +@RequestMapping("/event") +@Slf4j public class EventController { private final EventService eventService; private final JwtService jwtService; // 캘린더 일정 추가 + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "API 정상 작동",content = @Content(schema = @Schema(implementation = ResponseVO.class))), + @ApiResponse(responseCode = "???", description = "서버 에러",content = @Content(schema = @Schema(implementation = ErrorResponseVO.class)))} + ) + @Operation(summary = "일정 추가", description = " 일정 추가 API ") @PostMapping("/") public ResponseVO addEvent(@RequestBody EventRequest eventRequest) { - return new ResponseVO<>(eventService.createSchedule(eventRequest)); + return new ResponseVO<>(eventService.createEvent(eventRequest)); } - // 캘린더 일정 삭제 - @DeleteMapping("/{id}") - public ResponseVO deleteEvent(@PathVariable Long id) { - eventService.deleteSchedule(id); + // 캘린더 일정 수정 + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "API 정상 작동",content = @Content(schema = @Schema(implementation = ResponseVO.class))), + @ApiResponse(responseCode = "???", description = "서버 에러",content = @Content(schema = @Schema(implementation = ErrorResponseVO.class)))} + ) + @Parameter(name = "eventId", description = "일정 번호") + @Operation(summary = " 일정 수정 ", description = " 일정 수정 API ") + @PutMapping("/{eventId}") + public ResponseVO updateEvent(@PathVariable Long eventId, @RequestBody EventRequest eventRequest) { + return new ResponseVO<>(eventService.updateEvent(eventId, eventRequest)); + } - return new ResponseVO<>("Delete Success"); + // 캘린더 일정 삭제 + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "API 정상 작동",content = @Content(schema = @Schema(implementation = ResponseVO.class))), + @ApiResponse(responseCode = "???", description = "서버 에러",content = @Content(schema = @Schema(implementation = ErrorResponseVO.class)))} + ) + @Parameter(name = "eventId", description = "일정 번호") + @Operation(summary = " 일정 삭제 ", description = " 일정 삭제 API ") + @DeleteMapping("/{eventId}") + public ResponseVO deleteEvent(@PathVariable Long eventId) { + return new ResponseVO<>("Delete success"); } - // 캘린더 일정 수정 - @PutMapping("/{id}") - public ResponseVO updateEvent(@PathVariable Long id, @RequestBody EventRequest eventRequest) { - return new ResponseVO<>(eventService.updateSchedule(id, eventRequest)); + // 캘린더 일정 목록 조회 완성 + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "API 정상 작동",content = @Content(schema = @Schema(implementation = ResponseVO.class))), + @ApiResponse(responseCode = "???", description = "서버 에러",content = @Content(schema = @Schema(implementation = ErrorResponseVO.class)))} + ) + @Parameters({ + @Parameter(name = "year", description = "일정 검색 년도"), + @Parameter(name = "month", description = "일정 검색 월"), + }) + @Operation(summary = " 일정 조회 ", description = " 일정 조회 API ") + @GetMapping("") + public ResponseVO> getEventList(@RequestParam int year, @RequestParam int month) { + return new ResponseVO<>(eventService.getEventList(year, month)); } // 캘린더 일정 참가 - @PostMapping("/{id}/join") - public ResponseVO joinEvent(HttpServletRequest request, @PathVariable Long id) { + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "API 정상 작동",content = @Content(schema = @Schema(implementation = ResponseVO.class))), + @ApiResponse(responseCode = "???", description = "서버 에러",content = @Content(schema = @Schema(implementation = ErrorResponseVO.class)))} + ) + @Parameter(name = "eventId", description = "일정 번호") + @Operation(summary = " 일정 참가 ", description = " 일정 참가 API ") + @PostMapping("/join/{eventId}") + public ResponseVO joinEvent(HttpServletRequest request, @PathVariable Long eventId) { String username = jwtService.extractUsername(request) - .orElseThrow(() -> new CalendarException(ErrorCode.ACCESS_DENIED)); - - return new ResponseVO<>(eventService.joinSchedule(id, username)); + .orElseThrow(() -> new EventException(ErrorCode.ACCESS_DENIED)); + + return new ResponseVO<>(eventService.joinEvent(eventId, username)); } - + // 캘린더 일정 참가 취소 - @DeleteMapping("/cancel/{id}") - public ResponseVO cancelEvent(@PathVariable Long id) { - eventService.cancelSchedule(id); - - return new ResponseVO<>("Cancel Success"); - } + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "API 정상 작동",content = @Content(schema = @Schema(implementation = ResponseVO.class))), + @ApiResponse(responseCode = "???", description = "서버 에러",content = @Content(schema = @Schema(implementation = ErrorResponseVO.class)))} + ) + @Parameter(name = "eventId", description = "일정 번호") + @Operation(summary = " 일정 참가 취소 ", description = " 일정 참가 취소 API ") + @DeleteMapping("/cancel/{eventId}") + public ResponseVO cancelEvent(HttpServletRequest request, @PathVariable Long eventId) { + String username = jwtService.extractUsername(request) + .orElseThrow(() -> new EventException(ErrorCode.ACCESS_DENIED)); - // 캘린더 일정 목록 조회 - @GetMapping("/") - public ResponseVO> getEventList(@RequestParam Long year, @RequestParam Long month) { - return new ResponseVO<>(eventService.getScheduleList(year, month)); + return new ResponseVO<>(eventService.cancelEvent(eventId, username)); } } diff --git a/src/main/java/KKSC/page/domain/calendar/dto/EventResponseInterface.java b/src/main/java/KKSC/page/domain/calendar/dto/EventResponseInterface.java new file mode 100644 index 0000000..bb97108 --- /dev/null +++ b/src/main/java/KKSC/page/domain/calendar/dto/EventResponseInterface.java @@ -0,0 +1,24 @@ +package KKSC.page.domain.calendar.dto; + +import java.time.LocalDateTime; +import com.fasterxml.jackson.annotation.JsonFormat; + +import KKSC.page.domain.calendar.entity.Category; + +public interface EventResponseInterface { + + Long getId(); + String getTitle(); + String getDetail(); + + Category getCategory(); + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss", timezone = "Asia/Seoul") + LocalDateTime getStartDate(); + + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss", timezone = "Asia/Seoul") + LocalDateTime getEndDate(); + + Long getMaxParticipant(); + +} diff --git a/src/main/java/KKSC/page/domain/calendar/entity/Event.java b/src/main/java/KKSC/page/domain/calendar/entity/Event.java index 1c13e27..eceb811 100644 --- a/src/main/java/KKSC/page/domain/calendar/entity/Event.java +++ b/src/main/java/KKSC/page/domain/calendar/entity/Event.java @@ -1,6 +1,6 @@ package KKSC.page.domain.calendar.entity; -import KKSC.page.domain.member.entity.Member; +import KKSC.page.domain.calendar.dto.EventRequest; import KKSC.page.global.common.BaseTimeEntity; import jakarta.persistence.*; import lombok.AllArgsConstructor; @@ -26,10 +26,6 @@ public class Event extends BaseTimeEntity { @OneToMany(mappedBy = "event") private List participants; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; - // 일정 제목 private String title; @@ -50,12 +46,13 @@ public class Event extends BaseTimeEntity { private String detail; // 일정 수정(시작 날짜, 종료 날짜, 세부 사항 수정) - public void update(String title, String detail, Category category, LocalDateTime startDate, LocalDateTime endDate, Long maxParticipant) { - this.title = title; - this.detail = detail; - this.category = category; - this.startDate = startDate; - this.endDate = endDate; - this.maxParticipant = maxParticipant; + public void update(Long eventId, EventRequest eventRequest) { + this.id = eventId; + this.title = eventRequest.title(); + this.detail = eventRequest.detail(); + this.category = eventRequest.category(); + this.startDate = eventRequest.startDate(); + this.endDate = eventRequest.endDate(); + this.maxParticipant = eventRequest.maxParticipant(); } } diff --git a/src/main/java/KKSC/page/domain/calendar/entity/Participant.java b/src/main/java/KKSC/page/domain/calendar/entity/Participant.java index 32cf860..147eaa6 100644 --- a/src/main/java/KKSC/page/domain/calendar/entity/Participant.java +++ b/src/main/java/KKSC/page/domain/calendar/entity/Participant.java @@ -1,5 +1,6 @@ package KKSC.page.domain.calendar.entity; +import KKSC.page.domain.member.entity.Member; import KKSC.page.global.common.BaseTimeEntity; import jakarta.persistence.*; import lombok.AllArgsConstructor; @@ -18,9 +19,12 @@ public class Participant extends BaseTimeEntity { @Column(name = "participant_id") private Long id; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne @JoinColumn(name = "event_id") private Event event; - private String name; -} + @OneToOne + @JoinColumn(name = "member_id") + private Member member; + +} \ No newline at end of file diff --git a/src/main/java/KKSC/page/domain/calendar/exception/CalendarException.java b/src/main/java/KKSC/page/domain/calendar/exception/EventException.java similarity index 79% rename from src/main/java/KKSC/page/domain/calendar/exception/CalendarException.java rename to src/main/java/KKSC/page/domain/calendar/exception/EventException.java index 8dfcb31..db1edad 100644 --- a/src/main/java/KKSC/page/domain/calendar/exception/CalendarException.java +++ b/src/main/java/KKSC/page/domain/calendar/exception/EventException.java @@ -6,7 +6,7 @@ @Getter @RequiredArgsConstructor -public class CalendarException extends RuntimeException { +public class EventException extends RuntimeException { private final ErrorCode errorCode; } diff --git a/src/main/java/KKSC/page/domain/calendar/repoAndService/EventRepository.java b/src/main/java/KKSC/page/domain/calendar/repoAndService/EventRepository.java index b4fcace..e94453f 100644 --- a/src/main/java/KKSC/page/domain/calendar/repoAndService/EventRepository.java +++ b/src/main/java/KKSC/page/domain/calendar/repoAndService/EventRepository.java @@ -1,7 +1,27 @@ package KKSC.page.domain.calendar.repoAndService; +import KKSC.page.domain.calendar.dto.EventResponseInterface; import KKSC.page.domain.calendar.entity.Event; + +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + public interface EventRepository extends JpaRepository, EventRepositoryCustom { + @Query(value = "SELECT "+ + "event_id as id,"+ + "title as title,"+ + "detail as detail,"+ + "category as category,"+ + "start_date as startDate,"+ + "end_date as endDate ,"+ + "max_participant as maxParticipant "+ + "FROM event "+ + "WHERE YEAR(end_date) = :Year "+ + "AND MONTH(end_date) = :Month " + , nativeQuery = true) + List EventList(@Param("Year") int Year,@Param("Month") int Month); } diff --git a/src/main/java/KKSC/page/domain/calendar/repoAndService/EventService.java b/src/main/java/KKSC/page/domain/calendar/repoAndService/EventService.java index ca0b976..1595d00 100644 --- a/src/main/java/KKSC/page/domain/calendar/repoAndService/EventService.java +++ b/src/main/java/KKSC/page/domain/calendar/repoAndService/EventService.java @@ -4,6 +4,7 @@ import KKSC.page.domain.calendar.dto.EventRequest; import KKSC.page.domain.calendar.dto.EventResponse; +import KKSC.page.domain.calendar.dto.EventResponseInterface; import org.springframework.stereotype.Service; @@ -15,26 +16,27 @@ public interface EventService { // 일정 목록 조회 @PreAuthorize("hasRole('permission_level1')") - List getScheduleList(Long year, Long month); + List getEventList(int year, int month); // 일정 생성 @PreAuthorize("hasRole('permission_level0')") - Long createSchedule(EventRequest eventRequest); + Long createEvent(EventRequest eventRequest); - // 일정 삭제 + // 일정 수정 @PreAuthorize("hasRole('permission_level0')") - void deleteSchedule(Long id); + EventResponse updateEvent(Long evetnId, EventRequest eventRequest); - // 일정 수정 + // 일정 삭제 @PreAuthorize("hasRole('permission_level0')") - EventResponse updateSchedule(Long id, EventRequest eventRequest); + void deleteEvent(Long evetnId); + // 일정 참가 @PreAuthorize("hasRole('permission_level1')") - Long joinSchedule(Long id, String name); + Long joinEvent(Long evetnId, String userName); // 일정 참가 취소 @PreAuthorize("hasRole('permission_level1')") - void cancelSchedule (Long id); + String cancelEvent (Long evetnId, String userName); } diff --git a/src/main/java/KKSC/page/domain/calendar/repoAndService/ParticipantRepository.java b/src/main/java/KKSC/page/domain/calendar/repoAndService/ParticipantRepository.java new file mode 100644 index 0000000..1325172 --- /dev/null +++ b/src/main/java/KKSC/page/domain/calendar/repoAndService/ParticipantRepository.java @@ -0,0 +1,9 @@ +package KKSC.page.domain.calendar.repoAndService; + +import org.springframework.data.jpa.repository.JpaRepository; + +import KKSC.page.domain.calendar.entity.Participant; + +public interface ParticipantRepository extends JpaRepository { + +} diff --git a/src/main/java/KKSC/page/domain/calendar/repoAndService/impl/EventServiceImpl.java b/src/main/java/KKSC/page/domain/calendar/repoAndService/impl/EventServiceImpl.java index 926a6a2..2b60b8a 100644 --- a/src/main/java/KKSC/page/domain/calendar/repoAndService/impl/EventServiceImpl.java +++ b/src/main/java/KKSC/page/domain/calendar/repoAndService/impl/EventServiceImpl.java @@ -2,9 +2,15 @@ import KKSC.page.domain.calendar.dto.EventRequest; import KKSC.page.domain.calendar.dto.EventResponse; +import KKSC.page.domain.calendar.dto.EventResponseInterface; import KKSC.page.domain.calendar.entity.Event; +import KKSC.page.domain.calendar.exception.EventException; import KKSC.page.domain.calendar.repoAndService.EventRepository; import KKSC.page.domain.calendar.repoAndService.EventService; +import KKSC.page.domain.calendar.repoAndService.ParticipantRepository; +import KKSC.page.domain.member.exception.MemberException; +import KKSC.page.domain.member.repository.MemberRepository; +import KKSC.page.global.exception.ErrorCode; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -18,55 +24,82 @@ public class EventServiceImpl implements EventService { private final EventRepository eventRepository; - // 일정 목록 조회 - // 파라미터 : 몇년 몇월 받아오기 - @Override - public List getScheduleList(Long year, Long month) { - // getScheduleList 메소드 (Repo Impl)에서 구현하기 (한달치 긁어오기) + private final ParticipantRepository participantRepository; - eventRepository.getScheduleList(); - return null; + private final MemberRepository memberRepository; + + /* 만들어야하는 쿼리문 목록 + getEventList : year , month 파라미터 적용 ( eventRepositoryCustom ) + deleteEvent : 참여자 정보 삭제 ( ParticipantRepositoryCustom ) + getPersonalEventList : 사용자에 대한 일정 참가 목록 ( ParticipantRepositoryCustom ) + */ + + // 일정 목록 조회 + @Override + public List getEventList(int year, int month) { + + return eventRepository.EventList(year, month); }; // 일정 생성 // 파라미터 : 스케쥴 생성 값 @Override - public Long createSchedule(EventRequest eventRequest) { + public Long createEvent(EventRequest eventRequest) { Event event = eventRequest.toEntity(); - - // event에서 member 서로 추가해야 하는데 다대다 매핑 필요 - - eventRepository.save(event); - return null; + return eventRepository.save(event).getId(); }; // 일정 삭제 // 파라미터 : 스케줄 아이디 @Override - public void deleteSchedule(Long id) { - eventRepository.deleteAllById(null); + public void deleteEvent(Long eventId) { + eventRepository.findById(eventId) + .orElseThrow(() -> new EventException(ErrorCode.NOT_FOUND_SCHEDULE)); + // 참여자 정보 전부 삭제 + // 일정 삭제 + eventRepository.deleteById(eventId); }; // 일정 수정 // 파라미터 : 스케줄 수정 값 @Override - public EventResponse updateSchedule(Long id, EventRequest eventRequest) { - eventRepository.save(null); - return null; + public EventResponse updateEvent(Long eventId, EventRequest eventRequest) { + + eventRepository.findById(eventId) + .orElseThrow(() -> new EventException(ErrorCode.NOT_FOUND_SCHEDULE)); + + Event event = new Event(); + + event.update(eventId, eventRequest); + + eventRepository.save(event); + + return EventResponse.from(event); }; // 일정 참가 // 파라미터 : 스케줄 아이디, 유저아이디 @Override - public Long joinSchedule(Long id, String name) { - eventRepository.save(null); + public Long joinEvent(Long eventId, String userName) { + eventRepository.findById(eventId) + .orElseThrow(() -> new EventException(ErrorCode.NOT_FOUND_SCHEDULE)); + Long userId = memberRepository.findByEmail(userName) + .orElseThrow(() -> new MemberException(ErrorCode.NOT_FOUND_MEMBER)).getId(); + + participantRepository.save(null); return null; }; // 일정 참가 취소 // 파라미터 : 스케줄 아이디, 유저아이디 @Override - public void cancelSchedule (Long id) { + public String cancelEvent(Long eventId,String userName) { + eventRepository.findById(eventId) + .orElseThrow(() -> new EventException(ErrorCode.NOT_FOUND_SCHEDULE)); + Long userId = memberRepository.findByEmail(userName) + .orElseThrow(() -> new MemberException(ErrorCode.NOT_FOUND_MEMBER)).getId(); + eventRepository.delete(null); + return null; }; } diff --git a/src/main/java/KKSC/page/global/exception/GlobalExceptionHandler.java b/src/main/java/KKSC/page/global/exception/GlobalExceptionHandler.java index fe96c81..95c5af6 100644 --- a/src/main/java/KKSC/page/global/exception/GlobalExceptionHandler.java +++ b/src/main/java/KKSC/page/global/exception/GlobalExceptionHandler.java @@ -1,6 +1,6 @@ package KKSC.page.global.exception; -import KKSC.page.domain.calendar.exception.CalendarException; +import KKSC.page.domain.calendar.exception.EventException; import KKSC.page.domain.member.exception.MemberException; import KKSC.page.domain.notice.exeption.NoticeBoardException; import KKSC.page.domain.notice.exeption.NoticeFileException; @@ -30,8 +30,8 @@ public ErrorResponseVO handleNoticeFileException(NoticeFileException ex) { return getErrorResponse(errorCode); } - @ExceptionHandler(CalendarException.class) - public ErrorResponseVO handleCalendarException(CalendarException ex) { + @ExceptionHandler(EventException.class) + public ErrorResponseVO handleCalendarException(EventException ex) { ErrorCode errorCode = ex.getErrorCode(); return getErrorResponse(errorCode);