| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- package nju.seec.helper.service.impl;
- import com.google.common.collect.ImmutableSet;
- import nju.seec.helper.dao.*;
- import nju.seec.helper.dto.quiz.QuizDTO;
- import nju.seec.helper.aspect.auth.LoginUser;
- import nju.seec.helper.entity.Course;
- import nju.seec.helper.entity.Quiz;
- import nju.seec.helper.entity.Slide;
- import nju.seec.helper.service.MessageService;
- import nju.seec.helper.service.QuizService;
- import nju.seec.helper.service.util.AuthUtils;
- import nju.seec.helper.service.util.StringUtils;
- import nju.seec.helper.enums.*;
- import nju.seec.helper.exception.HelperException;
- import nju.seec.helper.vo.quiz.QuizVO;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.domain.Page;
- import org.springframework.data.domain.Pageable;
- import org.springframework.data.jpa.domain.Specification;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import java.util.List;
- import java.util.Set;
- /**
- * @author xst
- * <p>
- * updated by cst
- */
- @Service
- public class QuizServiceImpl implements QuizService {
- private final SlideDAO slideDAO;
- private final QuizDAO quizDAO;
- private final QuizStudentAnswerDAO quizStudentAnswerDAO;
- private final ChooseDAO chooseDAO;
- private final CourseDAO courseDAO;
- private final UserDAO userDAO;
- private final MessageService messageService;
- @Autowired
- public QuizServiceImpl(SlideDAO slideDAO, QuizDAO quizDAO, QuizStudentAnswerDAO quizStudentAnswerDAO, ChooseDAO chooseDAO, CourseDAO courseDAO, UserDAO userDAO, MessageService messageService) {
- this.slideDAO = slideDAO;
- this.quizDAO = quizDAO;
- this.quizStudentAnswerDAO = quizStudentAnswerDAO;
- this.chooseDAO = chooseDAO;
- this.courseDAO = courseDAO;
- this.userDAO = userDAO;
- this.messageService = messageService;
- }
- @Transactional(rollbackFor = Exception.class)
- @Override
- public QuizVO createQuiz(LoginUser user, QuizDTO quizDTO) {
- Slide slide = slideDAO.findSlideById(quizDTO.getSlideId());
- AuthUtils.checkDataAuth(user.getId(), slide.getTeacher().getId(), "您无权创建该课件的测试");
- checkSameName(0L, quizDTO.getSlideId(), quizDTO.getName());
- checkQuizTypeOkToSlideState(slide.getState(), quizDTO.getType());
- Quiz quiz = new Quiz()
- .setCourse(slide.getCourse())
- .setSlide(slide)
- .setTeacher(slide.getTeacher())
- .setType(quizDTO.getType())
- .setState(QuizState.getQuizStateBySlideStateAndQuizType(slide.getState(), quizDTO.getType()))
- .setName(quizDTO.getName())
- .setMaxSubmitNumber(quizDTO.getMaxSubmitTime())
- .setQuestions(quizDTO.getQuestions());
- return new QuizVO(quizDAO.save(quiz));
- }
- @Transactional(rollbackFor = Exception.class)
- @Override
- public QuizVO modifyQuiz(LoginUser user, Long quizId, QuizDTO quizDTO) {
- Quiz quiz = quizDAO.findQuizById(quizId);
- AuthUtils.checkDataAuth(user.getId(), quiz.getTeacher().getId(), "您无权修改该测试");
- checkSubmit(quiz);
- Slide slide = quiz.getSlide();
- checkQuizTypeOkToSlideState(slide.getState(), quizDTO.getType());
- checkSameName(quiz.getId(), quizDTO.getSlideId(), quizDTO.getName());
- quiz.setType(quizDTO.getType())
- .setState(QuizState.getQuizStateBySlideStateAndQuizType(slide.getState(), quizDTO.getType()))
- .setName(quizDTO.getName())
- .setMaxSubmitNumber(quizDTO.getMaxSubmitTime())
- .setQuestions(quizDTO.getQuestions());
- return new QuizVO(quizDAO.save(quiz));
- }
- private void checkSameName(Long quizId, Long slideId, String name) {
- long exists = quizDAO.count((Specification<Quiz>) (root, query, cb) ->
- cb.and(cb.notEqual(root.get("id"), quizId),
- cb.equal(root.get("slide").get("id"), slideId),
- cb.equal(root.get("name"), name)
- ));
- if (exists > 0) {
- throw HelperException.of(ExceptionType.CONFLICT, "该测试名已使用");
- }
- }
- private void checkQuizTypeOkToSlideState(SlideState slideState, QuizType quizType) {
- if (!QuizType.getQuizTypesBySlideState(slideState).contains(quizType)) {
- throw HelperException.of(ExceptionType.FORBIDDEN, "课件暂时不支持创建该类型的测试,请检查课件状态");
- }
- }
- private void checkSubmit(Quiz quiz) {
- if (quizStudentAnswerDAO.existsByQuiz(quiz)) {
- throw HelperException.of(ExceptionType.FORBIDDEN, "该测试已有提交,无法修改");
- }
- }
- @Transactional(rollbackFor = Exception.class)
- @Override
- public void deleteQuiz(LoginUser user, Long quizId) {
- Quiz quiz = quizDAO.findQuizById(quizId);
- AuthUtils.checkDataAuth(user.getId(), quiz.getTeacher().getId(), "您无权删除该测试");
- quiz.setDeleteAt(System.currentTimeMillis());
- quizDAO.save(quiz);
- }
- @Transactional(readOnly = true)
- @Override
- public Page<QuizVO> teacherGetQuizzesBySlide(LoginUser user, Long slideId, String key, Pageable pageable) {
- return findBySlideIdAndKey(slideId, key, pageable).map(QuizVO::new);
- }
- public static final Set<QuizState> STATES_NOT_GET_BY_STUDENT_SET = ImmutableSet.of(QuizState.NOT_STARTED);
- @Transactional(readOnly = true)
- @Override
- public Page<QuizVO> studentGetQuizzesBySlide(LoginUser user, Long slideId, String key, Pageable pageable) {
- return findBySlideIdAndStateNotInAndKey(slideId, STATES_NOT_GET_BY_STUDENT_SET, key, pageable).map(QuizVO::new);
- }
- @Transactional(readOnly = true)
- @Override
- public Page<QuizVO> studentGetQuizzesByState(LoginUser user, QuizState state, String key, Pageable pageable) {
- if (STATES_NOT_GET_BY_STUDENT_SET.contains(state)) {
- throw HelperException.of(ExceptionType.FORBIDDEN, "您暂时无法获取该状态的测试");
- }
- Set<Long> courseIds = chooseDAO.findCourseIdsByStudentId(user.getId());
- return findByCourseIdInAndStateAndKey(courseIds, state, key, pageable).map(QuizVO::new);
- }
- @Transactional(readOnly = true)
- @Override
- public QuizVO getOneQuiz(LoginUser user, Long quizId) {
- Quiz quiz = quizDAO.findQuizById(quizId);
- checkDataAccessAuth(user, quiz);
- return new QuizVO(quiz);
- }
- @Transactional(rollbackFor = Exception.class)
- @Override
- public void modifyQuizState(Slide slide) {
- List<Quiz> quizzes = quizDAO.findAllBySlide(slide);
- Course course = slide.getCourse();
- Set<Long> chooseStudentIds = chooseDAO.findStudentIdsByCourseId(course.getId());
- quizzes.forEach(quiz -> {
- QuizState quizState = QuizState.getQuizStateBySlideStateAndQuizType(slide.getState(), quiz.getType());
- quiz.setState(quizState);
- if (quizState == QuizState.ONGOING) {
- messageService.createMessage(chooseStudentIds, MessageType.QUIZ_NEW, String.format("[%s] - [%s] 的测试 [%s] 已开放", course.getName(), slide.getName(), quiz.getName()), slide.getId());
- }
- });
- }
- private void checkDataAccessAuth(LoginUser user, Quiz quiz) {
- HelperException forbiddenEx = HelperException.of(ExceptionType.FORBIDDEN, "您无权访问该测试");
- switch (user.getType()) {
- case TEACHER:
- break;
- case STUDENT:
- if (quiz.getState() == QuizState.NOT_STARTED) {
- throw forbiddenEx;
- }
- break;
- default:
- throw forbiddenEx;
- }
- }
- private Page<Quiz> findByCourseIdInAndStateAndKey(Set<Long> courseIds, QuizState state, String key, Pageable pageable) {
- return quizDAO.findAll(
- (Specification<Quiz>) (root, query, cb) -> cb.and(
- root.get("course").get("id").in(courseIds)
- , cb.equal(root.get("deleteAt"), 0L)
- , cb.equal(root.get("state"), state)
- , cb.like(root.get("name"), StringUtils.keyPattern(key))
- , cb.equal(root.get("slide").get("deleteAt"), 0L)
- , cb.equal(root.get("course").get("deleteAt"), 0L)
- ),
- pageable);
- }
- private Page<Quiz> findBySlideIdAndKey(Long slideId, String key, Pageable pageable) {
- return quizDAO.findAll(
- (Specification<Quiz>) (root, query, cb) -> cb.and(
- cb.equal(root.get("slide").get("id"), slideId)
- , cb.equal(root.get("deleteAt"), 0L)
- , cb.like(root.get("name"), StringUtils.keyPattern(key))
- , cb.equal(root.get("slide").get("deleteAt"), 0L)
- , cb.equal(root.get("course").get("deleteAt"), 0L)
- ),
- pageable);
- }
- private Page<Quiz> findBySlideIdAndStateNotInAndKey(Long slideId, Set<QuizState> exclusiveStates, String key, Pageable pageable) {
- return quizDAO.findAll(
- (Specification<Quiz>) (root, query, cb) -> cb.and(
- cb.equal(root.get("slide").get("id"), slideId)
- , cb.equal(root.get("deleteAt"), 0L)
- , cb.like(root.get("name"), StringUtils.keyPattern(key))
- , cb.not(root.get("state").in(exclusiveStates))
- , cb.equal(root.get("slide").get("deleteAt"), 0L)
- , cb.equal(root.get("course").get("deleteAt"), 0L)
- ),
- pageable);
- }
- }
|