From 2a5f90d046dd410ff75865029780416bbbdfa19f Mon Sep 17 00:00:00 2001 From: sangminee Date: Sun, 28 May 2023 00:34:06 +0900 Subject: [PATCH] =?UTF-8?q?[#16]=20feat=20:=20=EA=B0=95=EC=9D=98=20?= =?UTF-8?q?=EB=8B=B5=EB=B3=80=20CRD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 + .../application/lecture/LectureService.java | 6 +++ .../lecture/LectureServiceImpl.java | 53 +++++++++++++++++++ .../domain/model/lecture/LectureAnswer.java | 17 +++++- .../model/lecture/LectureAnswerPhoto.java | 16 +++++- .../domain/service/LectureDomainService.java | 28 ++++++---- .../controller/LectureController.java | 40 ++++++++++---- .../controller/RequestController.java | 4 ++ .../dto/request/AnswerCreateDto.java | 13 +++++ .../dto/response/LectureAnswerReadDto.java | 13 +++++ 10 files changed, 168 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/mju/course/presentation/controller/RequestController.java create mode 100644 src/main/java/com/mju/course/presentation/dto/request/AnswerCreateDto.java diff --git a/build.gradle b/build.gradle index 1cc7fde..299d073 100644 --- a/build.gradle +++ b/build.gradle @@ -69,6 +69,8 @@ dependencies { // 다중 파일 처리 implementation 'commons-io:commons-io:2.6' + + implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' } dependencyManagement { diff --git a/src/main/java/com/mju/course/application/lecture/LectureService.java b/src/main/java/com/mju/course/application/lecture/LectureService.java index 789b16e..e38d839 100644 --- a/src/main/java/com/mju/course/application/lecture/LectureService.java +++ b/src/main/java/com/mju/course/application/lecture/LectureService.java @@ -1,6 +1,7 @@ package com.mju.course.application.lecture; import com.mju.course.domain.model.other.Result.CommonResult; +import com.mju.course.presentation.dto.request.AnswerCreateDto; import com.mju.course.presentation.dto.request.LectureQuestionCreateDto; import org.springframework.data.domain.Pageable; import org.springframework.web.multipart.MultipartFile; @@ -12,10 +13,15 @@ public interface LectureService { CommonResult readQAndA(Long question_index); CommonResult readQuestions(Long lecture_index, Pageable pageable); + CommonResult readAnswer(Long lecture_answer_index); CommonResult createQuestion(Long lecture_index, List images, LectureQuestionCreateDto lectureQuestionCreateDto); CommonResult updateQuestion(Long question_index); CommonResult deleteQuestion(Long question_index); CommonResult lectureQuestionBookmark(Long question_index, Long userId); + + CommonResult createAnswer(Long question_index, List images, AnswerCreateDto answerCreateDto); + CommonResult deleteAnswer(Long lecture_answer_index); + } diff --git a/src/main/java/com/mju/course/application/lecture/LectureServiceImpl.java b/src/main/java/com/mju/course/application/lecture/LectureServiceImpl.java index d0ba12e..b6ac2bb 100644 --- a/src/main/java/com/mju/course/application/lecture/LectureServiceImpl.java +++ b/src/main/java/com/mju/course/application/lecture/LectureServiceImpl.java @@ -11,6 +11,7 @@ import com.mju.course.domain.repository.lecture.*; import com.mju.course.domain.service.LectureDomainService; import com.mju.course.domain.service.ResponseService; +import com.mju.course.presentation.dto.request.AnswerCreateDto; import com.mju.course.presentation.dto.request.LectureQuestionCreateDto; import com.mju.course.presentation.dto.response.LectureAnswerReadDto; import com.mju.course.presentation.dto.response.LectureQAndAReadDto; @@ -113,6 +114,16 @@ public CommonResult readQuestions(Long lecture_index, Pageable pageable) { return responseService.getSingleResult(result); } + /** 강의 답변 하나보기 + * @param lecture_answer_index + */ + @Override + public CommonResult readAnswer(Long lecture_answer_index) { + LectureAnswer lectureAnswer = lectureAnswerRepository.findById(lecture_answer_index) + .orElseThrow(()-> new CourseException(NOT_EXISTENT_LECTURE_ANSWER)); + return responseService.getSingleResult(LectureAnswerReadDto.of(lectureAnswer)); + } + /** 강의 질문 작성하기 * @param lecture_index * @param images @@ -186,4 +197,46 @@ public CommonResult lectureQuestionBookmark(Long question_index, Long userId) { } + /** 강의 질문 답변 달기 + * @param question_index + * @param images + * @param answerCreateDto + */ + @Override + @Transactional + public CommonResult createAnswer(Long question_index, List images, AnswerCreateDto answerCreateDto) { + LectureQuestion lectureQuestion = lectureQuestionRepository.findById(question_index) + .orElseThrow(()-> new CourseException(NOT_EXISTENT_LECTURE_QUESTION)); + User user = userRepository.findById(answerCreateDto.getUserId()).get(); + + LectureAnswer lectureAnswer = LectureAnswer.of(lectureQuestion, user, answerCreateDto.getAnswer()); + LectureAnswer saveAnswer = lectureAnswerRepository.save(lectureAnswer); + + // 사진 등록 + if(images != null){ + images.forEach(s->{ + try { + String basicFileName = UUID.randomUUID().toString(); + String dirName = "answer/" + String.valueOf(lectureQuestion.getId()) +"/"+String.valueOf(saveAnswer.getId()); + String questionPhotoKey = s3UploaderService.upload(s, dirName, basicFileName); + LectureAnswerPhoto lectureAnswerPhoto = LectureAnswerPhoto.of(saveAnswer, questionPhotoKey); + lectureAnswerPhotoRepository.save(lectureAnswerPhoto); + } catch (IOException e) { + e.printStackTrace(); + } + }); + } + return responseService.getSuccessfulResult(); + } + + /** 강의 질문 답변 삭제 + * @param lecture_answer_index + */ + @Override + @Transactional + public CommonResult deleteAnswer(Long lecture_answer_index) { + lectureDomainService.deleteAnswer(lecture_answer_index); + return responseService.getSuccessfulResult(); + } + } diff --git a/src/main/java/com/mju/course/domain/model/lecture/LectureAnswer.java b/src/main/java/com/mju/course/domain/model/lecture/LectureAnswer.java index d9f1ce7..671fab5 100644 --- a/src/main/java/com/mju/course/domain/model/lecture/LectureAnswer.java +++ b/src/main/java/com/mju/course/domain/model/lecture/LectureAnswer.java @@ -3,6 +3,7 @@ import com.mju.course.domain.model.BaseTimeEntity; import com.mju.course.domain.model.User; import jakarta.persistence.*; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -33,5 +34,19 @@ public class LectureAnswer extends BaseTimeEntity { // 양방향 매핑 @OneToMany(mappedBy = "lectureAnswer") private List lectureAnswerPhotoList = new ArrayList<>(); - + + @Builder + public LectureAnswer(LectureQuestion lectureQuestion, User user, String lectureAnswer) { + this.lectureQuestion = lectureQuestion; + this.user = user; + this.lectureAnswer = lectureAnswer; + } + + public static LectureAnswer of(LectureQuestion lectureQuestion, User user, String answer) { + return LectureAnswer.builder() + .lectureQuestion(lectureQuestion) + .user(user) + .lectureAnswer(answer) + .build(); + } } diff --git a/src/main/java/com/mju/course/domain/model/lecture/LectureAnswerPhoto.java b/src/main/java/com/mju/course/domain/model/lecture/LectureAnswerPhoto.java index 8105d10..1955a0e 100644 --- a/src/main/java/com/mju/course/domain/model/lecture/LectureAnswerPhoto.java +++ b/src/main/java/com/mju/course/domain/model/lecture/LectureAnswerPhoto.java @@ -1,8 +1,8 @@ package com.mju.course.domain.model.lecture; import com.mju.course.domain.model.BaseTimeEntity; -import com.mju.course.domain.model.User; import jakarta.persistence.*; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -22,5 +22,17 @@ public class LectureAnswerPhoto extends BaseTimeEntity { @Column(name = "lecture_answer_photo_key") private String lectureAnswerPhotoKey; - + + @Builder + public LectureAnswerPhoto(LectureAnswer lectureAnswer, String lectureAnswerPhotoKey) { + this.lectureAnswer = lectureAnswer; + this.lectureAnswerPhotoKey = lectureAnswerPhotoKey; + } + + public static LectureAnswerPhoto of(LectureAnswer saveAnswer, String questionPhotoKey) { + return LectureAnswerPhoto.builder() + .lectureAnswer(saveAnswer) + .lectureAnswerPhotoKey(questionPhotoKey) + .build(); + } } diff --git a/src/main/java/com/mju/course/domain/service/LectureDomainService.java b/src/main/java/com/mju/course/domain/service/LectureDomainService.java index 53e261b..5c0a73b 100644 --- a/src/main/java/com/mju/course/domain/service/LectureDomainService.java +++ b/src/main/java/com/mju/course/domain/service/LectureDomainService.java @@ -2,6 +2,7 @@ import com.mju.course.application.S3UploaderService; import com.mju.course.domain.model.lecture.Lecture; +import com.mju.course.domain.model.lecture.LectureAnswer; import com.mju.course.domain.model.lecture.LectureQuestion; import com.mju.course.domain.model.other.Exception.CourseException; import com.mju.course.domain.repository.UserRepository; @@ -36,7 +37,6 @@ public class LectureDomainService { * 강의 삭제 * @param lecture_index * */ - @Transactional public void deleteLecture(Long lecture_index){ Lecture lecture = lectureRepository.findById(lecture_index) .orElseThrow(() -> new CourseException(NOT_EXISTENT_LECTURE)); @@ -56,7 +56,6 @@ public void deleteLecture(Long lecture_index){ /** 강의 질문 삭제 * @param question_index */ - @Transactional public void deleteQuestion(Long question_index){ LectureQuestion lectureQuestion = lectureQuestionRepository.findById(question_index) .orElseThrow(()-> new CourseException(NOT_EXISTENT_LECTURE_QUESTION)); @@ -77,16 +76,25 @@ public void deleteQuestion(Long question_index){ if(lectureQuestion.getLectureAnswerList().size() != 0){ lectureQuestion.getLectureAnswerList() .forEach(lectureAnswer -> { - // 강의 답변 관련 사진 삭제 - lectureAnswer.getLectureAnswerPhotoList() - .forEach(lectureAnswerPhoto -> { - s3UploaderService.deleteS3File(lectureAnswerPhoto.getLectureAnswerPhotoKey()); - lectureAnswerPhotoRepository.delete(lectureAnswerPhoto); - }); - // 강의 답변 삭제 - lectureAnswerRepository.delete(lectureAnswer); + deleteAnswer(lectureAnswer.getId()); }); } } + /** 강의 질문 답변 삭제 + * @param lecture_answer_index + */ + public void deleteAnswer(Long lecture_answer_index) { + LectureAnswer lectureAnswer = lectureAnswerRepository.findById(lecture_answer_index) + .orElseThrow(()-> new CourseException(NOT_EXISTENT_LECTURE_ANSWER)); + // 강의 답변 관련 사진 삭제 + lectureAnswer.getLectureAnswerPhotoList() + .forEach(content->{ + s3UploaderService.deleteS3File(content.getLectureAnswerPhotoKey()); + lectureAnswerPhotoRepository.delete(content); + }); + // 강의 답변 삭제 + lectureAnswerRepository.delete(lectureAnswer); + } + } diff --git a/src/main/java/com/mju/course/presentation/controller/LectureController.java b/src/main/java/com/mju/course/presentation/controller/LectureController.java index 223475e..ec64949 100644 --- a/src/main/java/com/mju/course/presentation/controller/LectureController.java +++ b/src/main/java/com/mju/course/presentation/controller/LectureController.java @@ -4,7 +4,7 @@ import com.mju.course.application.UserServiceImpl; import com.mju.course.domain.model.enums.UserType; import com.mju.course.domain.model.other.Result.CommonResult; -import com.mju.course.presentation.dto.request.LectureQuestionCreateDto; +import com.mju.course.presentation.dto.request.*; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; @@ -12,7 +12,6 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.MultipartHttpServletRequest; import java.util.List; @@ -50,7 +49,13 @@ public CommonResult readQuestions(@PathVariable Long lecture_index, return lectureService.readQuestions(lecture_index, pageable); } - // 강의 질문 CUD + @Operation(summary = "강의 답변 하나보기", description = "강의 답변 하나보기 API 입니다. ") + @GetMapping("/answer/{lecture_answer_index}") + public CommonResult readAnswer(@PathVariable Long lecture_answer_index){ + return lectureService.readAnswer(lecture_answer_index); + } + + // 강의 질문 CD @Operation(summary = "강의 질문 작성하기", description = "강의 질문 작성하기 API 입니다. ") @PostMapping("/{lecture_index}/question") public CommonResult createQuestion(@PathVariable Long lecture_index, @@ -59,7 +64,6 @@ public CommonResult createQuestion(@PathVariable Long lecture_index, return lectureService.createQuestion(lecture_index, images, lectureQuestionCreateDto); } -// // 개발 필요 // @Operation(summary = "강의 질문 수정하기", description = "강의 질문 수정하기 API 입니다. ") // @PutMapping("/question/{question_index}") // public CommonResult updateQuestion(@PathVariable Long question_index){ @@ -80,13 +84,27 @@ public CommonResult lectureQuestionBookmark(@PathVariable Long question_index, return lectureService.lectureQuestionBookmark(question_index,userId); } -// // 강의 답변 CUD -// @Operation(summary = "강의 답변 작성하기", description = "강의 답변 작성하기 API 입니다. ") -// @PostMapping("/{question_index}/answer") -// public CommonResult createAnswer(@PathVariable Long question_index, -// @RequestPart(value="images", required=false) List images, -// @RequestPart(value="lectureQuestionDto") @Validated LectureQuestionCreateDto lectureQuestionCreateDto){ -// return lectureService.createAnswer(question_index, images, lectureQuestionCreateDto); + // 강의 답변 CD + @Operation(summary = "강의 답변 작성하기", description = "강의 답변 작성하기 API 입니다. ") + @PostMapping("/{question_index}/answer") + public CommonResult createAnswer(@PathVariable Long question_index, + @RequestPart(value="images", required=false) List images, + @RequestPart(value="answerCreateDto") AnswerCreateDto answerCreateDto){ + return lectureService.createAnswer(question_index, images, answerCreateDto); + } + +// @Operation(summary = "강의 답변 수정하기", description = "강의 답변 작성하기 API 입니다. ") +// @PutMapping("/answer/{lecture_answer_index}") +// public CommonResult updateAnswer(@PathVariable Long lecture_answer_index, +// @RequestPart(value="images", required=false) List images, +// @RequestPart(value="lectureAnswerCreateDto") @Validated LectureAnswerCreateDto lectureAnswerCreateDto){ +// return lectureService.updateAnswer(lecture_answer_index, images, lectureAnswerCreateDto); // } + @Operation(summary = "강의 답변 삭제하기", description = "강의 답변 삭제하기 API 입니다. ") + @DeleteMapping("/answer/{lecture_answer_index}") + public CommonResult deleteAnswer(@PathVariable Long lecture_answer_index){ + return lectureService.deleteAnswer(lecture_answer_index); + } + } diff --git a/src/main/java/com/mju/course/presentation/controller/RequestController.java b/src/main/java/com/mju/course/presentation/controller/RequestController.java new file mode 100644 index 0000000..bebaea7 --- /dev/null +++ b/src/main/java/com/mju/course/presentation/controller/RequestController.java @@ -0,0 +1,4 @@ +package com.mju.course.presentation.controller; + +public class RequestController { +} diff --git a/src/main/java/com/mju/course/presentation/dto/request/AnswerCreateDto.java b/src/main/java/com/mju/course/presentation/dto/request/AnswerCreateDto.java new file mode 100644 index 0000000..de728ee --- /dev/null +++ b/src/main/java/com/mju/course/presentation/dto/request/AnswerCreateDto.java @@ -0,0 +1,13 @@ +package com.mju.course.presentation.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class AnswerCreateDto { + private Long userId; + private String answer; +} diff --git a/src/main/java/com/mju/course/presentation/dto/response/LectureAnswerReadDto.java b/src/main/java/com/mju/course/presentation/dto/response/LectureAnswerReadDto.java index cfe03ab..f62b249 100644 --- a/src/main/java/com/mju/course/presentation/dto/response/LectureAnswerReadDto.java +++ b/src/main/java/com/mju/course/presentation/dto/response/LectureAnswerReadDto.java @@ -1,6 +1,7 @@ package com.mju.course.presentation.dto.response; import com.mju.course.domain.model.lecture.LectureAnswer; +import com.mju.course.domain.model.lecture.LectureAnswerPhoto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; @@ -8,6 +9,8 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; @Getter @AllArgsConstructor @@ -26,12 +29,22 @@ public class LectureAnswerReadDto { @Schema(description = "답변 시간") private LocalDateTime createdAt; + @Schema(description = "답변 사진") + private List lectureAnswerPhotoList; + public static LectureAnswerReadDto of(LectureAnswer lectureAnswer) { + List lectureAnswerPhotoList = new ArrayList<>(); + lectureAnswer.getLectureAnswerPhotoList() + .forEach(content->{ + lectureAnswerPhotoList.add("https://d19wla4ff811v8.cloudfront.net/" + content.getLectureAnswerPhotoKey()); + }); + return LectureAnswerReadDto.builder() .lectureAnswerIndex(lectureAnswer.getId()) .username("답변자") .lectureAnswer(lectureAnswer.getLectureAnswer()) .createdAt(lectureAnswer.getCreatedAt()) + .lectureAnswerPhotoList(lectureAnswerPhotoList) .build(); } }