|
|
@@ -1,5 +1,6 @@
|
|
|
package nju.seec.helper.service.impl;
|
|
|
|
|
|
+import com.google.common.collect.ImmutableMap;
|
|
|
import com.google.common.collect.ImmutableSet;
|
|
|
import nju.seec.helper.aspect.auth.LoginUser;
|
|
|
import nju.seec.helper.dao.ChooseDAO;
|
|
|
@@ -14,17 +15,17 @@ import nju.seec.helper.enums.*;
|
|
|
import nju.seec.helper.exception.HelperException;
|
|
|
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.vo.quiz.QuizVO;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.dao.DataIntegrityViolationException;
|
|
|
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.Collections;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
|
@@ -51,27 +52,60 @@ public class QuizServiceImpl implements QuizService {
|
|
|
this.messageService = messageService;
|
|
|
}
|
|
|
|
|
|
+ private static Map<SlideState, Map<QuizType, QuizState>> MAP = ImmutableMap.of(
|
|
|
+ SlideState.DRAFT, ImmutableMap.of(
|
|
|
+ QuizType.BEFORE_CLASS, QuizState.NOT_STARTED,
|
|
|
+ QuizType.IN_CLASS, QuizState.NOT_STARTED,
|
|
|
+ QuizType.AFTER_CLASS, QuizState.NOT_STARTED
|
|
|
+ ),
|
|
|
+ SlideState.BEFORE_CLASS, ImmutableMap.of(
|
|
|
+ QuizType.BEFORE_CLASS, QuizState.ONGOING,
|
|
|
+ QuizType.IN_CLASS, QuizState.NOT_STARTED,
|
|
|
+ QuizType.AFTER_CLASS, QuizState.NOT_STARTED
|
|
|
+ ),
|
|
|
+ SlideState.IN_CLASS, ImmutableMap.of(
|
|
|
+ QuizType.BEFORE_CLASS, QuizState.CLOSED,
|
|
|
+ QuizType.IN_CLASS, QuizState.ONGOING,
|
|
|
+ QuizType.AFTER_CLASS, QuizState.NOT_STARTED
|
|
|
+ ),
|
|
|
+ SlideState.AFTER_CLASS, ImmutableMap.of(
|
|
|
+ QuizType.BEFORE_CLASS, QuizState.CLOSED,
|
|
|
+ QuizType.IN_CLASS, QuizState.CLOSED,
|
|
|
+ QuizType.AFTER_CLASS, QuizState.ONGOING
|
|
|
+ ),
|
|
|
+ SlideState.FINISH, ImmutableMap.of(
|
|
|
+ QuizType.BEFORE_CLASS, QuizState.CLOSED,
|
|
|
+ QuizType.IN_CLASS, QuizState.CLOSED,
|
|
|
+ QuizType.AFTER_CLASS, QuizState.CLOSED
|
|
|
+ )
|
|
|
+ );
|
|
|
+
|
|
|
@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());
|
|
|
-
|
|
|
- QuizState quizState = QuizState.getQuizStateBySlideStateAndQuizType(slide.getState(), quizDTO.getType());
|
|
|
- Quiz quiz = quizDAO.save(new Quiz()
|
|
|
+ Quiz quiz = new Quiz()
|
|
|
.setCourse(slide.getCourse())
|
|
|
.setSlide(slide)
|
|
|
.setTeacher(slide.getTeacher())
|
|
|
.setType(quizDTO.getType())
|
|
|
- .setState(quizState)
|
|
|
+ .setState(MAP.get(slide.getState()).get(quizDTO.getType()))
|
|
|
.setName(quizDTO.getName())
|
|
|
.setMaxSubmitNumber(quizDTO.getMaxSubmitTime())
|
|
|
- .setQuestions(quizDTO.getQuestions()));
|
|
|
- sendMessages(quiz);
|
|
|
- return new QuizVO(quiz);
|
|
|
+ .setQuestions(quizDTO.getQuestions());
|
|
|
+
|
|
|
+ if (!existsAddAuth(user, quiz)) {
|
|
|
+ throw HelperException.of(ExceptionType.FORBIDDEN, "您无权创建该测试");
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ quiz = quizDAO.save(quiz);
|
|
|
+ sendMessages(quiz);
|
|
|
+ return new QuizVO(quiz);
|
|
|
+ } catch (DataIntegrityViolationException e) {
|
|
|
+ throw HelperException.of(ExceptionType.CONFLICT, "创建失败,请检查测试信息是否正确且不与已有测试冲突");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
@@ -79,70 +113,52 @@ public class QuizServiceImpl implements QuizService {
|
|
|
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());
|
|
|
-
|
|
|
- QuizState quizState = QuizState.getQuizStateBySlideStateAndQuizType(slide.getState(), quizDTO.getType());
|
|
|
- quiz = quizDAO.save(quiz
|
|
|
- .setType(quizDTO.getType())
|
|
|
- .setState(quizState)
|
|
|
- .setName(quizDTO.getName())
|
|
|
- .setMaxSubmitNumber(quizDTO.getMaxSubmitTime())
|
|
|
- .setQuestions(quizDTO.getQuestions()));
|
|
|
- sendMessages(quiz);
|
|
|
- return new QuizVO(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, "该测试名已使用");
|
|
|
+ if (existsUpdateAuth(user, quiz)) {
|
|
|
+ throw HelperException.of(ExceptionType.FORBIDDEN, "您无权修改该测试");
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- 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, "该测试已有提交,无法修改");
|
|
|
}
|
|
|
+
|
|
|
+ try {
|
|
|
+ quiz = quizDAO.save(quiz
|
|
|
+ .setType(quizDTO.getType())
|
|
|
+ .setState(MAP.get(quiz.getSlide().getState()).get(quizDTO.getType()))
|
|
|
+ .setName(quizDTO.getName())
|
|
|
+ .setMaxSubmitNumber(quizDTO.getMaxSubmitTime())
|
|
|
+ .setQuestions(quizDTO.getQuestions()));
|
|
|
+ sendMessages(quiz);
|
|
|
+ return new QuizVO(quiz);
|
|
|
+ } catch (DataIntegrityViolationException e) {
|
|
|
+ throw HelperException.of(ExceptionType.CONFLICT, "修改失败,请检查测试信息是否正确且不与已有测试冲突");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
@Override
|
|
|
public void deleteQuiz(LoginUser user, Long quizId) {
|
|
|
Quiz quiz = quizDAO.findQuizById(quizId);
|
|
|
- AuthUtils.checkDataAuth(user.getId(), quiz.getTeacher().getId(), "您无权删除该测试");
|
|
|
+ if (!existsDelAuth(user, quiz)) {
|
|
|
+ throw HelperException.of(ExceptionType.FORBIDDEN, "您无权删除该测试");
|
|
|
+ }
|
|
|
quiz.setDeleteAt(System.currentTimeMillis());
|
|
|
quizDAO.save(quiz);
|
|
|
messageService.deleteMessages(quizId, MessageType.QUIZ_NEW);
|
|
|
}
|
|
|
|
|
|
+ private static final Set<QuizState> STATES_NOT_GET_BY_STUDENT_SET = ImmutableSet.of(QuizState.NOT_STARTED);
|
|
|
+
|
|
|
@Transactional(readOnly = true)
|
|
|
@Override
|
|
|
public Page<QuizVO> teacherGetQuizzesBySlide(LoginUser user, Long slideId, String key, Pageable pageable) {
|
|
|
- return findBySlideIdAndKey(slideId, key, pageable).map(QuizVO::new);
|
|
|
+ return quizDAO.findBySlideAndNameContains(slideDAO.findSlideById(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);
|
|
|
+ return quizDAO.findBySlideAndStateNotInAndNameContains(slideDAO.findSlideById(slideId), STATES_NOT_GET_BY_STUDENT_SET, key, pageable).map(QuizVO::new);
|
|
|
}
|
|
|
|
|
|
@Transactional(readOnly = true)
|
|
|
@@ -152,24 +168,25 @@ public class QuizServiceImpl implements QuizService {
|
|
|
throw HelperException.of(ExceptionType.FORBIDDEN, "您暂时无法获取该状态的测试");
|
|
|
}
|
|
|
Set<Long> courseIds = chooseDAO.findCourseIdsByStudentId(user.getId());
|
|
|
- return findByCourseIdInAndStateAndKey(courseIds, state, key, pageable).map(QuizVO::new);
|
|
|
+ return quizDAO.findByCourseIdsAndStateAndNameContains(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);
|
|
|
+ if (!existsGetAuth(user, quiz)) {
|
|
|
+ throw HelperException.of(ExceptionType.FORBIDDEN, "您无权查看该测试");
|
|
|
+ }
|
|
|
return new QuizVO(quiz);
|
|
|
}
|
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
@Override
|
|
|
public void modifyQuizState(Slide slide) {
|
|
|
- List<Quiz> quizzes = quizDAO.findAllBySlide(slide);
|
|
|
+ List<Quiz> quizzes = quizDAO.findBySlide(slide);
|
|
|
quizzes.forEach(quiz -> {
|
|
|
- QuizState quizState = QuizState.getQuizStateBySlideStateAndQuizType(slide.getState(), quiz.getType());
|
|
|
- quiz.setState(quizState);
|
|
|
+ quiz.setState(MAP.get(slide.getState()).get(quiz.getType()));
|
|
|
sendMessages(quiz);
|
|
|
});
|
|
|
}
|
|
|
@@ -183,58 +200,24 @@ public class QuizServiceImpl implements QuizService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- 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;
|
|
|
- }
|
|
|
+ @Override
|
|
|
+ public boolean existsAddAuth(LoginUser user, Quiz quiz) {
|
|
|
+ return quiz.getCourse().getTeacher().getId().equals(user.getId());
|
|
|
}
|
|
|
|
|
|
- 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);
|
|
|
+ @Override
|
|
|
+ public boolean existsDelAuth(LoginUser user, Quiz quiz) {
|
|
|
+ return quiz.getTeacher().getId().equals(user.getId());
|
|
|
}
|
|
|
|
|
|
- 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);
|
|
|
+ @Override
|
|
|
+ public boolean existsUpdateAuth(LoginUser user, Quiz quiz) {
|
|
|
+ return quiz.getTeacher().getId().equals(user.getId());
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- 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);
|
|
|
+ @Override
|
|
|
+ public boolean existsGetAuth(LoginUser user, Quiz quiz) {
|
|
|
+ return quiz.getState() != QuizState.NOT_STARTED
|
|
|
+ || user.getType() == UserType.TEACHER;
|
|
|
}
|
|
|
}
|