diff --git a/src/main/generated/com/chwipoClova/feedback/entity/QFeedback.java b/src/main/generated/com/chwipoClova/feedback/entity/QFeedback.java new file mode 100644 index 0000000..fa7959f --- /dev/null +++ b/src/main/generated/com/chwipoClova/feedback/entity/QFeedback.java @@ -0,0 +1,59 @@ +package com.chwipoClova.feedback.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QFeedback is a Querydsl query type for Feedback + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QFeedback extends EntityPathBase { + + private static final long serialVersionUID = -267482617L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QFeedback feedback = new QFeedback("feedback"); + + public final StringPath content = createString("content"); + + public final NumberPath feedbackId = createNumber("feedbackId", Long.class); + + public final DateTimePath modifyDate = createDateTime("modifyDate", java.util.Date.class); + + public final com.chwipoClova.qa.entity.QQa qa; + + public final DateTimePath regDate = createDateTime("regDate", java.util.Date.class); + + public final NumberPath type = createNumber("type", Integer.class); + + public QFeedback(String variable) { + this(Feedback.class, forVariable(variable), INITS); + } + + public QFeedback(Path path) { + this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); + } + + public QFeedback(PathMetadata metadata) { + this(metadata, PathInits.getFor(metadata, INITS)); + } + + public QFeedback(PathMetadata metadata, PathInits inits) { + this(Feedback.class, metadata, inits); + } + + public QFeedback(Class type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.qa = inits.isInitialized("qa") ? new com.chwipoClova.qa.entity.QQa(forProperty("qa"), inits.get("qa")) : null; + } + +} + diff --git a/src/main/java/com/chwipoClova/common/exception/ExceptionCode.java b/src/main/java/com/chwipoClova/common/exception/ExceptionCode.java index 6a9e075..08bcf10 100644 --- a/src/main/java/com/chwipoClova/common/exception/ExceptionCode.java +++ b/src/main/java/com/chwipoClova/common/exception/ExceptionCode.java @@ -27,11 +27,17 @@ public enum ExceptionCode { FILE_EXT_IMAGE("851", "IMAGE 파일 형식이 아닙니다."), - FILE_SIZE("860", "파일 업로드 최대 크기는 50M 입니다."), + FILE_SIZE("852", "파일 업로드 최대 크기는 50M 입니다."), - RESUME_NULL("870", "이력서 정보가 올바르지 않습니다."), + RESUME_NULL("860", "이력서 정보가 올바르지 않습니다."), - RECRUIT_CONTENT_NULL("880", "채용공고 정보가 올바르지 않습니다.") + RECRUIT_CONTENT_NULL("870", "채용공고 정보가 올바르지 않습니다."), + + INTERVIEW_NULL("880", "면접 정보가 올바르지 않습니다."), + + QA_NULL("890", "질문 정보가 올바르지 않습니다."), + + TOKEN_NULL("950", "토큰정보가 올바르지 않습니다.") ; diff --git a/src/main/java/com/chwipoClova/common/filter/JwtAuthFilter.java b/src/main/java/com/chwipoClova/common/filter/JwtAuthFilter.java index c9521e1..c91ab8d 100644 --- a/src/main/java/com/chwipoClova/common/filter/JwtAuthFilter.java +++ b/src/main/java/com/chwipoClova/common/filter/JwtAuthFilter.java @@ -1,5 +1,6 @@ package com.chwipoClova.common.filter; +import com.chwipoClova.common.exception.ExceptionCode; import com.chwipoClova.common.response.CommonResponse; import com.chwipoClova.common.utils.JwtUtil; import com.fasterxml.jackson.databind.ObjectMapper; @@ -89,7 +90,7 @@ public void jwtExceptionHandler(HttpServletResponse response, String msg, HttpSt response.setStatus(status.value()); response.setContentType("application/json"); try { - String json = new ObjectMapper().writeValueAsString(new CommonResponse("RefreshToken Expired", null,"878")); + String json = new ObjectMapper().writeValueAsString(new CommonResponse(ExceptionCode.TOKEN_NULL.getCode(), null,ExceptionCode.TOKEN_NULL.getMessage())); response.getWriter().write(json); } catch (Exception e) { log.error(e.getMessage()); diff --git a/src/main/java/com/chwipoClova/common/response/MessageCode.java b/src/main/java/com/chwipoClova/common/response/MessageCode.java index 591574e..29c4e5e 100644 --- a/src/main/java/com/chwipoClova/common/response/MessageCode.java +++ b/src/main/java/com/chwipoClova/common/response/MessageCode.java @@ -9,6 +9,8 @@ @AllArgsConstructor public enum MessageCode { + OK("200", "OK"), + SUCCESS_SAVE("600", "정상적으로 저장되었습니다."), SUCCESS_DELETE("601", "정상적으로 삭제되었습니다."), diff --git a/src/main/java/com/chwipoClova/feedback/controller/FeedbackController.java b/src/main/java/com/chwipoClova/feedback/controller/FeedbackController.java new file mode 100644 index 0000000..30f1f25 --- /dev/null +++ b/src/main/java/com/chwipoClova/feedback/controller/FeedbackController.java @@ -0,0 +1,4 @@ +package com.chwipoClova.feedback.controller; + +public class FeedbackController { +} diff --git a/src/main/java/com/chwipoClova/feedback/entity/Feedback.java b/src/main/java/com/chwipoClova/feedback/entity/Feedback.java new file mode 100644 index 0000000..d75f613 --- /dev/null +++ b/src/main/java/com/chwipoClova/feedback/entity/Feedback.java @@ -0,0 +1,63 @@ +package com.chwipoClova.feedback.entity; + + +import com.chwipoClova.qa.entity.Qa; +import com.chwipoClova.user.entity.User; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.persistence.*; +import lombok.*; +import org.hibernate.annotations.DynamicInsert; + +import java.util.Date; + +@Entity(name = "Feedback") +@Table(name = "Feedback") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties() +@DynamicInsert +@Builder +@Getter +@ToString +@AllArgsConstructor +@NoArgsConstructor +public class Feedback { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "feedbackId") + @Schema(description = "피드백 ID") + private Long feedbackId; + + @Column(name = "type") + @Schema(description = "피드백타입(1, 2, 3)") + private Integer type; + + @Column(name = "content") + @Schema(description = "피드백내용") + private String content; + + @Column(name = "regDate") + @Schema(description = "등록일") + private Date regDate; + + @Column(name = "modifyDate") + @Schema(description = "수정일") + private Date modifyDate; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "qaId") + private Qa qa; + + // @PrePersist 메서드 정의 (최초 등록시 호출) + @PrePersist + public void prePersist() { + this.regDate = new Date(); // 현재 날짜와 시간으로 등록일 설정 + } + + @PreUpdate + public void preUpdate() { + this.modifyDate = new Date(); // 현재 날짜와 시간으로 수정일 업데이트 + } +} diff --git a/src/main/java/com/chwipoClova/feedback/repository/FeedbackRepository.java b/src/main/java/com/chwipoClova/feedback/repository/FeedbackRepository.java new file mode 100644 index 0000000..8e18734 --- /dev/null +++ b/src/main/java/com/chwipoClova/feedback/repository/FeedbackRepository.java @@ -0,0 +1,11 @@ +package com.chwipoClova.feedback.repository; + +import com.chwipoClova.feedback.entity.Feedback; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface FeedbackRepository extends JpaRepository { + + List findByQaQaIdOrderByFeedbackId(Long qaId); +} diff --git a/src/main/java/com/chwipoClova/feedback/request/FeedbackDataInsertReq.java b/src/main/java/com/chwipoClova/feedback/request/FeedbackDataInsertReq.java new file mode 100644 index 0000000..a2c3a2a --- /dev/null +++ b/src/main/java/com/chwipoClova/feedback/request/FeedbackDataInsertReq.java @@ -0,0 +1,14 @@ +package com.chwipoClova.feedback.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class FeedbackDataInsertReq { + + @Schema(description = "피드백타입", example = "1", name = "type") + private Integer type; + + @Schema(description = "피드백내용", example = "피드백1입니다.", name = "content") + private String content; +} diff --git a/src/main/java/com/chwipoClova/feedback/request/FeedbackInsertReq.java b/src/main/java/com/chwipoClova/feedback/request/FeedbackInsertReq.java new file mode 100644 index 0000000..c2e197b --- /dev/null +++ b/src/main/java/com/chwipoClova/feedback/request/FeedbackInsertReq.java @@ -0,0 +1,18 @@ +package com.chwipoClova.feedback.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class FeedbackInsertReq { + + @Schema(description = "질문답변 ID", example = "1", name = "qaId") + private Long qaId; + + @Schema(description = "질문", example = "질문1", name = "question") + private String question; + + @Schema(description = "답변", example = "답변1", name = "answer") + private String answer; + +} diff --git a/src/main/java/com/chwipoClova/feedback/request/FeedbackListReq.java b/src/main/java/com/chwipoClova/feedback/request/FeedbackListReq.java new file mode 100644 index 0000000..9285fd5 --- /dev/null +++ b/src/main/java/com/chwipoClova/feedback/request/FeedbackListReq.java @@ -0,0 +1,12 @@ +package com.chwipoClova.feedback.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class FeedbackListReq { + + @Schema(description = "질문답변 ID", example = "1", name = "qaId") + private Long qaId; + +} diff --git a/src/main/java/com/chwipoClova/feedback/response/FeedBackApiRes.java b/src/main/java/com/chwipoClova/feedback/response/FeedBackApiRes.java new file mode 100644 index 0000000..0ac60e6 --- /dev/null +++ b/src/main/java/com/chwipoClova/feedback/response/FeedBackApiRes.java @@ -0,0 +1,18 @@ +package com.chwipoClova.feedback.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class FeedBackApiRes { + + @Schema(description = "질문 ID", example = "1", name = "qaId") + private Long qaId; + + @Schema(description = "피드백 타입", example = "1", name = "type") + private Integer type; + + @Schema(description = "피드백 내용", example = "피드백1입니다.", name = "content") + private String content; + +} diff --git a/src/main/java/com/chwipoClova/feedback/response/FeedbackInsertRes.java b/src/main/java/com/chwipoClova/feedback/response/FeedbackInsertRes.java new file mode 100644 index 0000000..6d30e4a --- /dev/null +++ b/src/main/java/com/chwipoClova/feedback/response/FeedbackInsertRes.java @@ -0,0 +1,28 @@ +package com.chwipoClova.feedback.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + +@Data +public class FeedbackInsertRes { + @Schema(description = "질문답변 ID", example = "1", name = "qaId") + private Long qaId; + + @Schema(description = "피드백 ID", example = "1", name = "feedbackId") + private Long feedbackId; + + @Schema(description = "피드백 타입", example = "1", name = "type") + private Integer type; + + @Schema(description = "피드백 내용", example = "피드백입니다.", name = "content") + private String content; + + @Schema(description = "등록일", example = "2023-12-09T10:13:17.838+00:00", name = "regDate") + private Date regDate; + + @Schema(description = "수정일", example = "2023-12-09T10:13:17.838+00:00", name = "modifyDate") + private Date modifyDate; + +} diff --git a/src/main/java/com/chwipoClova/feedback/response/FeedbackListRes.java b/src/main/java/com/chwipoClova/feedback/response/FeedbackListRes.java new file mode 100644 index 0000000..b8457bd --- /dev/null +++ b/src/main/java/com/chwipoClova/feedback/response/FeedbackListRes.java @@ -0,0 +1,30 @@ +package com.chwipoClova.feedback.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +import java.util.Date; + +@Data +@Builder +public class FeedbackListRes { + @Schema(description = "질문답변 ID", example = "1", name = "qaId") + private Long qaId; + + @Schema(description = "피드백 ID", example = "1", name = "feedbackId") + private Long feedbackId; + + @Schema(description = "피드백 타입", example = "1", name = "type") + private Integer type; + + @Schema(description = "피드백 내용", example = "피드백입니다.", name = "content") + private String content; + + @Schema(description = "등록일", example = "2023-12-09T10:13:17.838+00:00", name = "regDate") + private Date regDate; + + @Schema(description = "수정일", example = "2023-12-09T10:13:17.838+00:00", name = "modifyDate") + private Date modifyDate; + +} diff --git a/src/main/java/com/chwipoClova/feedback/service/FeedbackService.java b/src/main/java/com/chwipoClova/feedback/service/FeedbackService.java new file mode 100644 index 0000000..f5fcf4f --- /dev/null +++ b/src/main/java/com/chwipoClova/feedback/service/FeedbackService.java @@ -0,0 +1,85 @@ +package com.chwipoClova.feedback.service; + +import com.chwipoClova.common.exception.CommonException; +import com.chwipoClova.common.exception.ExceptionCode; +import com.chwipoClova.common.response.CommonResponse; +import com.chwipoClova.common.response.MessageCode; +import com.chwipoClova.feedback.entity.Feedback; +import com.chwipoClova.feedback.repository.FeedbackRepository; +import com.chwipoClova.feedback.request.FeedbackInsertReq; +import com.chwipoClova.feedback.response.FeedBackApiRes; +import com.chwipoClova.feedback.response.FeedbackListRes; +import com.chwipoClova.qa.entity.Qa; +import com.chwipoClova.qa.repository.QaRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +@RequiredArgsConstructor +@Service +@Slf4j +public class FeedbackService { + + private final FeedbackRepository feedbackRepository; + + private final QaRepository qaRepository; + + @Transactional + public CommonResponse insertFeedback(List feedbackInsertListReq) throws IOException { + + // TODO 피드백 연동 필요함 + // 테스트 데이터 + List feedBackApiListRes = new ArrayList<>(); + feedbackInsertListReq.stream().forEach(feedbackInsertReq -> { + Long qaId = feedbackInsertReq.getQaId(); + FeedBackApiRes feedBackApiRes = new FeedBackApiRes(); + feedBackApiRes.setQaId(qaId); + feedBackApiRes.setType(1); + feedBackApiRes.setContent("피드백1입니다."); + feedBackApiListRes.add(feedBackApiRes); + FeedBackApiRes feedBackApiRes2 = new FeedBackApiRes(); + feedBackApiRes2.setQaId(qaId); + feedBackApiRes2.setType(2); + feedBackApiRes2.setContent("피드백2입니다."); + feedBackApiListRes.add(feedBackApiRes2); + }); + + feedBackApiListRes.stream().forEach(feedBackApiRes -> { + Long qaId = feedBackApiRes.getQaId(); + Qa qa = qaRepository.findById(qaId).orElseThrow(() -> new CommonException(ExceptionCode.QA_NULL.getMessage(), ExceptionCode.QA_NULL.getCode())); + + Feedback feedback = Feedback.builder() + .type(feedBackApiRes.getType()) + .content(feedBackApiRes.getContent()) + .qa(qa) + .build(); + feedbackRepository.save(feedback); + }); + + return new CommonResponse<>(MessageCode.OK.getCode(), null, MessageCode.OK.getMessage()); + } + + public List selectFeedbackList(Long qaId) { + List feedbackListResList = new ArrayList<>(); + + List feedbackList = feedbackRepository.findByQaQaIdOrderByFeedbackId(qaId); + feedbackList.stream().forEach(feedback -> { + FeedbackListRes feedbackListRes = FeedbackListRes.builder() + .qaId(feedback.getQa().getQaId()) + .feedbackId(feedback.getFeedbackId()) + .type(feedback.getType()) + .content(feedback.getContent()) + .regDate(feedback.getRegDate()) + .modifyDate(feedback.getModifyDate()) + .build(); + feedbackListResList.add(feedbackListRes); + }); + return feedbackListResList; + } + +} diff --git a/src/main/java/com/chwipoClova/interview/controller/InterviewController.java b/src/main/java/com/chwipoClova/interview/controller/InterviewController.java index 0814a46..d61156f 100644 --- a/src/main/java/com/chwipoClova/interview/controller/InterviewController.java +++ b/src/main/java/com/chwipoClova/interview/controller/InterviewController.java @@ -2,7 +2,10 @@ import com.chwipoClova.interview.request.InterviewInsertReq; import com.chwipoClova.interview.response.InterviewInsertRes; +import com.chwipoClova.interview.response.InterviewListRes; +import com.chwipoClova.interview.response.InterviewRes; import com.chwipoClova.interview.service.InterviewService; +import com.chwipoClova.resume.response.ResumeListRes; import com.chwipoClova.resume.response.ResumeUploadRes; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -18,6 +21,8 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import java.util.List; + @Slf4j @RestController @RequiredArgsConstructor @@ -40,4 +45,27 @@ public InterviewInsertRes insertInterview( return interviewService.insertInterview(interviewInsertReq, file); } + @Operation(summary = "면접 결과 조회", description = "면접 결과 조회") + @GetMapping(path = "/getInterview") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK") + } + ) + public InterviewRes getInterview( + @Schema(description = "userId", example = "1", name = "userId") @RequestParam(name = "userId") Long userId, + @Schema(description = "interviewId", example = "1", name = "interviewId") @RequestParam(name = "interviewId") Long interviewId + ) { + return interviewService.selectInterview(userId, interviewId); + } + + @Operation(summary = "면접 목록 조회", description = "면접 목록 조회") + @GetMapping(path = "/getInterviewList") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK") + } + ) + public List getInterviewList(@Schema(description = "userId", example = "1", name = "userId") @RequestParam(name = "userId") Long userId) { + return interviewService.selectInterviewList(userId); + } + } diff --git a/src/main/java/com/chwipoClova/interview/repository/InterviewRepository.java b/src/main/java/com/chwipoClova/interview/repository/InterviewRepository.java index 63d70dc..564f2c7 100644 --- a/src/main/java/com/chwipoClova/interview/repository/InterviewRepository.java +++ b/src/main/java/com/chwipoClova/interview/repository/InterviewRepository.java @@ -1,7 +1,15 @@ package com.chwipoClova.interview.repository; import com.chwipoClova.interview.entity.Interview; +import com.chwipoClova.resume.entity.Resume; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; +import java.util.Optional; + public interface InterviewRepository extends JpaRepository { + + Optional findByUserUserIdAndInterviewId(Long userId, Long interviewId); + + List findByUserUserIdOrderByRegDate(Long userId); } diff --git a/src/main/java/com/chwipoClova/interview/response/InterviewListRes.java b/src/main/java/com/chwipoClova/interview/response/InterviewListRes.java new file mode 100644 index 0000000..4e15eff --- /dev/null +++ b/src/main/java/com/chwipoClova/interview/response/InterviewListRes.java @@ -0,0 +1,33 @@ +package com.chwipoClova.interview.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +import java.util.Date; + +@Data +@Builder +public class InterviewListRes { + + @Schema(description = "면접 ID", example = "1", name = "interviewId") + private Long interviewId; + + @Schema(description = "유저 ID", example = "1", name = "userId") + private Long userId; + + @Schema(description = "면접 제목", example = "삼성채용", name = "title") + private String title; + + @Schema(description = "총개수", example = "10", name = "totalCnt") + private Integer totalCnt; + + @Schema(description = "답변개수", example = "1", name = "useCnt") + private Integer useCnt; + + @Schema(description = "등록일", example = "2023-12-09T10:13:17.838+00:00", name = "regDate") + private Date regDate; + + @Schema(description = "수정일", example = "2023-12-09T10:13:17.838+00:00", name = "modifyDate") + private Date modifyDate; +} diff --git a/src/main/java/com/chwipoClova/interview/response/InterviewRes.java b/src/main/java/com/chwipoClova/interview/response/InterviewRes.java new file mode 100644 index 0000000..06657cc --- /dev/null +++ b/src/main/java/com/chwipoClova/interview/response/InterviewRes.java @@ -0,0 +1,29 @@ +package com.chwipoClova.interview.response; + +import com.chwipoClova.qa.response.QaListRes; +import com.chwipoClova.qa.response.QaQuestionInsertRes; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +@Data +@Builder +public class InterviewRes { + + @Schema(description = "면접 ID", example = "1", name = "interviewId") + private Long interviewId; + @Schema(description = "유저 ID", example = "1", name = "userId") + private Long userId; + @Schema(description = "면접 제목", example = "삼성채용", name = "title") + private String title; + @Schema(description = "등록일", example = "2023-12-09T10:13:17.838+00:00", name = "regDate") + private Date regDate; + @Schema(description = "수정일", example = "2023-12-09T10:13:17.838+00:00", name = "modifyDate") + private Date modifyDate; + @Schema(description = "질문데이터", name = "qaData") + private List qaData; + +} diff --git a/src/main/java/com/chwipoClova/interview/service/InterviewService.java b/src/main/java/com/chwipoClova/interview/service/InterviewService.java index 4519c13..245d9bc 100644 --- a/src/main/java/com/chwipoClova/interview/service/InterviewService.java +++ b/src/main/java/com/chwipoClova/interview/service/InterviewService.java @@ -2,11 +2,18 @@ import com.chwipoClova.common.exception.CommonException; import com.chwipoClova.common.exception.ExceptionCode; +import com.chwipoClova.feedback.entity.Feedback; +import com.chwipoClova.feedback.response.FeedbackListRes; +import com.chwipoClova.feedback.service.FeedbackService; import com.chwipoClova.interview.entity.Interview; import com.chwipoClova.interview.repository.InterviewRepository; import com.chwipoClova.interview.request.InterviewInsertReq; import com.chwipoClova.interview.response.InterviewInsertRes; +import com.chwipoClova.interview.response.InterviewListRes; +import com.chwipoClova.interview.response.InterviewRes; import com.chwipoClova.qa.request.QaQuestionInsertReq; +import com.chwipoClova.qa.response.QaCountRes; +import com.chwipoClova.qa.response.QaListRes; import com.chwipoClova.qa.response.QaQuestionInsertRes; import com.chwipoClova.qa.service.QaService; import com.chwipoClova.recruit.request.RecruitInsertReq; @@ -41,6 +48,8 @@ public class InterviewService { private final QaService qaService; + private final FeedbackService feedbackService; + @Transactional public InterviewInsertRes insertInterview(InterviewInsertReq interviewInsertReq, MultipartFile file) throws IOException { Long userId = interviewInsertReq.getUserId(); @@ -102,4 +111,47 @@ public InterviewInsertRes insertInterview(InterviewInsertReq interviewInsertReq, .build(); } + public InterviewRes selectInterview(Long userId, Long interviewId) { + User user = userRepository.findById(userId).orElseThrow(() -> new CommonException(ExceptionCode.USER_NULL.getMessage(), ExceptionCode.USER_NULL.getCode())); + Interview interview = interviewRepository.findByUserUserIdAndInterviewId(userId, interviewId).orElseThrow(() -> new CommonException(ExceptionCode.INTERVIEW_NULL.getMessage(), ExceptionCode.INTERVIEW_NULL.getCode())); + + List qaListRes = qaService.selectQaList(interview.getInterviewId()); + + qaListRes.stream().forEach(qaListRes1 -> { + List feedbackListRes = feedbackService.selectFeedbackList(qaListRes1.getQaId()); + qaListRes1.setFeedbackData(feedbackListRes); + }); + + return InterviewRes.builder() + .interviewId(interview.getInterviewId()) + .userId(user.getUserId()) + .title(interview.getTitle()) + .regDate(interview.getRegDate()) + .modifyDate(interview.getModifyDate()) + .qaData(qaListRes) + .build(); + } + + public List selectInterviewList(Long userId) { + List interviewListRes = new ArrayList<>(); + + List interviewList = interviewRepository.findByUserUserIdOrderByRegDate(userId); + + interviewList.stream().forEach(interview -> { + QaCountRes qaCountRes = qaService.selectQaListUseCount(interview.getInterviewId()); + + InterviewListRes interviewListRes1 = InterviewListRes.builder() + .interviewId(interview.getInterviewId()) + .userId(interview.getUser().getUserId()) + .title(interview.getTitle()) + .useCnt(qaCountRes.getUseCnt()) + .totalCnt(qaCountRes.getTotalCnt()) + .regDate(interview.getRegDate()) + .modifyDate(interview.getModifyDate()) + .build(); + interviewListRes.add(interviewListRes1); + }); + + return interviewListRes; + } } diff --git a/src/main/java/com/chwipoClova/qa/controller/QaController.java b/src/main/java/com/chwipoClova/qa/controller/QaController.java index 441a5ad..20cb724 100644 --- a/src/main/java/com/chwipoClova/qa/controller/QaController.java +++ b/src/main/java/com/chwipoClova/qa/controller/QaController.java @@ -1,4 +1,37 @@ package com.chwipoClova.qa.controller; + +import com.chwipoClova.common.response.CommonResponse; +import com.chwipoClova.qa.request.QaAnswerInsertReq; +import com.chwipoClova.qa.service.QaService; +import com.chwipoClova.user.response.UserLoginRes; +import io.swagger.v3.oas.annotations.Operation; +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.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +@Slf4j +@RestController +@RequiredArgsConstructor +@Tag(name = "Qa", description = "답변 API") +@RequestMapping("qa") public class QaController { + + private final QaService qaService; + + @Operation(summary = "답변 저장", description = "답변 저장") + @PostMapping("/insertAnswer") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = String.class))) + } + ) + public CommonResponse insertAnswer(@RequestBody QaAnswerInsertReq qaAnswerInsertReq) throws Exception { + return qaService.insertAnswer(qaAnswerInsertReq); + } } diff --git a/src/main/java/com/chwipoClova/qa/entity/Qa.java b/src/main/java/com/chwipoClova/qa/entity/Qa.java index b2e14db..30b14cc 100644 --- a/src/main/java/com/chwipoClova/qa/entity/Qa.java +++ b/src/main/java/com/chwipoClova/qa/entity/Qa.java @@ -2,6 +2,7 @@ import com.chwipoClova.interview.entity.Interview; import com.chwipoClova.user.entity.User; +import com.chwipoClova.user.entity.UserEditor; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import io.swagger.v3.oas.annotations.media.Schema; @@ -62,4 +63,14 @@ public void prePersist() { public void preUpdate() { this.modifyDate = new Date(); // 현재 날짜와 시간으로 수정일 업데이트 } + + public QaEditor.QaEditorBuilder toEditor() { + return QaEditor.builder() + .answer(answer); + } + + public void edit(QaEditor qaEditor) { + answer = qaEditor.getAnswer(); + } + } diff --git a/src/main/java/com/chwipoClova/qa/entity/QaEditor.java b/src/main/java/com/chwipoClova/qa/entity/QaEditor.java new file mode 100644 index 0000000..91a003e --- /dev/null +++ b/src/main/java/com/chwipoClova/qa/entity/QaEditor.java @@ -0,0 +1,19 @@ +package com.chwipoClova.qa.entity; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.persistence.Column; +import lombok.Builder; +import lombok.Getter; + +import java.util.Date; + +@Getter +public class QaEditor { + + private String answer; + + @Builder + public QaEditor(String answer) { + this.answer = answer; + } +} diff --git a/src/main/java/com/chwipoClova/qa/repository/QaRepository.java b/src/main/java/com/chwipoClova/qa/repository/QaRepository.java index e511738..7ce2c76 100644 --- a/src/main/java/com/chwipoClova/qa/repository/QaRepository.java +++ b/src/main/java/com/chwipoClova/qa/repository/QaRepository.java @@ -1,7 +1,16 @@ package com.chwipoClova.qa.repository; import com.chwipoClova.qa.entity.Qa; +import com.chwipoClova.resume.entity.Resume; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; +import java.util.Optional; + public interface QaRepository extends JpaRepository { + + Optional findByInterviewInterviewIdAndQaId(Long interviewId, Long qaId); + + List findByInterviewInterviewIdOrderByQaId(Long interviewId); + } diff --git a/src/main/java/com/chwipoClova/qa/request/QaAnswerDataInsertReq.java b/src/main/java/com/chwipoClova/qa/request/QaAnswerDataInsertReq.java new file mode 100644 index 0000000..b04bdb7 --- /dev/null +++ b/src/main/java/com/chwipoClova/qa/request/QaAnswerDataInsertReq.java @@ -0,0 +1,14 @@ +package com.chwipoClova.qa.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class QaAnswerDataInsertReq { + + @Schema(description = "질문 ID", example = "1", name = "qaId") + private Long qaId; + + @Schema(description = "답변", example = "답변1", name = "answer") + private String answer; +} diff --git a/src/main/java/com/chwipoClova/qa/request/QaAnswerInsertReq.java b/src/main/java/com/chwipoClova/qa/request/QaAnswerInsertReq.java new file mode 100644 index 0000000..b971dcb --- /dev/null +++ b/src/main/java/com/chwipoClova/qa/request/QaAnswerInsertReq.java @@ -0,0 +1,20 @@ +package com.chwipoClova.qa.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Data +public class QaAnswerInsertReq { + + @Schema(description = "유저 ID", example = "1", name = "userId") + private Long userId; + + @Schema(description = "면접 ID", example = "1", name = "interviewId") + private Long interviewId; + + @Schema(description = "답변데이터", name = "answerData") + private List answerData; + +} diff --git a/src/main/java/com/chwipoClova/qa/response/QaAnswerInsertRes.java b/src/main/java/com/chwipoClova/qa/response/QaAnswerInsertRes.java new file mode 100644 index 0000000..7ee06e8 --- /dev/null +++ b/src/main/java/com/chwipoClova/qa/response/QaAnswerInsertRes.java @@ -0,0 +1,4 @@ +package com.chwipoClova.qa.response; + +public class QaAnswerInsertRes { +} diff --git a/src/main/java/com/chwipoClova/qa/response/QaCountRes.java b/src/main/java/com/chwipoClova/qa/response/QaCountRes.java new file mode 100644 index 0000000..6ac6d45 --- /dev/null +++ b/src/main/java/com/chwipoClova/qa/response/QaCountRes.java @@ -0,0 +1,16 @@ +package com.chwipoClova.qa.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class QaCountRes { + + @Schema(description = "사용개수", example = "1", name = "useCnt") + private Integer useCnt; + + @Schema(description = "총개수", example = "10", name = "totalCnt") + private Integer totalCnt; +} diff --git a/src/main/java/com/chwipoClova/qa/response/QaListRes.java b/src/main/java/com/chwipoClova/qa/response/QaListRes.java new file mode 100644 index 0000000..cb2d0d0 --- /dev/null +++ b/src/main/java/com/chwipoClova/qa/response/QaListRes.java @@ -0,0 +1,38 @@ +package com.chwipoClova.qa.response; + +import com.chwipoClova.feedback.response.FeedbackListRes; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +@Data +@Builder +public class QaListRes { + + @Schema(description = "면접 ID", example = "1", name = "interviewId") + private Long interviewId; + + @Schema(description = "질문 ID", example = "1", name = "qaId") + private Long qaId; + + @Schema(description = "질문", example = "질문1", name = "question") + private String question; + + @Schema(description = "답변", example = "답변1", name = "answer") + private String answer; + + @Schema(description = "AI 답변", example = "AI답변1", name = "aiAnswer") + private String aiAnswer; + + @Schema(description = "등록일", example = "2023-12-09T10:13:17.838+00:00", name = "regDate") + private Date regDate; + + @Schema(description = "수정일", example = "2023-12-09T10:13:17.838+00:00", name = "modifyDate") + private Date modifyDate; + + @Schema(description = "피드백 데이터", name = "feedbackData") + private List feedbackData; +} diff --git a/src/main/java/com/chwipoClova/qa/service/QaService.java b/src/main/java/com/chwipoClova/qa/service/QaService.java index a798da1..3a73dd7 100644 --- a/src/main/java/com/chwipoClova/qa/service/QaService.java +++ b/src/main/java/com/chwipoClova/qa/service/QaService.java @@ -1,21 +1,33 @@ package com.chwipoClova.qa.service; -import com.chwipoClova.interview.entity.Interview; +import com.chwipoClova.common.exception.CommonException; +import com.chwipoClova.common.exception.ExceptionCode; +import com.chwipoClova.common.response.CommonResponse; +import com.chwipoClova.common.response.MessageCode; +import com.chwipoClova.feedback.entity.Feedback; +import com.chwipoClova.feedback.request.FeedbackInsertReq; +import com.chwipoClova.feedback.response.FeedbackListRes; +import com.chwipoClova.feedback.service.FeedbackService; import com.chwipoClova.interview.repository.InterviewRepository; import com.chwipoClova.qa.entity.Qa; +import com.chwipoClova.qa.entity.QaEditor; import com.chwipoClova.qa.repository.QaRepository; +import com.chwipoClova.qa.request.QaAnswerDataInsertReq; +import com.chwipoClova.qa.request.QaAnswerInsertReq; import com.chwipoClova.qa.request.QaQuestionInsertReq; +import com.chwipoClova.qa.response.QaCountRes; +import com.chwipoClova.qa.response.QaListRes; import com.chwipoClova.qa.response.QaQuestionInsertRes; -import com.chwipoClova.recruit.request.RecruitInsertReq; -import com.chwipoClova.recruit.response.RecruitInsertRes; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; @RequiredArgsConstructor @Service @@ -24,6 +36,10 @@ public class QaService { private final QaRepository qaRepository; + private final InterviewRepository interviewRepository; + + private final FeedbackService feedbackService; + @Transactional public List insertQaQuestionList(List qaQuestionInsertReqList) throws IOException { List qaList = new ArrayList<>(); @@ -53,4 +69,75 @@ public List insertQaQuestionList(List return qaQuestionInsertResList; } + + @Transactional + public CommonResponse insertAnswer(QaAnswerInsertReq qaAnswerInsertReq) throws IOException { + Long userId = qaAnswerInsertReq.getUserId(); + Long interviewId = qaAnswerInsertReq.getInterviewId(); + interviewRepository.findByUserUserIdAndInterviewId(userId, interviewId).orElseThrow(() -> new CommonException(ExceptionCode.INTERVIEW_NULL.getMessage(), ExceptionCode.INTERVIEW_NULL.getCode())); + + List qaAnswerDataInsertReqList = qaAnswerInsertReq.getAnswerData(); + + List feedbackInsertListReq = new ArrayList<>(); + + qaAnswerDataInsertReqList.stream().forEach(qaAnswerDataInsertReq -> { + Qa qa = qaRepository.findByInterviewInterviewIdAndQaId(interviewId, qaAnswerDataInsertReq.getQaId()).orElseThrow(() -> new CommonException(ExceptionCode.QA_NULL.getMessage(), ExceptionCode.QA_NULL.getCode())); + QaEditor.QaEditorBuilder editorBuilder = qa.toEditor(); + QaEditor qaEditor = editorBuilder.answer(qaAnswerDataInsertReq.getAnswer()) + .build(); + qa.edit(qaEditor); + + // 피드백 정보 + FeedbackInsertReq feedbackInsertReq = new FeedbackInsertReq(); + feedbackInsertReq.setQaId(qa.getQaId()); + feedbackInsertReq.setAnswer(qa.getAnswer()); + feedbackInsertReq.setQuestion(qa.getQuestion()); + feedbackInsertListReq.add(feedbackInsertReq); + }); + + // 피드백 요청 및 등록 + feedbackService.insertFeedback(feedbackInsertListReq); + + return new CommonResponse<>(MessageCode.OK.getCode(), null, MessageCode.OK.getMessage()); + } + + public List selectQaList(Long interviewId) { + List qaListResList = new ArrayList<>(); + + List qaList = qaRepository.findByInterviewInterviewIdOrderByQaId(interviewId); + + qaList.stream().forEach(qa -> { + QaListRes qaListRes = QaListRes.builder() + .interviewId(qa.getInterview().getInterviewId()) + .qaId(qa.getQaId()) + .question(qa.getQuestion()) + .answer(qa.getAnswer()) + //.aiAnswer(qa.getAiAnswer()) + .regDate(qa.getRegDate()) + .modifyDate(qa.getModifyDate()) + .build(); + qaListResList.add(qaListRes); + }); + return qaListResList; + } + + public QaCountRes selectQaListUseCount(Long interviewId) { + List qaListRes = selectQaList(interviewId); + + AtomicInteger index = new AtomicInteger(0); // 시작 인덱스 + qaListRes.stream().forEach(qaListRes1 -> { + if (StringUtils.isNotBlank(qaListRes1.getAnswer())) { + index.getAndIncrement(); + } + }); + + int useCnt = index.get(); + int totalCnt = qaListRes.size(); + + return QaCountRes.builder() + .useCnt(useCnt) + .totalCnt(totalCnt) + .build(); + } + } diff --git a/src/main/java/com/chwipoClova/resume/service/ResumeService.java b/src/main/java/com/chwipoClova/resume/service/ResumeService.java index 378665c..f6cf637 100644 --- a/src/main/java/com/chwipoClova/resume/service/ResumeService.java +++ b/src/main/java/com/chwipoClova/resume/service/ResumeService.java @@ -182,6 +182,6 @@ private CommonResponse resumeDelete(Resume resume) { } resumeRepository.delete(resume); - return new CommonResponse<>(MessageCode.SUCCESS_DELETE.getCode(), null, MessageCode.SUCCESS_DELETE.getMessage()); + return new CommonResponse<>(MessageCode.OK.getCode(), null, MessageCode.OK.getMessage()); } } diff --git a/src/main/java/com/chwipoClova/user/entity/User.java b/src/main/java/com/chwipoClova/user/entity/User.java index 4ea50bf..2aebb16 100644 --- a/src/main/java/com/chwipoClova/user/entity/User.java +++ b/src/main/java/com/chwipoClova/user/entity/User.java @@ -72,13 +72,13 @@ public void preUpdate() { this.modifyDate = new Date(); // 현재 날짜와 시간으로 수정일 업데이트 } - public UsersEditor.UsersEditorBuilder toEditor() { - return UsersEditor.builder() + public UserEditor.UserEditorBuilder toEditor() { + return UserEditor.builder() .name(name) .modifyDate(modifyDate); } - public void edit(UsersEditor usersEditor) { + public void edit(UserEditor usersEditor) { name = usersEditor.getName(); modifyDate = usersEditor.getModifyDate(); } diff --git a/src/main/java/com/chwipoClova/user/entity/UsersEditor.java b/src/main/java/com/chwipoClova/user/entity/UserEditor.java similarity index 75% rename from src/main/java/com/chwipoClova/user/entity/UsersEditor.java rename to src/main/java/com/chwipoClova/user/entity/UserEditor.java index 0f8402d..3ff8634 100644 --- a/src/main/java/com/chwipoClova/user/entity/UsersEditor.java +++ b/src/main/java/com/chwipoClova/user/entity/UserEditor.java @@ -6,13 +6,13 @@ import java.util.Date; @Getter -public class UsersEditor { +public class UserEditor { private String name; private Date modifyDate; @Builder - public UsersEditor(String name, Date modifyDate) { + public UserEditor(String name, Date modifyDate) { this.name = name; this.modifyDate = modifyDate; }