From 8480987d277310768889b96b4bc715cb549012e9 Mon Sep 17 00:00:00 2001 From: Martin0o0 <8546088@naver.com> Date: Mon, 20 Nov 2023 15:20:47 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=EA=B2=80=EC=83=89=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=ED=99=95=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LearningMaterialRepository.java | 7 ++++++- .../service/LearningMaterialService.java | 21 ++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/teamh/khumon/repository/LearningMaterialRepository.java b/src/main/java/com/teamh/khumon/repository/LearningMaterialRepository.java index 37c8414..6b15e85 100644 --- a/src/main/java/com/teamh/khumon/repository/LearningMaterialRepository.java +++ b/src/main/java/com/teamh/khumon/repository/LearningMaterialRepository.java @@ -1,9 +1,12 @@ package com.teamh.khumon.repository; import com.teamh.khumon.domain.LearningMaterial; +import jakarta.persistence.criteria.Predicate; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -13,5 +16,7 @@ public interface LearningMaterialRepository extends JpaRepository findAllByTitleIsContainingAndMemberId(String search, Long memberId, Pageable pageable); +// Page findAllByTitleIsContainingAndMemberId(String search, Long memberId, Pageable pageable); + + Page findAll(Specification specification, Pageable pageable); } \ No newline at end of file diff --git a/src/main/java/com/teamh/khumon/service/LearningMaterialService.java b/src/main/java/com/teamh/khumon/service/LearningMaterialService.java index 4581ffb..73c4f9a 100644 --- a/src/main/java/com/teamh/khumon/service/LearningMaterialService.java +++ b/src/main/java/com/teamh/khumon/service/LearningMaterialService.java @@ -11,11 +11,13 @@ import com.teamh.khumon.util.AmazonS3Util; import com.teamh.khumon.util.MediaUtil; import com.teamh.khumon.util.ObjectToDtoUtil; +import jakarta.persistence.criteria.*; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.domain.Specification; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; @@ -126,9 +128,9 @@ public ResponseEntity getLearningMaterials(Principal principal, Pageable page log.info("search : " + search); Member member = memberRepository.findByUsername(principal.getName()).orElseThrow(); log.info("member ID : " + member.getId()); - //log.info(learningMaterialRepository.findAllByMemberId(member.getId()).toString()); - Page learningMaterials = learningMaterialRepository.findAllByTitleIsContainingAndMemberId(search, member.getId() , pageable); - //log.info(learningMaterials.getContent().toString()); + Specification specification = search(search, member.getId()); + Page learningMaterials = learningMaterialRepository.findAll(specification, pageable); + List learningMaterialContents = learningMaterials.getContent().stream().map(learningMaterial -> LearningMaterialContent.builder() .id(learningMaterial.getId()) .title(learningMaterial.getTitle()) @@ -181,4 +183,17 @@ public ResponseEntity delete(Principal principal, Long id) { return new ResponseEntity(HttpStatus.OK); } + private Specification search(String kw, Long memberId) { + return (Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) -> { + criteriaQuery.distinct(true); // 중복을 제거 + root.join("member", JoinType.INNER); + Predicate memberIdPredicate = criteriaBuilder.equal(root.get("member").get("id"), memberId); + Predicate searchPredicate = criteriaBuilder.or(criteriaBuilder.like(root.get("title"), "%" + kw + "%"), // 제목 + criteriaBuilder.like(root.get("content"), "%" + kw + "%"), // 내용 + criteriaBuilder.like(root.get("summary"), "%" + kw + "%")); //script + return criteriaBuilder.and(memberIdPredicate, searchPredicate); + + }; + } + } \ No newline at end of file From 17388b66e817743f16aa3f88501210f98a510812 Mon Sep 17 00:00:00 2001 From: Martin0o0 <8546088@naver.com> Date: Mon, 20 Nov 2023 16:28:35 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20nginx=20maxfilesize=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nginx/nginx.conf | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/nginx/nginx.conf b/nginx/nginx.conf index 8c809f7..f01b8f7 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -16,6 +16,10 @@ server { location / { return 301 https://$host$request_uri; } + + proxy_read_timeout 86400s; + proxy_send_timeout 86400s; + client_max_body_size 600M; } @@ -34,6 +38,11 @@ server { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; } + + proxy_read_timeout 86400s; + proxy_send_timeout 86400s; + client_max_body_size 600M; + } From 18a16e5b9d90c28beb29094226a0ee12d65fadee Mon Sep 17 00:00:00 2001 From: Martin0o0 <8546088@naver.com> Date: Mon, 20 Nov 2023 20:35:29 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20content=20type=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 2 ++ src/main/java/com/teamh/khumon/dto/LearningMaterialContent.java | 1 + .../java/com/teamh/khumon/service/LearningMaterialService.java | 1 + 3 files changed, 4 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 5d23b79..26b9ecb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -48,6 +48,8 @@ services: image: redis ports: - 6379:6379 + networks: + - reverseproxy khumon: container_name: khumon image: chy0310/khumon diff --git a/src/main/java/com/teamh/khumon/dto/LearningMaterialContent.java b/src/main/java/com/teamh/khumon/dto/LearningMaterialContent.java index ae4de3f..6b65c8b 100644 --- a/src/main/java/com/teamh/khumon/dto/LearningMaterialContent.java +++ b/src/main/java/com/teamh/khumon/dto/LearningMaterialContent.java @@ -15,6 +15,7 @@ public class LearningMaterialContent { private Long id; private String title; private String content; + private String type; private LocalDateTime createAt; private LocalDateTime modifiedAt; diff --git a/src/main/java/com/teamh/khumon/service/LearningMaterialService.java b/src/main/java/com/teamh/khumon/service/LearningMaterialService.java index 73c4f9a..3da3bda 100644 --- a/src/main/java/com/teamh/khumon/service/LearningMaterialService.java +++ b/src/main/java/com/teamh/khumon/service/LearningMaterialService.java @@ -135,6 +135,7 @@ public ResponseEntity getLearningMaterials(Principal principal, Pageable page .id(learningMaterial.getId()) .title(learningMaterial.getTitle()) .content(learningMaterial.getContent()) + .type(learningMaterial.getMediaFileType().getFileType()) .createAt(learningMaterial.getCreatedAt()) .modifiedAt(learningMaterial.getUpdateAt()) .build()).toList(); From 85094c9828df5037c9052e70b1ded845fb09c6f8 Mon Sep 17 00:00:00 2001 From: Martin0o0 <8546088@naver.com> Date: Mon, 20 Nov 2023 23:46:09 +0900 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=A0=95=EB=8B=B5=20=EC=97=AC=EB=B6=80=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LearningMaterialController.java | 10 +++++++ .../com/teamh/khumon/domain/MyAnswer.java | 26 +++++++++++++++++++ .../com/teamh/khumon/domain/Question.java | 10 +++++++ .../teamh/khumon/dto/MyAnswerAIResponse.java | 19 ++++++++++++++ .../com/teamh/khumon/dto/MyAnswerRequest.java | 16 ++++++++++++ .../teamh/khumon/dto/QuestionInformation.java | 3 +++ .../khumon/repository/MyAnswerRepository.java | 8 ++++++ .../khumon/repository/QuestionRepository.java | 3 +++ .../service/LearningMaterialService.java | 22 ++++++++++++++-- .../khumon/service/QuestionAnswerService.java | 20 +++++++++++--- .../java/com/teamh/khumon/util/MediaUtil.java | 22 ++++++++++++++++ 11 files changed, 153 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/teamh/khumon/domain/MyAnswer.java create mode 100644 src/main/java/com/teamh/khumon/dto/MyAnswerAIResponse.java create mode 100644 src/main/java/com/teamh/khumon/dto/MyAnswerRequest.java create mode 100644 src/main/java/com/teamh/khumon/repository/MyAnswerRepository.java diff --git a/src/main/java/com/teamh/khumon/controller/LearningMaterialController.java b/src/main/java/com/teamh/khumon/controller/LearningMaterialController.java index 798c7ee..92f2f02 100644 --- a/src/main/java/com/teamh/khumon/controller/LearningMaterialController.java +++ b/src/main/java/com/teamh/khumon/controller/LearningMaterialController.java @@ -1,8 +1,10 @@ package com.teamh.khumon.controller; import com.teamh.khumon.dto.ModifyLearningMaterialRequest; +import com.teamh.khumon.dto.MyAnswerRequest; import com.teamh.khumon.service.LearningMaterialService; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.web.PageableDefault; @@ -17,6 +19,7 @@ @RestController @RequiredArgsConstructor +@Slf4j @RequestMapping("/api") public class LearningMaterialController { @@ -54,5 +57,12 @@ public ResponseEntity modifyLearningMaterials(Principal principal, @PathVaria public ResponseEntity deleteLearning(Principal principal,@PathVariable(name ="learning-material-id")Long id){ return learningMaterialService.delete(principal, id); } + + @PreAuthorize("isAuthenticated()") + @PostMapping("/learning-material/{learning-material-id}/question/{question-id}") + public ResponseEntity postMyAnswer(Principal principal, @PathVariable(name="learning-material-id") Long learningMaterialId, @PathVariable(name="question-id") Long myanswerId, @RequestBody MyAnswerRequest myAnswerRequest) throws Exception { + log.info("엔드포인트 지남"); + return learningMaterialService.postMyAnswer(principal, learningMaterialId, myanswerId, myAnswerRequest); + } } diff --git a/src/main/java/com/teamh/khumon/domain/MyAnswer.java b/src/main/java/com/teamh/khumon/domain/MyAnswer.java new file mode 100644 index 0000000..98d3d23 --- /dev/null +++ b/src/main/java/com/teamh/khumon/domain/MyAnswer.java @@ -0,0 +1,26 @@ +//package com.teamh.khumon.domain; +// +// +//import jakarta.persistence.*; +//import lombok.*; +// +//@Entity +//@Getter +//@Setter +//@AllArgsConstructor +//@NoArgsConstructor +//@Builder +//public class MyAnswer { +// @Id +// @GeneratedValue(strategy = GenerationType.IDENTITY) +// private Long id; +// +// @Column +// private String myAnswer; +// +// @Column +// private Boolean isCorrect; +// +// @OneToOne(mappedBy = "answer") +// private Question question; +//} diff --git a/src/main/java/com/teamh/khumon/domain/Question.java b/src/main/java/com/teamh/khumon/domain/Question.java index f1fc632..a4c4947 100644 --- a/src/main/java/com/teamh/khumon/domain/Question.java +++ b/src/main/java/com/teamh/khumon/domain/Question.java @@ -27,6 +27,16 @@ public class Question extends BaseEntity { @JoinColumn(name = "answer_id") private Answer answer; +// @OneToOne(orphanRemoval = true, cascade = CascadeType.REMOVE) +// @JoinColumn(name = "my_answer_id") +// private MyAnswer myAnswer; + + private String myAnswer; + private String whatWrong; + private Boolean isCorrect; + + + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") @ToString.Exclude diff --git a/src/main/java/com/teamh/khumon/dto/MyAnswerAIResponse.java b/src/main/java/com/teamh/khumon/dto/MyAnswerAIResponse.java new file mode 100644 index 0000000..8d057ab --- /dev/null +++ b/src/main/java/com/teamh/khumon/dto/MyAnswerAIResponse.java @@ -0,0 +1,19 @@ +package com.teamh.khumon.dto; + + +import lombok.*; + +@Builder +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class MyAnswerAIResponse { + private String assessment; + private Boolean correct; +} + + +//question : STring +//answer: STring diff --git a/src/main/java/com/teamh/khumon/dto/MyAnswerRequest.java b/src/main/java/com/teamh/khumon/dto/MyAnswerRequest.java new file mode 100644 index 0000000..8c84f2f --- /dev/null +++ b/src/main/java/com/teamh/khumon/dto/MyAnswerRequest.java @@ -0,0 +1,16 @@ +package com.teamh.khumon.dto; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class MyAnswerRequest { + + private String content; +} diff --git a/src/main/java/com/teamh/khumon/dto/QuestionInformation.java b/src/main/java/com/teamh/khumon/dto/QuestionInformation.java index 2cae044..df50e6f 100644 --- a/src/main/java/com/teamh/khumon/dto/QuestionInformation.java +++ b/src/main/java/com/teamh/khumon/dto/QuestionInformation.java @@ -10,5 +10,8 @@ public class QuestionInformation { private Long id; private String content; + private String myAnswer; + private boolean isCorrect; + private String whatWrong; private String answer; } diff --git a/src/main/java/com/teamh/khumon/repository/MyAnswerRepository.java b/src/main/java/com/teamh/khumon/repository/MyAnswerRepository.java new file mode 100644 index 0000000..c9c3aca --- /dev/null +++ b/src/main/java/com/teamh/khumon/repository/MyAnswerRepository.java @@ -0,0 +1,8 @@ +//package com.teamh.khumon.repository; +// +//import com.teamh.khumon.domain.MyAnswer; +//import org.springframework.data.jpa.repository.JpaRepository; +// +//public interface MyAnswerRepository extends JpaRepository { +// +//} diff --git a/src/main/java/com/teamh/khumon/repository/QuestionRepository.java b/src/main/java/com/teamh/khumon/repository/QuestionRepository.java index 4ad0480..edebe3b 100644 --- a/src/main/java/com/teamh/khumon/repository/QuestionRepository.java +++ b/src/main/java/com/teamh/khumon/repository/QuestionRepository.java @@ -3,5 +3,8 @@ import com.teamh.khumon.domain.Question; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface QuestionRepository extends JpaRepository { + Optional findById(Long id); } diff --git a/src/main/java/com/teamh/khumon/service/LearningMaterialService.java b/src/main/java/com/teamh/khumon/service/LearningMaterialService.java index 3da3bda..0fb0a2d 100644 --- a/src/main/java/com/teamh/khumon/service/LearningMaterialService.java +++ b/src/main/java/com/teamh/khumon/service/LearningMaterialService.java @@ -8,6 +8,7 @@ import com.teamh.khumon.dto.*; import com.teamh.khumon.repository.LearningMaterialRepository; import com.teamh.khumon.repository.MemberRepository; +import com.teamh.khumon.repository.QuestionRepository; import com.teamh.khumon.util.AmazonS3Util; import com.teamh.khumon.util.MediaUtil; import com.teamh.khumon.util.ObjectToDtoUtil; @@ -41,7 +42,7 @@ public class LearningMaterialService { private final QuestionAnswerService questionAnswerService; - + private final QuestionRepository questionRepository; private final MediaUtil mediaUtil; private final AmazonS3Util amazonS3Util; @@ -103,6 +104,9 @@ public ResponseEntity getLearningMaterial(Long id, Principal principal) { List responses = learningMaterial.getQuestions().stream().map(question-> QuestionInformation.builder() .id(question.getId()) .content(question.getContent()) + .myAnswer(question.getMyAnswer() == null ? null : question.getMyAnswer()) + .isCorrect(question.getIsCorrect() != null && question.getIsCorrect()) + .whatWrong(question.getWhatWrong() == null ? null : question.getWhatWrong()) .answer(question.getAnswer().getAnswer()) .build()).toList(); @@ -193,8 +197,22 @@ private Specification search(String kw, Long memberId) { criteriaBuilder.like(root.get("content"), "%" + kw + "%"), // 내용 criteriaBuilder.like(root.get("summary"), "%" + kw + "%")); //script return criteriaBuilder.and(memberIdPredicate, searchPredicate); - }; } + public ResponseEntity postMyAnswer(Principal principal, Long learningMaterialId, Long questionId, MyAnswerRequest myAnswerRequest) throws Exception { + LearningMaterial learningMaterial = learningMaterialRepository.findById(learningMaterialId).orElseThrow(); + if(!principal.getName().equals(learningMaterial.getMember().getUsername())){ + throw new RuntimeException("작성자가 아님"); + } + Question question = questionRepository.findById(questionId).orElseThrow(); + String myanswerResponse = mediaUtil.postToLLMforUserAnswer(myAnswerRequest, question.getContent()); + MyAnswerAIResponse myAnswerAIResponse = (MyAnswerAIResponse) new ObjectToDtoUtil().jsonStrToObj(myanswerResponse, MyAnswerAIResponse.class); + log.info(myAnswerAIResponse.toString()); + + Long id = questionAnswerService.postMyAnswer(questionId, myAnswerRequest, myAnswerAIResponse); + Map response = new HashMap<>(); + response.put("questionId", id); + return new ResponseEntity<>(response, HttpStatus.CREATED); + } } \ No newline at end of file diff --git a/src/main/java/com/teamh/khumon/service/QuestionAnswerService.java b/src/main/java/com/teamh/khumon/service/QuestionAnswerService.java index 60f572e..9be6ef7 100644 --- a/src/main/java/com/teamh/khumon/service/QuestionAnswerService.java +++ b/src/main/java/com/teamh/khumon/service/QuestionAnswerService.java @@ -1,12 +1,12 @@ package com.teamh.khumon.service; -import com.teamh.khumon.domain.Answer; -import com.teamh.khumon.domain.LearningMaterial; -import com.teamh.khumon.domain.Member; -import com.teamh.khumon.domain.Question; +import com.teamh.khumon.domain.*; import com.teamh.khumon.dto.AIResponse; +import com.teamh.khumon.dto.MyAnswerAIResponse; +import com.teamh.khumon.dto.MyAnswerRequest; import com.teamh.khumon.dto.Problem; import com.teamh.khumon.repository.AnswerRepository; + import com.teamh.khumon.repository.QuestionRepository; import lombok.Builder; import lombok.RequiredArgsConstructor; @@ -26,6 +26,8 @@ public class QuestionAnswerService { private final AnswerRepository answerRepository; +// private final MyAnswerRepository myAnswerRepository; + @Transactional public List saveQuestionAndAnswer(AIResponse aiResponse, Member member, LearningMaterial learningMaterial){ List problems = aiResponse.getProblems(); @@ -52,4 +54,14 @@ void deleteQuestionAndAnswer(LearningMaterial learningMaterial){ questionRepository.deleteAll(questionList); } + + @Transactional + public Long postMyAnswer(Long questionId, MyAnswerRequest myAnswerRequest, MyAnswerAIResponse myAnswerAIResponse) { + Question question = questionRepository.findById(questionId).orElseThrow(); + question.setMyAnswer(myAnswerRequest.getContent()); + question.setIsCorrect(myAnswerAIResponse.getCorrect()); + question.setWhatWrong(myAnswerAIResponse.getAssessment()); + questionRepository.save(question); + return questionId; + } } diff --git a/src/main/java/com/teamh/khumon/util/MediaUtil.java b/src/main/java/com/teamh/khumon/util/MediaUtil.java index d9fa13e..85b96cd 100644 --- a/src/main/java/com/teamh/khumon/util/MediaUtil.java +++ b/src/main/java/com/teamh/khumon/util/MediaUtil.java @@ -1,6 +1,8 @@ package com.teamh.khumon.util; import com.teamh.khumon.domain.MediaFileType; +import com.teamh.khumon.domain.Question; +import com.teamh.khumon.dto.MyAnswerRequest; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.json.JSONException; @@ -153,6 +155,26 @@ public String postToLLMforVideo(MultipartFile multipartFile) throws Exception { } + public String postToLLMforUserAnswer(MyAnswerRequest myAnswerRequest, String question) throws Exception { + String postUrl = "http://facerain-dev.iptime.org:5000/api/v1/generation/assessment"; + RestTemplate restTemplate = new RestTemplate(); + + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("question", question); + jsonObject.put("answer", myAnswerRequest.getContent()); + +//question : STring +//answer: STring + HttpEntity requestHttpEntity = + new HttpEntity<>(jsonObject.toString(), httpHeaders); + String response = restTemplate.postForObject(postUrl, requestHttpEntity, String.class); + log.info(response); + return response; + } + + public void deleteMediaFile(String filePath) { File savedFile = new File(filePath);