diff --git a/.github/workflows/change-pr-target.yaml b/.github/workflows/change-pr-target.yaml new file mode 100644 index 0000000..b7e76f6 --- /dev/null +++ b/.github/workflows/change-pr-target.yaml @@ -0,0 +1,28 @@ +name: Change PR target if base branch is master + +on: + pull_request: + types: + - opened + - synchronize + - reopened + branches: + - master + +jobs: + change-pr-target: + runs-on: ubuntu-latest + steps: + - name: Set target environment variable + run: | + if [[ "${GITHUB_HEAD_REF}" == fe* || "${GITHUB_HEAD_REF}" == FE* ]]; then + echo "target=frontend" >> $GITHUB_ENV + elif [[ "${GITHUB_HEAD_REF}" == be* || "${GITHUB_HEAD_REF}" == BE* ]]; then + echo "target=backend" >> $GITHUB_ENV + fi + + - name: Change base branch for PR + if: env.target == 'frontend' || env.target == 'backend' + run: gh pr edit ${{ github.event.pull_request.number }} --base ${{ env.target }} --repo ${{ github.repository }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/backend/build.gradle b/backend/build.gradle index b21a1da..62702e7 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -21,6 +21,7 @@ dependencies { implementation 'io.livekit:livekit-server:0.5.11' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'mysql:mysql-connector-java:8.0.33' + implementation 'org.springframework.boot:spring-boot-starter-websocket' testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation group: 'io.livekit', name: 'livekit-server', version: '0.6.1' implementation 'org.projectlombok:lombok' @@ -29,6 +30,10 @@ dependencies { runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5' runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5' implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5' + implementation group: 'org.springframework.boot', name: 'spring-boot-starter-mail', version: '3.2.5' + implementation 'org.springframework.boot:spring-boot-starter-mail' + + implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '4.0.5' diff --git a/backend/src/main/java/com/edufocus/edufocus/board/controller/BoardController.java b/backend/src/main/java/com/edufocus/edufocus/board/controller/BoardController.java index d25d940..a1ead74 100644 --- a/backend/src/main/java/com/edufocus/edufocus/board/controller/BoardController.java +++ b/backend/src/main/java/com/edufocus/edufocus/board/controller/BoardController.java @@ -30,22 +30,18 @@ public class BoardController { } @GetMapping() - public ResponseEntity searchBoards( + public ResponseEntity> searchBoards( @RequestParam(value = "category", required = false, defaultValue = "announcement") String category, - @RequestParam(value = "lectureId", required = true) long lectureId, + @RequestParam(value = "lectureId") long lectureId, @RequestParam(value = "pageNo", required = false, defaultValue = "0") int pageNo ){ List boardSummaries = boardService.findBoards(pageNo, category, lectureId); - if(boardSummaries.isEmpty()){ - return new ResponseEntity<>(HttpStatus.NO_CONTENT); - } - return new ResponseEntity<>(boardSummaries, HttpStatus.OK); } @GetMapping(value = "/{boardId}") - public ResponseEntity getBoardDetail( + public ResponseEntity getBoardDetail( @PathVariable int boardId ){ ResponseBoardDetailDto responseBoardDetailDto = boardService.findBoardDetail(boardId); @@ -87,7 +83,7 @@ public class BoardController { } @GetMapping(value = "/comment/{boardId}") - public ResponseEntity getComments( + public ResponseEntity> getComments( @PathVariable int boardId ){ List comments = boardService.findComments(boardId); @@ -127,4 +123,10 @@ public class BoardController { return new ResponseEntity<>(HttpStatus.OK); } + + + @ExceptionHandler() + public ResponseEntity NoContentException(Exception exception){ + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } } diff --git a/backend/src/main/java/com/edufocus/edufocus/board/service/BoardServiceImpl.java b/backend/src/main/java/com/edufocus/edufocus/board/service/BoardServiceImpl.java index 29c5006..4e047f9 100644 --- a/backend/src/main/java/com/edufocus/edufocus/board/service/BoardServiceImpl.java +++ b/backend/src/main/java/com/edufocus/edufocus/board/service/BoardServiceImpl.java @@ -16,6 +16,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.NoSuchElementException; import java.util.stream.Collectors; @Service @@ -49,14 +50,14 @@ public class BoardServiceImpl implements BoardService { @Transactional public ResponseBoardDetailDto findBoardDetail(long boardId) { return boardRepository.findById(boardId) - .orElseThrow() + .orElseThrow(NoSuchElementException::new) .makeDetailDto(); } @Transactional public void createBoard(long userId, RequestBoardDto requestBoardDto) { - User user = userRepository.findById(userId).orElseThrow(); - Lecture lecture = lectureRepository.findById(requestBoardDto.getLectureId()).get(); + User user = userRepository.getReferenceById(userId); + Lecture lecture = lectureRepository.getReferenceById(requestBoardDto.getLectureId()); Board board = Board.builder() .title(requestBoardDto.getTitle()) @@ -71,7 +72,7 @@ public class BoardServiceImpl implements BoardService { @Transactional public void updateBoard(long boardId, RequestBoardUpdateDto requestBoardUpdateDto) { - Board board = boardRepository.findById(boardId).get(); + Board board = boardRepository.findById(boardId).orElseThrow(IllegalArgumentException::new); board.setTitle(requestBoardUpdateDto.getTitle()); board.setContent(requestBoardUpdateDto.getContent()); @@ -82,7 +83,7 @@ public class BoardServiceImpl implements BoardService { @Transactional public void deleteBoard(long boardId) { - Board board = boardRepository.findById(boardId).get(); + Board board = boardRepository.getReferenceById(boardId); boardRepository.delete(board); } @@ -96,8 +97,8 @@ public class BoardServiceImpl implements BoardService { @Transactional public void createComment(long userId, long boardId, RequestCommentDto requestCommentDto) { - User user = userRepository.findById(userId).get(); - Board board = boardRepository.findById(boardId).get(); + User user = userRepository.getReferenceById(userId); + Board board = boardRepository.getReferenceById(boardId); Comment comment = Comment.builder() .content(requestCommentDto.getContent()) @@ -112,7 +113,7 @@ public class BoardServiceImpl implements BoardService { @Transactional public void updateComment(long commentId, RequestCommentDto requestCommentDto) { - Comment comment = commentRepository.findById(commentId).get(); + Comment comment = commentRepository.findById(commentId).orElseThrow(IllegalArgumentException::new); comment.setContent(requestCommentDto.getContent()); @@ -121,7 +122,7 @@ public class BoardServiceImpl implements BoardService { @Transactional public void deleteComment(long commentId) { - Comment comment = commentRepository.findById(commentId).get(); + Comment comment = commentRepository.getReferenceById(commentId); commentRepository.delete(comment); } diff --git a/backend/src/main/java/com/edufocus/edufocus/lecture/controller/LectureController.java b/backend/src/main/java/com/edufocus/edufocus/lecture/controller/LectureController.java index e532525..b1895d5 100644 --- a/backend/src/main/java/com/edufocus/edufocus/lecture/controller/LectureController.java +++ b/backend/src/main/java/com/edufocus/edufocus/lecture/controller/LectureController.java @@ -1,20 +1,23 @@ package com.edufocus.edufocus.lecture.controller; +import com.edufocus.edufocus.lecture.entity.Lecture; import com.edufocus.edufocus.lecture.entity.LectureCreateRequest; import com.edufocus.edufocus.lecture.entity.LectureSearchResponse; import com.edufocus.edufocus.lecture.entity.LectureDetailResponse; import com.edufocus.edufocus.lecture.service.LectureService; -import com.edufocus.edufocus.user.model.entity.User; -import com.edufocus.edufocus.user.model.service.UserService; -import com.edufocus.edufocus.user.model.service.UserServiceImpl; import com.edufocus.edufocus.user.util.JWTUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import java.io.File; +import java.io.IOException; import java.util.List; +import java.util.UUID; @RestController @RequestMapping("/lecture") @@ -24,20 +27,44 @@ public class LectureController { private final LectureService lectureService; private final JWTUtil jwtUtil; - private final UserService userService; - @PostMapping - public ResponseEntity createLecture(@RequestHeader("Authorization") String accessToken, @RequestBody LectureCreateRequest lectureCreateRequest) { + @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public ResponseEntity createLecture(@RequestHeader("Authorization") String accessToken, @RequestPart LectureCreateRequest lectureCreateRequest + , @RequestPart(value = "image", required = false) MultipartFile image) throws Exception { Long userId = Long.parseLong(jwtUtil.getUserId(accessToken)); - lectureService.createLecture(userId, lectureCreateRequest); - return new ResponseEntity<>(HttpStatus.CREATED); + Lecture lecture = lectureService.findLectureByTitle(lectureCreateRequest.getTitle()); + if (lecture != null) { + String msg = new String("Duplicated Lecture"); + return new ResponseEntity<>(msg, HttpStatus.CONFLICT); + } + + lectureService.createLecture(userId, lectureCreateRequest, image); + + String msg = new String("Lecture registered successfully"); + return new ResponseEntity<>(msg, HttpStatus.CREATED); } + @PutMapping("/{lectureId}") + public ResponseEntity updateLecture(@RequestHeader("Authorization") String accessToken, @PathVariable Long lectureId, @RequestBody LectureCreateRequest lectureCreateRequest) { + Long userId = Long.parseLong(jwtUtil.getUserId(accessToken)); + + if (!lectureService.updateLecture(userId, lectureId, lectureCreateRequest)) { + String msg = new String("Can't update Lecture"); + return new ResponseEntity<>(msg, HttpStatus.UNAUTHORIZED); + } + String msg = new String("Lecture updated successfully"); + return new ResponseEntity<>(msg, HttpStatus.OK); + } + + @DeleteMapping("/{lectureId}") - public ResponseEntity deleteLecture(@RequestBody long userId, @PathVariable long lectureId) { + public ResponseEntity deleteLecture(@RequestHeader("Authorization") String accessToken, @PathVariable long lectureId) { + Long userId = Long.parseLong(jwtUtil.getUserId(accessToken)); + if (!lectureService.deleteLecture(userId, lectureId)) { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); + String msg = new String("Can't delete Lecture"); + return new ResponseEntity<>(msg, HttpStatus.UNAUTHORIZED); } return new ResponseEntity<>(HttpStatus.NO_CONTENT); @@ -48,31 +75,46 @@ public class LectureController { List lectures = lectureService.findAllLecture(); if (lectures.isEmpty()) { - return new ResponseEntity<>(HttpStatus.NO_CONTENT); + String msg = new String("No lectures found"); + return new ResponseEntity<>(msg, HttpStatus.OK); } return new ResponseEntity<>(lectures, HttpStatus.OK); } @GetMapping("/{lectureId}") - public ResponseEntity findById(@PathVariable long lectureId) { - LectureDetailResponse lectureDetailResponse = lectureService.findLectureById(lectureId); + public ResponseEntity findById(@RequestHeader(value = "Authorization", required = false) String accessToken, @PathVariable long lectureId) { + Long userId = null; + + if (accessToken != null) { + userId = Long.parseLong(jwtUtil.getUserId(accessToken)); + } + + LectureDetailResponse lectureDetailResponse = lectureService.findLectureById(userId, lectureId); if (lectureDetailResponse == null) { - return new ResponseEntity<>(HttpStatus.NO_CONTENT); + String msg = new String("Can't find Lecture"); + return new ResponseEntity<>(msg, HttpStatus.OK); } + return new ResponseEntity<>(lectureDetailResponse, HttpStatus.OK); } @GetMapping("/mylecture") - public ResponseEntity findMyLecture(@RequestHeader("Authorization") String accessToken) { + public ResponseEntity findMyLecture(@RequestHeader(value = "Authorization", required = false) String accessToken) { + if (accessToken == null) { + String msg = new String("Not logged in"); + return new ResponseEntity<>(msg, HttpStatus.OK); + } + Long userId = Long.parseLong(jwtUtil.getUserId(accessToken)); List myLectures = lectureService.findMyLecture(userId); if (myLectures.isEmpty()) { - return new ResponseEntity<>(HttpStatus.NO_CONTENT); + String msg = new String("No lectures found"); + return new ResponseEntity<>(msg, HttpStatus.OK); } return new ResponseEntity<>(myLectures, HttpStatus.OK); diff --git a/backend/src/main/java/com/edufocus/edufocus/lecture/entity/Lecture.java b/backend/src/main/java/com/edufocus/edufocus/lecture/entity/Lecture.java index d2f220b..0a9168a 100644 --- a/backend/src/main/java/com/edufocus/edufocus/lecture/entity/Lecture.java +++ b/backend/src/main/java/com/edufocus/edufocus/lecture/entity/Lecture.java @@ -3,19 +3,20 @@ package com.edufocus.edufocus.lecture.entity; import com.edufocus.edufocus.user.model.entity.User; import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; +import lombok.*; -import java.util.ArrayList; import java.util.Date; -import java.util.List; @Entity @Getter @Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor public class Lecture { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) @Column private Long id; @@ -29,6 +30,9 @@ public class Lecture { @Lob private String description; + @Lob + private String plan; + @Column private String image; @@ -40,8 +44,8 @@ public class Lecture { @Temporal(TemporalType.DATE) private Date endDate; - @Lob - private String plan; + @Column + private String time; @Column private boolean online; diff --git a/backend/src/main/java/com/edufocus/edufocus/lecture/entity/LectureCreateRequest.java b/backend/src/main/java/com/edufocus/edufocus/lecture/entity/LectureCreateRequest.java index 84c2181..dfd02fd 100644 --- a/backend/src/main/java/com/edufocus/edufocus/lecture/entity/LectureCreateRequest.java +++ b/backend/src/main/java/com/edufocus/edufocus/lecture/entity/LectureCreateRequest.java @@ -15,12 +15,12 @@ public class LectureCreateRequest { private String description; - private String image; + private String plan; private Date startDate; private Date endDate; - private String plan; + private String time; } diff --git a/backend/src/main/java/com/edufocus/edufocus/lecture/entity/LectureDetailResponse.java b/backend/src/main/java/com/edufocus/edufocus/lecture/entity/LectureDetailResponse.java index 08f9558..0a5629a 100644 --- a/backend/src/main/java/com/edufocus/edufocus/lecture/entity/LectureDetailResponse.java +++ b/backend/src/main/java/com/edufocus/edufocus/lecture/entity/LectureDetailResponse.java @@ -21,13 +21,17 @@ public class LectureDetailResponse { private String description; + private String plan; + private String image; private Date startDate; private Date endDate; - private String plan; + private String time; private boolean online; + + private String status; } diff --git a/backend/src/main/java/com/edufocus/edufocus/lecture/entity/UserStatus.java b/backend/src/main/java/com/edufocus/edufocus/lecture/entity/UserStatus.java new file mode 100644 index 0000000..3fbf6ba --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/lecture/entity/UserStatus.java @@ -0,0 +1,9 @@ +package com.edufocus.edufocus.lecture.entity; + +public enum UserStatus { + MANAGED_BY_ME, // 내가 관리하는 강의 - 강사 + MANAGED_BY_OTHERS, // 내가 관리하지 않은 강의 - 강사 + ENROLLED, // 내가 수강 중인 강의 - 학생 + PENDING, // 내가 수강신청하고 승인 대기 중인 강의 - 학생 + NOT_ENROLLED // 내가 수강신청하지 않은 강의 - 학생/비로그인 +} diff --git a/backend/src/main/java/com/edufocus/edufocus/lecture/repository/LectureRepository.java b/backend/src/main/java/com/edufocus/edufocus/lecture/repository/LectureRepository.java index 431b96a..eb708fd 100644 --- a/backend/src/main/java/com/edufocus/edufocus/lecture/repository/LectureRepository.java +++ b/backend/src/main/java/com/edufocus/edufocus/lecture/repository/LectureRepository.java @@ -10,8 +10,11 @@ import java.util.List; @Repository public interface LectureRepository extends JpaRepository { - Lecture findByTitle(@Param("title") String title); + Lecture findByTitle(String title); - List findAllByUserId(@Param("userId") Long userId); + List findAllByUserId(Long userId); + List findLecturesByUserId(Long userId); + + Lecture findByIdAndUserId(long id, long userId); } diff --git a/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureService.java b/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureService.java index b359aa0..962ed5d 100644 --- a/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureService.java +++ b/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureService.java @@ -1,9 +1,11 @@ package com.edufocus.edufocus.lecture.service; +import com.edufocus.edufocus.lecture.entity.Lecture; import com.edufocus.edufocus.lecture.entity.LectureCreateRequest; import com.edufocus.edufocus.lecture.entity.LectureSearchResponse; import com.edufocus.edufocus.lecture.entity.LectureDetailResponse; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -11,14 +13,17 @@ import java.util.List; @Service public interface LectureService { - void createLecture(long userId, LectureCreateRequest lectureCreateRequest); + void createLecture(long userId, LectureCreateRequest lectureCreateRequest, MultipartFile image) throws Exception; + + boolean updateLecture(long userId, long lectureId, LectureCreateRequest lectureCreateRequest); boolean deleteLecture(long userId, long LectureId); List findAllLecture(); - LectureDetailResponse findLectureById(long lectureId); + LectureDetailResponse findLectureById(Long userId, long lectureId); List findMyLecture(long userId); + Lecture findLectureByTitle(String title); } diff --git a/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureServiceImpl.java b/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureServiceImpl.java index 9f9eec8..52a8824 100644 --- a/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureServiceImpl.java +++ b/backend/src/main/java/com/edufocus/edufocus/lecture/service/LectureServiceImpl.java @@ -1,21 +1,27 @@ package com.edufocus.edufocus.lecture.service; -import com.edufocus.edufocus.lecture.entity.Lecture; -import com.edufocus.edufocus.lecture.entity.LectureCreateRequest; -import com.edufocus.edufocus.lecture.entity.LectureSearchResponse; -import com.edufocus.edufocus.lecture.entity.LectureDetailResponse; +import com.edufocus.edufocus.lecture.entity.*; import com.edufocus.edufocus.lecture.repository.LectureRepository; import com.edufocus.edufocus.registration.entity.Registration; +import com.edufocus.edufocus.registration.entity.RegistrationStatus; import com.edufocus.edufocus.registration.repository.RegistrationRepository; import com.edufocus.edufocus.user.model.entity.User; +import com.edufocus.edufocus.user.model.entity.UserRole; import com.edufocus.edufocus.user.model.repository.UserRepository; import jakarta.transaction.Transactional; import lombok.Builder; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.UUID; @Builder @Service @@ -30,31 +36,82 @@ public class LectureServiceImpl implements LectureService { private final RegistrationRepository registrationRepository; @Override - public void createLecture(long userId, LectureCreateRequest lectureCreateRequest) { - + public void createLecture(long userId, LectureCreateRequest lectureCreateRequest, MultipartFile image) throws IOException { User user = userRepository.findById(userId).get(); - Lecture lecture = new Lecture(); - lecture.setUser(user); + Lecture lecture = new Lecture().builder() + .user(user) + .title(lectureCreateRequest.getTitle()) + .description(lectureCreateRequest.getDescription()) + .plan(lectureCreateRequest.getPlan()) + .startDate(lectureCreateRequest.getStartDate()) + .endDate(lectureCreateRequest.getEndDate()) + .time(lectureCreateRequest.getTime()) + .build(); - lecture.setTitle(lectureCreateRequest.getTitle()); - lecture.setDescription(lectureCreateRequest.getDescription()); - lecture.setImage(lectureCreateRequest.getImage()); - lecture.setStartDate(lectureCreateRequest.getStartDate()); - lecture.setEndDate(lectureCreateRequest.getEndDate()); - lecture.setPlan(lectureCreateRequest.getPlan()); + if (image != null && !image.isEmpty()) { + String uid = UUID.randomUUID().toString(); + + String currentPath = "backend/src/main/resources/images/"; + File checkPathFile = new File(currentPath); + if (!checkPathFile.exists()) { + checkPathFile.mkdirs(); + } + + File savingImage = new File(currentPath + uid + "_" + image.getOriginalFilename()); + image.transferTo(savingImage.toPath()); + String savePath = savingImage.toPath().toString(); + + lecture.setImage(savePath); + } lectureRepository.save(lecture); } @Override - public boolean deleteLecture(long userId, long lectureId) { + public boolean updateLecture(long userId, long lectureId, LectureCreateRequest lectureCreateRequest) { Lecture lecture = lectureRepository.findById(lectureId).get(); if (lecture.getUser().getId() != userId) { return false; } + if (lectureCreateRequest.getTitle() != null) { + lecture.setTitle(lectureCreateRequest.getTitle()); + } + if (lectureCreateRequest.getDescription() != null) { + lecture.setDescription(lectureCreateRequest.getDescription()); + } + if (lectureCreateRequest.getPlan() != null) { + lecture.setPlan(lectureCreateRequest.getPlan()); + } + if (lectureCreateRequest.getStartDate() != null) { + lecture.setStartDate(lectureCreateRequest.getStartDate()); + } + if (lectureCreateRequest.getEndDate() != null) { + lecture.setEndDate(lectureCreateRequest.getEndDate()); + } + if (lectureCreateRequest.getTime() != null) { + lecture.setTime(lectureCreateRequest.getTime()); + } + + lectureRepository.save(lecture); + return true; + } + + @Override + public boolean deleteLecture(long userId, long lectureId) { + Optional lecture = lectureRepository.findById(lectureId); + + if (lecture.isEmpty()) { + return false; + } + lecture = Optional.of(lecture.get()); + + if (lecture.get().getUser().getId() != userId) { + return false; + } + lectureRepository.deleteById(lectureId); return true; } @@ -77,24 +134,51 @@ public class LectureServiceImpl implements LectureService { } @Override - public LectureDetailResponse findLectureById(long lectureId) { + public LectureDetailResponse findLectureById(Long userId, long lectureId) { + Optional lecture = lectureRepository.findById(lectureId); - Lecture lecture = lectureRepository.findById(lectureId).get(); - - if (lecture == null) { + if (lecture.isEmpty()) { return null; } + lecture = Optional.of(lecture.get()); + + String userStatus; + if (userId == null) { + userStatus = String.valueOf(UserStatus.NOT_ENROLLED); + } else { + User user = userRepository.findById(userId).get(); + + if (user.getRole() == UserRole.ADMIN) { + if (lecture.get().getUser().getId() == user.getId()) { + userStatus = String.valueOf(UserStatus.MANAGED_BY_ME); + } else { + userStatus = String.valueOf(UserStatus.MANAGED_BY_OTHERS); + } + } else { + Registration registration = registrationRepository.findByUserIdAndLectureId(userId, lectureId); + + if (registration == null) { + userStatus = String.valueOf(UserStatus.NOT_ENROLLED); + } else if (registration.getStatus() == RegistrationStatus.ACCEPTED) { + userStatus = String.valueOf(UserStatus.ENROLLED); + } else { + userStatus = String.valueOf(UserStatus.PENDING); + } + } + } LectureDetailResponse lectureDetailResponse = new LectureDetailResponse().builder() - .id(lecture.getId()) - .title(lecture.getTitle()) - .description(lecture.getDescription()) - .image(lecture.getImage()) - .startDate(lecture.getStartDate()) - .endDate(lecture.getEndDate()) - .plan(lecture.getPlan()) - .online(lecture.isOnline()) - .teacherName(lecture.getUser().getName()) + .id(lecture.get().getId()) + .title(lecture.get().getTitle()) + .description(lecture.get().getDescription()) + .plan(lecture.get().getPlan()) + .image(lecture.get().getImage()) + .startDate(lecture.get().getStartDate()) + .endDate(lecture.get().getEndDate()) + .time(lecture.get().getTime()) + .online(lecture.get().isOnline()) + .teacherName(lecture.get().getUser().getName()) + .status(userStatus) .build(); return lectureDetailResponse; @@ -105,9 +189,8 @@ public class LectureServiceImpl implements LectureService { List myLectureList = new ArrayList<>(); - if (user.getRole().equals("ADMIN")) { - List lectureList = lectureRepository.findAllByUserId(userId); - + if (user.getRole() == UserRole.ADMIN) { + List lectureList = lectureRepository.findLecturesByUserId(userId); for (Lecture lecture : lectureList) { LectureSearchResponse lectureSearchResponse = new LectureSearchResponse().builder() .id(lecture.getId()) @@ -134,4 +217,8 @@ public class LectureServiceImpl implements LectureService { return myLectureList; } + @Override + public Lecture findLectureByTitle(String title) { + return lectureRepository.findByTitle(title); + } } diff --git a/backend/src/main/java/com/edufocus/edufocus/qna/controller/QnaController.java b/backend/src/main/java/com/edufocus/edufocus/qna/controller/QnaController.java index 0a4c1d2..6ba7628 100644 --- a/backend/src/main/java/com/edufocus/edufocus/qna/controller/QnaController.java +++ b/backend/src/main/java/com/edufocus/edufocus/qna/controller/QnaController.java @@ -1,6 +1,8 @@ package com.edufocus.edufocus.qna.controller; import com.edufocus.edufocus.qna.entity.Qna; +import com.edufocus.edufocus.qna.entity.QnaRequestDto; +import com.edufocus.edufocus.qna.entity.QnaResponseDto; import com.edufocus.edufocus.qna.service.QnaService; import com.edufocus.edufocus.user.util.JWTUtil; import jakarta.servlet.http.HttpServletRequest; @@ -21,28 +23,71 @@ import java.util.List; public class QnaController { private final QnaService qnaService; private final JWTUtil jwtUtil; + private static int PAGE_SIZE=10; - @PostMapping - public ResponseEntity createQna(@RequestBody Qna qna , HttpServletRequest request) { + + @PostMapping("/{lecture_id}") + public ResponseEntity createQna(@PathVariable("lecture_id") Long lecture_id, @RequestBody QnaRequestDto qnaRequestDto , HttpServletRequest request) { try{ String token = request.getHeader("Authorization"); Long userId = Long.parseLong(jwtUtil.getUserId(token)); - qnaService.createQna(userId,qna); - return new ResponseEntity<>(qna, HttpStatus.CREATED); + QnaResponseDto qnaResponseDto= qnaService.createQna(userId,qnaRequestDto,lecture_id); + return new ResponseEntity<>( qnaResponseDto,HttpStatus.CREATED); }catch (Exception e){ throw new RuntimeException(e); } } + + @PostMapping({"/answer/create/{qna_id}"}) + public ResponseEntity createAnswer(@PathVariable("qna_id") Long qna_id, @RequestBody QnaRequestDto qnaRequestDto) + { + try { + QnaResponseDto responseDto = qnaService.createAnswer(qna_id,qnaRequestDto); + return new ResponseEntity<>(responseDto,HttpStatus.ACCEPTED); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + @PutMapping({"/answer/update/{qna_id}"}) + public ResponseEntity updateAnswer(@PathVariable("qna_id") Long qna_id, @RequestBody QnaRequestDto qnaRequestDto) + { + try { + QnaResponseDto responseDto = qnaService.updateAnswer(qna_id,qnaRequestDto); + return new ResponseEntity<>(responseDto,HttpStatus.ACCEPTED); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + @DeleteMapping("/answer/delete/{qna_id}") + public ResponseEntity deleteAnswer(@PathVariable("qna_id") Long qna_id) + { + try { + qnaService.deleteAnswer(qna_id); + return new ResponseEntity<>(HttpStatus.ACCEPTED); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + @PutMapping("/{id}") - public ResponseEntity updateQna(@PathVariable Long id, @RequestBody Qna qna) { + public ResponseEntity updateQna(@PathVariable Long id, @RequestBody QnaRequestDto qnaRequestDto) { try{ - qnaService.updateQna(id,qna); - return new ResponseEntity<>(qna, HttpStatus.ACCEPTED); + QnaResponseDto qnaResponseDto= qnaService.updateQna(id,qnaRequestDto); + return new ResponseEntity<>(qnaResponseDto, HttpStatus.ACCEPTED); }catch (Exception e) { @@ -61,9 +106,9 @@ public class QnaController { } @GetMapping("/{id}") - public ResponseEntity getQna(@PathVariable Long id) { + public ResponseEntity getQna(@PathVariable Long id) { try{ - Qna findQna= qnaService.getQna(id); + QnaResponseDto findQna= qnaService.getQna(id); return new ResponseEntity<>(findQna, HttpStatus.ACCEPTED); } catch (SQLException e) { @@ -72,15 +117,12 @@ public class QnaController { } @GetMapping("/all/{id}") - public ResponseEntity> getAllQna(@PathVariable Long id) { + public ResponseEntity> getAllQna(@PathVariable Long id) { try { - System.out.print("@@@@@@@@@@@@@@@@@@@@@@@>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); - List qnaList= qnaService.getAllQnasByLecture(id); - for(Qna qna:qnaList) - { - System.out.print(qna.toString()); - } + + List qnaList= qnaService.getAllQnasByLecture(id,PAGE_SIZE); + return new ResponseEntity<>(qnaList, HttpStatus.ACCEPTED); } catch (SQLException e) { throw new RuntimeException(e); diff --git a/backend/src/main/java/com/edufocus/edufocus/qna/entity/Qna.java b/backend/src/main/java/com/edufocus/edufocus/qna/entity/Qna.java index 4451568..993484e 100644 --- a/backend/src/main/java/com/edufocus/edufocus/qna/entity/Qna.java +++ b/backend/src/main/java/com/edufocus/edufocus/qna/entity/Qna.java @@ -3,8 +3,7 @@ package com.edufocus.edufocus.qna.entity; import com.edufocus.edufocus.lecture.entity.Lecture; import com.edufocus.edufocus.user.model.entity.User; import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; +import lombok.*; import org.checkerframework.checker.units.qual.C; import java.util.Date; @@ -12,6 +11,9 @@ import java.util.Date; @Entity @Getter @Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor public class Qna { // 연관관계 주인 @@ -42,6 +44,7 @@ public class Qna { private String answer; + private String name; @ManyToOne @JoinColumn(name= "id") private User user; @@ -51,4 +54,5 @@ public class Qna { private Lecture lecture; + } diff --git a/backend/src/main/java/com/edufocus/edufocus/qna/entity/QnaRequestDto.java b/backend/src/main/java/com/edufocus/edufocus/qna/entity/QnaRequestDto.java new file mode 100644 index 0000000..f73eeae --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/qna/entity/QnaRequestDto.java @@ -0,0 +1,24 @@ +package com.edufocus.edufocus.qna.entity; + +import jakarta.persistence.Column; +import lombok.*; + +@Getter +public class QnaRequestDto { + + + private String title; + private String content; + private String answer; + + public static Qna toEntity(QnaRequestDto qnaRequestDto) { + { + + return Qna.builder() + .content(qnaRequestDto.getContent()) + .title(qnaRequestDto.getTitle()) + .answer(qnaRequestDto.getAnswer()) + .build(); + } + } +} diff --git a/backend/src/main/java/com/edufocus/edufocus/qna/entity/QnaResponseDto.java b/backend/src/main/java/com/edufocus/edufocus/qna/entity/QnaResponseDto.java new file mode 100644 index 0000000..ee7c768 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/qna/entity/QnaResponseDto.java @@ -0,0 +1,39 @@ +package com.edufocus.edufocus.qna.entity; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Date; + +@Getter + +@NoArgsConstructor +@AllArgsConstructor +public class QnaResponseDto { + + + private Long id; + private String title; + private String username; + private String content; + private Date createtAt; + private String answer; + public static QnaResponseDto toEntity(Qna qna) + { + return new QnaResponseDto( + qna.getId(), + qna.getTitle(), + qna.getUser().getName(), + qna.getContent(), + qna.getCreatedAt(), + qna.getAnswer() + ); + } + + +} + + + diff --git a/backend/src/main/java/com/edufocus/edufocus/qna/repository/QnaRepository.java b/backend/src/main/java/com/edufocus/edufocus/qna/repository/QnaRepository.java index beeba54..9d1c71e 100644 --- a/backend/src/main/java/com/edufocus/edufocus/qna/repository/QnaRepository.java +++ b/backend/src/main/java/com/edufocus/edufocus/qna/repository/QnaRepository.java @@ -1,6 +1,8 @@ package com.edufocus.edufocus.qna.repository; import com.edufocus.edufocus.qna.entity.Qna; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -11,8 +13,6 @@ import java.util.List; @Repository public interface QnaRepository extends JpaRepository { - @Query(value = "SELECT * FROM qna WHERE lecture_id = :lectureId", nativeQuery = true) - List findLecture(@Param("lectureId") Long lectureId); - - + List findByLectureId(Long lecturerId); + Page findByLectureId(Long lectureId, Pageable pageable); } diff --git a/backend/src/main/java/com/edufocus/edufocus/qna/service/QnaService.java b/backend/src/main/java/com/edufocus/edufocus/qna/service/QnaService.java index 8acf0f5..de97f93 100644 --- a/backend/src/main/java/com/edufocus/edufocus/qna/service/QnaService.java +++ b/backend/src/main/java/com/edufocus/edufocus/qna/service/QnaService.java @@ -2,6 +2,8 @@ package com.edufocus.edufocus.qna.service; import com.edufocus.edufocus.lecture.entity.Lecture; import com.edufocus.edufocus.qna.entity.Qna; +import com.edufocus.edufocus.qna.entity.QnaRequestDto; +import com.edufocus.edufocus.qna.entity.QnaResponseDto; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -11,9 +13,14 @@ import java.util.List; @Service public interface QnaService { - void createQna(Long id,Qna qna) throws SQLException; - void updateQna(Long id,Qna qna) throws SQLException; + QnaResponseDto createQna(Long id, QnaRequestDto qnaRequestDto, Long lecture_id) throws SQLException; + QnaResponseDto updateQna(Long id,QnaRequestDto qnaRequestDto) throws SQLException; void deleteQna(Long id) throws SQLException; - Qna getQna(Long id) throws SQLException; - List getAllQnasByLecture(Long lectureId) throws SQLException; + QnaResponseDto getQna(Long id) throws SQLException; + + List getAllQnasByLecture(Long lectureId,int pageNumber) throws SQLException; + QnaResponseDto createAnswer(Long id,QnaRequestDto qnaRequestDto) throws SQLException; + QnaResponseDto updateAnswer(Long id,QnaRequestDto qnaRequestDto) throws SQLException; + void deleteAnswer(Long id) throws SQLException; + } diff --git a/backend/src/main/java/com/edufocus/edufocus/qna/service/QnaServiceImpl.java b/backend/src/main/java/com/edufocus/edufocus/qna/service/QnaServiceImpl.java index 4e6cdc2..bed4103 100644 --- a/backend/src/main/java/com/edufocus/edufocus/qna/service/QnaServiceImpl.java +++ b/backend/src/main/java/com/edufocus/edufocus/qna/service/QnaServiceImpl.java @@ -1,15 +1,28 @@ package com.edufocus.edufocus.qna.service; +import com.edufocus.edufocus.lecture.entity.Lecture; +import com.edufocus.edufocus.lecture.repository.LectureRepository; import com.edufocus.edufocus.qna.entity.Qna; +import com.edufocus.edufocus.qna.entity.QnaRequestDto; +import com.edufocus.edufocus.qna.entity.QnaResponseDto; import com.edufocus.edufocus.qna.repository.QnaRepository; +import com.edufocus.edufocus.user.model.entity.User; +import com.edufocus.edufocus.user.model.repository.UserRepository; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.Setter; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; +import java.sql.SQLException; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; @Service @Transactional @@ -17,25 +30,46 @@ import java.util.Optional; public class QnaServiceImpl implements QnaService{ private final QnaRepository qnaRepository; + private final LectureRepository lectureRepository; + private final UserRepository userRepository; + @Override - public void createQna(Long id,Qna qna) { + public QnaResponseDto createQna(Long id, QnaRequestDto qnaRequestDto, Long lecture_id) { - qna.setId(id); + Lecture lecture = lectureRepository.findById(lecture_id).orElse(null); + + User user = userRepository.findById(id).orElse(null); + + + + Qna qna = QnaRequestDto.toEntity(qnaRequestDto); + qna.setLecture(lecture); + qna.setUser(user); + + qna.setCreatedAt(new Date()); + qnaRepository.save(qna); - + return QnaResponseDto.toEntity(qna); } @Override - public void updateQna(Long id,Qna qna) { + public QnaResponseDto updateQna(Long id,QnaRequestDto qnaRequestDto) { - Optional findQna = qnaRepository.findById(id); + Qna findQna = qnaRepository.findById(id) + .orElseThrow(() -> new RuntimeException("QnA not found")); - qna.setModifiedAt(new Date()); - qnaRepository.save(qna); + findQna.setModifiedAt(new Date()); + findQna.setTitle(qnaRequestDto.getTitle()); + findQna.setContent(qnaRequestDto.getContent()); + + qnaRepository.save(findQna); + + + return QnaResponseDto.toEntity(findQna); } @@ -46,16 +80,65 @@ qnaRepository.deleteById(id); } @Override - public Qna getQna(Long id) { - return null; + public QnaResponseDto getQna(Long id) { + Optional qna; + try { + + qna= qnaRepository.findById(id); + + + } catch (Exception e) { + + throw new RuntimeException("Qna 없음 " + id, e); + } + + + + return QnaResponseDto.toEntity(qna.get()); + } @Override - public List getAllQnasByLecture(Long lectureId) { + public List getAllQnasByLecture(Long lectureId,int pageSize) + { + + Pageable pageable = PageRequest.of(0, pageSize); + + Page qnaPage = qnaRepository.findByLectureId(lectureId, pageable); - System.out.printf(lectureId+"!!!!!!!!!!!!!!!!!!!!!!"); - return qnaRepository.findLecture(lectureId); + return qnaPage.getContent().stream() + .map(QnaResponseDto::toEntity) + .collect(Collectors.toList()); } + + @Override + public QnaResponseDto createAnswer(Long id, QnaRequestDto qnaRequestDto) throws SQLException { + + Qna findQna = qnaRepository.findById(id).orElse(null); + findQna.setAnswer(qnaRequestDto.getAnswer()); + + qnaRepository.save(findQna); + + return QnaResponseDto.toEntity(findQna); + + } + + @Override + public QnaResponseDto updateAnswer(Long id, QnaRequestDto qnaRequestDto) throws SQLException { + + Qna findQna = qnaRepository.findById(id).orElse(null); + findQna.setAnswer(qnaRequestDto.getAnswer()); + + qnaRepository.save(findQna); + + return QnaResponseDto.toEntity(findQna); + } + + @Override + public void deleteAnswer(Long id) throws SQLException { + + qnaRepository.deleteById(id); + } } diff --git a/backend/src/main/java/com/edufocus/edufocus/quiz/controller/QuizController.java b/backend/src/main/java/com/edufocus/edufocus/quiz/controller/QuizController.java index 3c18199..fc3abcd 100644 --- a/backend/src/main/java/com/edufocus/edufocus/quiz/controller/QuizController.java +++ b/backend/src/main/java/com/edufocus/edufocus/quiz/controller/QuizController.java @@ -3,15 +3,18 @@ package com.edufocus.edufocus.quiz.controller; import com.edufocus.edufocus.quiz.entity.*; import com.edufocus.edufocus.quiz.service.QuizService; import com.edufocus.edufocus.quiz.service.QuizSetService; -import com.edufocus.edufocus.user.model.service.UserService; +import com.edufocus.edufocus.user.util.JWTUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.util.UUID; @RestController @RequestMapping("/quiz") @@ -23,19 +26,32 @@ public class QuizController { private final QuizSetService quizSetService; - private final UserService userService; + private final JWTUtil jwtUtil; - @PostMapping - public ResponseEntity createQuizSet(@RequestBody QuizSetCreateRequest quizSetCreateRequest) { - - Long userId = 1L; + @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public ResponseEntity createQuizSet(@RequestHeader("Authorization") String accessToken, @RequestPart QuizSetCreateRequest quizSetCreateRequest + , @RequestPart(value = "image", required = false) MultipartFile image) throws IOException { + Long userId = Long.parseLong(jwtUtil.getUserId(accessToken)); String title = quizSetCreateRequest.getTitle(); - String image = quizSetCreateRequest.getImage(); - - SetCreateRequest setCreateRequest = new SetCreateRequest(userId, title, image); + SetCreateRequest setCreateRequest = new SetCreateRequest(userId, title); QuizSet quizSet = quizSetService.createQuizSet(setCreateRequest); + if (image != null && !image.isEmpty()) { + String uid = UUID.randomUUID().toString(); + + String currentPath = "backend/src/main/resources/images/"; + File checkPathFile = new File(currentPath); + if (!checkPathFile.exists()) { + checkPathFile.mkdirs(); + } + + File savingImage = new File(currentPath + uid + "_" + image.getOriginalFilename()); + image.transferTo(savingImage.toPath()); + String savePath = savingImage.toPath().toString(); + + quizSet.setImage(savePath); + } for (QuizCreateRequest quizCreateRequest : quizSetCreateRequest.getQuizzes()) { quizService.createQuiz(quizSet.getId(), quizCreateRequest); @@ -43,4 +59,11 @@ public class QuizController { return new ResponseEntity<>(HttpStatus.CREATED); } + + @GetMapping("/{quizsetId}") + public ResponseEntity getQuizzes(@PathVariable Long quizsetId) { + QuizSet quizSet = quizSetService.findQuizSet(quizsetId); + + return new ResponseEntity<>(quizSet, HttpStatus.OK); + } } diff --git a/backend/src/main/java/com/edufocus/edufocus/quiz/entity/MutipleQuizCreateRequest.java b/backend/src/main/java/com/edufocus/edufocus/quiz/entity/MutipleQuizCreateRequest.java deleted file mode 100644 index 20dbf54..0000000 --- a/backend/src/main/java/com/edufocus/edufocus/quiz/entity/MutipleQuizCreateRequest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.edufocus.edufocus.quiz.entity; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.ToString; - -@Getter -@NoArgsConstructor -@AllArgsConstructor -public class MutipleQuizCreateRequest extends QuizCreateRequest { - - private String choice1; - - private String choice2; - - private String choice3; - - private String choice4; -} diff --git a/backend/src/main/java/com/edufocus/edufocus/quiz/entity/Quiz.java b/backend/src/main/java/com/edufocus/edufocus/quiz/entity/Quiz.java index 4ea9b43..ad429ac 100644 --- a/backend/src/main/java/com/edufocus/edufocus/quiz/entity/Quiz.java +++ b/backend/src/main/java/com/edufocus/edufocus/quiz/entity/Quiz.java @@ -1,12 +1,17 @@ package com.edufocus.edufocus.quiz.entity; +import com.edufocus.edufocus.user.model.entity.UserRole; +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonManagedReference; import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; +import lombok.*; @Entity @Getter @Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor public class Quiz { @Id @@ -15,6 +20,7 @@ public class Quiz { @ManyToOne @JoinColumn(name = "quizset_id") + @JsonBackReference private QuizSet quizSet; @Column @@ -26,8 +32,8 @@ public class Quiz { @Column private String answer; - @Column (name = "is_single") - private boolean isSingle; + @Enumerated(EnumType.STRING) + private QuizType quizType; @Column private String image; diff --git a/backend/src/main/java/com/edufocus/edufocus/quiz/entity/QuizCreateRequest.java b/backend/src/main/java/com/edufocus/edufocus/quiz/entity/QuizCreateRequest.java index d5c38da..c140c79 100644 --- a/backend/src/main/java/com/edufocus/edufocus/quiz/entity/QuizCreateRequest.java +++ b/backend/src/main/java/com/edufocus/edufocus/quiz/entity/QuizCreateRequest.java @@ -3,7 +3,6 @@ package com.edufocus.edufocus.quiz.entity; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.ToString; @Getter @NoArgsConstructor @@ -14,10 +13,15 @@ public class QuizCreateRequest { private String description; - private boolean isSingle; - private String answer; - private String image; + private String quizType; + private String choice1; + + private String choice2; + + private String choice3; + + private String choice4; } diff --git a/backend/src/main/java/com/edufocus/edufocus/quiz/entity/QuizSet.java b/backend/src/main/java/com/edufocus/edufocus/quiz/entity/QuizSet.java index b067277..89a2b4d 100644 --- a/backend/src/main/java/com/edufocus/edufocus/quiz/entity/QuizSet.java +++ b/backend/src/main/java/com/edufocus/edufocus/quiz/entity/QuizSet.java @@ -1,6 +1,8 @@ package com.edufocus.edufocus.quiz.entity; import com.edufocus.edufocus.user.model.entity.User; +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonManagedReference; import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; @@ -19,6 +21,7 @@ public class QuizSet { @ManyToOne @JoinColumn(name = "user_id") + @JsonBackReference private User user; @Column @@ -28,6 +31,7 @@ public class QuizSet { private String image; @OneToMany(mappedBy = "quizSet") + @JsonManagedReference private List quizzes = new ArrayList(); public void addQuiz(Quiz quiz) { diff --git a/backend/src/main/java/com/edufocus/edufocus/quiz/entity/QuizType.java b/backend/src/main/java/com/edufocus/edufocus/quiz/entity/QuizType.java new file mode 100644 index 0000000..b58f56c --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/quiz/entity/QuizType.java @@ -0,0 +1,5 @@ +package com.edufocus.edufocus.quiz.entity; + +public enum QuizType { + SINGLE, MULTIPLE +} diff --git a/backend/src/main/java/com/edufocus/edufocus/quiz/entity/SetCreateRequest.java b/backend/src/main/java/com/edufocus/edufocus/quiz/entity/SetCreateRequest.java index a391ceb..83caff8 100644 --- a/backend/src/main/java/com/edufocus/edufocus/quiz/entity/SetCreateRequest.java +++ b/backend/src/main/java/com/edufocus/edufocus/quiz/entity/SetCreateRequest.java @@ -13,6 +13,4 @@ public class SetCreateRequest { private String title; - private String image; - } diff --git a/backend/src/main/java/com/edufocus/edufocus/quiz/repository/QuizRepository.java b/backend/src/main/java/com/edufocus/edufocus/quiz/repository/QuizRepository.java index 7428689..9e7d345 100644 --- a/backend/src/main/java/com/edufocus/edufocus/quiz/repository/QuizRepository.java +++ b/backend/src/main/java/com/edufocus/edufocus/quiz/repository/QuizRepository.java @@ -3,5 +3,7 @@ package com.edufocus.edufocus.quiz.repository; import com.edufocus.edufocus.quiz.entity.Quiz; import org.springframework.data.jpa.repository.JpaRepository; + public interface QuizRepository extends JpaRepository { + } diff --git a/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizService.java b/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizService.java index 3174e89..8b0725f 100644 --- a/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizService.java +++ b/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizService.java @@ -1,9 +1,10 @@ package com.edufocus.edufocus.quiz.service; -import com.edufocus.edufocus.quiz.entity.MutipleQuizCreateRequest; import com.edufocus.edufocus.quiz.entity.QuizCreateRequest; import org.springframework.stereotype.Service; +import java.util.List; + @Service public interface QuizService { diff --git a/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizServiceImpl.java b/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizServiceImpl.java index 5f34010..0412f68 100644 --- a/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizServiceImpl.java +++ b/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizServiceImpl.java @@ -1,9 +1,9 @@ package com.edufocus.edufocus.quiz.service; -import com.edufocus.edufocus.quiz.entity.MutipleQuizCreateRequest; import com.edufocus.edufocus.quiz.entity.Quiz; import com.edufocus.edufocus.quiz.entity.QuizCreateRequest; import com.edufocus.edufocus.quiz.entity.QuizSet; +import com.edufocus.edufocus.quiz.entity.QuizType; import com.edufocus.edufocus.quiz.repository.QuizRepository; import com.edufocus.edufocus.quiz.repository.QuizSetRepository; import jakarta.transaction.Transactional; @@ -23,15 +23,20 @@ public class QuizServiceImpl implements QuizService { public void createQuiz(long quizSetId, QuizCreateRequest quizCreateRequest) { QuizSet quizSet = quizSetRepository.findById(quizSetId).get(); - Quiz quiz = new Quiz(); + Quiz quiz = new Quiz().builder() + .title(quizCreateRequest.getTitle()) + .description(quizCreateRequest.getDescription()) + .answer(quizCreateRequest.getAnswer()) + .quizType(QuizType.valueOf(quizCreateRequest.getQuizType())) + .quizSet(quizSet) + .build(); - quiz.setTitle(quizCreateRequest.getTitle()); - quiz.setDescription(quizCreateRequest.getDescription()); - quiz.setAnswer(quizCreateRequest.getAnswer()); - quiz.setImage(quizCreateRequest.getImage()); - - - quiz.setQuizSet(quizSet); + if (!quiz.getQuizType().equals(QuizType.MULTIPLE)) { + quiz.setChoice1(quizCreateRequest.getChoice1()); + quiz.setChoice2(quizCreateRequest.getChoice2()); + quiz.setChoice3(quizCreateRequest.getChoice3()); + quiz.setChoice4(quizCreateRequest.getChoice4()); + } quizRepository.save(quiz); } @@ -46,4 +51,5 @@ public class QuizServiceImpl implements QuizService { quizRepository.deleteById(quizId); return true; } + } diff --git a/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizSetService.java b/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizSetService.java index 748283b..a62a979 100644 --- a/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizSetService.java +++ b/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizSetService.java @@ -13,4 +13,5 @@ public interface QuizSetService { void deleteQuizSet(long quizSetId); + QuizSet findQuizSet(long quizSetId); } diff --git a/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizSetServiceImpl.java b/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizSetServiceImpl.java index a167cca..1836ce5 100644 --- a/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizSetServiceImpl.java +++ b/backend/src/main/java/com/edufocus/edufocus/quiz/service/QuizSetServiceImpl.java @@ -1,7 +1,7 @@ package com.edufocus.edufocus.quiz.service; -import com.edufocus.edufocus.quiz.entity.QuizSet; -import com.edufocus.edufocus.quiz.entity.SetCreateRequest; +import com.edufocus.edufocus.quiz.entity.*; +import com.edufocus.edufocus.quiz.repository.QuizRepository; import com.edufocus.edufocus.quiz.repository.QuizSetRepository; import com.edufocus.edufocus.user.model.entity.User; import com.edufocus.edufocus.user.model.repository.UserRepository; @@ -28,7 +28,6 @@ public class QuizSetServiceImpl implements QuizSetService { quizSet.setUser(user); quizSet.setTitle(setCreateRequest.getTitle()); - quizSet.setImage(setCreateRequest.getImage()); return quizSetRepository.save(quizSet); } @@ -42,4 +41,9 @@ public class QuizSetServiceImpl implements QuizSetService { public void deleteQuizSet(long quizSetId) { quizSetRepository.deleteById(quizSetId); } + + @Override + public QuizSet findQuizSet(long quizSetId) { + return quizSetRepository.findById(quizSetId).get(); + } } diff --git a/backend/src/main/java/com/edufocus/edufocus/registration/controller/RegistrationController.java b/backend/src/main/java/com/edufocus/edufocus/registration/controller/RegistrationController.java index fc6e67d..1d28aaf 100644 --- a/backend/src/main/java/com/edufocus/edufocus/registration/controller/RegistrationController.java +++ b/backend/src/main/java/com/edufocus/edufocus/registration/controller/RegistrationController.java @@ -1,42 +1,62 @@ package com.edufocus.edufocus.registration.controller; -import com.edufocus.edufocus.registration.entity.Registration; import com.edufocus.edufocus.registration.service.RegistrationService; +import com.edufocus.edufocus.user.util.JWTUtil; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.util.Map; + @RestController @RequestMapping("/registration") @Slf4j +@RequiredArgsConstructor public class RegistrationController { private final RegistrationService registrationServiceImpl; - public RegistrationController(RegistrationService registrationServiceImpl) { - this.registrationServiceImpl = registrationServiceImpl; - } + private final JWTUtil jwtUtil; @PostMapping - public ResponseEntity register(@RequestBody Registration registration) { - registrationServiceImpl.createRegistration(registration); + public ResponseEntity register(@RequestHeader("Authorization") String accessToken, @RequestBody Map map) { + Long userId = Long.parseLong(jwtUtil.getUserId(accessToken)); + Long lectureId = map.get("lectureId"); + if (!registrationServiceImpl.createRegistration(userId, lectureId)) { + String msg = new String("Duplicated Registration"); + return new ResponseEntity<>(msg, HttpStatus.CONFLICT); + } + + String msg = new String("registration successful"); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @PutMapping("/{registrationId}") + public ResponseEntity acceptRigistration(@RequestHeader("Authorization") String accessToken, @PathVariable long registrationId) { + Long userId = Long.parseLong(jwtUtil.getUserId(accessToken)); + + if (!registrationServiceImpl.acceptRegistration(userId, registrationId)) { + String msg = new String("Not Acceptable"); + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } + + String msg = new String("registration accepted"); return new ResponseEntity<>(HttpStatus.OK); } - @PatchMapping("/registrationId/{registrationId}") - public ResponseEntity acceptRigistration(@PathVariable long registrationId) { - registrationServiceImpl.acceptRegistration(registrationId); + @DeleteMapping("/{registrationId}") + public ResponseEntity deleteRigistration(@RequestHeader("Authorization") String accessToken, @PathVariable long registrationId) { + Long userId = Long.parseLong(jwtUtil.getUserId(accessToken)); - return new ResponseEntity<>(HttpStatus.OK); - } + if (!registrationServiceImpl.deleteRegistration(userId, registrationId)) { + String msg = new String("Not Acceptable"); + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } - @DeleteMapping("/registrationId/{registrationId}") - public ResponseEntity deleteRigistration(@PathVariable long registrationId) { - registrationServiceImpl.deleteRegistration(registrationId); - - return new ResponseEntity<>(HttpStatus.OK); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); } } diff --git a/backend/src/main/java/com/edufocus/edufocus/registration/entity/Registration.java b/backend/src/main/java/com/edufocus/edufocus/registration/entity/Registration.java index 7e1cce6..4a81aba 100644 --- a/backend/src/main/java/com/edufocus/edufocus/registration/entity/Registration.java +++ b/backend/src/main/java/com/edufocus/edufocus/registration/entity/Registration.java @@ -3,12 +3,14 @@ package com.edufocus.edufocus.registration.entity; import com.edufocus.edufocus.lecture.entity.Lecture; import com.edufocus.edufocus.user.model.entity.User; import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; +import lombok.*; @Entity @Getter @Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor public class Registration { @Id diff --git a/backend/src/main/java/com/edufocus/edufocus/registration/repository/RegistrationRepository.java b/backend/src/main/java/com/edufocus/edufocus/registration/repository/RegistrationRepository.java index 34358a2..251acaf 100644 --- a/backend/src/main/java/com/edufocus/edufocus/registration/repository/RegistrationRepository.java +++ b/backend/src/main/java/com/edufocus/edufocus/registration/repository/RegistrationRepository.java @@ -10,4 +10,6 @@ import java.util.List; @Repository public interface RegistrationRepository extends JpaRepository { List findAllByUserId(@Param("userId") Long userId); + + Registration findByUserIdAndLectureId(Long userId, Long lectureId); } diff --git a/backend/src/main/java/com/edufocus/edufocus/registration/service/RegistrationService.java b/backend/src/main/java/com/edufocus/edufocus/registration/service/RegistrationService.java index fcaac94..96d89f6 100644 --- a/backend/src/main/java/com/edufocus/edufocus/registration/service/RegistrationService.java +++ b/backend/src/main/java/com/edufocus/edufocus/registration/service/RegistrationService.java @@ -6,12 +6,10 @@ import org.springframework.stereotype.Service; @Service public interface RegistrationService { - void createRegistration(Registration registration); + boolean createRegistration(long userId, long registrationId); - void acceptRegistration(long RegistrationId); + boolean acceptRegistration(long userId, long RegistrationId); - void deleteRegistration(long registrationId); - - boolean isAcceptedRegistration(long registrationId); + boolean deleteRegistration(long userId, long registrationId); } diff --git a/backend/src/main/java/com/edufocus/edufocus/registration/service/RegistrationServiceImpl.java b/backend/src/main/java/com/edufocus/edufocus/registration/service/RegistrationServiceImpl.java index 6eadce6..7c156bf 100644 --- a/backend/src/main/java/com/edufocus/edufocus/registration/service/RegistrationServiceImpl.java +++ b/backend/src/main/java/com/edufocus/edufocus/registration/service/RegistrationServiceImpl.java @@ -1,8 +1,10 @@ package com.edufocus.edufocus.registration.service; +import com.edufocus.edufocus.lecture.repository.LectureRepository; import com.edufocus.edufocus.registration.entity.Registration; import com.edufocus.edufocus.registration.entity.RegistrationStatus; import com.edufocus.edufocus.registration.repository.RegistrationRepository; +import com.edufocus.edufocus.user.model.repository.UserRepository; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -15,32 +17,49 @@ import java.util.Optional; public class RegistrationServiceImpl implements RegistrationService { private final RegistrationRepository registrationRepository; + private final UserRepository userRepository; + private final LectureRepository lectureRepository; @Override - public void createRegistration(Registration registration) { - registrationRepository.save(registration); - } - - @Override - public void acceptRegistration(long registrationId) { - Optional registration = registrationRepository.findById(registrationId); - - if (registration.isPresent()) { - Registration reg = registration.get(); - reg.setStatus(RegistrationStatus.valueOf("ACCEPTED")); - registrationRepository.save(reg); + public boolean createRegistration(long userId, long lectureId) { + if (registrationRepository.findByUserIdAndLectureId(userId, lectureId) != null) { + return false; } + + Registration registration = new Registration().builder() + .user(userRepository.getReferenceById(userId)) + .lecture(lectureRepository.getReferenceById(lectureId)) + .status(RegistrationStatus.WAITING) + .build(); + + registrationRepository.save(registration); + return true; } @Override - public void deleteRegistration(long registrationId) { + public boolean acceptRegistration(long userId, long registrationId) { + Registration registration = registrationRepository.findById(registrationId).get(); + + if (registration.getLecture().getUser().getId() != userId) { + return false; + } + + registration.setStatus(RegistrationStatus.valueOf("ACCEPTED")); + registrationRepository.save(registration); + + return true; + } + + @Override + public boolean deleteRegistration(long userId, long registrationId) { + Registration registration = registrationRepository.findById(registrationId).get(); + + if (registration.getLecture().getUser().getId() != userId) { + return false; + } + registrationRepository.deleteById(registrationId); + return true; } - @Override - public boolean isAcceptedRegistration(long registrationId) { - Optional registration = registrationRepository.findById(registrationId); - - return registration.isPresent() && registration.get().getStatus().equals("ACCEPTED"); - } } diff --git a/backend/src/main/java/com/edufocus/edufocus/report/controller/ReportController.java b/backend/src/main/java/com/edufocus/edufocus/report/controller/ReportController.java new file mode 100644 index 0000000..f07149f --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/report/controller/ReportController.java @@ -0,0 +1,37 @@ +package com.edufocus.edufocus.report.controller; + +import com.edufocus.edufocus.report.entity.dto.ReportResponse; +import com.edufocus.edufocus.report.entity.vo.Report; +import com.edufocus.edufocus.report.entity.dto.ReportRequset; +import com.edufocus.edufocus.report.service.ReportService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.sql.SQLException; + +@RestController +@RequestMapping("/report") +@Slf4j +@RequiredArgsConstructor +public class ReportController{ + + + private final ReportService reportService; + + + + + @PostMapping("/submit") + public ResponseEntity submit(@RequestBody ReportRequset reportRequset) throws SQLException { + ReportResponse report = reportService.grading(reportRequset); + return new ResponseEntity<>(report,HttpStatus.CREATED); + + } + +} diff --git a/backend/src/main/java/com/edufocus/edufocus/report/entity/dto/AnswerInput.java b/backend/src/main/java/com/edufocus/edufocus/report/entity/dto/AnswerInput.java new file mode 100644 index 0000000..ba1ff2e --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/report/entity/dto/AnswerInput.java @@ -0,0 +1,11 @@ +package com.edufocus.edufocus.report.entity.dto; + +import lombok.Getter; + +@Getter +public class AnswerInput { + + Long answerinputID; + String answer; + +} diff --git a/backend/src/main/java/com/edufocus/edufocus/report/entity/dto/QuizSubmissionDto.java b/backend/src/main/java/com/edufocus/edufocus/report/entity/dto/QuizSubmissionDto.java new file mode 100644 index 0000000..24413b2 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/report/entity/dto/QuizSubmissionDto.java @@ -0,0 +1,6 @@ +package com.edufocus.edufocus.report.entity.dto; + +public class QuizSubmissionDto { + private Long quizSetId; + private Long userId; +} diff --git a/backend/src/main/java/com/edufocus/edufocus/report/entity/dto/ReportRequset.java b/backend/src/main/java/com/edufocus/edufocus/report/entity/dto/ReportRequset.java new file mode 100644 index 0000000..ca20596 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/report/entity/dto/ReportRequset.java @@ -0,0 +1,25 @@ +package com.edufocus.edufocus.report.entity.dto; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class ReportRequset { + + + private Long userId; + private Long quizsetId; + List answerInputList; + + +// List a +// userID : +// quizSetId : +// answerList : [ +// { ans1 : 1}, +// {ans2 : 2} +// ] +} diff --git a/backend/src/main/java/com/edufocus/edufocus/report/entity/dto/ReportResponse.java b/backend/src/main/java/com/edufocus/edufocus/report/entity/dto/ReportResponse.java new file mode 100644 index 0000000..7d6a439 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/report/entity/dto/ReportResponse.java @@ -0,0 +1,26 @@ +package com.edufocus.edufocus.report.entity.dto; + +import com.edufocus.edufocus.report.entity.vo.Answer; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.util.Date; +import java.util.List; + +@Getter +@Setter +@Builder +public class ReportResponse { + + private Long quizesetId; + private Long userId; + + private String title; + private int allCount; + private int correctCount; + private Date testAt; + + + +} diff --git a/backend/src/main/java/com/edufocus/edufocus/report/entity/vo/Answer.java b/backend/src/main/java/com/edufocus/edufocus/report/entity/vo/Answer.java new file mode 100644 index 0000000..1437626 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/report/entity/vo/Answer.java @@ -0,0 +1,33 @@ +package com.edufocus.edufocus.report.entity.vo; + + +import com.edufocus.edufocus.quiz.entity.Quiz; +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class Answer { + + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + private String userAnswer; + private boolean isCorrect; + + @ManyToOne + @JoinColumn(name= "report_id") + private Report report; + + @ManyToOne + @JoinColumn(name= "quiz_id") + private Quiz quiz; + + +} diff --git a/backend/src/main/java/com/edufocus/edufocus/report/entity/vo/Report.java b/backend/src/main/java/com/edufocus/edufocus/report/entity/vo/Report.java new file mode 100644 index 0000000..6165358 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/report/entity/vo/Report.java @@ -0,0 +1,35 @@ +package com.edufocus.edufocus.report.entity.vo; + +import com.edufocus.edufocus.quiz.entity.QuizSet; +import com.edufocus.edufocus.user.model.entity.User; +import jakarta.persistence.*; +import lombok.*; + +import java.util.Date; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class Report { + + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private int allCount; + private int correctCount; + private Date testAt; + + @ManyToOne + @JoinColumn(name= "user_id") + private User user; + + @ManyToOne + @JoinColumn(name= "quizset_id") + private QuizSet quizSet; + +} diff --git a/backend/src/main/java/com/edufocus/edufocus/report/repository/AnswerRepository.java b/backend/src/main/java/com/edufocus/edufocus/report/repository/AnswerRepository.java new file mode 100644 index 0000000..aa2ec9a --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/report/repository/AnswerRepository.java @@ -0,0 +1,7 @@ +package com.edufocus.edufocus.report.repository; + +import com.edufocus.edufocus.report.entity.vo.Answer; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface AnswerRepository extends JpaRepository { +} diff --git a/backend/src/main/java/com/edufocus/edufocus/report/repository/ReportRepository.java b/backend/src/main/java/com/edufocus/edufocus/report/repository/ReportRepository.java new file mode 100644 index 0000000..954473e --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/report/repository/ReportRepository.java @@ -0,0 +1,9 @@ +package com.edufocus.edufocus.report.repository; + +import com.edufocus.edufocus.report.entity.vo.Report; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ReportRepository extends JpaRepository { +} diff --git a/backend/src/main/java/com/edufocus/edufocus/report/service/AnswerService.java b/backend/src/main/java/com/edufocus/edufocus/report/service/AnswerService.java new file mode 100644 index 0000000..de98121 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/report/service/AnswerService.java @@ -0,0 +1,8 @@ +package com.edufocus.edufocus.report.service; + +import com.edufocus.edufocus.report.entity.vo.Answer; + +public interface AnswerService { + + void save(Answer answer); +} diff --git a/backend/src/main/java/com/edufocus/edufocus/report/service/AnswerServiceImpl.java b/backend/src/main/java/com/edufocus/edufocus/report/service/AnswerServiceImpl.java new file mode 100644 index 0000000..e19f53e --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/report/service/AnswerServiceImpl.java @@ -0,0 +1,22 @@ +package com.edufocus.edufocus.report.service; + +import com.edufocus.edufocus.report.entity.vo.Answer; +import com.edufocus.edufocus.report.repository.AnswerRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@Transactional +@RequiredArgsConstructor +public class AnswerServiceImpl implements AnswerService{ + + private final AnswerRepository answerRepository; + + @Override + public void save(Answer answer) { + + answerRepository.save(answer); + + } +} diff --git a/backend/src/main/java/com/edufocus/edufocus/report/service/ReportService.java b/backend/src/main/java/com/edufocus/edufocus/report/service/ReportService.java new file mode 100644 index 0000000..bfead76 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/report/service/ReportService.java @@ -0,0 +1,14 @@ +package com.edufocus.edufocus.report.service; + +import com.edufocus.edufocus.report.entity.dto.ReportResponse; +import com.edufocus.edufocus.report.entity.vo.Report; +import com.edufocus.edufocus.report.entity.dto.ReportRequset; +import org.springframework.stereotype.Service; + +import java.sql.SQLException; + +@Service +public interface ReportService { + ReportResponse grading(ReportRequset reportRequset) throws SQLException; + +} diff --git a/backend/src/main/java/com/edufocus/edufocus/report/service/ReportServiceImpl.java b/backend/src/main/java/com/edufocus/edufocus/report/service/ReportServiceImpl.java new file mode 100644 index 0000000..dd22a44 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/report/service/ReportServiceImpl.java @@ -0,0 +1,105 @@ +package com.edufocus.edufocus.report.service; + +import com.edufocus.edufocus.quiz.entity.Quiz; +import com.edufocus.edufocus.quiz.entity.QuizSet; +import com.edufocus.edufocus.quiz.repository.QuizRepository; +import com.edufocus.edufocus.quiz.service.QuizService; +import com.edufocus.edufocus.quiz.service.QuizSetService; +import com.edufocus.edufocus.report.entity.dto.ReportResponse; +import com.edufocus.edufocus.report.entity.vo.Answer; +import com.edufocus.edufocus.report.entity.dto.AnswerInput; +import com.edufocus.edufocus.report.entity.vo.Report; +import com.edufocus.edufocus.report.entity.dto.ReportRequset; +import com.edufocus.edufocus.report.repository.ReportRepository; +import com.edufocus.edufocus.user.model.entity.User; +import com.edufocus.edufocus.user.model.repository.UserRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.sql.SQLException; +import java.util.Date; +import java.util.List; + +@Service +@Transactional +@RequiredArgsConstructor +public class ReportServiceImpl implements ReportService { + + private final QuizSetService quizSetService; + private final QuizService quizService; + + private final ReportRepository reportRepository; + private final QuizRepository quizRepository; + + private final AnswerService answerService; + private final UserRepository userRepository; + + + @Override + public ReportResponse grading(ReportRequset reportRequset) throws SQLException { + + + QuizSet quizSet = quizSetService.findQuizSet(reportRequset.getQuizsetId()); + + List quizList = quizSet.getQuizzes(); + List answerInputList = reportRequset.getAnswerInputList(); + + Report report = new Report(); + + Long reportNum = report.getId(); + int allCount= quizList.size(); + int correctCount =0 ; + + User testuser= userRepository.findById(reportRequset.getUserId()).orElse(null); + + for (Quiz quiz : quizList) { + for (AnswerInput answerInput : answerInputList) { + if (quiz.getId().equals(answerInput.getAnswerinputID())) { + + if(quiz.getAnswer().equals(answerInput.getAnswer())) { + correctCount++; + + Answer answer = Answer.builder() + .userAnswer(answerInput.getAnswer()) + .isCorrect(true) + .report(report) + .quiz(quiz) + .build(); + + } + else{ + Answer answer = Answer.builder() + .userAnswer(answerInput.getAnswer()) + .isCorrect(false) + .report(report) + .quiz(quiz) + .build(); + + + + } + + } + + } + } + + report = Report.builder() + .user(testuser) + .quizSet(quizSet) + .allCount(allCount) + .correctCount(correctCount) + .testAt(new Date()).build(); + ReportResponse reportResponse = ReportResponse.builder() + .quizesetId(quizSet.getId()) + .userId(testuser.getId()) + .title(quizSet.getTitle()) + .allCount(allCount) + .correctCount(correctCount) + .testAt(new Date()) + .build(); + + return reportResponse; + } +} diff --git a/backend/src/main/java/com/edufocus/edufocus/swagger/SwaggerConfig.java b/backend/src/main/java/com/edufocus/edufocus/swagger/SwaggerConfig.java index 7d71ef7..970f7ba 100644 --- a/backend/src/main/java/com/edufocus/edufocus/swagger/SwaggerConfig.java +++ b/backend/src/main/java/com/edufocus/edufocus/swagger/SwaggerConfig.java @@ -15,6 +15,7 @@ public class SwaggerConfig { .info(new Info() .title("에듀포커스 API") .description("") + .version("1.0.0")); } } \ No newline at end of file diff --git a/backend/src/main/java/com/edufocus/edufocus/user/config/WebConfiguration.java b/backend/src/main/java/com/edufocus/edufocus/user/config/WebConfiguration.java index 362e689..4bc3d83 100644 --- a/backend/src/main/java/com/edufocus/edufocus/user/config/WebConfiguration.java +++ b/backend/src/main/java/com/edufocus/edufocus/user/config/WebConfiguration.java @@ -18,6 +18,7 @@ public class WebConfiguration implements WebMvcConfigurer { public WebConfiguration(JWTInterceptor jwtInterceptor) { super(); + this.jwtInterceptor = jwtInterceptor; } @@ -25,10 +26,12 @@ public class WebConfiguration implements WebMvcConfigurer { public void addCorsMappings(CorsRegistry registry) { registry .addMapping("/**") - .allowedOrigins("*") + .allowedOrigins("http://i11a701.p.ssafy.io/", "http://localhost:5173", "http://localhost:4173") .allowedMethods(HttpMethod.GET.name(), HttpMethod.POST.name(), HttpMethod.PUT.name(), HttpMethod.DELETE.name(), HttpMethod.HEAD.name(), HttpMethod.OPTIONS.name(), HttpMethod.PATCH.name()) + .allowCredentials(true) + .allowedHeaders("*") .maxAge(1800); // Pre-flight Caching } @@ -37,5 +40,13 @@ public class WebConfiguration implements WebMvcConfigurer { registry.addResourceHandler("/img/**").addResourceLocations("classpath:/static/assets/img/"); registry.addResourceHandler("/*.html**").addResourceLocations("classpath:/static/"); } + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(jwtInterceptor) + .addPathPatterns("/**") // 모든 경로에 대해 인터셉터 적용 + .excludePathPatterns("/v3/api-docs/**","/swagger-resources/**","/webjars/**","/swagger-ui/**","/auth/**", "/board/**", "/user/**","/lecture/**","/qna/**", "/quiz/**"); // 인증 없이 접근 가능한 경로 설정 + + ///v3/api-docs/**, /swagger-resources/**, /webjars/** + } } \ No newline at end of file diff --git a/backend/src/main/java/com/edufocus/edufocus/user/controller/UserController.java b/backend/src/main/java/com/edufocus/edufocus/user/controller/UserController.java index 16e8b9f..5b36459 100644 --- a/backend/src/main/java/com/edufocus/edufocus/user/controller/UserController.java +++ b/backend/src/main/java/com/edufocus/edufocus/user/controller/UserController.java @@ -34,18 +34,14 @@ public class UserController { userService.join(user); return ResponseEntity.ok("User registered successfully"); } + @PostMapping("/findpassword/{user_id}") + public ResponseEntity findpassword(@PathVariable("user_id") Long user_id) throws Exception { + + userService.userCheck(user_id); + return ResponseEntity.ok("임시 비밀번호가 이메일로 전송되었습니다."); + + } -// -// @PostMapping("/login") -// public ResponseEntity login(@RequestBody User user) { -// try { -// User loggedInUser = userService.login(user); -// return ResponseEntity.ok(loggedInUser); -// -// } catch (Exception e) { -// throw new RuntimeException(e); -// } - // } @Operation(summary = "로그인", description = "아이디와 비밀번호를 이용하여 로그인 처리.") @PostMapping("/login") @@ -53,30 +49,34 @@ public class UserController { @RequestBody @Parameter(description = "로그인 시 필요한 회원정보(아이디, 비밀번호).", required = true) User user, HttpServletResponse response) { Map resultMap = new HashMap<>(); HttpStatus status = HttpStatus.ACCEPTED; + + + try { User loginUser = userService.login(user); if (loginUser != null) { + + String name = loginUser.getName(); + resultMap.put("name",name); String accessToken = jwtUtil.createAccessToken(String.valueOf(loginUser.getId())); String refreshToken = jwtUtil.createRefreshToken(String.valueOf(loginUser.getId())); - // 발급받은 refresh token 을 DB에 저장. userService.saveRefreshToken(loginUser.getId(), refreshToken); - // JSON 으로 token 전달. System.out.println(accessToken); resultMap.put("access-token", accessToken); - // resultMap.put("refresh-token", refreshToken); - // 쿠키 저장 + + Cookie refreshCookie = new Cookie("refresh-token", refreshToken); refreshCookie.setPath("/"); refreshCookie.setHttpOnly(true); - refreshCookie.setSecure(true); // HTTPS에서만 전송되도록 설정 + // refreshCookie.setSecure(true); // HTTPS에서만 전송되도록 설정 // refreshCookie.setSameSite(Cookie.SameSite.NONE); // Cross-Origin 요청에 대해 모두 전송 response.addCookie(refreshCookie); - // 쿠키저장 + status = HttpStatus.CREATED; } else { resultMap.put("message", "아이디 또는 패스워드를 확인해 주세요."); @@ -94,12 +94,9 @@ public class UserController { public ResponseEntity> getInfo( @PathVariable("userId") @Parameter(description = "인증할 회원의 아이디.", required = true) Long userId, HttpServletRequest request) { - //logger.debug("userId : {} ", userId); String id = String.valueOf(userId); - System.out.println("!>>>>>>>>>>>>>>>>>>>>>>>>"); - System.out.println(id); - System.out.println(id.getClass().getName()); + Map resultMap = new HashMap<>(); HttpStatus status = HttpStatus.ACCEPTED; if (jwtUtil.checkToken(request.getHeader("Authorization"))) { diff --git a/backend/src/main/java/com/edufocus/edufocus/user/model/entity/MailDto.java b/backend/src/main/java/com/edufocus/edufocus/user/model/entity/MailDto.java new file mode 100644 index 0000000..b2e1e51 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/user/model/entity/MailDto.java @@ -0,0 +1,20 @@ +package com.edufocus.edufocus.user.model.entity; + +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@ToString +@Data +public class MailDto { + + private String address; + private String title; + private String message; + +} \ No newline at end of file diff --git a/backend/src/main/java/com/edufocus/edufocus/user/model/entity/MemberChangeDto.java b/backend/src/main/java/com/edufocus/edufocus/user/model/entity/MemberChangeDto.java new file mode 100644 index 0000000..5576813 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/user/model/entity/MemberChangeDto.java @@ -0,0 +1,19 @@ +package com.edufocus.edufocus.user.model.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString +@Data +public class MemberChangeDto { + Long id; + String password; +} \ No newline at end of file diff --git a/backend/src/main/java/com/edufocus/edufocus/user/model/entity/User.java b/backend/src/main/java/com/edufocus/edufocus/user/model/entity/User.java index 8bc7952..f0403f8 100644 --- a/backend/src/main/java/com/edufocus/edufocus/user/model/entity/User.java +++ b/backend/src/main/java/com/edufocus/edufocus/user/model/entity/User.java @@ -2,6 +2,8 @@ package com.edufocus.edufocus.user.model.entity; import com.edufocus.edufocus.qna.entity.Qna; import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -25,7 +27,12 @@ public class User { @Column(name = "user_id", unique = true, nullable = false) + @Pattern(regexp = "(?=.*[0-9])(?=.*[a-zA-Z])(?=.*\\W)(?=\\S+$).{8,16}", message = "비밀번호는 8~16자 영문 대 소문자, 숫자, 특수문자를 사용하세요.") + @NotBlank(message = "아이디는 필수 입력 값입니다.") + private String userId; + + @Pattern(regexp = "^(?:\\w+\\.?)*\\w+@(?:\\w+\\.)+\\w+$", message = "이메일 형식이 올바르지 않습니다.") private String email; private String password; @Enumerated(EnumType.STRING) // 혹은 EnumType.ORDINAL diff --git a/backend/src/main/java/com/edufocus/edufocus/user/model/repository/UserRepository.java b/backend/src/main/java/com/edufocus/edufocus/user/model/repository/UserRepository.java index 53e6289..026c4aa 100644 --- a/backend/src/main/java/com/edufocus/edufocus/user/model/repository/UserRepository.java +++ b/backend/src/main/java/com/edufocus/edufocus/user/model/repository/UserRepository.java @@ -23,6 +23,12 @@ public interface UserRepository extends JpaRepository { @Query("UPDATE User u SET u.refreshToken = NULL WHERE u.id = :id") void deleteRefreshToken(@Param("id") Long id); + @Transactional + @Modifying + @Query("UPDATE User u set u.password = :password where u.id= :id") + void updatePassword(@Param("id") Long id , @Param("password") String password); + + Optional findByUserId(String userId); } diff --git a/backend/src/main/java/com/edufocus/edufocus/user/model/service/UserService.java b/backend/src/main/java/com/edufocus/edufocus/user/model/service/UserService.java index 3ba4454..f661fd1 100644 --- a/backend/src/main/java/com/edufocus/edufocus/user/model/service/UserService.java +++ b/backend/src/main/java/com/edufocus/edufocus/user/model/service/UserService.java @@ -9,4 +9,7 @@ public interface UserService { String getRefreshToken(Long id) throws Exception; void deleteRefreshToken(Long id) throws Exception; User userInfo(Long id) throws Exception; + void sendEamail(User user) throws Exception; + void userCheck(Long id) throws Exception; + String getUserName(Long id) throws Exception; } diff --git a/backend/src/main/java/com/edufocus/edufocus/user/model/service/UserServiceImpl.java b/backend/src/main/java/com/edufocus/edufocus/user/model/service/UserServiceImpl.java index 0f70838..554d971 100644 --- a/backend/src/main/java/com/edufocus/edufocus/user/model/service/UserServiceImpl.java +++ b/backend/src/main/java/com/edufocus/edufocus/user/model/service/UserServiceImpl.java @@ -1,12 +1,16 @@ package com.edufocus.edufocus.user.model.service; +import com.edufocus.edufocus.user.model.entity.MailDto; +import com.edufocus.edufocus.user.model.entity.MemberChangeDto; import com.edufocus.edufocus.user.model.entity.User; import com.edufocus.edufocus.user.model.exception.UserException; import com.edufocus.edufocus.user.model.repository.UserRepository; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; import org.springframework.stereotype.Service; import java.sql.SQLException; @@ -19,8 +23,10 @@ import java.util.Optional; @RequiredArgsConstructor public class UserServiceImpl implements UserService{ - @Autowired + private final UserRepository userRepository; + private final JavaMailSender mailSender; + public void join(User user) @@ -74,6 +80,81 @@ public class UserServiceImpl implements UserService{ } } + + @Override + public void sendEamail(User user) throws Exception { + MailDto mailDto = createMailAndChargePassword(user); + + System.out.println("이메일 전송 완료"); + SimpleMailMessage message = new SimpleMailMessage(); + + + + message.setTo(mailDto.getAddress()); + message.setFrom("passfinder111@gmail.com"); + message.setSubject(mailDto.getTitle()); + message.setText(mailDto.getMessage()); + System.out.println("!!!!!!!!!!!!!!!!!!"+ message); + + mailSender.send(message); + + + } + + public MailDto createMailAndChargePassword(User user) throws SQLException { + String str = getTempPassword(); + MailDto dto = new MailDto(); + dto.setAddress(user.getEmail()); + dto.setTitle(user.getUserId()+"님의 임시비밀번호 안내 이메일 입니다."); + dto.setMessage("안녕하세요. EduFoucs 입니다. "+ "\n"+ "임시비밀번호 안내 관련 메일 입니다." + "\n[" + user.getName() + "]" + "님의 임시 비밀번호는 " + + str + " 입니다."); + + System.out.println(dto); + + MemberChangeDto memberChangeDto = new MemberChangeDto(user.getId(),str); + System.out.println(memberChangeDto); + userRepository.updatePassword(memberChangeDto.getId(),memberChangeDto.getPassword()); + System.out.println(); + + return dto; + } + + @Override + public void userCheck(Long id) throws Exception { + + User user = userRepository.findById(id).orElse(null); + + + if(user == null) + { + System.out.println("불가"); + throw new RuntimeException("유효하지 않은 아이디입니다. 다시 입력하세요"); + + } + else { + + sendEamail(user); + } + } + + @Override + public String getUserName(Long id) throws Exception { + + return userRepository.findById(id).get().getName(); + } + + public String getTempPassword() { + char[] charSet = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; + String str = ""; + + int idx = 0; + for (int i=0; i<10; i++) { + idx = (int) (charSet.length * Math.random()); + str += charSet[idx]; + } + return str; + } @Override public void saveRefreshToken(Long id, String refreshToken) throws Exception { userRepository.saveRefreshToken(id, refreshToken); diff --git a/backend/src/main/java/com/edufocus/edufocus/video/controller/Controller.java b/backend/src/main/java/com/edufocus/edufocus/video/controller/Controller.java index ab3a751..ed35745 100644 --- a/backend/src/main/java/com/edufocus/edufocus/video/controller/Controller.java +++ b/backend/src/main/java/com/edufocus/edufocus/video/controller/Controller.java @@ -30,6 +30,13 @@ public class Controller { String roomName = params.get("roomName"); String participantName = params.get("participantName"); + // + // + // + // + // + // + if (roomName == null || participantName == null) { return ResponseEntity.badRequest().body(Map.of("errorMessage", "roomName and participantName are required")); } diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/config/WebSocketConfigurer.java b/backend/src/main/java/com/edufocus/edufocus/ws/config/WebSocketConfigurer.java new file mode 100644 index 0000000..eabc28d --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/config/WebSocketConfigurer.java @@ -0,0 +1,25 @@ +package com.edufocus.edufocus.ws.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +@Configuration +@EnableWebSocketMessageBroker +public class WebSocketConfigurer implements WebSocketMessageBrokerConfigurer { + + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.enableSimpleBroker("/sub"); + registry.setApplicationDestinationPrefixes("/pub"); + } + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry + .addEndpoint("/ws") + .setAllowedOrigins("*"); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/controller/ChatController.java b/backend/src/main/java/com/edufocus/edufocus/ws/controller/ChatController.java new file mode 100644 index 0000000..a5a0e58 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/controller/ChatController.java @@ -0,0 +1,92 @@ +package com.edufocus.edufocus.ws.controller; + + +import com.edufocus.edufocus.user.util.JWTUtil; +import com.edufocus.edufocus.ws.entity.dto.MessageDto; +import com.edufocus.edufocus.ws.entity.dto.QuizDto; +import com.edufocus.edufocus.ws.entity.dto.ChatUserDto; +import com.edufocus.edufocus.ws.service.ChatService; +import org.springframework.context.event.EventListener; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.messaging.handler.annotation.DestinationVariable; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.SendTo; +import org.springframework.messaging.simp.SimpMessageHeaderAccessor; +import org.springframework.messaging.simp.SimpMessageSendingOperations; +import org.springframework.messaging.simp.stomp.StompHeaderAccessor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.socket.messaging.SessionDisconnectEvent; + +import java.util.List; + +@RestController +public class ChatController { + + private final SimpMessageSendingOperations simpMessageSendingOperations; + + private final ChatService chatService; + + private final JWTUtil jwtUtil; + + public ChatController(SimpMessageSendingOperations simpMessageSendingOperations, ChatService chatService, JWTUtil jwtUtil){ + this.simpMessageSendingOperations = simpMessageSendingOperations; + this.chatService = chatService; + this.jwtUtil = jwtUtil; + } + +// @GetMapping("/chat/enter/{lectureId}") +// public ResponseEntity enter(@PathVariable long lectureId){ +// List chatUsers = chatService.findChatUsers(lectureId); +// +// return new ResponseEntity<>(chatUsers, HttpStatus.OK); +// } + + +// @MessageMapping("/hello/{channelId}") +// @SendTo("/sub/channel/{channelId}") +// public ChatUserDto hello(@DestinationVariable long channelId, SimpMessageHeaderAccessor simpMessageHeaderAccessor, @Header("Authorization") String token){ +// String sessionId = simpMessageHeaderAccessor.getSessionId(); +// +// System.out.println("session" + sessionId); +// +// long userId = Long.parseLong(jwtUtil.getUserId(token)); +// +// chatService.saveChatUserInfo(userId, channelId, sessionId); +// +// return chatService.getChatUserInfo(userId); +// } + + @MessageMapping("/message/{lectureId}") + @SendTo("/sub/channel/{lectureId}") + public MessageDto sendMessage(@DestinationVariable long lectureId, MessageDto messageDto){return messageDto;} + + @MessageMapping("/quiz/{lectureId}") + @SendTo("/sub/channel/{lectureId}") + public QuizDto quizStart(@DestinationVariable long lectureId, QuizDto quizDto){ + return quizDto; + } + +// @EventListener +// public void handleWebSocketDisconnectListener(SessionDisconnectEvent event){ +// StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage()); +// String sessionId = headerAccessor.getSessionId(); +// +// +// ChatUserDto chatUserDto = chatService.getChatUserInfo(sessionId); +// +// +// if(chatService.checkTeacher(chatUserDto)){ +// chatService.closeChatRoom(chatUserDto.getLectureId()); +// simpMessageSendingOperations.convertAndSend("/sub/channel/" + chatUserDto.getLectureId(), "강의가 종료 됐습니다."); +// return; +// } +// +// chatService.deleteChatUserInfo(chatUserDto.getUserId()); +// simpMessageSendingOperations.convertAndSend("/sub/channel/" + chatUserDto.getLectureId(), chatUserDto); +// } +} + diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/ChatUserDto.java b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/ChatUserDto.java new file mode 100644 index 0000000..3830c35 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/ChatUserDto.java @@ -0,0 +1,14 @@ +package com.edufocus.edufocus.ws.entity.dto; + + +import lombok.*; + +@Builder +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class ChatUserDto { + long userId; + long lectureId; + String name; +} diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/HelloDto.java b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/HelloDto.java new file mode 100644 index 0000000..6d1eb41 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/HelloDto.java @@ -0,0 +1,13 @@ +package com.edufocus.edufocus.ws.entity.dto; + + +import lombok.*; + +@Builder +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class HelloDto { + long lectureId; + String name; +} diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/MessageDto.java b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/MessageDto.java new file mode 100644 index 0000000..0e12619 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/MessageDto.java @@ -0,0 +1,13 @@ +package com.edufocus.edufocus.ws.entity.dto; + + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class MessageDto { + long userId; + String name; + String content; +} diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/QuizDto.java b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/QuizDto.java new file mode 100644 index 0000000..bd97f35 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/entity/dto/QuizDto.java @@ -0,0 +1,12 @@ +package com.edufocus.edufocus.ws.entity.dto; + + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class QuizDto { + long userId; + long quizSetId; +} diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/entity/vo/ChatUser.java b/backend/src/main/java/com/edufocus/edufocus/ws/entity/vo/ChatUser.java new file mode 100644 index 0000000..7a1d8d6 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/entity/vo/ChatUser.java @@ -0,0 +1,33 @@ +package com.edufocus.edufocus.ws.entity.vo; + +import com.edufocus.edufocus.lecture.entity.Lecture; +import com.edufocus.edufocus.user.model.entity.User; +import com.edufocus.edufocus.ws.entity.dto.ChatUserDto; +import jakarta.persistence.*; +import lombok.*; + + +@Entity +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ChatUser { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + int id; + @Column + String sessionId; + @OneToOne + User user; + @ManyToOne + Lecture lecture; + + public ChatUserDto makeChatUserDto(){ + return ChatUserDto.builder() + .userId(user.getId()) + .name(user.getName()) + .lectureId(lecture.getId()) + .build(); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/repository/ChatUserRepository.java b/backend/src/main/java/com/edufocus/edufocus/ws/repository/ChatUserRepository.java new file mode 100644 index 0000000..a59fd9e --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/repository/ChatUserRepository.java @@ -0,0 +1,15 @@ +package com.edufocus.edufocus.ws.repository; + +import com.edufocus.edufocus.ws.entity.vo.ChatUser; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface ChatUserRepository extends JpaRepository { + public ChatUser findBySessionId(String sessionId); + public List findByLectureId(long lectureId); + + @Query("delete from ChatUser c where c.lecture.id=:lectureId") + public void deleteByLectureId(long lectureId); +} diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/service/ChatService.java b/backend/src/main/java/com/edufocus/edufocus/ws/service/ChatService.java new file mode 100644 index 0000000..5399bb9 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/service/ChatService.java @@ -0,0 +1,15 @@ +package com.edufocus.edufocus.ws.service; + +import com.edufocus.edufocus.ws.entity.dto.ChatUserDto; + +import java.util.List; + +public interface ChatService { + public void saveChatUserInfo(long userId, long channelId, String sessionId); + public ChatUserDto getChatUserInfo(long userId); + public ChatUserDto getChatUserInfo(String sessionId); + public List findChatUsers(long lectureId); + public boolean checkTeacher(ChatUserDto chatUser); + public void closeChatRoom(long chatRoomId); + public void deleteChatUserInfo(long userId); +} diff --git a/backend/src/main/java/com/edufocus/edufocus/ws/service/ChatServiceImpl.java b/backend/src/main/java/com/edufocus/edufocus/ws/service/ChatServiceImpl.java new file mode 100644 index 0000000..7cc7866 --- /dev/null +++ b/backend/src/main/java/com/edufocus/edufocus/ws/service/ChatServiceImpl.java @@ -0,0 +1,83 @@ +package com.edufocus.edufocus.ws.service; + + +import com.edufocus.edufocus.lecture.entity.Lecture; +import com.edufocus.edufocus.lecture.repository.LectureRepository; +import com.edufocus.edufocus.user.model.entity.User; +import com.edufocus.edufocus.user.model.repository.UserRepository; +import com.edufocus.edufocus.ws.entity.dto.ChatUserDto; +import com.edufocus.edufocus.ws.entity.vo.ChatUser; +import com.edufocus.edufocus.ws.repository.ChatUserRepository; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class ChatServiceImpl implements ChatService{ + + private final ChatUserRepository chatUserRepository; + private final UserRepository userRepository; + private final LectureRepository lectureRepository; + + public ChatServiceImpl(ChatUserRepository chatUserRepository, UserRepository userRepository, LectureRepository lectureRepository) { + this.chatUserRepository = chatUserRepository; + this.userRepository = userRepository; + this.lectureRepository = lectureRepository; + } + + + @Override + public void saveChatUserInfo(long userId, long lectureId, String sessionId) { + User user = userRepository.getReferenceById(userId); + Lecture lecture = lectureRepository.getReferenceById(lectureId); + + ChatUser chatUser = ChatUser.builder() + .user(user) + .lecture(lecture) + .sessionId(sessionId) + .build(); + + chatUserRepository.save(chatUser); + } + + @Override + public ChatUserDto getChatUserInfo(long userId) { + ChatUser chatUser = chatUserRepository.findById(userId).orElseThrow(IllegalArgumentException::new); + + return chatUser.makeChatUserDto(); + } + + @Override + public ChatUserDto getChatUserInfo(String sessionId) { + ChatUser chatUser = chatUserRepository.findBySessionId(sessionId); + + return chatUser.makeChatUserDto(); + } + + @Override + public List findChatUsers(long lectureId) { + return chatUserRepository.findByLectureId(lectureId) + .stream() + .map(ChatUser::makeChatUserDto) + .collect(Collectors.toList()); + } + + @Override + public boolean checkTeacher(ChatUserDto chatUser) { + Lecture lecture = lectureRepository.findByIdAndUserId(chatUser.getLectureId(), chatUser.getUserId()); + return lecture != null; + } + + @Override + public void closeChatRoom(long lectureId) { + chatUserRepository.deleteByLectureId(lectureId); + } + + @Override + public void deleteChatUserInfo(long userId) { + ChatUser chatUser = chatUserRepository.getReferenceById(userId); + + chatUserRepository.delete(chatUser); + } +} diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index e67341c..37b4488 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -38,4 +38,4 @@ spring.mail.username=passfinder111@gmail.com spring.mail.password=mnlyfkiprltjlsmw spring.mail.properties.mail.smtp.auth=true -spring.mail.properties.mail.smtp.starttls.enable=true \ No newline at end of file +spring.mail.properties.mail.smtp.starttls.enable=true