| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- package com.nju.edu.eval.service.serviceImpl;
- import cn.seecoder.codejudge.client.JudgeDTO;
- import cn.seecoder.codejudge.client.JudgeResult;
- import cn.seecoder.codejudge.client.JudgeResultType;
- import cn.seecoder.judgement.dto.StudentAnswerDTO;
- import cn.seecoder.judgement.vo.JudgedAnswersVO;
- import com.nju.edu.eval.data.dao.ExamDao;
- import com.nju.edu.eval.data.dao.RecordDao;
- import com.nju.edu.eval.data.dao.ScoreDao;
- import com.nju.edu.eval.data.dao.UserDao;
- import com.nju.edu.eval.data.entity.Exam;
- import com.nju.edu.eval.data.entity.QuestionRecord;
- import com.nju.edu.eval.data.entity.Score;
- import com.nju.edu.eval.data.entity.User;
- import com.nju.edu.eval.exception.MyServiceException;
- import com.nju.edu.eval.exception.ThirdPartyServiceException;
- import com.nju.edu.eval.manager.JudgeManager;
- import com.nju.edu.eval.manager.QuestionManager;
- import com.nju.edu.eval.model.vo.judge.CodeJudgeVO;
- import com.nju.edu.eval.model.vo.judge.ObjectiveJudgeResOfExerciseVO;
- import com.nju.edu.eval.model.vo.judge.ObjectiveJudgeResVO;
- import com.nju.edu.eval.model.vo.judge.ObjectiveJudgeVO;
- import com.nju.edu.eval.model.vo.logdata.AnswerDTO;
- import com.nju.edu.eval.model.vo.logdata.ExamRecordLog;
- import com.nju.edu.eval.model.vo.question.CompleteQuestionVO;
- import com.nju.edu.eval.publicdatas.enums.CodeJudgeResultType;
- import com.nju.edu.eval.service.JudgeService;
- import com.nju.edu.eval.util.LogTracingUtil;
- import com.nju.edu.logTracking.enums.SeecSystem;
- import org.apache.logging.log4j.LogBuilder;
- import org.springframework.stereotype.Service;
- import java.util.*;
- import java.util.stream.Collectors;
- /**
- * @author mars
- */
- @Service
- public class JudgeServiceImpl implements JudgeService {
- private final JudgeManager judgeManager;
- private final QuestionManager questionManager;
- private final ScoreDao scoreDao;
- private final RecordDao recordDao;
- private final ExamDao examDao;
- private final UserDao userDao;
- public JudgeServiceImpl(JudgeManager judgeManager, QuestionManager questionManager, ScoreDao scoreDao, RecordDao recordDao, ExamDao examDao, UserDao userDao) {
- this.judgeManager = judgeManager;
- this.questionManager = questionManager;
- this.scoreDao = scoreDao;
- this.recordDao = recordDao;
- this.examDao = examDao;
- this.userDao = userDao;
- }
- @Override
- public ObjectiveJudgeResVO judgeObjectiveQuestionAnswers(Integer userId, Integer examId, ObjectiveJudgeVO objectiveJudgeVO) {
- try {
- // 提交给判题系统
- JudgedAnswersVO judgedAnswersVO = judgeManager.judgeObjectiveQuestionAnswers(userId, objectiveJudgeVO);
- User user = userDao.findById(userId).orElse(null);
- Exam exam = examDao.findById(examId).orElse(null);
- Score score = scoreDao.findByUserIdAndExamId(userId, examId);
- Date currentTime = new Date();
- if (score == null) {
- score = new Score(user, exam);
- }
- score.setSubmitTime(currentTime);
- scoreDao.save(score);
- List<QuestionRecord> records = score.getRecords();
- // 存储用以打日志的错题集
- List<AnswerDTO> err = new ArrayList<>();
- double curScore = 0.0;
- // 存储用户提交的记录
- for (Map.Entry<String, StudentAnswerDTO.AnswerRecordDTO> entry : objectiveJudgeVO.getRecords().entrySet()) {
- // 获得该题满分
- assert exam != null;
- String questionId = entry.getKey();
- double scoreOfQuestion = exam.getQuestionAndScore().get(questionId);
- // 看该题是否正确
- boolean isTrue = judgedAnswersVO.getAnswers().get(questionId).getCorrect();
- // 填入错题集
- if (!isTrue)
- err.add(new AnswerDTO(questionId, scoreOfQuestion));
- double actualScore = isTrue ? scoreOfQuestion : 0;
- curScore += actualScore;
- QuestionRecord questionRecord = new QuestionRecord(user, exam, entry.getKey(), score, (String) entry.getValue().getAnswer(), actualScore, currentTime);
- records.add(questionRecord);
- }
- double maxScore = Math.max(score.getScore() - score.getObjectiveScore() + curScore, score.getScore());
- score.setObjectiveScore(Math.max(curScore, score.getObjectiveScore()));
- score.setScore(maxScore);
- scoreDao.save(score);;
- // 提交记录日志
- LogTracingUtil.logRecord(new ExamRecordLog(examId, userId, currentTime, curScore, err));
- return new ObjectiveJudgeResVO(judgedAnswersVO.getSubmitAt(), judgedAnswersVO.getSubmitNumber());
- } catch (ThirdPartyServiceException exception) {
- throw new MyServiceException(exception.getCode(), exception.getMessage());
- }
- }
- @Override
- public JudgeResult judgeCodeQuestionAnswers(Integer userId, Integer examId, String questionId, CodeJudgeVO codeJudgeVO) {
- try {
- JudgeDTO judgeDTO = new JudgeDTO();
- judgeDTO.setCode(codeJudgeVO.getCode());
- judgeDTO.setLanguage(codeJudgeVO.getLanguage());
- CompleteQuestionVO question = questionManager.getQuestionById(questionId).get();
- judgeDTO.setMemoryLimit(question.getMemoryLimit());
- judgeDTO.setInputList(question.getInputOutputMapping().entrySet().stream().map(Map.Entry<String,String>::getKey).collect(Collectors.toList()));
- judgeDTO.setOutputList(question.getInputOutputMapping().entrySet().stream().map(Map.Entry<String,String>::getValue).collect(Collectors.toList()));
- JudgeResult judgeResult = judgeManager.judgeCodeQuestionAnswers(judgeDTO);
- CodeJudgeResultType message = CodeJudgeResultType.values()[JudgeResultType.ACCEPT.ordinal()];
- for (JudgeResult.Item item : judgeResult.getResultList()) {
- if (item.getResult() != JudgeResultType.ACCEPT) {
- message = CodeJudgeResultType.values()[item.getResult().ordinal()];
- break;
- }
- }
- User user = userDao.findById(userId).orElse(null);
- Exam exam = examDao.findById(examId).orElse(null);
- Score score = scoreDao.findByUserIdAndExamId(userId, examId);
- Date currentTime = new Date();
- if (score == null) {
- score = new Score(user, exam);
- }
- score.setSubmitTime(currentTime);
- scoreDao.save(score);
- List<QuestionRecord> records = score.getRecords();
- // 获得上一次用户提交的代码分数,如果没有,那就是0
- double preScore = 0.0;
- QuestionRecord previousRecord = recordDao.findFirstByUserIdAndExamIdAndQuestionIdOrderByActualScore(userId, examId, questionId);
- if (previousRecord != null) {
- preScore = previousRecord.getActualScore();
- }
- double curScore = 0.0;
- // 存储用户提交的记录
- // 获得该题满分
- double scoreOfQuestion = exam.getQuestionAndScore().get(questionId);
- // 遍历OJ结果,如果该测试用例AC则得分
- int accecptedNum = 0;
- for (JudgeResult.Item item: judgeResult.getResultList()) {
- if (item.getResult() == JudgeResultType.ACCEPT) {
- accecptedNum++;
- }
- }
- // 获得该题满分
- curScore = ((double) accecptedNum / judgeResult.getResultList().size()) * scoreOfQuestion;
- QuestionRecord questionRecord = new QuestionRecord(user, exam, questionId, score, judgeDTO.getCode(), curScore, currentTime);
- questionRecord.setMessage(message);
- records.add(questionRecord);
- // 更新成绩报告中的分数,通过减去该题最高得分来获得
- double maxScore = Math.max(score.getScore() - preScore + curScore, score.getScore());
- score.setScore(maxScore);
- scoreDao.save(score);
- // 提交记录日志
- List<AnswerDTO> err = new ArrayList<>();
- if (curScore != scoreOfQuestion)
- err.add(new AnswerDTO(questionId, scoreOfQuestion));
- LogTracingUtil.logRecord(new ExamRecordLog(examId, userId, currentTime, curScore, err));
- return judgeResult;
- } catch (ThirdPartyServiceException exception) {
- throw new MyServiceException(exception.getCode(), exception.getMessage());
- }
- }
- @Override
- public ObjectiveJudgeResOfExerciseVO judgeObjectiveQuestionAnswersOfExercise(Integer userId, ObjectiveJudgeVO objectiveJudgeVO) {
- try {
- // 提交给判题系统
- JudgedAnswersVO judgedAnswersVO = judgeManager.judgeObjectiveQuestionAnswers(userId, objectiveJudgeVO);
- Map<String, Boolean> result = new HashMap<>();
- User user = userDao.findById(userId).orElse(null);
- Date currentTime = new Date();
- double curScore = 0.0;
- // 存储用户提交的记录
- for (Map.Entry<String, StudentAnswerDTO.AnswerRecordDTO> entry : objectiveJudgeVO.getRecords().entrySet()) {
- // 获得该题满分
- String questionId = entry.getKey();
- // 看该题是否正确
- boolean isTrue = judgedAnswersVO.getAnswers().get(questionId).getCorrect();
- result.put(questionId, isTrue);
- }
- return new ObjectiveJudgeResOfExerciseVO(result);
- } catch (ThirdPartyServiceException exception) {
- throw new MyServiceException(exception.getCode(), exception.getMessage());
- }
- }
- @Override
- public JudgeResult judgeCodeQuestionAnswersOfExercise(Integer userId, String questionId, CodeJudgeVO codeJudgeVO) {
- try {
- JudgeDTO judgeDTO = new JudgeDTO();
- judgeDTO.setCode(codeJudgeVO.getCode());
- judgeDTO.setLanguage(codeJudgeVO.getLanguage());
- CompleteQuestionVO question = questionManager.getQuestionById(questionId).get();
- judgeDTO.setMemoryLimit(question.getMemoryLimit());
- judgeDTO.setInputList(question.getInputOutputMapping().entrySet().stream().map(Map.Entry<String,String>::getKey).collect(Collectors.toList()));
- judgeDTO.setOutputList(question.getInputOutputMapping().entrySet().stream().map(Map.Entry<String,String>::getValue).collect(Collectors.toList()));
- JudgeResult judgeResult = judgeManager.judgeCodeQuestionAnswers(judgeDTO);
- return judgeResult;
- } catch (ThirdPartyServiceException exception) {
- throw new MyServiceException(exception.getCode(), exception.getMessage());
- }
- }
- }
|