Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] 제출물 평가 시스템 개선 및 ENUM 타입 생성 #96

Merged
merged 11 commits into from
Nov 20, 2024
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package com.example.epari.assignment.controller;

import com.example.epari.assignment.dto.submission.GradeRequestDto;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import com.example.epari.assignment.dto.submission.SubmissionRequestDto;
import com.example.epari.assignment.dto.submission.SubmissionResponseDto;
import com.example.epari.assignment.service.SubmissionService;
import com.example.epari.global.annotation.CurrentUserEmail;
import com.example.epari.user.domain.Student;
import com.example.epari.user.repository.StudentRepository;

import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
Expand Down Expand Up @@ -50,6 +48,22 @@ public ResponseEntity<SubmissionResponseDto> getSubmission(
);
}

@PreAuthorize("hasRole('STUDENT')")
@GetMapping
public ResponseEntity<SubmissionResponseDto> getStudentSubmission(
@PathVariable Long courseId,
@PathVariable Long assignmentId,
@CurrentUserEmail String email) {
Student student = studentRepository.findByEmail(email)
.orElseThrow(() -> new IllegalArgumentException("학생 정보를 찾을 수 없습니다."));

SubmissionResponseDto submission = submissionService.getStudentSubmission(
courseId, assignmentId, student.getId());

// 제출물이 없는 경우 404 대신 200 OK와 null을 반환
return ResponseEntity.ok(submission);
}

@PreAuthorize("hasRole('STUDENT')")
@PutMapping("/{submissionId}")
public ResponseEntity<SubmissionResponseDto> updateSubmission(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
package com.example.epari.assignment.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.epari.assignment.dto.submission.SubmissionResponseDto;
import com.example.epari.assignment.service.SubmissionService;

import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
Expand Down
20 changes: 14 additions & 6 deletions src/main/java/com/example/epari/assignment/domain/Submission.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.List;

import com.example.epari.global.common.base.BaseTimeEntity;
import com.example.epari.global.common.enums.SubmissionGrade;
import com.example.epari.global.common.enums.SubmissionStatus;
import com.example.epari.user.domain.Student;

Expand Down Expand Up @@ -42,8 +43,9 @@ public class Submission extends BaseTimeEntity {
private String description;

@Column
private String grade;
private SubmissionGrade grade;

@Column
private String feedback;

@ManyToOne(fetch = FetchType.LAZY)
Expand All @@ -59,31 +61,37 @@ public class Submission extends BaseTimeEntity {

@Enumerated(EnumType.STRING)
@Column(nullable = false)
private SubmissionStatus status = SubmissionStatus.SUBMITTED;
private SubmissionStatus status = SubmissionStatus.NOT_SUBMITTED;

@Builder
private Submission(String description, Assignment assignment, Student student) {
private Submission(String description, Assignment assignment, Student student, SubmissionGrade grade) {
this.description = description;
this.assignment = assignment;
this.student = student;
this.grade = "F";
this.grade = SubmissionGrade.UNDER_REVIEW;
this.status = SubmissionStatus.SUBMITTED;
}

public static Submission createSubmission(String description,
Assignment assignment, Student student) {
return Submission.builder()
Submission submission = Submission.builder()
.description(description)
.assignment(assignment)
.student(student)
.build();
submission.submit();
return submission;
}

public void submit() {
this.status = SubmissionStatus.SUBMITTED;
}

public void updateSubmission(String description) {
this.description = description;
}

public void updateGrade(String grade, String feedback) {
public void updateGrade(SubmissionGrade grade, String feedback) {
this.grade = grade;
this.feedback = feedback;
this.status = SubmissionStatus.GRADED;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.example.epari.assignment.dto.assignment;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

import com.example.epari.assignment.domain.Assignment;
import com.example.epari.assignment.dto.file.AssignmentFileResponseDto;
import com.example.epari.user.domain.Instructor;

import lombok.Builder;
import lombok.Getter;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Getter
@Builder
public class AssignmentResponseDto {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.example.epari.assignment.dto.submission;

import com.example.epari.global.common.enums.SubmissionGrade;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class GradeRequestDto {
private String grade;
private SubmissionGrade grade;
private String feedback;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ public class SubmissionResponseDto {

private String description;

private String grade; // 추가
private String grade;

private String feedback; // 추가
private String feedback;

private String status;

private LocalDateTime createdAt;

Expand Down Expand Up @@ -57,8 +59,9 @@ public static SubmissionResponseDto from(Submission submission) {
return SubmissionResponseDto.builder()
.id(submission.getId())
.description(submission.getDescription())
.grade(submission.getGrade()) // 추가
.feedback(submission.getFeedback()) // 추가
.grade(submission.getGrade() != null ? submission.getGrade().getDescription() : null)
.feedback(submission.getFeedback())
.status(submission.getStatus().getDescription())
.createdAt(submission.getCreatedAt())
.updatedAt(submission.getUpdatedAt())
.files(submission.getFiles().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import org.springframework.data.jpa.repository.JpaRepository;

import com.example.epari.assignment.domain.Submission;
import org.springframework.data.jpa.repository.Query;

public interface SubmissionRepository extends JpaRepository<Submission, Long> {
import java.util.Optional;

public interface SubmissionRepository extends JpaRepository<Submission, Long> {
@Query("SELECT s FROM Submission s WHERE s.assignment.id = :assignmentId AND s.student.id = :studentId")
Optional<Submission> findByAssignment_IdAndStudent_Id(Long assignmentId, Long studentId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.example.epari.assignment.repository.SubmissionRepository;
import com.example.epari.course.domain.Course;
import com.example.epari.course.repository.CourseRepository;
import com.example.epari.global.common.enums.SubmissionGrade;
import com.example.epari.global.common.service.S3FileService;
import com.example.epari.user.domain.Student;
import com.example.epari.user.repository.StudentRepository;
Expand All @@ -19,6 +20,7 @@
import org.springframework.web.multipart.MultipartFile;

import java.time.Duration;
import java.util.Optional;

@Slf4j
@Service
Expand Down Expand Up @@ -51,15 +53,34 @@ public SubmissionResponseDto addSubmission(Long courseId, Long assignmentId, Sub
Student student = studentRepository.findById(studentId)
.orElseThrow(() -> new IllegalArgumentException("학생 정보를 찾을 수 없습니다."));

Submission submission = Submission.createSubmission(requestDto.getDescription(), assignment, student);
// 기존 제출물이 있는지 확인
Optional<Submission> existingSubmission = submissionRepository
.findByAssignment_IdAndStudent_Id(assignmentId, studentId);

Submission submission;
if (existingSubmission.isPresent()) {
// 기존 제출물이 있으면 업데이트
submission = existingSubmission.get();
submission.updateSubmission(requestDto.getDescription());

// 새로운 파일 추가 전에 기존 파일 유지
} else {
// 새로운 제출물 생성
submission = Submission.createSubmission(requestDto.getDescription(), assignment, student);
}

// 파일 업로드 처리
if (requestDto.getFiles() != null && !requestDto.getFiles().isEmpty()) {
for (MultipartFile file : requestDto.getFiles()) {
String fileUrl = s3FileService.uploadFile("submissions", file);

SubmissionFile submissionFile = SubmissionFile.createSubmissionFile(file.getOriginalFilename(),
extractStoredFileName(fileUrl), fileUrl, file.getSize(), submission);
SubmissionFile submissionFile = SubmissionFile.createSubmissionFile(
file.getOriginalFilename(),
extractStoredFileName(fileUrl),
fileUrl,
file.getSize(),
submission
);

submission.addFile(submissionFile);
}
Expand All @@ -86,6 +107,26 @@ public SubmissionResponseDto getSubmissionById(Long courseId, Long assignmentId,
return SubmissionResponseDto.from(submission);
}

/**
* 학생의 과제 제출물 조회
*/
public SubmissionResponseDto getStudentSubmission(Long courseId, Long assignmentId, Long studentId) {
Optional<Submission> submission = submissionRepository.findByAssignment_IdAndStudent_Id(assignmentId, studentId);

// 제출물이 없으면 null 반환 (404 대신)
if (submission.isEmpty()) {
return null;
}

Submission foundSubmission = submission.get();
// 제출된 과제가 해당 코스에 속하는지 확인
if (!foundSubmission.getAssignment().getCourse().getId().equals(courseId)) {
throw new IllegalArgumentException("해당 과제의 제출물이 아닙니다.");
}

return SubmissionResponseDto.from(foundSubmission);
}

/**
* 과제 제출물 수정
*/
Expand Down Expand Up @@ -121,7 +162,7 @@ public SubmissionResponseDto updateSubmission(Long courseId, Long assignmentId,
* 과제 채점
*/
@Transactional
public SubmissionResponseDto gradeSubmission(Long submissionId, String grade, String feedback) {
public SubmissionResponseDto gradeSubmission(Long submissionId, SubmissionGrade grade, String feedback) {
Submission submission = submissionRepository.findById(submissionId)
.orElseThrow(() -> new IllegalArgumentException("제출된 과제를 찾을 수 없습니다."));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.epari.global.common.enums;

import lombok.Getter;

@Getter
public enum SubmissionGrade {
PASS("pass"),
NONE_PASS("none pass"),
UNDER_REVIEW("검토중");

private final String description;

SubmissionGrade(String description) {
this.description = description;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
public enum SubmissionStatus {
NOT_SUBMITTED("미제출"),
SUBMITTED("제출완료"),
GRADING("채점중"),
GRADED("채점완료");

private final String description;
Expand Down
Loading