| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- package nju.seec.helper.service.impl;
- import cn.hutool.core.util.StrUtil;
- import com.google.common.collect.Maps;
- import nju.seec.helper.aspect.auth.LoginUser;
- import nju.seec.helper.dao.QuizDAO;
- import nju.seec.helper.dao.QuizStudentAnswerDAO;
- import nju.seec.helper.dao.UserDAO;
- import nju.seec.helper.dto.question.StudentAnswerDTO;
- import nju.seec.helper.entity.Quiz;
- import nju.seec.helper.entity.QuizStudentAnswer;
- import nju.seec.helper.entity.User;
- import nju.seec.helper.enums.ExceptionType;
- import nju.seec.helper.exception.HelperException;
- import nju.seec.helper.service.QuestionService;
- import nju.seec.helper.service.QuizStudentAnswerService;
- import nju.seec.helper.vo.question.BaseQuestionVO;
- import nju.seec.helper.vo.quiz.QuizStudentAnswerStatisticVO;
- import nju.seec.helper.vo.quiz.QuizStudentAnswerVO;
- import org.springframework.data.domain.Page;
- import org.springframework.data.domain.Pageable;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import java.math.BigDecimal;
- import java.math.RoundingMode;
- import java.util.List;
- import java.util.Map;
- import java.util.concurrent.atomic.AtomicInteger;
- /**
- * @author cst
- */
- @Service
- public class QuizStudentAnswerServiceImpl implements QuizStudentAnswerService {
- private final QuizDAO quizDAO;
- private final UserDAO userDAO;
- private final QuizStudentAnswerDAO quizStudentAnswerDAO;
- private final QuestionService questionService;
- public QuizStudentAnswerServiceImpl(QuizDAO quizDAO, UserDAO userDAO, QuizStudentAnswerDAO quizStudentAnswerDAO, QuestionService questionService) {
- this.quizDAO = quizDAO;
- this.userDAO = userDAO;
- this.quizStudentAnswerDAO = quizStudentAnswerDAO;
- this.questionService = questionService;
- }
- @Transactional(rollbackFor = Exception.class)
- @Override
- public QuizStudentAnswerVO submitQuizStudentAnswer(LoginUser user, Long quizId, StudentAnswerDTO studentAnswerDTO) {
- Quiz quiz = quizDAO.findQuizById(quizId);
- switch (quiz.getState()) {
- case NOT_STARTED:
- throw HelperException.of(ExceptionType.FORBIDDEN, "测试未开始,无法提交");
- case CLOSED:
- throw HelperException.of(ExceptionType.FORBIDDEN, "测试已关闭,无法提交");
- default:
- break;
- }
- User student = userDAO.findUserById(user.getId());
- QuizStudentAnswer quizStudentAnswer = quizStudentAnswerDAO.findByQuizAndStudent(quiz, student).orElse(new QuizStudentAnswer());
- if (quizStudentAnswer.getSubmitNumber() >= quiz.getMaxSubmitNumber()) {
- throw HelperException.of(ExceptionType.FORBIDDEN, StrUtil.format("已达最大提交次数{}次,无法提交", quiz.getMaxSubmitNumber()));
- }
- // 计算得分
- List<BaseQuestionVO> questionVOList = questionService.getQuestionsByIds(quiz.getQuestions());
- AtomicInteger correct = new AtomicInteger();
- Map<String, StudentAnswerDTO.AnswerRecordDTO> records = studentAnswerDTO.getRecords();
- questionVOList.forEach(baseQuestionVO -> {
- String questionId = baseQuestionVO.getId();
- Object answer;
- if (records.get(questionId) != null) {
- answer = records.get(questionId).getAnswer();
- } else {
- answer = quizStudentAnswer.getAnswers().get(questionId);
- }
- if (baseQuestionVO.pass(answer)) {
- correct.getAndIncrement();
- }
- quizStudentAnswer.getAnswers().put(questionId, answer);
- });
- BigDecimal score = BigDecimal.valueOf(correct.get() * 100).divide(BigDecimal.valueOf(questionVOList.size()), 2, RoundingMode.HALF_UP);
- // 计算完毕
- quizStudentAnswer.setQuiz(quiz)
- .setStudent(student)
- .setSubmitNumber(quizStudentAnswer.getSubmitNumber() + 1)
- .setScore(score);
- questionService.record(user, studentAnswerDTO);
- return new QuizStudentAnswerVO(quizStudentAnswerDAO.save(quizStudentAnswer), questionVOList);
- }
- @Transactional(readOnly = true)
- @Override
- public Page<QuizStudentAnswerVO> getQuizStudentAnswers(LoginUser user, Long quizId, String key, Pageable pageable) {
- return quizStudentAnswerDAO.findByQuizIdAndKey(quizId, key, pageable).map(quizStudentAnswer -> new QuizStudentAnswerVO(quizStudentAnswer, questionService.getQuestionsByIds(quizDAO.findQuizById(quizId).getQuestions())));
- }
- @Transactional(readOnly = true)
- @Override
- public QuizStudentAnswerVO getQuizStudentAnswer(LoginUser user, Long quizId) {
- return quizStudentAnswerDAO
- .findByQuizAndStudent(quizDAO.findQuizById(quizId), userDAO.findUserById(user.getId()))
- .map(quizStudentAnswer -> new QuizStudentAnswerVO(quizStudentAnswer, questionService.getQuestionsByIds(quizDAO.findQuizById(quizId).getQuestions())))
- .orElse(null);
- }
- @Transactional(readOnly = true)
- @Override
- public QuizStudentAnswerStatisticVO getQuizStudentAnswerStatistic(LoginUser user, Long quizId) {
- List<QuizStudentAnswer> quizStudentAnswers = quizStudentAnswerDAO.findByQuiz(quizDAO.findQuizById(quizId));
- Map<BigDecimal, Integer> scores = Maps.newHashMapWithExpectedSize(quizStudentAnswers.size());
- Map<Integer, Integer> submitNums = Maps.newHashMapWithExpectedSize(quizStudentAnswers.size());
- quizStudentAnswers.forEach(
- quizStudentAnswer -> {
- scores.merge(quizStudentAnswer.getScore(), 1, Integer::sum);
- submitNums.merge(quizStudentAnswer.getSubmitNumber(), 1, Integer::sum);
- }
- );
- return QuizStudentAnswerStatisticVO.of(quizId, scores, submitNums);
- }
- }
|