Merge branch 'backend' into be/board

This commit is contained in:
김기창 2024-07-26 16:32:29 +09:00 committed by GitHub
commit cee1ae40d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
70 changed files with 1507 additions and 238 deletions

28
.github/workflows/change-pr-target.yaml vendored Normal file
View File

@ -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 }}

View File

@ -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'

View File

@ -30,22 +30,18 @@ public class BoardController {
}
@GetMapping()
public ResponseEntity<?> searchBoards(
public ResponseEntity<List<ResponseBoardSummaryDto>> 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<ResponseBoardSummaryDto> 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<ResponseBoardDetailDto> 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<List<ResponseCommentDto>> getComments(
@PathVariable int boardId
){
List<ResponseCommentDto> 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);
}
}

View File

@ -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);
}

View File

@ -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<LectureSearchResponse> 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<LectureSearchResponse> 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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -0,0 +1,9 @@
package com.edufocus.edufocus.lecture.entity;
public enum UserStatus {
MANAGED_BY_ME, // 내가 관리하는 강의 - 강사
MANAGED_BY_OTHERS, // 내가 관리하지 않은 강의 - 강사
ENROLLED, // 내가 수강 중인 강의 - 학생
PENDING, // 내가 수강신청하고 승인 대기 중인 강의 - 학생
NOT_ENROLLED // 내가 수강신청하지 않은 강의 - 학생/비로그인
}

View File

@ -10,8 +10,11 @@ import java.util.List;
@Repository
public interface LectureRepository extends JpaRepository<Lecture, Long> {
Lecture findByTitle(@Param("title") String title);
Lecture findByTitle(String title);
List<Lecture> findAllByUserId(@Param("userId") Long userId);
List<Lecture> findAllByUserId(Long userId);
List<Lecture> findLecturesByUserId(Long userId);
Lecture findByIdAndUserId(long id, long userId);
}

View File

@ -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<LectureSearchResponse> findAllLecture();
LectureDetailResponse findLectureById(long lectureId);
LectureDetailResponse findLectureById(Long userId, long lectureId);
List<LectureSearchResponse> findMyLecture(long userId);
Lecture findLectureByTitle(String title);
}

View File

@ -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> 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> 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<LectureSearchResponse> myLectureList = new ArrayList<>();
if (user.getRole().equals("ADMIN")) {
List<Lecture> lectureList = lectureRepository.findAllByUserId(userId);
if (user.getRole() == UserRole.ADMIN) {
List<Lecture> 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);
}
}

View File

@ -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<Qna> createQna(@RequestBody Qna qna , HttpServletRequest request) {
@PostMapping("/{lecture_id}")
public ResponseEntity<QnaResponseDto> 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<QnaResponseDto> 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<QnaResponseDto> 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<QnaResponseDto> 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<Qna> updateQna(@PathVariable Long id, @RequestBody Qna qna) {
public ResponseEntity<QnaResponseDto> 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<Qna> getQna(@PathVariable Long id) {
public ResponseEntity<QnaResponseDto> 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<List<Qna>> getAllQna(@PathVariable Long id) {
public ResponseEntity<List<QnaResponseDto>> getAllQna(@PathVariable Long id) {
try {
System.out.print("@@@@@@@@@@@@@@@@@@@@@@@>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
List<Qna> qnaList= qnaService.getAllQnasByLecture(id);
for(Qna qna:qnaList)
{
System.out.print(qna.toString());
}
List<QnaResponseDto> qnaList= qnaService.getAllQnasByLecture(id,PAGE_SIZE);
return new ResponseEntity<>(qnaList, HttpStatus.ACCEPTED);
} catch (SQLException e) {
throw new RuntimeException(e);

View File

@ -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;
}

View File

@ -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();
}
}
}

View File

@ -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()
);
}
}

View File

@ -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<Qna, Long> {
@Query(value = "SELECT * FROM qna WHERE lecture_id = :lectureId", nativeQuery = true)
List<Qna> findLecture(@Param("lectureId") Long lectureId);
List<Qna> findByLectureId(Long lecturerId);
Page<Qna> findByLectureId(Long lectureId, Pageable pageable);
}

View File

@ -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<Qna> getAllQnasByLecture(Long lectureId) throws SQLException;
QnaResponseDto getQna(Long id) throws SQLException;
List<QnaResponseDto> 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;
}

View File

@ -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<Qna> 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> qna;
try {
qna= qnaRepository.findById(id);
} catch (Exception e) {
throw new RuntimeException("Qna 없음 " + id, e);
}
return QnaResponseDto.toEntity(qna.get());
}
@Override
public List<Qna> getAllQnasByLecture(Long lectureId) {
public List<QnaResponseDto> getAllQnasByLecture(Long lectureId,int pageSize)
{
Pageable pageable = PageRequest.of(0, pageSize);
Page<Qna> 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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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<Quiz> quizzes = new ArrayList<Quiz>();
public void addQuiz(Quiz quiz) {

View File

@ -0,0 +1,5 @@
package com.edufocus.edufocus.quiz.entity;
public enum QuizType {
SINGLE, MULTIPLE
}

View File

@ -13,6 +13,4 @@ public class SetCreateRequest {
private String title;
private String image;
}

View File

@ -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<Quiz, Long> {
}

View File

@ -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 {

View File

@ -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;
}
}

View File

@ -13,4 +13,5 @@ public interface QuizSetService {
void deleteQuizSet(long quizSetId);
QuizSet findQuizSet(long quizSetId);
}

View File

@ -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();
}
}

View File

@ -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<String, Long> 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);
}
}

View File

@ -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

View File

@ -10,4 +10,6 @@ import java.util.List;
@Repository
public interface RegistrationRepository extends JpaRepository<Registration, Long> {
List<Registration> findAllByUserId(@Param("userId") Long userId);
Registration findByUserIdAndLectureId(Long userId, Long lectureId);
}

View File

@ -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);
}

View File

@ -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) {
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 acceptRegistration(long registrationId) {
Optional<Registration> registration = registrationRepository.findById(registrationId);
public boolean acceptRegistration(long userId, long registrationId) {
Registration registration = registrationRepository.findById(registrationId).get();
if (registration.isPresent()) {
Registration reg = registration.get();
reg.setStatus(RegistrationStatus.valueOf("ACCEPTED"));
registrationRepository.save(reg);
if (registration.getLecture().getUser().getId() != userId) {
return false;
}
registration.setStatus(RegistrationStatus.valueOf("ACCEPTED"));
registrationRepository.save(registration);
return true;
}
@Override
public void deleteRegistration(long registrationId) {
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> registration = registrationRepository.findById(registrationId);
return registration.isPresent() && registration.get().getStatus().equals("ACCEPTED");
}
}

View File

@ -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<ReportResponse> submit(@RequestBody ReportRequset reportRequset) throws SQLException {
ReportResponse report = reportService.grading(reportRequset);
return new ResponseEntity<>(report,HttpStatus.CREATED);
}
}

View File

@ -0,0 +1,11 @@
package com.edufocus.edufocus.report.entity.dto;
import lombok.Getter;
@Getter
public class AnswerInput {
Long answerinputID;
String answer;
}

View File

@ -0,0 +1,6 @@
package com.edufocus.edufocus.report.entity.dto;
public class QuizSubmissionDto {
private Long quizSetId;
private Long userId;
}

View File

@ -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<AnswerInput> answerInputList;
// List<answerDto> a
// userID :
// quizSetId :
// answerList : [
// { ans1 : 1},
// {ans2 : 2}
// ]
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<Answer,Long> {
}

View File

@ -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<Report, Long> {
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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<Quiz> quizList = quizSet.getQuizzes();
List<AnswerInput> 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;
}
}

View File

@ -15,6 +15,7 @@ public class SwaggerConfig {
.info(new Info()
.title("에듀포커스 API")
.description("")
.version("1.0.0"));
}
}

View File

@ -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/**
}
}

View File

@ -34,18 +34,14 @@ public class UserController {
userService.join(user);
return ResponseEntity.ok("User registered successfully");
}
@PostMapping("/findpassword/{user_id}")
public ResponseEntity<String> findpassword(@PathVariable("user_id") Long user_id) throws Exception {
userService.userCheck(user_id);
return ResponseEntity.ok("임시 비밀번호가 이메일로 전송되었습니다.");
}
//
// @PostMapping("/login")
// public ResponseEntity<User> 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<String, Object> 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<Map<String, Object>> 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<String, Object> resultMap = new HashMap<>();
HttpStatus status = HttpStatus.ACCEPTED;
if (jwtUtil.checkToken(request.getHeader("Authorization"))) {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -23,6 +23,12 @@ public interface UserRepository extends JpaRepository<User,Long> {
@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<User> findByUserId(String userId);
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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"));
}

View File

@ -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("*");
}
}

View File

@ -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<ChatUserDto> 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);
// }
}

View File

@ -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;
}

View File

@ -0,0 +1,13 @@
package com.edufocus.edufocus.ws.entity.dto;
import lombok.*;
@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class HelloDto {
long lectureId;
String name;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -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<ChatUser, Long> {
public ChatUser findBySessionId(String sessionId);
public List<ChatUser> findByLectureId(long lectureId);
@Query("delete from ChatUser c where c.lecture.id=:lectureId")
public void deleteByLectureId(long lectureId);
}

View File

@ -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<ChatUserDto> findChatUsers(long lectureId);
public boolean checkTeacher(ChatUserDto chatUser);
public void closeChatRoom(long chatRoomId);
public void deleteChatUserInfo(long userId);
}

View File

@ -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<ChatUserDto> 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);
}
}