package com.nju.edu.eval.service.serviceImpl; import cn.seecoder.bok.common.QuestionType; import com.alibaba.fastjson.JSON; import com.nju.edu.eval.data.dao.*; import com.nju.edu.eval.data.entity.*; import com.nju.edu.eval.exception.MyServiceException; import com.nju.edu.eval.manager.QuestionManager; import com.nju.edu.eval.model.vo.exam.*; import com.nju.edu.eval.model.vo.logdata.ExamLog; import com.nju.edu.eval.model.vo.question.QuestionAndScoreVO; import com.nju.edu.eval.service.ExamService; import com.nju.edu.eval.service.convertor.ExamConvertor; import com.nju.edu.eval.util.InviteCodeUtil; import com.nju.edu.eval.util.LogTracingUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import java.util.*; import java.util.stream.Collectors; /** * @author mars */ @Service public class ExamServiceImpl implements ExamService { private final ExamDao examDao; private final CourseDao courseDao; private final UserDao userDao; private final ScoreDao scoreDao; private final SampleExamPaperDao sampleExamPaperDao; private final QuestionManager questionManager; @Autowired public ExamServiceImpl(ExamDao examDao, CourseDao courseDao, UserDao userDao, ScoreDao scoreDao, QuestionManager questionManager, SampleExamPaperDao sampleExamPaperDao) { this.examDao = examDao; this.courseDao = courseDao; this.userDao = userDao; this.scoreDao = scoreDao; this.questionManager = questionManager; this.sampleExamPaperDao = sampleExamPaperDao; } @Override public NewExamVO createExam(CreateExamVO examVO, Integer creatorId) { User user = userDao.findById(creatorId).get(); Course course = courseDao.findById(examVO.getCourseId()).get(); Exam exam = new Exam(examVO.getExamName(), examVO.getPosition(), examVO.getSkills(), examVO.getStartTime(), examVO.getEndTime(), examVO.getComment(), user, course); exam.setIsHidden(0); // 只有非公开的考试才需要邀请码 if (!examVO.getIsPublic()) { exam.setIsPublic(0); exam.setInviteCode(InviteCodeUtil.produceInviteCode()); } else { exam.setIsPublic(1); } if (examVO.getAntiCheating()) { exam.setAntiCheating(1); } else { exam.setAntiCheating(0); } examDao.save(exam); // 日志输出 LogTracingUtil.logExam(exam, 0); // List questionVOs = questionManager.getRecommendQuestions(examVO.getSkills(), examVO.getDifficulty()); return new NewExamVO(exam.getId(), exam.getInviteCode(), exam.getDifficulty()); } @Override public ExamListAndNumVO getExamList(int userId, int pageSize, int pageNum) { // Page examEntities = examDao.findAll(PageRequest.of(pageNum, pageSize, Sort.by(Sort.Direction.DESC, "startTime"))); // List examVOList = examEntities.get() // .map(ExamConvertor::convertToVO).collect(Collectors.toList()); // return new ExamListAndNumVO(examVOList, (int) examEntities.getTotalElements()); List exams = examDao.findAllByIsHidden(0); List examVOList = exams.stream() .sorted(Comparator.comparing(Exam::getStartTime).reversed()) .filter(exam -> exam.getIsHidden() == 0) .skip(pageSize * (pageNum - 1)).limit(pageSize) .map(ExamConvertor::convertToVO).collect(Collectors.toList()); User user = userDao.findById(userId).orElse(null); List currentUserExams = user.getExams(); for (ExamVO examVO : examVOList) { Exam exam = examDao.findById(examVO.getExamId()).orElse(null); if (currentUserExams.contains(exam)) { examVO.setIsJoined(true); } } return new ExamListAndNumVO(examVOList, (int) exams.size()); } @Override public List getExamListOfTimeRange(Date startTime, Date endTime) { List examList = examDao.findAllByStartTimeBetweenOrderByStartTime(startTime, endTime); return examList.stream().map(ExamConvertor::convertToExamInfoVO).collect(Collectors.toList()); } @Override public ExamVO getExamById(Integer id) { Exam exam = examDao.findById(id).orElse(null); return ExamConvertor.convertToVO(exam); } @Override public QuestionAndScoreVO getExamQuestionAndScoreById(Integer id) { Exam exam = examDao.findById(id).orElse(null); if (exam == null) { throw new MyServiceException("A0411", "没有对应的考试"); } if (exam.getQuestionAndScore().size() == 0) { throw new MyServiceException("A0411", "该考试还未设置题目"); } return new QuestionAndScoreVO(exam.getQuestionAndScore()); } @Override public List getCodeQuestionIdsByExamId(Integer id) { Exam exam = examDao.findById(id).orElse(null); if (exam == null) { throw new MyServiceException("A0411", "没有对应的考试"); } Set questionIds = exam.getQuestionAndScore().keySet(); return questionIds.stream() .filter(questionId -> questionManager.getQuestionById(questionId).get().getType() == QuestionType.CODE) .collect(Collectors.toList()); } @Override public void updateQuestionsOfExam(Integer examId, QuestionScoreMapVO questionScoreMapVO) { Exam exam = examDao.findById(examId).orElse(null); if (exam == null) { throw new MyServiceException("A0411", "没有对应的考试"); } Map questionScoreMap = questionScoreMapVO.getQuestionScoreMap(); // for (Map.Entry entry : questionScoreMap.entrySet()) { // exam.getQuestionAndScore().put(entry.getKey(), entry.getValue()); // } exam.setQuestionAndScore(questionScoreMap); examDao.save(exam); // 日志输出 LogTracingUtil.logExam(exam, 1); } @Override public Optional extendExamTime(Integer examId, Date endTime) throws MyServiceException { Exam exam = examDao.findById(examId).orElse(null); if (exam != null) { if (endTime.before(exam.getStartTime()) || endTime.before(exam.getEndTime())) { throw new MyServiceException("A0420", "结束时间不能早于原先结束时间和开始时间"); } exam.setEndTime(endTime); examDao.save(exam); // 日志输出 LogTracingUtil.logExam(exam, 1); } else { throw new MyServiceException("A0411", "没有对应的考试"); } return Optional.of(exam); } @Override public ExamListAndNumVO getExamsByCurrentStudent(Integer id, int pageSize, int pageNum, int state) { User student = userDao.findById(id).orElse(null); if (student != null) { List exams = student.getExams(); return new ExamListAndNumVO( exams.stream() .sorted(Comparator.comparing(Exam::getStartTime).reversed()) .filter(exam -> state == 0 || exam.getState().ordinal() + 1 == state) .filter(exam -> exam.getIsHidden() == 0) .skip(pageSize * (pageNum - 1)).limit(pageSize) .map(ExamConvertor::convertToJoinedVO).collect(Collectors.toList()), //输出总个数,用于前端分页 (int) exams.stream().filter(exam -> state == 0 || exam.getState().ordinal() + 1 == state).filter(exam -> exam.getIsHidden() == 0).count()); } else { throw new MyServiceException("A0201", "用户账号不存在"); } } @Override public ExamListAndNumVO getExamsCreatedByCurrentTeacherOrHR(Integer id, int pageSize, int pageNum, int state) { User user = userDao.findById(id).orElse(null); if (user != null) { return new ExamListAndNumVO(examDao.findAllByCreator_Id(user.getId()).stream() .filter(exam -> state == 0 || exam.getState().ordinal() + 1 == state) .sorted(Comparator.comparing(Exam::getStartTime).reversed()) .skip(pageSize * (pageNum - 1)).limit(pageSize) .map(ExamConvertor::convertToVO).collect(Collectors.toList()), //输出总个数,用于前端分页 (int) examDao.findAllByCreator_Id(user.getId()).stream() .filter(exam -> state == 0 || exam.getState().ordinal() + 1 == state).count()); } else { throw new MyServiceException("A0201", "用户账号不存在"); } } @Override public boolean takeExam(Integer userId, Integer examId, String inviteCodeInput) { User user = userDao.findById(userId).orElse(null); System.out.println(user.getExams()); Exam exam = examDao.findById(examId).orElse(null); if (user.getExams().contains(exam)) { throw new MyServiceException("A0506", "已加入考试!"); } if (user != null) { String correctInviteCode = exam.getInviteCode(); if (exam.getIsPublic() == 1 || correctInviteCode.equals(inviteCodeInput)) { // List examsOfUser = user.getExams(); // // 更新用户参加的考试 // examsOfUser.add(exam); // userDao.save(user); Score score = new Score(user, exam); scoreDao.save(score); return true; } else { throw new MyServiceException("A0210", "邀请码输入错误"); } } else { throw new MyServiceException("A0201", "用户账号不存在"); } } @Override public void setExamQuestionsBySampleExamPaper(int examId, int sampleExamPaperId) { Exam exam = examDao.findById(examId).orElse(null); SampleExamPaper sampleExamPaper = sampleExamPaperDao.findById(sampleExamPaperId).orElse(null); if (exam == null) { throw new MyServiceException("A0201", "无对应的考试"); } if (sampleExamPaper == null) { throw new MyServiceException("A0201", "无对应样卷"); } Map questionAndScore = new HashMap<>(sampleExamPaper.getQuestionAndScore()); exam.setQuestionAndScore(questionAndScore); examDao.save(exam); // 日志输出 LogTracingUtil.logExam(exam, 0); } @Override public boolean updateExamName (Integer userId, Integer examId, String name){ Exam exam = examDao.findById(examId).orElse(null); if (exam == null) { throw new MyServiceException("A0201", "无对应的考试"); } exam.setExamName(name); examDao.save(exam); // 日志输出 LogTracingUtil.logExam(exam, 1); return true; } @Override public boolean setIsHidden (Integer userId, Integer examId, Integer hidden){ Exam exam = examDao.findById(examId).orElse(null); if (exam == null) { throw new MyServiceException("A0201", "无对应的考试"); } exam.setIsHidden(hidden); examDao.save(exam); // 日志输出 LogTracingUtil.logExam(exam, 1); return true; } @Override public List getRecommendExam() { //todo 目前只是推荐最晚开始的开放测试 List examList = examDao.findAllByIsHidden(0); return examList.stream() .filter(exam -> exam.getCourse().getIsPublic() == 1) .sorted(Comparator.comparing(Exam::getStartTime).reversed()) .map(ExamConvertor::convertToExamInfoVO).collect(Collectors.toList()); } @Override public List getRecommendExam(Integer courseId) { Course course = courseDao.findById(courseId).orElse(null); if(course == null) { throw new MyServiceException("A0201", "无对应的课程"); } else if(course.getIsPublic() == 0) { throw new MyServiceException("A0201", "对应课程是私有课程无法推荐"); } //todo 目前只是推荐最晚开始的开放测试 List examList = examDao.findAllByCourseId(courseId); return examList.stream() .filter(exam -> exam.getIsHidden() == 0) .sorted(Comparator.comparing(Exam::getStartTime).reversed()) .map(ExamConvertor::convertToExamInfoVO).collect(Collectors.toList()); } @Override public List getExamByCourseId (Integer courseId) { return examDao.findAllByCourseId(courseId).stream() .sorted(Comparator.comparing(Exam::getStartTime).reversed()) .map(ExamConvertor::convertToVO).collect(Collectors.toList()); } @Override public List getExamByCourseIdAndIsHiddenFalse (Integer courseId, Integer userId) { List examVOList = examDao.findAllByCourseIdAndIsHidden(courseId, 0).stream() .sorted(Comparator.comparing(Exam::getStartTime).reversed()) .map(ExamConvertor::convertToVO).collect(Collectors.toList()); User user = userDao.findById(userId).orElse(null); if (user == null) { throw new MyServiceException("A0201", "用户账号不存在"); } else { List currentUserExams = user.getExams(); for (ExamVO examVO : examVOList) { Exam exam = examDao.findById(examVO.getExamId()).orElse(null); if (currentUserExams.contains(exam)) { examVO.setIsJoined(true); } } return examVOList; } } @Override public ExamListAndNumVO getExamLIstByCurrentStudent(Integer id) { User student = userDao.findById(id).orElse(null); if (student != null) { List exams = student.getExams(); return new ExamListAndNumVO( exams.stream() .sorted(Comparator.comparing(Exam::getStartTime).reversed()) .map(ExamConvertor::convertToJoinedVO).collect(Collectors.toList()), //输出总个数,用于前端分页 (int) exams.stream().filter(exam -> exam.getIsHidden() == 0).count()); } else { throw new MyServiceException("A0201", "用户账号不存在"); } } }