Skip to content

Commit

Permalink
BE: [feature] 시험 등록 #6
Browse files Browse the repository at this point in the history
  • Loading branch information
HOJEONGKIMM committed Nov 5, 2024
1 parent 53d65d4 commit 5b5b934
Show file tree
Hide file tree
Showing 104 changed files with 122 additions and 11,307 deletions.
17 changes: 0 additions & 17 deletions .github/ISSUE_TEMPLATE/bug.md

This file was deleted.

19 changes: 0 additions & 19 deletions .github/ISSUE_TEMPLATE/feature.md

This file was deleted.

15 changes: 0 additions & 15 deletions .github/PULL_REQUEST_TEMPLATE.md

This file was deleted.

1 change: 1 addition & 0 deletions src/backend/Eyesee/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.apache.commons:commons-lang3:3.12.0'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,10 @@ public enum BaseResponseCode {
// Exam Errors
NOT_FOUND_EXAM("E0001", HttpStatus.NOT_FOUND, "시험을 찾을 수 없습니다."),
NOT_FOUND_EXAM_CODE("E0002", HttpStatus.NOT_FOUND, "시험 코드를 찾을 수 없습니다."),

// Exam Errors
EXAM_NOT_FOUND("E0001", HttpStatus.NOT_FOUND, "시험을 찾을 수 없습니다."),
SESSION_NOT_FOUND("E0002", HttpStatus.NOT_FOUND, "세션을 찾을 수 없습니다."),
EXAM_ALREADY_EXISTS("E0003", HttpStatus.CONFLICT, "이미 존재하는 시험입니다."),
INVALID_EXAM_STATUS("E0004", HttpStatus.BAD_REQUEST, "유효하지 않은 시험 상태입니다."),
EXAM_ACCESS_DENIED("E0005", HttpStatus.FORBIDDEN, "시험에 접근할 권한이 없습니다."),
NOT_FOUND_SESSION("E0003", HttpStatus.NOT_FOUND, "세션을 찾을 수 없습니다."),
EXAM_ALREADY_EXISTS("E0004", HttpStatus.CONFLICT, "이미 존재하는 시험입니다."),
INVALID_EXAM_STATUS("E0005", HttpStatus.BAD_REQUEST, "유효하지 않은 시험 상태입니다."),
EXAM_ACCESS_DENIED("E0006", HttpStatus.FORBIDDEN, "시험에 접근할 권한이 없습니다."),

// 기타 추가 오류 코드 ...

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
import com.fortune.eyesee.common.exception.BaseException;
import com.fortune.eyesee.common.response.BaseResponse;
import com.fortune.eyesee.common.response.BaseResponseCode;
import com.fortune.eyesee.dto.ExamCodeRequestDTO;
import com.fortune.eyesee.dto.ExamResponseDTO;
import com.fortune.eyesee.dto.UserDetailResponseDTO;
import com.fortune.eyesee.dto.UserListResponseDTO;
import com.fortune.eyesee.dto.*;
import com.fortune.eyesee.enums.ExamStatus;
import com.fortune.eyesee.service.ExamService;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -15,7 +12,10 @@
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpSession;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/exams")
Expand Down Expand Up @@ -58,6 +58,35 @@ public class ExamController {
// return ResponseEntity.ok(new BaseResponse<>(examList));
// }

// 시험 등록
// @PostMapping
// public ResponseEntity<BaseResponse<ExamResponseDTO>> registerExam(@RequestBody ExamRequestDTO examRequestDTO, HttpSession session) {
// Integer adminId = (Integer) session.getAttribute("adminId");
// if (adminId == null) {
// // 로그인되지 않은 경우 예외처리
// throw new BaseException(BaseResponseCode.UNAUTHORIZED);
// }
//
// // 시험 생성 및 랜덤 코드 생성
// ExamResponseDTO response = examService.registerExam(adminId, examRequestDTO);
// return ResponseEntity.ok(new BaseResponse<>(response, "시험 등록에 성공했습니다."));
// }
@PostMapping
public ResponseEntity<BaseResponse<Map<String, String>>> registerExam(@RequestBody ExamRequestDTO examRequestDTO, HttpSession session) {
Integer adminId = (Integer) session.getAttribute("adminId");
if (adminId == null) {
throw new BaseException(BaseResponseCode.UNAUTHORIZED);
}

ExamResponseDTO response = examService.registerExam(adminId, examRequestDTO);

// examRandomCode만 포함된 응답 생성
Map<String, String> responseData = new HashMap<>();
responseData.put("examRandomCode", response.getExamRandomCode());

return ResponseEntity.ok(new BaseResponse<>(responseData, "시험 등록에 성공했습니다."));
}

// "before" 상태의 Exam 리스트 조회
@GetMapping("/before")
public ResponseEntity<BaseResponse<List<ExamResponseDTO>>> getBeforeExams() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.fortune.eyesee.dto;

import lombok.Data;

import java.time.LocalDate;
import java.time.LocalTime;

@Data
public class ExamRequestDTO {
private String examName;
private String examSemester;
private Integer examStudentNumber;
private String examLocation;
private LocalDate examDate;
private LocalTime examStartTime;
private Integer examDuration;
private Integer examQuestionNumber;
private Integer examTotalScore;
private String examNotice;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ public class Session {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer sessionId; // 자동 증가


@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "examId", nullable = false) // exam_id를 외래 키로 설정
@JoinColumn(name = "examId", nullable = false) // examId를 외래 키로 설정
private Exam exam; // Exam과 1:1 관계

private String sessionReport;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fortune.eyesee.common.exception.BaseException;
import com.fortune.eyesee.common.response.BaseResponseCode;
import com.fortune.eyesee.dto.ExamRequestDTO;
import com.fortune.eyesee.dto.ExamResponseDTO;
import com.fortune.eyesee.dto.UserDetailResponseDTO;
import com.fortune.eyesee.dto.UserListResponseDTO;
Expand All @@ -10,6 +11,8 @@
import com.fortune.eyesee.repository.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.apache.commons.lang3.RandomStringUtils;


import java.util.ArrayList;
import java.util.List;
Expand All @@ -26,6 +29,7 @@ public class ExamService {
private final VideoRecordingRepository videoRecordingRepository;
private final DetectedCheatingRepository detectedCheatingRepository;
private final CheatingTypeRepository cheatingTypeRepository;
private final AdminRepository adminRepository;

@Autowired
public ExamService(ExamRepository examRepository,
Expand All @@ -34,14 +38,66 @@ public ExamService(ExamRepository examRepository,
CheatingStatisticsRepository cheatingStatisticsRepository,
VideoRecordingRepository videoRecordingRepository,
DetectedCheatingRepository detectedCheatingRepository,
CheatingTypeRepository cheatingTypeRepository) {
CheatingTypeRepository cheatingTypeRepository,
AdminRepository adminRepository) {
this.examRepository = examRepository;
this.userRepository = userRepository;
this.sessionRepository = sessionRepository;
this.cheatingStatisticsRepository = cheatingStatisticsRepository;
this.videoRecordingRepository = videoRecordingRepository;
this.detectedCheatingRepository = detectedCheatingRepository;
this.cheatingTypeRepository = cheatingTypeRepository;
this.adminRepository = adminRepository;
}


// 시험 등록 메서드
public ExamResponseDTO registerExam(Integer adminId, ExamRequestDTO examRequestDTO) {
Admin admin = adminRepository.findById(adminId)
.orElseThrow(() -> new BaseException(BaseResponseCode.UNAUTHORIZED));

// 10자리 랜덤 영숫자 코드 생성
String examRandomCode = RandomStringUtils.randomAlphanumeric(10);

// Exam 생성
Exam exam = new Exam();
exam.setAdmin(admin);
exam.setExamName(examRequestDTO.getExamName());
exam.setExamSemester(examRequestDTO.getExamSemester());
exam.setExamStudentNumber(examRequestDTO.getExamStudentNumber());
exam.setExamLocation(examRequestDTO.getExamLocation());
exam.setExamDate(examRequestDTO.getExamDate());
exam.setExamStartTime(examRequestDTO.getExamStartTime());
exam.setExamDuration(examRequestDTO.getExamDuration());
exam.setExamQuestionNumber(examRequestDTO.getExamQuestionNumber());
exam.setExamTotalScore(examRequestDTO.getExamTotalScore());
exam.setExamNotice(examRequestDTO.getExamNotice());
exam.setExamStatus(ExamStatus.BEFORE);
exam.setExamRandomCode(examRandomCode);

// Exam 저장 후 ID 생성
examRepository.save(exam);

// ExamId를 사용해 Session 생성 및 설정
Session session = new Session();
session.setSessionId(exam.getExamId()); // ExamId와 동일하게 설정
session.setExam(exam);
sessionRepository.save(session);

return new ExamResponseDTO(
exam.getExamId(),
exam.getExamName(),
exam.getExamSemester(),
exam.getExamStudentNumber(),
exam.getExamLocation(),
exam.getExamDate(),
exam.getExamStartTime(),
exam.getExamDuration(),
exam.getExamStatus(),
exam.getExamNotice(),
session.getSessionId(),
exam.getExamRandomCode()
);
}

// 특정 시험 ID로 존재 여부 확인
Expand Down Expand Up @@ -135,7 +191,7 @@ public ExamResponseDTO getExamByCode(String examCode) {
// 특정 Exam ID로 사용자 리스트 조회
public UserListResponseDTO getUserListByExamId(Integer examId) {
Exam exam = examRepository.findById(examId)
.orElseThrow(() -> new IllegalArgumentException("시험을 찾을 수 없습니다"));
.orElseThrow(() -> new BaseException(BaseResponseCode.NOT_FOUND_EXAM));

List<UserListResponseDTO.UserInfo> users = new ArrayList<>();
List<Session> sessions = sessionRepository.findByExam_ExamId(examId); // 수정된 부분
Expand Down Expand Up @@ -164,12 +220,11 @@ public UserListResponseDTO getUserListByExamId(Integer examId) {
);
}


// 특정 Exam ID와 User ID로 User 상세 정보 조회
public UserDetailResponseDTO getUserDetailByExamIdAndUserId(Integer examId, Integer userId) {
List<Session> sessions = sessionRepository.findByExam_ExamId(examId); // 수정된 부분
List<Session> sessions = sessionRepository.findByExam_ExamId(examId);
if (sessions.isEmpty()) {
throw new IllegalArgumentException("시험을 찾을 수 없거나 세션이 없습니다");
throw new BaseException(BaseResponseCode.NOT_FOUND_SESSION);
}

Optional<User> userOpt = sessions.stream()
Expand All @@ -178,8 +233,7 @@ public UserDetailResponseDTO getUserDetailByExamIdAndUserId(Integer examId, Inte
.map(Optional::get)
.findFirst();

User user = userOpt.orElseThrow(() -> new IllegalArgumentException("사용자를 찾을 수 없습니다"));

User user = userOpt.orElseThrow(() -> new BaseException(BaseResponseCode.NOT_FOUND_USER));

List<UserDetailResponseDTO.CheatingStatistic> cheatingStatistics = cheatingStatisticsRepository.findByUserId(userId).stream()
.map(stat -> {
Expand Down Expand Up @@ -216,4 +270,5 @@ public UserDetailResponseDTO getUserDetailByExamIdAndUserId(Integer examId, Inte
cheatingVideos
);
}

}
18 changes: 0 additions & 18 deletions src/frontend/eyesee-admin/.eslintrc.json

This file was deleted.

40 changes: 0 additions & 40 deletions src/frontend/eyesee-admin/.gitignore

This file was deleted.

Loading

0 comments on commit 5b5b934

Please sign in to comment.