From 3ec05c244a4fdb30cd699a73fa36061072913bdf Mon Sep 17 00:00:00 2001 From: jeongju Date: Mon, 23 Dec 2024 19:00:07 +0900 Subject: [PATCH 1/6] =?UTF-8?q?fix:=20=EB=A9=B4=EC=A0=91=EA=B0=80=EB=8A=A5?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=20=EC=84=A4=EC=A0=95=20=EC=8B=9C=20=EA=B8=B0?= =?UTF-8?q?=EC=A1=B4=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=ED=9B=84=20=EC=9E=AC=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../innerjoin/post/repository/MeetingTimeRepository.java | 1 + .../likelion/innerjoin/post/service/MeetingTimeService.java | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/main/java/com/likelion/innerjoin/post/repository/MeetingTimeRepository.java b/src/main/java/com/likelion/innerjoin/post/repository/MeetingTimeRepository.java index 243b360..4ed1a53 100644 --- a/src/main/java/com/likelion/innerjoin/post/repository/MeetingTimeRepository.java +++ b/src/main/java/com/likelion/innerjoin/post/repository/MeetingTimeRepository.java @@ -8,4 +8,5 @@ public interface MeetingTimeRepository extends JpaRepository { List findByRecruiting(Recruiting recruiting); + List findByRecruitingId(Long recruitingId); } diff --git a/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java b/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java index 34ef2e2..7cd7ebf 100644 --- a/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java +++ b/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java @@ -47,6 +47,12 @@ public void createMeetingTimes(Long recruitingId, List existingMeetingTimes = meetingTimeRepository.findByRecruitingId(recruitingId); + if (!existingMeetingTimes.isEmpty()) { + meetingTimeRepository.deleteAll(existingMeetingTimes); + } + // 요청DTO를 MeetingTime 엔티티로 변환 List meetingTimes = meetingTimeDtos.stream() .map(dto -> { From 8a9d020f91ca26268bc54bd2a4ccb050dc0adc17 Mon Sep 17 00:00:00 2001 From: jeongju Date: Mon, 23 Dec 2024 19:05:12 +0900 Subject: [PATCH 2/6] =?UTF-8?q?fix:=20recruiting=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=EC=97=90=20=EC=98=88=EC=95=BD=20=EC=8B=9C=EC=9E=91/?= =?UTF-8?q?=EB=81=9D=20=EC=9D=BC=EC=8B=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../innerjoin/post/model/entity/Recruiting.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/com/likelion/innerjoin/post/model/entity/Recruiting.java b/src/main/java/com/likelion/innerjoin/post/model/entity/Recruiting.java index 2b59529..1e41d46 100644 --- a/src/main/java/com/likelion/innerjoin/post/model/entity/Recruiting.java +++ b/src/main/java/com/likelion/innerjoin/post/model/entity/Recruiting.java @@ -1,5 +1,6 @@ package com.likelion.innerjoin.post.model.entity; +import com.fasterxml.jackson.annotation.JsonFormat; import com.likelion.innerjoin.common.entity.DataEntity; import jakarta.persistence.*; import lombok.AllArgsConstructor; @@ -7,6 +8,7 @@ import lombok.Data; import lombok.NoArgsConstructor; +import java.time.LocalDateTime; import java.util.List; @Entity @@ -32,6 +34,14 @@ public class Recruiting extends DataEntity { @Column(name = "job_title") private String jobTitle; + @Column(name = "reservation_start_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime reservationStartTime; + + @Column(name = "reservation_end_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime reservationEndTime; + @OneToMany(mappedBy = "recruiting", orphanRemoval = true, cascade = CascadeType.ALL) private List application; From 870374bc7f5f7c2a63604ee73da9b1d251bb9e12 Mon Sep 17 00:00:00 2001 From: jeongju Date: Mon, 23 Dec 2024 19:13:49 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20=ED=8A=B9=EC=A0=95=20=EC=A7=81?= =?UTF-8?q?=EB=AC=B4=EC=9D=98=20=EB=A9=B4=EC=A0=91=EC=98=88=EC=95=BD=20?= =?UTF-8?q?=EC=8B=9C=EC=9E=91/=EC=A2=85=EB=A3=8C=20=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../post/controller/PostController.java | 4 ++-- .../dto/request/MeetingTimeRequestDTO.java | 2 ++ .../post/service/MeetingTimeService.java | 17 +++++++++++++---- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/likelion/innerjoin/post/controller/PostController.java b/src/main/java/com/likelion/innerjoin/post/controller/PostController.java index 79382f9..ff6311f 100644 --- a/src/main/java/com/likelion/innerjoin/post/controller/PostController.java +++ b/src/main/java/com/likelion/innerjoin/post/controller/PostController.java @@ -148,7 +148,7 @@ public CommonResponse getApplications(@PathVariable Long pos @PostMapping("/interview-times") - @Operation(summary = "특정 recruiting의 면접 가능 시간 생성") + @Operation(summary = "특정 recruiting의 면접 가능 시간 생성, 예약 가능 시간 설정") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "면접 가능 시간 생성 성공"), @ApiResponse(responseCode = "401", description = "세션값이 잘못되었습니다"), @@ -156,7 +156,7 @@ public CommonResponse getApplications(@PathVariable Long pos @ApiResponse(responseCode = "500", description = "서버 내부 오류") }) public CommonResponse createInterviewTimes(@RequestBody MeetingTimeRequestDTO request, HttpSession session) { - meetingTimeService.createMeetingTimes(request.getRecruitingId(), request.getMeetingTimes(), session); + meetingTimeService.createMeetingTimes(request.getRecruitingId(), request, session); return new CommonResponse<>("면접 가능 시간이 성공적으로 생성되었습니다."); } diff --git a/src/main/java/com/likelion/innerjoin/post/model/dto/request/MeetingTimeRequestDTO.java b/src/main/java/com/likelion/innerjoin/post/model/dto/request/MeetingTimeRequestDTO.java index a422606..3a0cf37 100644 --- a/src/main/java/com/likelion/innerjoin/post/model/dto/request/MeetingTimeRequestDTO.java +++ b/src/main/java/com/likelion/innerjoin/post/model/dto/request/MeetingTimeRequestDTO.java @@ -9,6 +9,8 @@ public class MeetingTimeRequestDTO { private Long recruitingId; private List meetingTimes; + private LocalDateTime reservationStartTime; + private LocalDateTime reservationEndTime; @Data public static class MeetingTimeDto { diff --git a/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java b/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java index 7cd7ebf..272d553 100644 --- a/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java +++ b/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java @@ -18,6 +18,7 @@ import com.likelion.innerjoin.user.model.entity.User; import com.likelion.innerjoin.user.util.SessionVerifier; import jakarta.servlet.http.HttpSession; +import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -34,15 +35,17 @@ public class MeetingTimeService { private final SessionVerifier sessionVerifier; //면접시간 리스트 생성 - public void createMeetingTimes(Long recruitingId, List meetingTimeDtos, HttpSession session) { + @Transactional + public void createMeetingTimes(Long recruitingId, MeetingTimeRequestDTO request, HttpSession session) { + // Recruiting 조회 Recruiting recruiting = recruitingRepository.findById(recruitingId) .orElseThrow(() -> new RecruitingNotFoundException("Recruiting not found with id: " + recruitingId)); + // Post 조회 및 Club 검증 Post post = postRepository.findById(recruiting.getPost().getId()) .orElseThrow(() -> new PostNotFoundException("Post not found")); - // post의 club_id가 유저의 club_id와 일치하는지 확인 if (!post.getClub().getId().equals(checkClub(session).getId())) { throw new UnauthorizedException("홍보글의 club_id가 현재 유저의 club_id와 일치하지 않습니다."); } @@ -53,8 +56,8 @@ public void createMeetingTimes(Long recruitingId, List meetingTimes = meetingTimeDtos.stream() + // 새로운 MeetingTime 엔티티 생성 및 저장 + List meetingTimes = request.getMeetingTimes().stream() .map(dto -> { MeetingTime meetingTime = new MeetingTime(); meetingTime.setAllowedNum(dto.getAllowedNum()); @@ -66,9 +69,15 @@ public void createMeetingTimes(Long recruitingId, List Date: Mon, 23 Dec 2024 19:27:58 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20=EC=98=88=EC=95=BD=20=EC=A2=85?= =?UTF-8?q?=EB=A3=8C=20=EC=8B=9C=EA=B0=84=EC=9D=B4=20=EC=A7=80=EB=82=AC?= =?UTF-8?q?=EC=9D=84=20=EA=B2=BD=EC=9A=B0=20=EB=A9=B4=EC=A0=91=20=EC=98=88?= =?UTF-8?q?=EC=95=BD=20=EB=B6=88=EA=B0=80=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../innerjoin/post/controller/PostController.java | 2 +- .../innerjoin/post/service/ApplicationService.java | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/likelion/innerjoin/post/controller/PostController.java b/src/main/java/com/likelion/innerjoin/post/controller/PostController.java index ff6311f..37f6ec1 100644 --- a/src/main/java/com/likelion/innerjoin/post/controller/PostController.java +++ b/src/main/java/com/likelion/innerjoin/post/controller/PostController.java @@ -157,7 +157,7 @@ public CommonResponse getApplications(@PathVariable Long pos }) public CommonResponse createInterviewTimes(@RequestBody MeetingTimeRequestDTO request, HttpSession session) { meetingTimeService.createMeetingTimes(request.getRecruitingId(), request, session); - return new CommonResponse<>("면접 가능 시간이 성공적으로 생성되었습니다."); + return new CommonResponse<>("면접 가능 시간 리스트가 설정되었습니다. 예약 가능 시간이 설정되었습니다."); } diff --git a/src/main/java/com/likelion/innerjoin/post/service/ApplicationService.java b/src/main/java/com/likelion/innerjoin/post/service/ApplicationService.java index 4f86eac..d2a5c53 100644 --- a/src/main/java/com/likelion/innerjoin/post/service/ApplicationService.java +++ b/src/main/java/com/likelion/innerjoin/post/service/ApplicationService.java @@ -20,6 +20,7 @@ import org.springframework.mail.javamail.JavaMailSender; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -252,6 +253,13 @@ public MeetingTimeResponseDTO selectMeetingTime (MeetingTimeSelectionDto dto, Ht throw new AllowedNumExceededException("면접 허용 인원을 초과했습니다."); } + // 예약 종료 시간 확인 + LocalDateTime reservationEndTime = meetingTime.getRecruiting().getReservationEndTime(); + if (reservationEndTime != null && LocalDateTime.now().isAfter(reservationEndTime)) { + throw new IllegalStateException("면접 예약이 종료되었습니다."); + } + + //면접 시간 설정 application.setMeetingTime(meetingTime); applicationRepository.save(application); From 4c3a6caa2bef381525ae97e11de7e6f785a41068 Mon Sep 17 00:00:00 2001 From: jeongju Date: Mon, 23 Dec 2024 19:33:30 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20=ED=99=8D=EB=B3=B4=EA=B8=80=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=EA=B0=80=20TIME=5FSET=EC=9D=B8=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EB=A9=B4=EC=A0=91=EC=8B=9C=EA=B0=84=20=EC=9E=AC?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EB=B6=88=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../innerjoin/post/service/MeetingTimeService.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java b/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java index 272d553..6c4591f 100644 --- a/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java +++ b/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java @@ -6,10 +6,7 @@ import com.likelion.innerjoin.post.exception.UnauthorizedException; import com.likelion.innerjoin.post.model.dto.response.MeetingTimeResponseDTO; import com.likelion.innerjoin.post.model.dto.response.MeetingTimeListResponseDTO; -import com.likelion.innerjoin.post.model.entity.Application; -import com.likelion.innerjoin.post.model.entity.MeetingTime; -import com.likelion.innerjoin.post.model.entity.Recruiting; -import com.likelion.innerjoin.post.model.entity.Post; +import com.likelion.innerjoin.post.model.entity.*; import com.likelion.innerjoin.post.model.dto.request.MeetingTimeRequestDTO; import com.likelion.innerjoin.post.repository.MeetingTimeRepository; import com.likelion.innerjoin.post.repository.PostRepository; @@ -50,6 +47,11 @@ public void createMeetingTimes(Long recruitingId, MeetingTimeRequestDTO request, throw new UnauthorizedException("홍보글의 club_id가 현재 유저의 club_id와 일치하지 않습니다."); } + // 홍보글의 RecruitmentStatus 확인 (면접 시간이 이미 확정된 경우) + if (post.getRecruitmentStatus() == RecruitmentStatus.TIME_SET) { + throw new IllegalStateException("면접 시간이 이미 공개되어서(TIME_SET) 다시 설정할 수 없습니다."); + } + // 기존 MeetingTime 삭제 List existingMeetingTimes = meetingTimeRepository.findByRecruitingId(recruitingId); if (!existingMeetingTimes.isEmpty()) { From c8a0df61988be66e6878e7602bad6ddcd74b7702 Mon Sep 17 00:00:00 2001 From: jeongju Date: Mon, 23 Dec 2024 19:43:05 +0900 Subject: [PATCH 6/6] =?UTF-8?q?feat:=20=ED=8A=B9=EC=A0=95=20=EB=A6=AC?= =?UTF-8?q?=ED=81=AC=EB=A3=A8=ED=8C=85=20=EC=A0=95=EB=B3=B4=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20(=EB=A9=B4=EC=A0=91=EA=B0=80=EB=8A=A5=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=20=EB=A6=AC=EC=8A=A4=ED=8A=B8,=20=EC=A7=81=EB=AC=B4?= =?UTF-8?q?=EB=AA=85,=20=EC=98=88=EC=95=BD=EC=8B=9C=EA=B0=84=20=EB=93=B1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../innerjoin/post/controller/PostController.java | 2 +- .../dto/response/MeetingTimeListResponseDTO.java | 6 ++++++ .../innerjoin/post/service/MeetingTimeService.java | 12 ++++++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/likelion/innerjoin/post/controller/PostController.java b/src/main/java/com/likelion/innerjoin/post/controller/PostController.java index 37f6ec1..2436827 100644 --- a/src/main/java/com/likelion/innerjoin/post/controller/PostController.java +++ b/src/main/java/com/likelion/innerjoin/post/controller/PostController.java @@ -162,7 +162,7 @@ public CommonResponse createInterviewTimes(@RequestBody MeetingTimeReque @GetMapping("/interview-times/{recruiting_id}") - @Operation(summary = "특정 recruiting의 면접 가능 시간 목록 조회") + @Operation(summary = "특정 recruiting의 정보 조회 (직무명, 면접가능시간, 예약시간 등)") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "면접 가능 시간 목록 조회 성공"), @ApiResponse(responseCode = "404", description = "해당 recruiting id를 찾을 수 없음"), diff --git a/src/main/java/com/likelion/innerjoin/post/model/dto/response/MeetingTimeListResponseDTO.java b/src/main/java/com/likelion/innerjoin/post/model/dto/response/MeetingTimeListResponseDTO.java index 7fe3578..fa1bcf3 100644 --- a/src/main/java/com/likelion/innerjoin/post/model/dto/response/MeetingTimeListResponseDTO.java +++ b/src/main/java/com/likelion/innerjoin/post/model/dto/response/MeetingTimeListResponseDTO.java @@ -1,13 +1,19 @@ package com.likelion.innerjoin.post.model.dto.response; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import java.time.LocalDateTime; import java.util.List; @Data @AllArgsConstructor +@Builder public class MeetingTimeListResponseDTO { private Long recruitingId; + private String jobTitle; + private LocalDateTime reservationStartTime; + private LocalDateTime reservationEndTime; private List meetingTimes; } diff --git a/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java b/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java index 6c4591f..2ab2642 100644 --- a/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java +++ b/src/main/java/com/likelion/innerjoin/post/service/MeetingTimeService.java @@ -88,7 +88,7 @@ Club checkClub(HttpSession session) { return club; } - //면접시간 정보 조회 + // 특정 recruiting의 면접시간 정보 조회 public CommonResponse getMeetingTimesByRecruitingId(Long recruitingId) { // recruiting 찾기 Recruiting recruiting = recruitingRepository.findById(recruitingId) @@ -121,7 +121,15 @@ public CommonResponse getMeetingTimesByRecruitingId( }) .collect(Collectors.toList()); - MeetingTimeListResponseDTO responseDto = new MeetingTimeListResponseDTO(recruitingId, meetingTimeDtos); + MeetingTimeListResponseDTO responseDto = new MeetingTimeListResponseDTO( + recruiting.getId(), + recruiting.getJobTitle(), + recruiting.getReservationStartTime(), + recruiting.getReservationEndTime(), + meetingTimeDtos + ); + return new CommonResponse<>(responseDto); } + }