Skip to content

Commit

Permalink
BE: [fix] 시험 등록 시 On/Off 기능 추가 및 CheatingStatistic 수정
Browse files Browse the repository at this point in the history
BE: [fix] 시험 등록 시 On/Off 기능 추가 및 CheatingStatistic 수정
  • Loading branch information
JongbeomLee623 authored Dec 1, 2024
2 parents 2c6c7b0 + 3a8b27d commit 3cf4416
Show file tree
Hide file tree
Showing 15 changed files with 267 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling // 스케줄러 활성화
public class EyeseeApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
"/api/admins/login",
"/api/sessions/join",
"/api/sessions/student",
"/api/cheatings"
"/api/cheatings",
"/api/exams/cheating-types"
).permitAll() // 인증 불필요 경로
.anyRequest().authenticated() // 나머지 요청은 인증 필요
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ public ResponseEntity<BaseResponse<UserDetailResponseDTO>> getUserDetailByExamId
@PathVariable Integer examId,
@PathVariable Integer userId) {
UserDetailResponseDTO response = examService.getUserDetailByExamIdAndUserId(examId, userId);

return ResponseEntity.ok(new BaseResponse<>(response, "학생 상세 정보 조회 성공"));
}

Expand Down Expand Up @@ -165,4 +166,10 @@ public ResponseEntity<InputStreamResource> downloadExamReport(@PathVariable Inte
}


@GetMapping("/{examId}/cheating-types")
public ResponseEntity<Map<String, Boolean>> getCheatingTypes(@PathVariable Integer examId) {
Map<String, Boolean> cheatingTypes = examService.getCheatingTypesByExamId(examId);
return ResponseEntity.ok(cheatingTypes);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.fortune.eyesee.dto;

import lombok.Data;
import java.util.ArrayList;
import java.util.List;

@Data
public class CheatingStatistic {
private Integer cheatingStatisticsId;
private String koreanTypeName;
private Integer cheatingCount;
private String detectedTime;

// 생성자
public CheatingStatistic(Integer cheatingStatisticsId, String koreanTypeName, Integer cheatingCount, String detectedTime) {
this.cheatingStatisticsId = cheatingStatisticsId;
this.koreanTypeName = koreanTypeName;
this.cheatingCount = cheatingCount;
this.detectedTime = detectedTime;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;

@Data
public class ExamRequestDTO {
Expand All @@ -17,4 +18,6 @@ public class ExamRequestDTO {
private Integer examQuestionNumber;
private Integer examTotalScore;
private String examNotice;

private List<String> cheatingTypes; // 부정행위 유형 리스트
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package com.fortune.eyesee.dto;


public class TokenWithUserIdResponseDTO extends TokenResponseDTO {
private Integer userId;
private Integer examId;

public TokenWithUserIdResponseDTO(String accessToken, String refreshToken, Integer userId) {
public TokenWithUserIdResponseDTO(String accessToken, String refreshToken, Integer userId, Integer examId) {
super(accessToken, refreshToken);
this.userId = userId;
this.examId = examId;
}

public Integer getUserId() {
return userId;
}

public Integer getExamId() {
return examId;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.fortune.eyesee.dto;

import lombok.Data;

import java.time.LocalTime;
import java.util.List;

@Data
Expand All @@ -11,32 +13,39 @@ public class UserDetailResponseDTO {
private Integer seatNum;
private List<CheatingStatistic> cheatingStatistics;
private List<CheatingVideo> cheatingVideos;
private String examName;
private LocalTime examStartTime; // 시험 시작 시간
private Integer examDuration; // 진행 시간

public UserDetailResponseDTO(Integer userId, String userName, Integer userNum, Integer seatNum,
List<CheatingStatistic> cheatingStatistics, List<CheatingVideo> cheatingVideos) {
List<CheatingStatistic> cheatingStatistics, List<CheatingVideo> cheatingVideos
, String examName, LocalTime examStartTime, Integer examDuration) {
this.userId = userId;
this.userName = userName;
this.userNum = userNum;
this.seatNum = seatNum;
this.cheatingStatistics = cheatingStatistics;
this.cheatingVideos = cheatingVideos;
this.examName = examName;
this.examStartTime = examStartTime;
this.examDuration = examDuration;
}

@Data
public static class CheatingStatistic {
private Integer cheatingStatisticsId;
private String cheatingTypeName; // String으로 변경
private Integer cheatingCount;
private String detectedTime;

// 부정행위 통계 생성자
public CheatingStatistic(Integer cheatingStatisticsId, String cheatingTypeName, Integer cheatingCount, String detectedTime) {
this.cheatingStatisticsId = cheatingStatisticsId;
this.cheatingTypeName = cheatingTypeName;
this.cheatingCount = cheatingCount;
this.detectedTime = detectedTime;
}
}
// @Data
// public static class CheatingStatistic {
// private Integer cheatingStatisticsId;
// private String cheatingTypeName; // String으로 변경git
// private Integer cheatingCount;
// private String detectedTime;
//
// // 부정행위 통계 생성자
// public CheatingStatistic(Integer cheatingStatisticsId, String cheatingTypeName, Integer cheatingCount, String detectedTime) {
// this.cheatingStatisticsId = cheatingStatisticsId;
// this.cheatingTypeName = cheatingTypeName;
// this.cheatingCount = cheatingCount;
// this.detectedTime = detectedTime != null ? detectedTime : "N/A"; // 기본값 "N/A"
// }
// }


@Data
Expand All @@ -51,7 +60,7 @@ public CheatingVideo(Integer videoId, String startTime, String endTime, String f
this.videoId = videoId;
this.startTime = startTime;
this.endTime = endTime;
this.filepath = filepath;
this.filepath = filepath != null ? filepath : "No file available"; // 기본값
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ public class CheatingType {
private Integer cheatingTypeId;

private String cheatingTypeName; // 부정행위 종류 이름
private String koreanTypeName; // 한글 부정행위 이름
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fortune.eyesee.enums.ExamStatus;
import com.fortune.eyesee.utils.CheatingTypeConverter;
import lombok.Data;

import jakarta.persistence.*;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;


@Entity
Expand Down Expand Up @@ -41,4 +43,7 @@ public class Exam {

@OneToOne(mappedBy = "exam", cascade = CascadeType.ALL)
private Session session; // 1:1 관계 설정

@Convert(converter = CheatingTypeConverter.class) // JSON 컬럼 변환기
private List<String> cheatingTypes;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.fortune.eyesee.enums;

public enum CheatingTypeEnum {
LOOK_AROUND("look_around", "주변 응시"),
REPEATED_GAZE("repeated_gaze", "반복된 응시"),
OBJECT("object", "부정행위 물체 감지"),
FACE_ABSENCE_LONG("face_absence_long", "장기 화면 이탈"),
FACE_ABSENCE_REPEAT("face_absence_repeat", "반복 화면 이탈"),
HAND_GESTURE("hand_gesture", "특정 손동작 반복"),
HEAD_TURN_LONG("head_turn_long", "고개 돌림 유지"),
HEAD_TURN_REPEAT("head_turn_repeat", "고개 돌림 반복");

private final String englishName;
private final String koreanName;

CheatingTypeEnum(String englishName, String koreanName) {
this.englishName = englishName;
this.koreanName = koreanName;
}

public String getEnglishName() {
return englishName;
}

public String getKoreanName() {
return koreanName;
}

public static String getKoreanNameByEnglish(String englishName) {
for (CheatingTypeEnum type : values()) {
if (type.getEnglishName().equalsIgnoreCase(englishName)) { // 대소문자 무시 비교
return type.getKoreanName();
}
}
return "알 수 없음";
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,40 @@
package com.fortune.eyesee.repository;


import com.fortune.eyesee.dto.CheatingStatistic;
import com.fortune.eyesee.dto.UserDetailResponseDTO;
import com.fortune.eyesee.entity.CheatingStatistics;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface CheatingStatisticsRepository extends JpaRepository<CheatingStatistics, Integer> {
List<CheatingStatistics> findByUserId(Integer userId);
int countByUserId(Integer userId);

//int countByUserId(Integer userId);
// 특정 userId와 cheatingTypeId에 대한 통계 정보를 조회
CheatingStatistics findByUserIdAndCheatingTypeId(Integer userId, Integer cheatingTypeId);

@Query("""
SELECT new com.fortune.eyesee.dto.CheatingStatistic(
cs.cheatingStatisticsId,
ct.koreanTypeName,
cs.cheatingCount,
CAST(dc.detectedTime AS string)
)
FROM CheatingStatistics cs
JOIN CheatingType ct ON cs.cheatingTypeId = ct.cheatingTypeId
LEFT JOIN DetectedCheating dc ON cs.userId = dc.userId AND cs.cheatingTypeId = dc.cheatingTypeId
WHERE cs.userId = :userId
ORDER BY CAST(dc.detectedTime AS string) ASC
""")
List<CheatingStatistic> findStatisticsByUserId(@Param("userId") Integer userId);

// 특정 사용자 ID의 부정행위 횟수를 합산
@Query("SELECT SUM(cs.cheatingCount) FROM CheatingStatistics cs WHERE cs.userId = :userId")
Integer findTotalCheatingCountByUserId(@Param("userId") Integer userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
import com.fortune.eyesee.enums.ExamStatus;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.Optional;

Expand All @@ -28,4 +32,13 @@ public interface ExamRepository extends JpaRepository<Exam, Integer> {
// 특정 sessionId와 adminId를 기준으로 Exam 데이터 조회
Optional<Exam> findBySession_SessionIdAndAdmin_AdminId(Integer sessionId, Integer adminId);

@Query("""
SELECT e
FROM Exam e
WHERE
e.examDate >= :currentDate OR
(e.examDate = :currentDate AND e.examStartTime >= :currentTime)
""")
List<Exam> findActiveExams(@Param("currentDate") LocalDate currentDate, @Param("currentTime") LocalTime currentTime);

}
Loading

0 comments on commit 3cf4416

Please sign in to comment.