ExamServiceImpl.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. package com.nju.edu.eval.service.serviceImpl;
  2. import cn.seecoder.bok.common.QuestionType;
  3. import com.alibaba.fastjson.JSON;
  4. import com.nju.edu.eval.data.dao.*;
  5. import com.nju.edu.eval.data.entity.*;
  6. import com.nju.edu.eval.exception.MyServiceException;
  7. import com.nju.edu.eval.manager.QuestionManager;
  8. import com.nju.edu.eval.model.vo.exam.*;
  9. import com.nju.edu.eval.model.vo.logdata.ExamLog;
  10. import com.nju.edu.eval.model.vo.question.QuestionAndScoreVO;
  11. import com.nju.edu.eval.service.ExamService;
  12. import com.nju.edu.eval.service.convertor.ExamConvertor;
  13. import com.nju.edu.eval.util.InviteCodeUtil;
  14. import com.nju.edu.eval.util.LogTracingUtil;
  15. import org.springframework.beans.factory.annotation.Autowired;
  16. import org.springframework.data.domain.Page;
  17. import org.springframework.data.domain.PageRequest;
  18. import org.springframework.data.domain.Sort;
  19. import org.springframework.stereotype.Service;
  20. import java.util.*;
  21. import java.util.stream.Collectors;
  22. /**
  23. * @author mars
  24. */
  25. @Service
  26. public class ExamServiceImpl implements ExamService {
  27. private final ExamDao examDao;
  28. private final CourseDao courseDao;
  29. private final UserDao userDao;
  30. private final ScoreDao scoreDao;
  31. private final SampleExamPaperDao sampleExamPaperDao;
  32. private final QuestionManager questionManager;
  33. @Autowired
  34. public ExamServiceImpl(ExamDao examDao, CourseDao courseDao, UserDao userDao, ScoreDao scoreDao, QuestionManager questionManager, SampleExamPaperDao sampleExamPaperDao) {
  35. this.examDao = examDao;
  36. this.courseDao = courseDao;
  37. this.userDao = userDao;
  38. this.scoreDao = scoreDao;
  39. this.questionManager = questionManager;
  40. this.sampleExamPaperDao = sampleExamPaperDao;
  41. }
  42. @Override
  43. public NewExamVO createExam(CreateExamVO examVO, Integer creatorId) {
  44. User user = userDao.findById(creatorId).get();
  45. Course course = courseDao.findById(examVO.getCourseId()).get();
  46. Exam exam = new Exam(examVO.getExamName(), examVO.getPosition(),
  47. examVO.getSkills(), examVO.getStartTime(),
  48. examVO.getEndTime(), examVO.getComment(), user, course);
  49. exam.setIsHidden(0);
  50. // 只有非公开的考试才需要邀请码
  51. if (!examVO.getIsPublic()) {
  52. exam.setIsPublic(0);
  53. exam.setInviteCode(InviteCodeUtil.produceInviteCode());
  54. } else {
  55. exam.setIsPublic(1);
  56. }
  57. if (examVO.getAntiCheating()) {
  58. exam.setAntiCheating(1);
  59. } else {
  60. exam.setAntiCheating(0);
  61. }
  62. examDao.save(exam);
  63. // 日志输出
  64. LogTracingUtil.logExam(exam, 0);
  65. // List<CompleteQuestionVO> questionVOs = questionManager.getRecommendQuestions(examVO.getSkills(), examVO.getDifficulty());
  66. return new NewExamVO(exam.getId(), exam.getInviteCode(), exam.getDifficulty());
  67. }
  68. @Override
  69. public ExamListAndNumVO getExamList(int userId, int pageSize, int pageNum) {
  70. // Page<Exam> examEntities = examDao.findAll(PageRequest.of(pageNum, pageSize, Sort.by(Sort.Direction.DESC, "startTime")));
  71. // List<ExamVO> examVOList = examEntities.get()
  72. // .map(ExamConvertor::convertToVO).collect(Collectors.toList());
  73. // return new ExamListAndNumVO(examVOList, (int) examEntities.getTotalElements());
  74. List<Exam> exams = examDao.findAllByIsHidden(0);
  75. List<ExamVO> examVOList = exams.stream()
  76. .sorted(Comparator.comparing(Exam::getStartTime).reversed())
  77. .filter(exam -> exam.getIsHidden() == 0)
  78. .skip(pageSize * (pageNum - 1)).limit(pageSize)
  79. .map(ExamConvertor::convertToVO).collect(Collectors.toList());
  80. User user = userDao.findById(userId).orElse(null);
  81. List<Exam> currentUserExams = user.getExams();
  82. for (ExamVO examVO : examVOList) {
  83. Exam exam = examDao.findById(examVO.getExamId()).orElse(null);
  84. if (currentUserExams.contains(exam)) {
  85. examVO.setIsJoined(true);
  86. }
  87. }
  88. return new ExamListAndNumVO(examVOList, (int) exams.size());
  89. }
  90. @Override
  91. public List<ExamInfoVO> getExamListOfTimeRange(Date startTime, Date endTime) {
  92. List<Exam> examList = examDao.findAllByStartTimeBetweenOrderByStartTime(startTime, endTime);
  93. return examList.stream().map(ExamConvertor::convertToExamInfoVO).collect(Collectors.toList());
  94. }
  95. @Override
  96. public ExamVO getExamById(Integer id) {
  97. Exam exam = examDao.findById(id).orElse(null);
  98. return ExamConvertor.convertToVO(exam);
  99. }
  100. @Override
  101. public QuestionAndScoreVO getExamQuestionAndScoreById(Integer id) {
  102. Exam exam = examDao.findById(id).orElse(null);
  103. if (exam == null) {
  104. throw new MyServiceException("A0411", "没有对应的考试");
  105. }
  106. if (exam.getQuestionAndScore().size() == 0) {
  107. throw new MyServiceException("A0411", "该考试还未设置题目");
  108. }
  109. return new QuestionAndScoreVO(exam.getQuestionAndScore());
  110. }
  111. @Override
  112. public List<String> getCodeQuestionIdsByExamId(Integer id) {
  113. Exam exam = examDao.findById(id).orElse(null);
  114. if (exam == null) {
  115. throw new MyServiceException("A0411", "没有对应的考试");
  116. }
  117. Set<String> questionIds = exam.getQuestionAndScore().keySet();
  118. return questionIds.stream()
  119. .filter(questionId -> questionManager.getQuestionById(questionId).get().getType() == QuestionType.CODE)
  120. .collect(Collectors.toList());
  121. }
  122. @Override
  123. public void updateQuestionsOfExam(Integer examId, QuestionScoreMapVO questionScoreMapVO) {
  124. Exam exam = examDao.findById(examId).orElse(null);
  125. if (exam == null) {
  126. throw new MyServiceException("A0411", "没有对应的考试");
  127. }
  128. Map<String, Double> questionScoreMap = questionScoreMapVO.getQuestionScoreMap();
  129. // for (Map.Entry<String, Double> entry : questionScoreMap.entrySet()) {
  130. // exam.getQuestionAndScore().put(entry.getKey(), entry.getValue());
  131. // }
  132. exam.setQuestionAndScore(questionScoreMap);
  133. examDao.save(exam);
  134. // 日志输出
  135. LogTracingUtil.logExam(exam, 1);
  136. }
  137. @Override
  138. public Optional<Exam> extendExamTime(Integer examId, Date endTime) throws MyServiceException {
  139. Exam exam = examDao.findById(examId).orElse(null);
  140. if (exam != null) {
  141. if (endTime.before(exam.getStartTime()) || endTime.before(exam.getEndTime())) {
  142. throw new MyServiceException("A0420", "结束时间不能早于原先结束时间和开始时间");
  143. }
  144. exam.setEndTime(endTime);
  145. examDao.save(exam);
  146. // 日志输出
  147. LogTracingUtil.logExam(exam, 1);
  148. } else {
  149. throw new MyServiceException("A0411", "没有对应的考试");
  150. }
  151. return Optional.of(exam);
  152. }
  153. @Override
  154. public ExamListAndNumVO getExamsByCurrentStudent(Integer id, int pageSize, int pageNum, int state) {
  155. User student = userDao.findById(id).orElse(null);
  156. if (student != null) {
  157. List<Exam> exams = student.getExams();
  158. return new ExamListAndNumVO(
  159. exams.stream()
  160. .sorted(Comparator.comparing(Exam::getStartTime).reversed())
  161. .filter(exam -> state == 0 || exam.getState().ordinal() + 1 == state)
  162. .filter(exam -> exam.getIsHidden() == 0)
  163. .skip(pageSize * (pageNum - 1)).limit(pageSize)
  164. .map(ExamConvertor::convertToJoinedVO).collect(Collectors.toList()),
  165. //输出总个数,用于前端分页
  166. (int) exams.stream().filter(exam -> state == 0 || exam.getState().ordinal() + 1 == state).filter(exam -> exam.getIsHidden() == 0).count());
  167. } else {
  168. throw new MyServiceException("A0201", "用户账号不存在");
  169. }
  170. }
  171. @Override
  172. public ExamListAndNumVO getExamsCreatedByCurrentTeacherOrHR(Integer id, int pageSize, int pageNum, int state) {
  173. User user = userDao.findById(id).orElse(null);
  174. if (user != null) {
  175. return new ExamListAndNumVO(examDao.findAllByCreator_Id(user.getId()).stream()
  176. .filter(exam -> state == 0 || exam.getState().ordinal() + 1 == state)
  177. .sorted(Comparator.comparing(Exam::getStartTime).reversed())
  178. .skip(pageSize * (pageNum - 1)).limit(pageSize)
  179. .map(ExamConvertor::convertToVO).collect(Collectors.toList()),
  180. //输出总个数,用于前端分页
  181. (int) examDao.findAllByCreator_Id(user.getId()).stream()
  182. .filter(exam -> state == 0 || exam.getState().ordinal() + 1 == state).count());
  183. } else {
  184. throw new MyServiceException("A0201", "用户账号不存在");
  185. }
  186. }
  187. @Override
  188. public boolean takeExam(Integer userId, Integer examId, String inviteCodeInput) {
  189. User user = userDao.findById(userId).orElse(null);
  190. System.out.println(user.getExams());
  191. Exam exam = examDao.findById(examId).orElse(null);
  192. if (user.getExams().contains(exam)) {
  193. throw new MyServiceException("A0506", "已加入考试!");
  194. }
  195. if (user != null) {
  196. String correctInviteCode = exam.getInviteCode();
  197. if (exam.getIsPublic() == 1 || correctInviteCode.equals(inviteCodeInput)) {
  198. // List<Exam> examsOfUser = user.getExams();
  199. // // 更新用户参加的考试
  200. // examsOfUser.add(exam);
  201. // userDao.save(user);
  202. Score score = new Score(user, exam);
  203. scoreDao.save(score);
  204. return true;
  205. } else {
  206. throw new MyServiceException("A0210", "邀请码输入错误");
  207. }
  208. } else {
  209. throw new MyServiceException("A0201", "用户账号不存在");
  210. }
  211. }
  212. @Override
  213. public void setExamQuestionsBySampleExamPaper(int examId, int sampleExamPaperId) {
  214. Exam exam = examDao.findById(examId).orElse(null);
  215. SampleExamPaper sampleExamPaper = sampleExamPaperDao.findById(sampleExamPaperId).orElse(null);
  216. if (exam == null) {
  217. throw new MyServiceException("A0201", "无对应的考试");
  218. }
  219. if (sampleExamPaper == null) {
  220. throw new MyServiceException("A0201", "无对应样卷");
  221. }
  222. Map<String, Double> questionAndScore = new HashMap<>(sampleExamPaper.getQuestionAndScore());
  223. exam.setQuestionAndScore(questionAndScore);
  224. examDao.save(exam);
  225. // 日志输出
  226. LogTracingUtil.logExam(exam, 0);
  227. }
  228. @Override
  229. public boolean updateExamName (Integer userId, Integer examId, String name){
  230. Exam exam = examDao.findById(examId).orElse(null);
  231. if (exam == null) {
  232. throw new MyServiceException("A0201", "无对应的考试");
  233. }
  234. exam.setExamName(name);
  235. examDao.save(exam);
  236. // 日志输出
  237. LogTracingUtil.logExam(exam, 1);
  238. return true;
  239. }
  240. @Override
  241. public boolean setIsHidden (Integer userId, Integer examId, Integer hidden){
  242. Exam exam = examDao.findById(examId).orElse(null);
  243. if (exam == null) {
  244. throw new MyServiceException("A0201", "无对应的考试");
  245. }
  246. exam.setIsHidden(hidden);
  247. examDao.save(exam);
  248. // 日志输出
  249. LogTracingUtil.logExam(exam, 1);
  250. return true;
  251. }
  252. @Override
  253. public List<ExamInfoVO> getRecommendExam() {
  254. //todo 目前只是推荐最晚开始的开放测试
  255. List<Exam> examList = examDao.findAllByIsHidden(0);
  256. return examList.stream()
  257. .filter(exam -> exam.getCourse().getIsPublic() == 1)
  258. .sorted(Comparator.comparing(Exam::getStartTime).reversed())
  259. .map(ExamConvertor::convertToExamInfoVO).collect(Collectors.toList());
  260. }
  261. @Override
  262. public List<ExamInfoVO> getRecommendExam(Integer courseId) {
  263. Course course = courseDao.findById(courseId).orElse(null);
  264. if(course == null) {
  265. throw new MyServiceException("A0201", "无对应的课程");
  266. } else if(course.getIsPublic() == 0) {
  267. throw new MyServiceException("A0201", "对应课程是私有课程无法推荐");
  268. }
  269. //todo 目前只是推荐最晚开始的开放测试
  270. List<Exam> examList = examDao.findAllByCourseId(courseId);
  271. return examList.stream()
  272. .filter(exam -> exam.getIsHidden() == 0)
  273. .sorted(Comparator.comparing(Exam::getStartTime).reversed())
  274. .map(ExamConvertor::convertToExamInfoVO).collect(Collectors.toList());
  275. }
  276. @Override
  277. public List<ExamVO> getExamByCourseId (Integer courseId) {
  278. return examDao.findAllByCourseId(courseId).stream()
  279. .sorted(Comparator.comparing(Exam::getStartTime).reversed())
  280. .map(ExamConvertor::convertToVO).collect(Collectors.toList());
  281. }
  282. @Override
  283. public List<ExamVO> getExamByCourseIdAndIsHiddenFalse (Integer courseId, Integer userId) {
  284. List<ExamVO> examVOList = examDao.findAllByCourseIdAndIsHidden(courseId, 0).stream()
  285. .sorted(Comparator.comparing(Exam::getStartTime).reversed())
  286. .map(ExamConvertor::convertToVO).collect(Collectors.toList());
  287. User user = userDao.findById(userId).orElse(null);
  288. if (user == null) {
  289. throw new MyServiceException("A0201", "用户账号不存在");
  290. } else {
  291. List<Exam> currentUserExams = user.getExams();
  292. for (ExamVO examVO : examVOList) {
  293. Exam exam = examDao.findById(examVO.getExamId()).orElse(null);
  294. if (currentUserExams.contains(exam)) {
  295. examVO.setIsJoined(true);
  296. }
  297. }
  298. return examVOList;
  299. }
  300. }
  301. @Override
  302. public ExamListAndNumVO getExamLIstByCurrentStudent(Integer id) {
  303. User student = userDao.findById(id).orElse(null);
  304. if (student != null) {
  305. List<Exam> exams = student.getExams();
  306. return new ExamListAndNumVO(
  307. exams.stream()
  308. .sorted(Comparator.comparing(Exam::getStartTime).reversed())
  309. .map(ExamConvertor::convertToJoinedVO).collect(Collectors.toList()),
  310. //输出总个数,用于前端分页
  311. (int) exams.stream().filter(exam -> exam.getIsHidden() == 0).count());
  312. } else {
  313. throw new MyServiceException("A0201", "用户账号不存在");
  314. }
  315. }
  316. }