Procházet zdrojové kódy

docs: 注释掉quiz相关文件

ChenSiTong před 6 roky
rodič
revize
bdc7518f24
29 změnil soubory, kde provedl 1807 přidání a 1723 odebrání
  1. 100 100
      src/main/java/nju/seec/helper/controller/QuestionController.java
  2. 150 149
      src/main/java/nju/seec/helper/controller/QuizController.java
  3. 51 36
      src/main/java/nju/seec/helper/dao/QuizDAO.java
  4. 18 18
      src/main/java/nju/seec/helper/dao/QuizStudentAnswerDAO.java
  5. 7 7
      src/main/java/nju/seec/helper/dao/StudentScoreDAO.java
  6. 21 21
      src/main/java/nju/seec/helper/dto/QuestionStudentAnswerDTO.java
  7. 10 10
      src/main/java/nju/seec/helper/dto/QuizAnswerDTO.java
  8. 33 24
      src/main/java/nju/seec/helper/dto/QuizDTO.java
  9. 20 20
      src/main/java/nju/seec/helper/dto/QuizUpdateDTO.java
  10. 66 63
      src/main/java/nju/seec/helper/entity/Quiz.java
  11. 60 58
      src/main/java/nju/seec/helper/entity/QuizStudentAnswer.java
  12. 25 25
      src/main/java/nju/seec/helper/entity/StudentScore.java
  13. 23 0
      src/main/java/nju/seec/helper/entity/converter/ListConverter.java
  14. 23 0
      src/main/java/nju/seec/helper/entity/converter/MapConverter.java
  15. 34 34
      src/main/java/nju/seec/helper/service/QuestionService.java
  16. 93 95
      src/main/java/nju/seec/helper/service/QuizService.java
  17. 68 68
      src/main/java/nju/seec/helper/service/impl/QuestionServiceImpl.java
  18. 355 370
      src/main/java/nju/seec/helper/service/impl/QuizServiceImpl.java
  19. 2 2
      src/main/java/nju/seec/helper/service/impl/SlideServiceImpl.java
  20. 283 283
      src/main/java/nju/seec/helper/util/BokUtil.java
  21. 5 0
      src/main/java/nju/seec/helper/util/JsonUtils.java
  22. 3 1
      src/main/java/nju/seec/helper/util/enums/QuizState.java
  23. 27 0
      src/main/java/nju/seec/helper/util/enums/QuizType.java
  24. 95 95
      src/main/java/nju/seec/helper/vo/quiz/BaseQuestionVO.java
  25. 26 26
      src/main/java/nju/seec/helper/vo/quiz/BokQuestion.java
  26. 54 54
      src/main/java/nju/seec/helper/vo/quiz/ChoiceQuestionVO.java
  27. 27 27
      src/main/java/nju/seec/helper/vo/quiz/QuizResultVO.java
  28. 84 93
      src/main/java/nju/seec/helper/vo/quiz/QuizVO.java
  29. 44 44
      src/main/java/nju/seec/helper/vo/quiz/TrueOrFalseQuestionVO.java

+ 100 - 100
src/main/java/nju/seec/helper/controller/QuestionController.java

@@ -1,100 +1,100 @@
-package nju.seec.helper.controller;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import nju.seec.helper.aspect.auth.Auth;
-import nju.seec.helper.controller.response.PageResponse;
-import nju.seec.helper.dao.CourseDAO;
-import nju.seec.helper.dao.SlideDAO;
-import nju.seec.helper.dto.LoginUser;
-import nju.seec.helper.service.QuestionService;
-import nju.seec.helper.util.enums.ExceptionType;
-import nju.seec.helper.util.enums.UserType;
-import nju.seec.helper.util.exception.HelperException;
-import nju.seec.helper.vo.quiz.BaseQuestionVO;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.web.PageableDefault;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.*;
-
-/**
- * 题库
- *
- * @doc http://47.100.18.120:3000/SEEC-BOK/API-DOC/src/master/helper/api/Quiz-%e6%b5%8b%e8%af%95.md
- */
-@RestController
-@RequestMapping("/api/question")
-public class QuestionController {
-    @Autowired
-    private CourseDAO courseDAO;
-    @Autowired
-    private SlideDAO slideDAO;
-    @Autowired
-    private QuestionService questionService;
-
-    /**
-     * 获得题目列表
-     */
-    @Auth(roles = {UserType.TEACHER}, message = "获得题目列表")
-    @GetMapping("")
-    public Map getQuestionList(LoginUser user, String stem, @PageableDefault(Integer.MAX_VALUE) Pageable pageable) throws JsonProcessingException {
-
-        final Page<BaseQuestionVO> page = questionService.getQuestionList(user, stem, pageable);
-        Map ret = new LinkedHashMap(2);
-        ret.put("questions", page.getContent());
-        ret.put("page", PageResponse.PageInfo.of(page.getNumber() + 1, page.getSize(), page.getTotalPages(), Long.valueOf(page.getTotalElements()).intValue()));
-        return ret;
-    }
-
-    /**
-     * 获得题目列表
-     */
-    @Auth(roles = {UserType.TEACHER}, message = "获得题目详情")
-    @GetMapping("/{questionId}")
-    public BaseQuestionVO getQuestion(LoginUser user, @PathVariable("questionId") String questionId) throws JsonProcessingException {
-        return questionService.getQuestion(questionId);
-    }
-
-
-    /**
-     * 创建题目
-     */
-    @Auth(roles = {UserType.TEACHER}, message = "创建题目")
-    @PostMapping
-    public BaseQuestionVO postQuestion(LoginUser user, @RequestBody Map question) {
-        if (question.get("kind") == null) {
-            throw HelperException.of(ExceptionType.PARAM_ERROR, "无类型");
-        }
-
-        return questionService.newQuestion(BaseQuestionVO.parse(question));
-    }
-
-    /**
-     * 更新题目
-     */
-    @Auth(roles = {UserType.TEACHER}, message = "更新题目")
-    @PutMapping("/{questionId}")
-    public BaseQuestionVO updateQuestion(LoginUser user, @RequestBody Map question, @PathVariable("questionId") String questionId) {
-        if (question.get("kind") == null) {
-            throw HelperException.of(ExceptionType.PARAM_ERROR, "无类型");
-        }
-
-        return questionService.updateQuestion(BaseQuestionVO.parse(question));
-    }
-
-
-    /**
-     * 删除题目
-     */
-    @Auth(roles = {UserType.TEACHER}, message = "删除题目")
-    @DeleteMapping("/{questionId}")
-    public Map deleteQuestion(LoginUser user, @PathVariable("questionId") String questionId) {
-
-        questionService.deleteQuestion(questionId);
-        Map map = new HashMap();
-        map.put("message", "success");
-        return map;
-    }
-}
+//package nju.seec.helper.controller;
+//
+//import com.fasterxml.jackson.core.JsonProcessingException;
+//import nju.seec.helper.aspect.auth.Auth;
+//import nju.seec.helper.controller.response.PageResponse;
+//import nju.seec.helper.dao.CourseDAO;
+//import nju.seec.helper.dao.SlideDAO;
+//import nju.seec.helper.dto.LoginUser;
+//import nju.seec.helper.service.QuestionService;
+//import nju.seec.helper.util.enums.ExceptionType;
+//import nju.seec.helper.util.enums.UserType;
+//import nju.seec.helper.util.exception.HelperException;
+//import nju.seec.helper.vo.quiz.BaseQuestionVO;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.data.domain.Page;
+//import org.springframework.data.domain.Pageable;
+//import org.springframework.data.web.PageableDefault;
+//import org.springframework.web.bind.annotation.*;
+//
+//import java.util.*;
+//
+///**
+// * 题库
+// *
+// * @doc http://47.100.18.120:3000/SEEC-BOK/API-DOC/src/master/helper/api/Quiz-%e6%b5%8b%e8%af%95.md
+// */
+//@RestController
+//@RequestMapping("/api/question")
+//public class QuestionController {
+//    @Autowired
+//    private CourseDAO courseDAO;
+//    @Autowired
+//    private SlideDAO slideDAO;
+//    @Autowired
+//    private QuestionService questionService;
+//
+//    /**
+//     * 获得题目列表
+//     */
+//    @Auth(roles = {UserType.TEACHER}, message = "获得题目列表")
+//    @GetMapping("")
+//    public Map getQuestionList(LoginUser user, String stem, @PageableDefault(Integer.MAX_VALUE) Pageable pageable) throws JsonProcessingException {
+//
+//        final Page<BaseQuestionVO> page = questionService.getQuestionList(user, stem, pageable);
+//        Map ret = new LinkedHashMap(2);
+//        ret.put("questions", page.getContent());
+//        ret.put("page", PageResponse.PageInfo.of(page.getNumber() + 1, page.getSize(), page.getTotalPages(), Long.valueOf(page.getTotalElements()).intValue()));
+//        return ret;
+//    }
+//
+//    /**
+//     * 获得题目列表
+//     */
+//    @Auth(roles = {UserType.TEACHER}, message = "获得题目详情")
+//    @GetMapping("/{questionId}")
+//    public BaseQuestionVO getQuestion(LoginUser user, @PathVariable("questionId") String questionId) throws JsonProcessingException {
+//        return questionService.getQuestion(questionId);
+//    }
+//
+//
+//    /**
+//     * 创建题目
+//     */
+//    @Auth(roles = {UserType.TEACHER}, message = "创建题目")
+//    @PostMapping
+//    public BaseQuestionVO postQuestion(LoginUser user, @RequestBody Map question) {
+//        if (question.get("kind") == null) {
+//            throw HelperException.of(ExceptionType.PARAM_ERROR, "无类型");
+//        }
+//
+//        return questionService.newQuestion(BaseQuestionVO.parse(question));
+//    }
+//
+//    /**
+//     * 更新题目
+//     */
+//    @Auth(roles = {UserType.TEACHER}, message = "更新题目")
+//    @PutMapping("/{questionId}")
+//    public BaseQuestionVO updateQuestion(LoginUser user, @RequestBody Map question, @PathVariable("questionId") String questionId) {
+//        if (question.get("kind") == null) {
+//            throw HelperException.of(ExceptionType.PARAM_ERROR, "无类型");
+//        }
+//
+//        return questionService.updateQuestion(BaseQuestionVO.parse(question));
+//    }
+//
+//
+//    /**
+//     * 删除题目
+//     */
+//    @Auth(roles = {UserType.TEACHER}, message = "删除题目")
+//    @DeleteMapping("/{questionId}")
+//    public Map deleteQuestion(LoginUser user, @PathVariable("questionId") String questionId) {
+//
+//        questionService.deleteQuestion(questionId);
+//        Map map = new HashMap();
+//        map.put("message", "success");
+//        return map;
+//    }
+//}

+ 150 - 149
src/main/java/nju/seec/helper/controller/QuizController.java

@@ -1,149 +1,150 @@
-package nju.seec.helper.controller;
-
-import nju.seec.helper.aspect.auth.Auth;
-import nju.seec.helper.controller.response.PageResponse;
-import nju.seec.helper.dao.CourseDAO;
-import nju.seec.helper.dao.SlideDAO;
-import nju.seec.helper.dto.LoginUser;
-import nju.seec.helper.dto.QuizAnswerDTO;
-import nju.seec.helper.dto.QuizDTO;
-import nju.seec.helper.dto.QuizUpdateDTO;
-import nju.seec.helper.entity.Quiz;
-import nju.seec.helper.service.QuizService;
-import nju.seec.helper.util.BokUtil;
-import nju.seec.helper.util.enums.QuizState;
-import nju.seec.helper.util.enums.UserType;
-import nju.seec.helper.vo.quiz.QuizResultVO;
-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.web.PageableDefault;
-import org.springframework.web.bind.annotation.*;
-
-import javax.persistence.EntityNotFoundException;
-import java.util.*;
-import java.util.stream.Collectors;
-
-/**
- * 测试
- *
- * @doc http://47.100.18.120:3000/SEEC-BOK/API-DOC/src/master/helper/api/Quiz-%e6%b5%8b%e8%af%95.md
- */
-@RestController
-@RequestMapping("/api/quiz")
-public class QuizController {
-    @Autowired
-    private CourseDAO courseDAO;
-    @Autowired
-    private SlideDAO slideDAO;
-    @Autowired
-    private BokUtil bokUtil;
-    @Autowired
-    private QuizService quizService;
-
-    /**
-     * 获得测试列表
-     */
-    @Auth(roles = {UserType.STUDENT, UserType.TEACHER}, message = "获得测试列表")
-    @GetMapping("")
-    public Map getBasicQuizList(LoginUser user, String slideId,
-                                QuizState state, @PageableDefault(Integer.MAX_VALUE) Pageable pageable) {
-        List<QuizVO> quizzes = new ArrayList<QuizVO>();
-        Map ret = new LinkedHashMap(2);
-        Page<Quiz> page;
-        if (slideId != null) {
-            page = quizService.getAllBasicQuizBySlide(Long.valueOf(slideId), pageable, state, user.getId());
-        } else {
-            page = quizService.getAllBasicQuizByUser(pageable, state, user.getId());
-        }
-        quizzes.addAll(page.getContent().stream().map(QuizVO::new).collect(Collectors.toList()));
-        ret.put("page", PageResponse.PageInfo.of(page.getNumber() + 1, page.getSize(), page.getTotalPages(), Long.valueOf(page.getTotalElements()).intValue()));
-        ret.put("quizzes", quizzes);
-        return ret;
-    }
-
-    /**
-     * 获得某一测试的详细内容
-     */
-    @Auth(roles = {UserType.STUDENT, UserType.TEACHER}, message = "获得某一测试的详细内容")
-    @GetMapping("/{quizId}")
-    public QuizVO getOneQuiz(LoginUser user, @PathVariable("quizId") String quizId) {
-        QuizVO quizVO = quizService.combineQuizWithAnswer(Long.valueOf(quizId), user.getId(), user.getType());
-
-        if (user.getType().equals(UserType.STUDENT) && !quizVO.getState().equals(QuizState.CLOSED)) {
-            quizVO.excludeCorrectAnswer();
-        }
-        return quizVO;
-    }
-
-    /**
-     * 创建测试
-     */
-    @Auth(roles = {UserType.TEACHER}, message = "创建测试")
-    @PostMapping("")
-    public QuizVO createQuiz(LoginUser user, @RequestBody QuizDTO newQuiz) {
-        final Quiz quiz = quizService.createQuiz(newQuiz.getName(), user.getId(), newQuiz.getQuizTime(),
-                Long.valueOf(newQuiz.getSlideId()), newQuiz.getQuestions());
-        return quizService.combineQuiz(quiz.getId());
-    }
-
-    /**
-     * 修改测试 (仅限未开始时可以修改)
-     */
-    @Auth(roles = {UserType.TEACHER}, message = "修改测试")
-    @PutMapping("/{quizId}")
-    public QuizVO updateQuiz(LoginUser user, @RequestBody QuizUpdateDTO newQuiz, @PathVariable("quizId") String quizId) {
-        Quiz ret = quizService.modifyQuiz(Long.valueOf(quizId), newQuiz.getName(),
-                newQuiz.getQuestions(), newQuiz.getQuizTime(), newQuiz.getSlideId());
-        return quizService.combineQuiz(ret.getId());
-    }
-
-    /**
-     * 删除测试 (仅限未开始时可以删除)
-     */
-    @Auth(roles = {UserType.TEACHER}, message = "删除测试")
-    @DeleteMapping("/{quizId}")
-    public Map deleteQuiz(LoginUser user, @PathVariable("quizId") String quizId) {
-        Map map = new HashMap();
-        String message = quizService.deleteQuiz(Long.valueOf(quizId));
-        map.put("message", message);
-        return map;
-    }
-
-    /**
-     * 获得测试结果统计
-     */
-    @Auth(roles = {UserType.TEACHER}, message = "获得测试结果统计")
-    @GetMapping("/{quizId}/result")
-    public Map getQuizResult(LoginUser user, @PathVariable("quizId") String quizId) {
-        if (quizId == null) {
-            throw new EntityNotFoundException("quiz can't be null");
-        }
-        Map map = new HashMap();
-
-        List<QuizResultVO> list = quizService.getQuizResult(Long.valueOf(quizId));
-        map.put("message", "success");
-        map.put("average", list.stream().mapToInt(QuizResultVO::getScore).average());
-        map.put("data", list);
-        return map;
-    }
-
-    /**
-     * 提交答案
-     */
-
-    @Auth(roles = {UserType.STUDENT}, message = "提交答案")
-    @PutMapping("/{quizId}/student-answer")
-    public Map putStudentAnswer(LoginUser user, @PathVariable("quizId") String quizId, @RequestBody QuizAnswerDTO quizAnswerDTO) {
-
-        if (quizId == null) {
-            throw new EntityNotFoundException("quiz can't be null");
-        }
-        Integer match = quizService.upStudentAnswer(Long.valueOf(quizId), user.getId(), quizAnswerDTO.getAnswers());
-        Map map = new HashMap();
-        map.put("message", "success");
-        map.put("matchNum", match);
-        return map;
-    }
-}
+//package nju.seec.helper.controller;
+//
+//import nju.seec.helper.aspect.auth.Auth;
+//import nju.seec.helper.controller.response.PageResponse;
+//import nju.seec.helper.dao.CourseDAO;
+//import nju.seec.helper.dao.SlideDAO;
+//import nju.seec.helper.dto.LoginUser;
+//import nju.seec.helper.dto.QuizAnswerDTO;
+//import nju.seec.helper.dto.QuizDTO;
+//import nju.seec.helper.dto.QuizUpdateDTO;
+//import nju.seec.helper.dto.groups.Create;
+//import nju.seec.helper.entity.Quiz;
+//import nju.seec.helper.service.QuizService;
+//import nju.seec.helper.util.BokUtil;
+//import nju.seec.helper.util.enums.QuizState;
+//import nju.seec.helper.util.enums.UserType;
+//import nju.seec.helper.vo.quiz.QuizResultVO;
+//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.web.PageableDefault;
+//import org.springframework.validation.annotation.Validated;
+//import org.springframework.web.bind.annotation.*;
+//
+//import javax.persistence.EntityNotFoundException;
+//import java.util.*;
+//import java.util.stream.Collectors;
+//
+///**
+// * 测试
+// *
+// * @doc http://47.100.18.120:3000/SEEC-BOK/API-DOC/src/master/helper/api/Quiz-%e6%b5%8b%e8%af%95.md
+// */
+//@RestController
+//@RequestMapping("/api/quiz")
+//public class QuizController {
+//    @Autowired
+//    private CourseDAO courseDAO;
+//    @Autowired
+//    private SlideDAO slideDAO;
+//    @Autowired
+//    private BokUtil bokUtil;
+//    @Autowired
+//    private QuizService quizService;
+//
+//    /**
+//     * 获得测试列表
+//     */
+//    @Auth(roles = {UserType.STUDENT, UserType.TEACHER}, message = "获得测试列表")
+//    @GetMapping("")
+//    public Map getBasicQuizList(LoginUser user, String slideId,
+//                                QuizState state, @PageableDefault(Integer.MAX_VALUE) Pageable pageable) {
+//        List<QuizVO> quizzes = new ArrayList<QuizVO>();
+//        Map ret = new LinkedHashMap(2);
+//        Page<Quiz> page;
+//        if (slideId != null) {
+//            page = quizService.getAllBasicQuizBySlide(Long.valueOf(slideId), pageable, state, user.getId());
+//        } else {
+//            page = quizService.getAllBasicQuizByUser(pageable, state, user.getId());
+//        }
+//        quizzes.addAll(page.getContent().stream().map(QuizVO::new).collect(Collectors.toList()));
+//        ret.put("page", PageResponse.PageInfo.of(page.getNumber() + 1, page.getSize(), page.getTotalPages(), Long.valueOf(page.getTotalElements()).intValue()));
+//        ret.put("quizzes", quizzes);
+//        return ret;
+//    }
+//
+//    /**
+//     * 获得某一测试的详细内容
+//     */
+//    @Auth(roles = {UserType.STUDENT, UserType.TEACHER}, message = "获得某一测试的详细内容")
+//    @GetMapping("/{quizId}")
+//    public QuizVO getOneQuiz(LoginUser user, @PathVariable("quizId") String quizId) {
+//        QuizVO quizVO = quizService.combineQuizWithAnswer(Long.valueOf(quizId), user.getId(), user.getType());
+//
+//        if (user.getType().equals(UserType.STUDENT) && !quizVO.getState().equals(QuizState.CLOSED)) {
+//            quizVO.excludeCorrectAnswer();
+//        }
+//        return quizVO;
+//    }
+//
+//    /**
+//     * 创建测试
+//     */
+//    @Auth(roles = {UserType.TEACHER}, message = "创建测试")
+//    @PostMapping
+//    public QuizVO createQuiz(LoginUser user, @Validated(Create.class) @RequestBody QuizDTO newQuiz) {
+//        final Quiz quiz = quizService.createQuiz(user, newQuiz);
+//        return quizService.combineQuiz(quiz.getId());
+//    }
+//
+//    /**
+//     * 修改测试 (仅限未开始时可以修改)
+//     */
+//    @Auth(roles = {UserType.TEACHER}, message = "修改测试")
+//    @PutMapping("/{quizId}")
+//    public QuizVO updateQuiz(LoginUser user, @RequestBody QuizUpdateDTO newQuiz, @PathVariable("quizId") String quizId) {
+//        Quiz ret = quizService.modifyQuiz(Long.valueOf(quizId), newQuiz.getName(),
+//                newQuiz.getQuestions(), newQuiz.getQuizTime(), newQuiz.getSlideId());
+//        return quizService.combineQuiz(ret.getId());
+//    }
+//
+//    /**
+//     * 删除测试 (仅限未开始时可以删除)
+//     */
+//    @Auth(roles = {UserType.TEACHER}, message = "删除测试")
+//    @DeleteMapping("/{quizId}")
+//    public Map deleteQuiz(LoginUser user, @PathVariable("quizId") String quizId) {
+//        Map map = new HashMap();
+//        String message = quizService.deleteQuiz(Long.valueOf(quizId));
+//        map.put("message", message);
+//        return map;
+//    }
+//
+//    /**
+//     * 获得测试结果统计
+//     */
+//    @Auth(roles = {UserType.TEACHER}, message = "获得测试结果统计")
+//    @GetMapping("/{quizId}/result")
+//    public Map getQuizResult(LoginUser user, @PathVariable("quizId") String quizId) {
+//        if (quizId == null) {
+//            throw new EntityNotFoundException("quiz can't be null");
+//        }
+//        Map map = new HashMap();
+//
+//        List<QuizResultVO> list = quizService.getQuizResult(Long.valueOf(quizId));
+//        map.put("message", "success");
+//        map.put("average", list.stream().mapToInt(QuizResultVO::getScore).average());
+//        map.put("data", list);
+//        return map;
+//    }
+//
+//    /**
+//     * 提交答案
+//     */
+//
+//    @Auth(roles = {UserType.STUDENT}, message = "提交答案")
+//    @PutMapping("/{quizId}/student-answer")
+//    public Map putStudentAnswer(LoginUser user, @PathVariable("quizId") String quizId, @RequestBody QuizAnswerDTO quizAnswerDTO) {
+//
+//        if (quizId == null) {
+//            throw new EntityNotFoundException("quiz can't be null");
+//        }
+//        Integer match = quizService.upStudentAnswer(Long.valueOf(quizId), user.getId(), quizAnswerDTO.getAnswers());
+//        Map map = new HashMap();
+//        map.put("message", "success");
+//        map.put("matchNum", match);
+//        return map;
+//    }
+//}

+ 51 - 36
src/main/java/nju/seec/helper/dao/QuizDAO.java

@@ -1,36 +1,51 @@
-package nju.seec.helper.dao;
-
-import nju.seec.helper.entity.Course;
-import nju.seec.helper.entity.Quiz;
-import nju.seec.helper.entity.Slide;
-import nju.seec.helper.entity.User;
-import nju.seec.helper.util.enums.ExceptionType;
-import nju.seec.helper.util.enums.QuizState;
-import nju.seec.helper.util.exception.HelperException;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.Collection;
-import java.util.List;
-
-public interface QuizDAO extends JpaRepository<Quiz, Long> {
-    default Quiz findQuizById(Long id) {
-        return this.findById(id)
-                .orElseThrow(() -> HelperException.of(ExceptionType.NOT_FOUND, "找不到测试"));
-    }
-
-    Page<Quiz> findAllBySlideAndState(Slide slide, QuizState state, Pageable pageable);
-
-    Page<Quiz> findAllBySlide(Slide slide, Pageable pageable);
-
-    List<Quiz> findAllBySlide(Slide slide);
-
-    Page<Quiz> findAllByCourseIn(Collection<Course> course, Pageable pageable);
-
-    Page<Quiz> findAllByCourseInAndState(Collection<Course> course, QuizState state, Pageable pageable);
-
-    Page<Quiz> findByTeacher(User teacher, Pageable pageable);
-
-    Page<Quiz> findByTeacherAndState(User teacher, QuizState state, Pageable pageable);
-}
+//package nju.seec.helper.dao;
+//
+//import nju.seec.helper.entity.Course;
+//import nju.seec.helper.entity.Quiz;
+//import nju.seec.helper.entity.Slide;
+//import nju.seec.helper.entity.User;
+//import nju.seec.helper.util.enums.ExceptionType;
+//import nju.seec.helper.util.enums.QuizState;
+//import nju.seec.helper.util.exception.HelperException;
+//import org.springframework.data.domain.Page;
+//import org.springframework.data.domain.Pageable;
+//import org.springframework.data.jpa.repository.JpaRepository;
+//import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+//import org.springframework.stereotype.Repository;
+//
+//import java.util.Collection;
+//import java.util.List;
+//
+//
+///**
+// * @author sheen
+// * <p>
+// * updated by cst
+// */
+//@Repository
+//public interface QuizDAO extends JpaRepository<Quiz, Long>, JpaSpecificationExecutor<Quiz> {
+//    /**
+//     * 封装findById
+//     *
+//     * @param id
+//     * @return
+//     */
+//    default Quiz findQuizById(Long id) {
+//        return this.findById(id)
+//                .orElseThrow(() -> HelperException.of(ExceptionType.NOT_FOUND, "找不到测试"));
+//    }
+//
+//    Page<Quiz> findAllBySlideAndState(Slide slide, QuizState state, Pageable pageable);
+//
+//    Page<Quiz> findAllBySlide(Slide slide, Pageable pageable);
+//
+//    List<Quiz> findAllBySlide(Slide slide);
+//
+//    Page<Quiz> findAllByCourseIn(Collection<Course> course, Pageable pageable);
+//
+//    Page<Quiz> findAllByCourseInAndState(Collection<Course> course, QuizState state, Pageable pageable);
+//
+//    Page<Quiz> findByTeacher(User teacher, Pageable pageable);
+//
+//    Page<Quiz> findByTeacherAndState(User teacher, QuizState state, Pageable pageable);
+//}

+ 18 - 18
src/main/java/nju/seec/helper/dao/QuizStudentAnswerDAO.java

@@ -1,18 +1,18 @@
-package nju.seec.helper.dao;
-
-import nju.seec.helper.entity.Quiz;
-import nju.seec.helper.entity.QuizStudentAnswer;
-import nju.seec.helper.entity.User;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.Set;
-
-public interface QuizStudentAnswerDAO extends JpaRepository<QuizStudentAnswer, Long> {
-    Set<QuizStudentAnswer> findAllByQuiz(Quiz quiz);
-
-    Set<QuizStudentAnswer> findAllByStudent(User student);
-
-    Set<QuizStudentAnswer> findByStudentAndQuiz(User student, Quiz quiz);
-
-    Set<QuizStudentAnswer> findByStudentAndQuestionId(User student, String questionId);
-}
+//package nju.seec.helper.dao;
+//
+//import nju.seec.helper.entity.Quiz;
+//import nju.seec.helper.entity.QuizStudentAnswer;
+//import nju.seec.helper.entity.User;
+//import org.springframework.data.jpa.repository.JpaRepository;
+//
+//import java.util.Set;
+//
+//public interface QuizStudentAnswerDAO extends JpaRepository<QuizStudentAnswer, Long> {
+//    Set<QuizStudentAnswer> findAllByQuiz(Quiz quiz);
+//
+//    Set<QuizStudentAnswer> findAllByStudent(User student);
+//
+//    Set<QuizStudentAnswer> findByStudentAndQuiz(User student, Quiz quiz);
+//
+//    Set<QuizStudentAnswer> findByStudentAndQuestionId(User student, String questionId);
+//}

+ 7 - 7
src/main/java/nju/seec/helper/dao/StudentScoreDAO.java

@@ -1,7 +1,7 @@
-package nju.seec.helper.dao;
-
-import nju.seec.helper.entity.StudentScore;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-public interface StudentScoreDAO extends JpaRepository<StudentScore, Long> {
-}
+//package nju.seec.helper.dao;
+//
+//import nju.seec.helper.entity.StudentScore;
+//import org.springframework.data.jpa.repository.JpaRepository;
+//
+//public interface StudentScoreDAO extends JpaRepository<StudentScore, Long> {
+//}

+ 21 - 21
src/main/java/nju/seec/helper/dto/QuestionStudentAnswerDTO.java

@@ -1,21 +1,21 @@
-package nju.seec.helper.dto;
-
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotNull;
-
-/**
- * @author sheen
- */
-@Data
-public class QuestionStudentAnswerDTO {
-    @JsonProperty(value = "id")
-    @NotBlank
-    private String questionId;
-    @JsonProperty(value = "studentAnswer")
-    @NotNull
-    private Object studentAnswer;
-}
+//package nju.seec.helper.dto;
+//
+//
+//import com.fasterxml.jackson.annotation.JsonProperty;
+//import lombok.Data;
+//
+//import javax.validation.constraints.NotBlank;
+//import javax.validation.constraints.NotNull;
+//
+///**
+// * @author sheen
+// */
+//@Data
+//public class QuestionStudentAnswerDTO {
+//    @JsonProperty(value = "id")
+//    @NotBlank
+//    private String questionId;
+//    @JsonProperty(value = "studentAnswer")
+//    @NotNull
+//    private Object studentAnswer;
+//}

+ 10 - 10
src/main/java/nju/seec/helper/dto/QuizAnswerDTO.java

@@ -1,10 +1,10 @@
-package nju.seec.helper.dto;
-
-import lombok.Data;
-
-import java.util.List;
-
-@Data
-public class QuizAnswerDTO {
-    List<QuestionStudentAnswerDTO> answers;
-}
+//package nju.seec.helper.dto;
+//
+//import lombok.Data;
+//
+//import java.util.List;
+//
+//@Data
+//public class QuizAnswerDTO {
+//    List<QuestionStudentAnswerDTO> answers;
+//}

+ 33 - 24
src/main/java/nju/seec/helper/dto/QuizDTO.java

@@ -1,24 +1,33 @@
-package nju.seec.helper.dto;
-
-import lombok.Data;
-import nju.seec.helper.util.enums.SlideState;
-
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotNull;
-import java.util.List;
-
-/**
- * @author sheen
- */
-@Data
-public class QuizDTO {
-    @NotBlank
-    String name;
-    @NotNull
-    SlideState quizTime;
-    @NotBlank
-    String slideId;
-    @NotBlank
-    List<String> questions;
-
-}
+//package nju.seec.helper.dto;
+//
+//import lombok.Data;
+//import nju.seec.helper.dto.groups.Create;
+//import nju.seec.helper.dto.groups.Modify;
+//import nju.seec.helper.util.enums.QuizType;
+//import org.hibernate.validator.constraints.Length;
+//
+//import javax.validation.constraints.NotBlank;
+//import javax.validation.constraints.NotEmpty;
+//import javax.validation.constraints.NotNull;
+//import java.io.Serializable;
+//import java.util.List;
+//
+///**
+// * @author sheen
+// */
+//@Data
+//public class QuizDTO implements Serializable {
+//    private static final long serialVersionUID = -5856536594930871925L;
+//    @NotNull(message = "缺少测试ID", groups = Modify.class)
+//    private Long id;
+//    @NotBlank(message = "测试名不能为空")
+//    @Length(max = 50, message = "测试名长度不能超过50")
+//    private String name;
+//    @NotNull(message = "缺少测试类型")
+//    private QuizType type;
+//    @NotNull(message = "缺少课件ID", groups = Create.class)
+//    private Long slideId;
+//    @NotEmpty(message = "问题列表不能为空")
+//    private List<String> questions;
+//
+//}

+ 20 - 20
src/main/java/nju/seec/helper/dto/QuizUpdateDTO.java

@@ -1,20 +1,20 @@
-package nju.seec.helper.dto;
-
-import lombok.Data;
-import nju.seec.helper.util.enums.SlideState;
-
-import java.util.List;
-
-/**
- * @author sheen
- */
-
-@Data
-public class QuizUpdateDTO {
-    String id;
-    String name;
-    SlideState quizTime;
-    String slideId;
-    List<String> questions;
-
-}
+//package nju.seec.helper.dto;
+//
+//import lombok.Data;
+//import nju.seec.helper.util.enums.SlideState;
+//
+//import java.util.List;
+//
+///**
+// * @author sheen
+// */
+//
+//@Data
+//public class QuizUpdateDTO {
+//    String id;
+//    String name;
+//    SlideState quizTime;
+//    String slideId;
+//    List<String> questions;
+//
+//}

+ 66 - 63
src/main/java/nju/seec/helper/entity/Quiz.java

@@ -1,63 +1,66 @@
-package nju.seec.helper.entity;
-
-import lombok.Data;
-import nju.seec.helper.util.enums.QuizState;
-import nju.seec.helper.util.enums.SlideState;
-import org.springframework.data.annotation.CreatedDate;
-import org.springframework.data.jpa.domain.support.AuditingEntityListener;
-
-import javax.persistence.*;
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Data
-@Entity
-@Table(name = "quiz", indexes = {@Index(columnList = "course"), @Index(columnList = "slide")}
-        , uniqueConstraints = @UniqueConstraint(name = "测试名约束", columnNames = {"teacher", "name"}))
-@EntityListeners(AuditingEntityListener.class)
-public class Quiz {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private Long id;
-
-    @Basic
-    @Column(name = "name", nullable = false)
-    private String name;
-
-    @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
-    @JoinColumn(name = "slide", referencedColumnName = "id")
-    private Slide slide;
-
-    @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
-    @JoinColumn(name = "course", referencedColumnName = "id")
-    private Course course;
-
-    @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
-    @JoinColumn(name = "teacher", referencedColumnName = "id")
-    private User teacher;
-
-    @ElementCollection
-    private List<String> questions;
-
-    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
-    @JoinColumn(name = "studentScore")
-    private List<StudentScore> studentScore;
-
-    @Enumerated(value = EnumType.STRING)
-    @Column(name = "quizTime")
-    private SlideState quizTime = SlideState.BEFORE_CLASS;
-    @Enumerated(value = EnumType.STRING)
-    @Column(name = "state", nullable = false)
-    private QuizState state;
-
-    @Basic
-    @Column(name = "create_at", nullable = false)
-    @CreatedDate
-    private LocalDateTime createAt;
-
-    @Basic
-    @Column(name = "modified_at", nullable = false)
-    @CreatedDate
-    private LocalDateTime modifiedAt;
-}
+//package nju.seec.helper.entity;
+//
+//import lombok.Data;
+//import lombok.experimental.Accessors;
+//import nju.seec.helper.entity.converter.ListConverter;
+//import nju.seec.helper.util.enums.QuizState;
+//import nju.seec.helper.util.enums.QuizType;
+//import org.hibernate.annotations.CreationTimestamp;
+//import org.hibernate.annotations.DynamicInsert;
+//import org.hibernate.annotations.DynamicUpdate;
+//import org.hibernate.annotations.UpdateTimestamp;
+//
+//import javax.persistence.*;
+//import java.time.LocalDateTime;
+//import java.util.List;
+//
+///**
+// * @author sheen
+// * <p>
+// * updated by cst
+// */
+//@Data
+//@Accessors(chain = true)
+//@Entity
+//@Table(name = "quiz", uniqueConstraints = @UniqueConstraint(name = "测试名约束", columnNames = {"slide_id", "name"}))
+//@DynamicInsert
+//@DynamicUpdate
+//public class Quiz {
+//    @Id
+//    @GeneratedValue(strategy = GenerationType.IDENTITY)
+//    @Column(name = "id")
+//    private Long id;
+//
+//    @Basic
+//    @Column(name = "name", nullable = false)
+//    private String name;
+//
+//    @ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.LAZY)
+//    @JoinColumn(name = "slide_id", referencedColumnName = "id")
+//    private Slide slide;
+//
+//    @ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.LAZY)
+//    @JoinColumn(name = "teacher_id", referencedColumnName = "id")
+//    private User teacher;
+//
+//    @Convert(converter = ListConverter.class)
+//    private List<String> questions;
+//
+//    @Enumerated(value = EnumType.STRING)
+//    @Column(name = "type", nullable = false)
+//    private QuizType type;
+//
+//    @Enumerated(value = EnumType.STRING)
+//    @Column(name = "state", nullable = false)
+//    private QuizState state;
+//
+//    @Basic
+//    @Column(name = "create_at", nullable = false, updatable = false)
+//    @CreationTimestamp
+//    private LocalDateTime createAt;
+//
+//    @Basic
+//    @Column(name = "update_at", nullable = false)
+//    @UpdateTimestamp
+//    private LocalDateTime updateAt;
+//}

+ 60 - 58
src/main/java/nju/seec/helper/entity/QuizStudentAnswer.java

@@ -1,58 +1,60 @@
-package nju.seec.helper.entity;
-
-
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.springframework.data.annotation.CreatedDate;
-import org.springframework.data.jpa.domain.support.AuditingEntityListener;
-
-import javax.persistence.*;
-import java.time.LocalDateTime;
-
-@Data
-@Entity
-@Builder
-@Table(name = "quiz_student_answer",
-        indexes = {@Index(columnList = "quiz"),
-                @Index(columnList = "student ,quiz")})
-@EntityListeners(AuditingEntityListener.class)
-@AllArgsConstructor
-@NoArgsConstructor
-public class QuizStudentAnswer {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private Long id;
-
-    @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
-    @JoinColumn(name = "quiz", referencedColumnName = "id")
-    private Quiz quiz;
-
-    @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
-    @JoinColumn(name = "student", referencedColumnName = "id")
-    private User student;
-
-    @Basic
-    @Column(name = "questionId", nullable = false)
-    private String questionId;
-
-    @Basic
-    @Column(name = "create_at", nullable = false)
-    @CreatedDate
-    private LocalDateTime createAt;
-
-    @Basic
-    @Column(name = "modified_at", nullable = false)
-    @CreatedDate
-    private LocalDateTime modifiedAt;
-
-    @Basic
-    @Column(name = "student_answer", nullable = true)
-    private String studentAnswer;
-
-    @Basic
-    @Column(name = "pass", nullable = true)
-    private Boolean pass;
-}
+//package nju.seec.helper.entity;
+//
+//
+//import lombok.Data;
+//import nju.seec.helper.entity.converter.MapConverter;
+//import org.hibernate.annotations.CreationTimestamp;
+//import org.hibernate.annotations.DynamicInsert;
+//import org.hibernate.annotations.DynamicUpdate;
+//import org.hibernate.annotations.UpdateTimestamp;
+//
+//import javax.persistence.*;
+//import java.math.BigDecimal;
+//import java.time.LocalDateTime;
+//import java.util.Map;
+//
+///**
+// * @author sxt
+// * <p>
+// * updated by cst
+// */
+//@Data
+//@Entity
+//@Table(name = "quiz_student_answer",
+//        indexes = {@Index(columnList = "quiz"),
+//                @Index(columnList = "student ,quiz")})
+//@DynamicUpdate
+//@DynamicInsert
+//public class QuizStudentAnswer {
+//    @Id
+//    @GeneratedValue(strategy = GenerationType.IDENTITY)
+//    @Column(name = "id")
+//    private Long id;
+//
+//    @ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.LAZY)
+//    @JoinColumn(name = "quiz_id", referencedColumnName = "id")
+//    private Quiz quiz;
+//
+//    @ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.LAZY)
+//    @JoinColumn(name = "student_id", referencedColumnName = "id")
+//    private User student;
+//
+//    @SuppressWarnings("all")
+//    @Convert(converter = MapConverter.class)
+//    @Column(nullable = false)
+//    private Map<String, String> answers;
+//
+//    @Column(name = "create_at", nullable = false, updatable = false)
+//    @CreationTimestamp
+//    private LocalDateTime createAt;
+//
+//    @Column(name = "modified_at", nullable = false)
+//    @UpdateTimestamp
+//    private LocalDateTime modifiedAt;
+//
+//    @Column(name = "submit_number", nullable = false, columnDefinition = "int default 1 not null")
+//    private Integer submitNumber;
+//
+//    @Column(nullable = false)
+//    private BigDecimal score;
+//}

+ 25 - 25
src/main/java/nju/seec/helper/entity/StudentScore.java

@@ -1,25 +1,25 @@
-package nju.seec.helper.entity;
-
-import lombok.Data;
-
-import javax.persistence.*;
-import java.io.Serializable;
-
-@Data
-@Entity
-@Table(name = "student_score")
-public class StudentScore implements Serializable {
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "id")
-    private Long id;
-
-    @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
-    @JoinColumn(name = "student", referencedColumnName = "id")
-    private User student;
-
-    @Column(name = "quiz_id")
-    private Long quizId;
-    @Column(name = "score")
-    private Integer score;
-}
+//package nju.seec.helper.entity;
+//
+//import lombok.Data;
+//
+//import javax.persistence.*;
+//import java.io.Serializable;
+//
+//@Data
+//@Entity
+//@Table(name = "student_score")
+//public class StudentScore implements Serializable {
+//    @Id
+//    @GeneratedValue(strategy = GenerationType.IDENTITY)
+//    @Column(name = "id")
+//    private Long id;
+//
+//    @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
+//    @JoinColumn(name = "student", referencedColumnName = "id")
+//    private User student;
+//
+//    @Column(name = "quiz_id")
+//    private Long quizId;
+//    @Column(name = "score")
+//    private Integer score;
+//}

+ 23 - 0
src/main/java/nju/seec/helper/entity/converter/ListConverter.java

@@ -0,0 +1,23 @@
+package nju.seec.helper.entity.converter;
+
+import com.google.gson.reflect.TypeToken;
+import nju.seec.helper.util.JsonUtils;
+
+import javax.persistence.AttributeConverter;
+import java.util.List;
+
+/**
+ * @author cst
+ */
+public class ListConverter implements AttributeConverter<List<String>, String> {
+    @Override
+    public String convertToDatabaseColumn(List<String> attribute) {
+        return JsonUtils.toJson(attribute);
+    }
+
+    @Override
+    public List<String> convertToEntityAttribute(String dbData) {
+        return JsonUtils.fromJson(dbData, new TypeToken<List<String>>() {
+        });
+    }
+}

+ 23 - 0
src/main/java/nju/seec/helper/entity/converter/MapConverter.java

@@ -0,0 +1,23 @@
+package nju.seec.helper.entity.converter;
+
+import com.google.gson.reflect.TypeToken;
+import nju.seec.helper.util.JsonUtils;
+
+import javax.persistence.AttributeConverter;
+import java.util.Map;
+
+/**
+ * @author cst
+ */
+public class MapConverter implements AttributeConverter<Map<String, String>, String> {
+    @Override
+    public String convertToDatabaseColumn(Map<String, String> attribute) {
+        return JsonUtils.toJson(attribute);
+    }
+
+    @Override
+    public Map<String, String> convertToEntityAttribute(String dbData) {
+        return JsonUtils.fromJson(dbData, new TypeToken<Map<String, String>>() {
+        });
+    }
+}

+ 34 - 34
src/main/java/nju/seec/helper/service/QuestionService.java

@@ -1,34 +1,34 @@
-package nju.seec.helper.service;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import nju.seec.helper.dto.LoginUser;
-import nju.seec.helper.vo.quiz.BaseQuestionVO;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-
-public interface QuestionService {
-    /**
-     * @param user
-     * @param stem
-     * @param pageable
-     * @return
-     * @throws JsonProcessingException
-     */
-    Page<BaseQuestionVO> getQuestionList(LoginUser user, String stem, Pageable pageable) throws JsonProcessingException;
-
-    /**
-     * @param questionId
-     * @return
-     */
-    BaseQuestionVO getQuestion(String questionId);
-
-    /**
-     * @param newQuestion
-     * @return
-     */
-    BaseQuestionVO newQuestion(BaseQuestionVO newQuestion);
-
-    BaseQuestionVO updateQuestion(BaseQuestionVO newQuestion);
-
-    void deleteQuestion(String questionId);
-}
+//package nju.seec.helper.service;
+//
+//import com.fasterxml.jackson.core.JsonProcessingException;
+//import nju.seec.helper.dto.LoginUser;
+//import nju.seec.helper.vo.quiz.BaseQuestionVO;
+//import org.springframework.data.domain.Page;
+//import org.springframework.data.domain.Pageable;
+//
+//public interface QuestionService {
+//    /**
+//     * @param user
+//     * @param stem
+//     * @param pageable
+//     * @return
+//     * @throws JsonProcessingException
+//     */
+//    Page<BaseQuestionVO> getQuestionList(LoginUser user, String stem, Pageable pageable) throws JsonProcessingException;
+//
+//    /**
+//     * @param questionId
+//     * @return
+//     */
+//    BaseQuestionVO getQuestion(String questionId);
+//
+//    /**
+//     * @param newQuestion
+//     * @return
+//     */
+//    BaseQuestionVO newQuestion(BaseQuestionVO newQuestion);
+//
+//    BaseQuestionVO updateQuestion(BaseQuestionVO newQuestion);
+//
+//    void deleteQuestion(String questionId);
+//}

+ 93 - 95
src/main/java/nju/seec/helper/service/QuizService.java

@@ -1,17 +1,8 @@
 package nju.seec.helper.service;
 package nju.seec.helper.service;
 
 
-import nju.seec.helper.dto.QuestionStudentAnswerDTO;
-import nju.seec.helper.entity.Quiz;
-import nju.seec.helper.entity.Slide;
-import nju.seec.helper.util.enums.QuizState;
-import nju.seec.helper.util.enums.SlideState;
-import nju.seec.helper.util.enums.UserType;
-import nju.seec.helper.vo.quiz.QuizResultVO;
-import nju.seec.helper.vo.quiz.QuizVO;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-
-import java.util.List;
+import nju.seec.helper.dto.LoginUser;
+//import nju.seec.helper.dto.QuizDTO;
+//import nju.seec.helper.vo.quiz.QuizVO;
 
 
 /**
 /**
  * @author xst
  * @author xst
@@ -20,94 +11,101 @@ import java.util.List;
  */
  */
 public interface QuizService {
 public interface QuizService {
 
 
-    /**
-     * @param name
-     * @param uid
-     * @param quizTime
-     * @param slideId
-     * @param questions
-     * @return
-     */
-    Quiz createQuiz(String name, Long uid, SlideState quizTime,
-                    Long slideId, List<String> questions);
-
-    /**
-     * @param quizId
-     * @param uid
-     * @param answers
-     * @return
-     */
-    Integer upStudentAnswer(Long quizId, Long uid, List<QuestionStudentAnswerDTO> answers);
-
-    /**
-     * @param slideId
-     * @param pageable
-     * @param state
-     * @param uid
-     * @return
-     */
-    Page<Quiz> getAllBasicQuizBySlide(Long slideId, Pageable pageable, QuizState state, Long uid);
-
-    /**
-     * @param quiz
-     * @param slide
-     * @return
-     */
-    QuizState checkQuizState(Quiz quiz, Slide slide);
-
-    /**
-     * @param quizId
-     * @param slideId
-     * @return
-     */
-    QuizState checkQuizState(Long quizId, Long slideId);
+//    /**
+//     * 创建测试
+//     *
+//     * @param user
+//     * @param quizDTO
+//     * @return
+//     */
+//    QuizVO createQuiz(LoginUser user, QuizDTO quizDTO);
 
 
-    /**
-     * @param quizId
-     * @return
-     */
-    QuizVO combineQuiz(Long quizId);
+//    /**
+//     * 修改测试
+//     *
+//     * @param user
+//     * @param quizDTO
+//     * @return
+//     */
+//    QuizVO modifyQuiz(LoginUser user, QuizDTO quizDTO);
 
 
-    /**
-     * @param quizId
-     * @param uid
-     * @param type
-     * @return
-     */
-    QuizVO combineQuizWithAnswer(Long quizId, Long uid, UserType type);
+//    /**
+//     * @param quizId
+//     * @param uid
+//     * @param answers
+//     * @return
+//     */
+//    Integer upStudentAnswer(Long quizId, Long uid, List<QuestionStudentAnswerDTO> answers);
 
 
-    /**
-     * @param quizId
-     * @return
-     */
-    String deleteQuiz(Long quizId);
+//    /**
+//     * @param slideId
+//     * @param pageable
+//     * @param state
+//     * @param uid
+//     * @return
+//     */
+//    Page<Quiz> getAllBasicQuizBySlide(Long slideId, Pageable pageable, QuizState state, Long uid);
 
 
-    /**
-     * @param quizId
-     * @param name
-     * @param questions
-     * @param quizTime
-     * @param slideId
-     * @return
-     */
-    Quiz modifyQuiz(Long quizId, String name, List<String> questions, SlideState quizTime, String slideId);
+//    /**
+//     * @param quiz
+//     * @param slide
+//     * @return
+//     */
+//    QuizState checkQuizState(Quiz quiz, Slide slide);
 
 
-    /**
-     * @param pageable
-     * @param state
-     * @param uid
-     * @return
-     */
-    Page<Quiz> getAllBasicQuizByUser(Pageable pageable, QuizState state, Long uid);
+//    /**
+//     * @param quizId
+//     * @param slideId
+//     * @return
+//     */
+//    QuizState checkQuizState(Long quizId, Long slideId);
 
 
-    /**
-     * @param aLong
-     * @return
-     */
-    List<QuizResultVO> getQuizResult(Long aLong);
+//    /**
+//     * @param quizId
+//     * @return
+//     */
+//    QuizVO combineQuiz(Long quizId);
 
 
-    /**
-     * @param slide
-     */
-    void modifySlideState(Slide slide);
+//    /**
+//     * @param quizId
+//     * @param uid
+//     * @param type
+//     * @return
+//     */
+//    QuizVO combineQuizWithAnswer(Long quizId, Long uid, UserType type);
+//
+//    /**
+//     * @param quizId
+//     * @return
+//     */
+//    String deleteQuiz(Long quizId);
+//
+//    /**
+//     * @param quizId
+//     * @param name
+//     * @param questions
+//     * @param quizTime
+//     * @param slideId
+//     * @return
+//     */
+//    Quiz modifyQuiz(Long quizId, String name, List<String> questions, SlideState quizTime, String slideId);
+//
+//    /**
+//     * @param pageable
+//     * @param state
+//     * @param uid
+//     * @return
+//     */
+//    Page<Quiz> getAllBasicQuizByUser(Pageable pageable, QuizState state, Long uid);
+//
+//    /**
+//     * @param aLong
+//     * @return
+//     */
+//    List<QuizResultVO> getQuizResult(Long aLong);
+//
+//    /**
+//     * @param slide
+//     */
+//    void modifySlideState(Slide slide);
 }
 }

+ 68 - 68
src/main/java/nju/seec/helper/service/impl/QuestionServiceImpl.java

@@ -1,68 +1,68 @@
-package nju.seec.helper.service.impl;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import nju.seec.helper.dto.LoginUser;
-import nju.seec.helper.service.QuestionService;
-import nju.seec.helper.util.BokUtil;
-import nju.seec.helper.util.enums.ExceptionType;
-import nju.seec.helper.util.exception.HelperException;
-import nju.seec.helper.vo.quiz.BaseQuestionVO;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.Pageable;
-import org.springframework.stereotype.Service;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-@Service
-public class QuestionServiceImpl implements QuestionService {
-    private final BokUtil bokUtil;
-
-    @Autowired
-    public QuestionServiceImpl(BokUtil bokUtil) {
-        this.bokUtil = bokUtil;
-    }
-
-    @Override
-    public Page<BaseQuestionVO> getQuestionList(LoginUser user, String stem, Pageable pageable) {
-        //应该对象化
-        List<BaseQuestionVO> questions = new ArrayList<>();
-        Map page = new HashMap();
-
-        bokUtil.bokFindByStemLike(stem, questions, page, pageable);
-        return new PageImpl<>(questions, pageable, Long.valueOf((Integer) page.get("totalElements")));
-    }
-
-    @Override
-    public BaseQuestionVO getQuestion(String questionId) {
-        return bokUtil.bokFindById(questionId);
-    }
-
-    @Override
-    public BaseQuestionVO newQuestion(BaseQuestionVO newQuestion) {
-        try {
-            return bokUtil.postNewQuestion(newQuestion);
-        } catch (JsonProcessingException e) {
-            throw HelperException.of(ExceptionType.ERROR, "请求BOK题库数据错误:" + e.getMessage());
-        }
-    }
-
-    @Override
-    public BaseQuestionVO updateQuestion(BaseQuestionVO newQuestion) {
-        try {
-            return bokUtil.putQuestion(newQuestion);
-        } catch (JsonProcessingException e) {
-            throw HelperException.of(ExceptionType.ERROR, "请求BOK题库数据错误:" + e.getMessage());
-        }
-    }
-
-    @Override
-    public void deleteQuestion(String questionId) {
-        bokUtil.deleteQuestion(questionId);
-    }
-
-}
+//package nju.seec.helper.service.impl;
+//
+//import com.fasterxml.jackson.core.JsonProcessingException;
+//import nju.seec.helper.dto.LoginUser;
+//import nju.seec.helper.service.QuestionService;
+//import nju.seec.helper.util.BokUtil;
+//import nju.seec.helper.util.enums.ExceptionType;
+//import nju.seec.helper.util.exception.HelperException;
+//import nju.seec.helper.vo.quiz.BaseQuestionVO;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.data.domain.Page;
+//import org.springframework.data.domain.PageImpl;
+//import org.springframework.data.domain.Pageable;
+//import org.springframework.stereotype.Service;
+//
+//import java.util.ArrayList;
+//import java.util.HashMap;
+//import java.util.List;
+//import java.util.Map;
+//
+//@Service
+//public class QuestionServiceImpl implements QuestionService {
+//    private final BokUtil bokUtil;
+//
+//    @Autowired
+//    public QuestionServiceImpl(BokUtil bokUtil) {
+//        this.bokUtil = bokUtil;
+//    }
+//
+//    @Override
+//    public Page<BaseQuestionVO> getQuestionList(LoginUser user, String stem, Pageable pageable) {
+//        //应该对象化
+//        List<BaseQuestionVO> questions = new ArrayList<>();
+//        Map page = new HashMap();
+//
+//        bokUtil.bokFindByStemLike(stem, questions, page, pageable);
+//        return new PageImpl<>(questions, pageable, Long.valueOf((Integer) page.get("totalElements")));
+//    }
+//
+//    @Override
+//    public BaseQuestionVO getQuestion(String questionId) {
+//        return bokUtil.bokFindById(questionId);
+//    }
+//
+//    @Override
+//    public BaseQuestionVO newQuestion(BaseQuestionVO newQuestion) {
+//        try {
+//            return bokUtil.postNewQuestion(newQuestion);
+//        } catch (JsonProcessingException e) {
+//            throw HelperException.of(ExceptionType.ERROR, "请求BOK题库数据错误:" + e.getMessage());
+//        }
+//    }
+//
+//    @Override
+//    public BaseQuestionVO updateQuestion(BaseQuestionVO newQuestion) {
+//        try {
+//            return bokUtil.putQuestion(newQuestion);
+//        } catch (JsonProcessingException e) {
+//            throw HelperException.of(ExceptionType.ERROR, "请求BOK题库数据错误:" + e.getMessage());
+//        }
+//    }
+//
+//    @Override
+//    public void deleteQuestion(String questionId) {
+//        bokUtil.deleteQuestion(questionId);
+//    }
+//
+//}

+ 355 - 370
src/main/java/nju/seec/helper/service/impl/QuizServiceImpl.java

@@ -1,27 +1,11 @@
 package nju.seec.helper.service.impl;
 package nju.seec.helper.service.impl;
 
 
-import nju.seec.helper.dao.*;
-import nju.seec.helper.dto.QuestionStudentAnswerDTO;
-import nju.seec.helper.entity.*;
+import nju.seec.helper.dto.LoginUser;
+//import nju.seec.helper.dto.QuizDTO;
 import nju.seec.helper.service.QuizService;
 import nju.seec.helper.service.QuizService;
-import nju.seec.helper.util.BokUtil;
-import nju.seec.helper.util.enums.ExceptionType;
-import nju.seec.helper.util.enums.QuizState;
-import nju.seec.helper.util.enums.SlideState;
-import nju.seec.helper.util.enums.UserType;
-import nju.seec.helper.util.exception.HelperException;
-import nju.seec.helper.vo.quiz.BaseQuestionVO;
-import nju.seec.helper.vo.quiz.QuizResultVO;
-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 nju.seec.helper.vo.quiz.QuizVO;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.Assert;
-
-import java.util.*;
-import java.util.stream.Collectors;
 
 
 
 
 /**
 /**
@@ -31,355 +15,356 @@ import java.util.stream.Collectors;
  */
  */
 @Service
 @Service
 public class QuizServiceImpl implements QuizService {
 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 BokUtil bokUtil;
-
-    @Autowired
-    public QuizServiceImpl(SlideDAO slideDAO, QuizDAO quizDAO, QuizStudentAnswerDAO quizStudentAnswerDAO, ChooseDAO chooseDAO, CourseDAO courseDAO, UserDAO userDAO, BokUtil bokUtil) {
-        this.slideDAO = slideDAO;
-        this.quizDAO = quizDAO;
-        this.quizStudentAnswerDAO = quizStudentAnswerDAO;
-        this.chooseDAO = chooseDAO;
-        this.courseDAO = courseDAO;
-        this.userDAO = userDAO;
-        this.bokUtil = bokUtil;
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public Quiz createQuiz(String name, Long uid, SlideState quizTime,
-                           Long slideId, List<String> questions) {
-        User teacher = new User();
-        teacher.setId(uid);
-        Slide slide = slideDAO.findSlideById(slideId);
-        Course course = new Course();
-        course.setId(slide.getCourse().getId());
-        Quiz quiz = new Quiz();
-
-        quiz.setCourse(course);
-        quiz.setName(name);
-        quiz.setQuestions(questions);
-        quiz.setQuizTime(quizTime);
-        quiz.setSlide(slide);
-        quiz.setTeacher(teacher);
-
-        checkQuizState(quiz, slide);
-
-        quiz = quizDAO.saveAndFlush(quiz);
-        return quiz;
-    }
-
-    @Override
-    public String deleteQuiz(Long quizId) {
-        Quiz quiz = quizDAO.findQuizById(quizId);
-        if (quiz.getState() != QuizState.NOT_STARTED) {
-            throw HelperException.of(ExceptionType.FORBIDDEN, "不能删除已经开始的测试!");
-        }
-        quizDAO.delete(quiz);
-        return "delete success";
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public Quiz modifyQuiz(Long quizId, String name, List<String> questions, SlideState quizTime, String slideId) {
-
-        Quiz quiz = quizDAO.findQuizById(quizId);
-        if (quiz.getState() != QuizState.NOT_STARTED) {
-            throw HelperException.of(ExceptionType.FORBIDDEN, "不能修改已经开始的测试!");
-        }
-        if (name != null) {
-            quiz.setName(name);
-        }
-        if (questions != null) {
-            quiz.setQuestions(questions);
-        }
-        if (quizTime != null) {
-            quiz.setQuizTime(quizTime);
-            checkQuizState(quiz, quiz.getSlide());
-        }
-        return quizDAO.saveAndFlush(quiz);
-
-    }
-
-    @Override
-    public Page<Quiz> getAllBasicQuizByUser(Pageable pageable, QuizState state, Long uid) {
-        User user = userDAO.findUserById(uid);
-        //todo: 这里写的太狗屎了,可以用重写sql或者用实例查询
-        if (user.getType().equals(UserType.STUDENT)) {
-            final Set<Long> courseIdsByStudentId = chooseDAO.findCourseIdsByStudentId(uid);
-            final Set<Course> collect = courseIdsByStudentId.stream().map(i -> {
-                Course c = new Course();
-                c.setId(i);
-                return c;
-            }).collect(Collectors.toSet());
-            if (state != null) {
-                return quizDAO.findAllByCourseInAndState(collect, state, pageable);
-            } else {
-                return quizDAO.findAllByCourseIn(collect, pageable);
-            }
-        } else {
-            if (state != null) {
-                return quizDAO.findByTeacherAndState(user, state, pageable);
-            } else {
-                return quizDAO.findByTeacher(user, pageable);
-            }
-
-        }
-
-    }
-
-    @Override
-    public List<QuizResultVO> getQuizResult(Long quizId) {
-        Assert.notNull(quizId, "错误的测试!");
-        final Quiz quiz = quizDAO.findQuizById(quizId);
-        if (quiz.getState() != QuizState.CLOSED) {
-            throw new RuntimeException("测试未关闭,无法得到测试结果");
-        }
-        List<QuizResultVO> retList = new ArrayList<>();
-        final List<StudentScore> studentScoreList = quiz.getStudentScore();
-        Map<Long, List<QuizStudentAnswer>> idQuizStudentAnswerMap = new HashMap<>();
-        for (QuizStudentAnswer qsa : quizStudentAnswerDAO.findAllByQuiz(quiz)) {
-            idQuizStudentAnswerMap.computeIfAbsent(qsa.getStudent().getId(), k -> new ArrayList<>());
-            idQuizStudentAnswerMap.get(qsa.getStudent().getId()).add(qsa);
-        }
-        for (StudentScore studentScore : studentScoreList) {
-            final User student = studentScore.getStudent();
-            final List<QuizStudentAnswer> list = idQuizStudentAnswerMap.get(student.getId());
-            retList.add(new QuizResultVO(studentScore, student, list));
-        }
-        return retList;
-    }
-
-    @Override
-    public void modifySlideState(Slide slide) {
-        final List<Quiz> quizzes = quizDAO.findAllBySlide(slide);
-        quizzes.forEach(quiz -> checkQuizState(quiz, slide));
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public Integer upStudentAnswer(Long quizId, Long uid, List<QuestionStudentAnswerDTO> answers) {
-        Assert.notNull(quizId, "错误的测试!");
-        final Quiz quiz = quizDAO.findQuizById(quizId);
-        if (quiz.getState() != QuizState.ONGOING) {
-            throw HelperException.of(ExceptionType.FORBIDDEN, "不能提交尚未开始或已经结束的作业!");
-        }
-        User student = new User();
-        student.setId(uid);
-        Set<QuizStudentAnswer> quizAnswers = quizStudentAnswerDAO.findByStudentAndQuiz(student, quiz);
-        Set<String> questionIdSet = new HashSet<>(quiz.getQuestions());
-        Map<String, QuizStudentAnswer> qsaMap = new HashMap<>(questionIdSet.size());
-        for (QuizStudentAnswer qsa : quizAnswers) {
-            qsaMap.put(qsa.getQuestionId(), qsa);
-        }
-        //确定被更新或者新建的学生答案提交
-        List<QuizStudentAnswer> quizStudentAnswers = new ArrayList<>();
-        for (QuestionStudentAnswerDTO studentAnswer : answers) {
-            String id = studentAnswer.getQuestionId();
-            String answer = studentAnswer.getStudentAnswer().toString();
-            if (!questionIdSet.contains(id)) {
-                break;
-            }
-            if (qsaMap.get(id) != null) {
-                if (qsaMap.get(id).getStudentAnswer().equals(answer)) {
-                    continue;
-                }
-                qsaMap.get(id).setStudentAnswer(answer);
-                System.out.println(answer);
-                quizStudentAnswers.add(qsaMap.get(id));
-            } else {
-                QuizStudentAnswer qsa = QuizStudentAnswer.builder()
-                        .questionId(id).quiz(quiz).student(student).studentAnswer(answer)
-                        .build();
-                quizStudentAnswers.add(qsa);
-            }
-
-        }
-        Integer savedNum = quizStudentAnswers.size();
-        quizStudentAnswerDAO.saveAll(quizStudentAnswers);
-        return savedNum;
-    }
-
-    @Override
-    public Page<Quiz> getAllBasicQuizBySlide(Long slideId, Pageable pageable, QuizState state, Long uid) {
-        Assert.notNull(slideId, "错误的幻灯片!");
-        Slide slide = new Slide();
-        slide.setId(slideId);
-        if (state != null) {
-            return quizDAO.findAllBySlideAndState(slide, state, pageable);
-        } else {
-            return quizDAO.findAllBySlide(slide, pageable);
-        }
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public QuizState checkQuizState(Quiz quiz, Slide slide) {
-        int quizTime = quiz.getQuizTime().getNum();
-        int slideTime = slide.getState().getNum();
-        if (quiz.getId() == null) {
-            //未持久化的quiz
-            quiz.setState(slideTime < quizTime ? QuizState.NOT_STARTED : QuizState.ONGOING);
-        } else {
-            //持久化后,不仅仅需要推进状态,还需要判分,保存等步骤
-            if (slideTime < quizTime) {
-                if (quiz.getState().equals(QuizState.NOT_STARTED)) {
-                    return QuizState.NOT_STARTED;
-                }
-                //未开始
-                quiz.setState(QuizState.NOT_STARTED);
-            } else if (slideTime == quizTime) {
-                if (quiz.getState().equals(QuizState.ONGOING)) {
-                    return QuizState.ONGOING;
-                }
-                quiz.setState(QuizState.ONGOING);
-            } else {
-                if (quiz.getState().equals(QuizState.CLOSED)) {
-                    return QuizState.CLOSED;
-                }
-                quiz.setState(QuizState.CLOSED);
-                Set<QuizStudentAnswer> quizAnswers = quizStudentAnswerDAO.findAllByQuiz(quiz);
-                final Set<Long> studentIds = chooseDAO.findStudentIdsByCourseId(slide.getCourse().getId());
-                Student2QuestionId2Answer triadMap = new Student2QuestionId2Answer(studentIds, quiz.getQuestions().size());
-                //将已经作答的学生答案加入
-                for (QuizStudentAnswer answers : quizAnswers) {
-                    triadMap.addAnswer(answers);
-                }
-                //生成未作答的学生答案
-                triadMap.fullAnswer(quiz);
-                //检查答案,赋分
-                triadMap.checkAnswerAndFullPass(bokUtil.bokFindByIdIn(quiz.getQuestions()), quiz);
-                //保存现场
-                quizStudentAnswerDAO.saveAll(triadMap.getAll());
-            }
-
-            quizDAO.save(quiz);
-        }
-        return quiz.getState();
-    }
-
-    @Override
-    public QuizState checkQuizState(Long quizId, Long slideId) {
-        Quiz quiz = quizDAO.findQuizById(quizId);
-        Slide slide = slideDAO.findSlideById(slideId);
-        return checkQuizState(quiz, slide);
-    }
-
-    private class Student2QuestionId2Answer {
-        Map<Long, Map<String, QuizStudentAnswer>> student2QuestionId2Answer;
-
-        Student2QuestionId2Answer(Set<Long> studentIds, Integer quizQuestionSize) {
-            student2QuestionId2Answer = new LinkedHashMap<>(studentIds.size());
-            for (Long studentId : studentIds) {
-                Map<String, QuizStudentAnswer> questionId2Answer = new LinkedHashMap<>(quizQuestionSize);
-                student2QuestionId2Answer.put(studentId, questionId2Answer);
-            }
-        }
-
-        void addAnswer(QuizStudentAnswer answers) {
-            Map<String, QuizStudentAnswer> stringQuizStudentAnswerMap = student2QuestionId2Answer.get(answers.getStudent().getId());
-            if (stringQuizStudentAnswerMap == null) {
-                return;
-            }
-            stringQuizStudentAnswerMap.put(answers.getQuestionId(), answers);
-        }
-
-        void fullAnswer(Quiz quiz) {
-            List<String> questions = quiz.getQuestions();
-            student2QuestionId2Answer.forEach((studentId, map) -> {
-                if (questions.size() != map.size()) {
-                    for (String questionId : questions) {
-                        if (map.get(questionId) == null) {
-                            User student = new User();
-                            student.setId(studentId);
-                            QuizStudentAnswer qsa = QuizStudentAnswer.builder()
-                                    .questionId(questionId).quiz(quiz).student(student)
-                                    .build();
-                            map.put(questionId, qsa);
-                        }
-                    }
-                }
-            });
-        }
-
-        void checkAnswerAndFullPass(List<BaseQuestionVO> questionVos, Quiz quiz) {
-            if (quiz.getStudentScore() == null) {
-                quiz.setStudentScore(new ArrayList<>(student2QuestionId2Answer.size()));
-            }
-            student2QuestionId2Answer.forEach((studentId, map) -> {
-                int passCount = 0;
-                for (BaseQuestionVO vo : questionVos) {
-                    final String studentAnswer = map.get(vo.getQuestionId()).getStudentAnswer();
-                    boolean pass = vo.checkAnswer(studentAnswer);
-                    if (pass) {
-                        passCount++;
-                    }
-                    map.get(vo.getQuestionId()).setPass(pass);
-                }
-                Double score = (100.0 * passCount) / questionVos.size();
-                User student = new User();
-                student.setId(studentId);
-                StudentScore studentScore = new StudentScore();
-                studentScore.setQuizId(quiz.getId());
-                studentScore.setScore(Long.valueOf(Math.round(score)).intValue());
-                studentScore.setStudent(student);
-                quiz.getStudentScore().add(studentScore);
-            });
-        }
-
-        List<QuizStudentAnswer> getAll() {
-            List<QuizStudentAnswer> list = new ArrayList<>();
-            for (Long sid : student2QuestionId2Answer.keySet()) {
-                list.addAll(student2QuestionId2Answer.get(sid).values());
-            }
-            return list;
-        }
-    }
-
-    @Override
-    public QuizVO combineQuiz(Long quizId) {
-        Assert.notNull(quizId, "错误的测试!");
-        final Quiz quizById = quizDAO.findQuizById(quizId);
-        final List<BaseQuestionVO> questionVoS = bokUtil.bokFindByIdIn(quizById.getQuestions());
-        return new QuizVO(quizById, questionVoS);
-    }
-
-    @Override
-    public QuizVO combineQuizWithAnswer(Long quizId, Long uid, UserType userType) {
-        Assert.notNull(quizId, "错误的测试!");
-        final Quiz quizById = quizDAO.findQuizById(quizId);
-        User student = new User();
-        student.setId(uid);
-
-        if (userType == null || userType.equals(UserType.TEACHER)) {
-            //向老师展示
-            List<BaseQuestionVO> questionVoS = bokUtil.bokFindByIdIn(quizById.getQuestions());
-            return new QuizVO(quizById, questionVoS);
-        }
-        if (quizById.getState().equals(QuizState.NOT_STARTED)) {
-            //未开始看不到题目
-            return new QuizVO(quizById);
-        }
-
-        List<BaseQuestionVO> questionVos = bokUtil.bokFindByIdIn(quizById.getQuestions());
-        final Set<QuizStudentAnswer> quizAnswers = quizStudentAnswerDAO.findByStudentAndQuiz(student, quizById);
-        Map<String, QuizStudentAnswer> qsaMap = new HashMap<>(quizAnswers.size());
-        for (QuizStudentAnswer qsa : quizAnswers) {
-            qsaMap.put(qsa.getQuestionId(), qsa);
-        }
-        for (BaseQuestionVO vo : questionVos) {
-            if (qsaMap.get(vo.getQuestionId()) != null) {
-                vo.exAddAnswer(qsaMap.get(vo.getQuestionId()));
-            }
-        }
-
-        return new QuizVO(quizById, questionVos);
-    }
-
-
+//    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 BokUtil bokUtil;
+//
+//    @Autowired
+//    public QuizServiceImpl(SlideDAO slideDAO, QuizDAO quizDAO, QuizStudentAnswerDAO quizStudentAnswerDAO, ChooseDAO chooseDAO, CourseDAO courseDAO, UserDAO userDAO, BokUtil bokUtil) {
+//        this.slideDAO = slideDAO;
+//        this.quizDAO = quizDAO;
+//        this.quizStudentAnswerDAO = quizStudentAnswerDAO;
+//        this.chooseDAO = chooseDAO;
+//        this.courseDAO = courseDAO;
+//        this.userDAO = userDAO;
+//        this.bokUtil = bokUtil;
+//    }
+
+//    @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()
+//                .setSlide(slide)
+//                .setTeacher(slide.getTeacher())
+//                .setType(quizDTO.getType())
+//                .setName(quizDTO.getName())
+//                .setQuestions(quizDTO.getQuestions());
+//
+//        return new QuizVO(quizDAO.save(quiz));
+//    }
+
+//    @Transactional(rollbackFor = Exception.class)
+//    @Override
+//    public QuizVO modifyQuiz(LoginUser user, QuizDTO quizDTO) {
+//        Quiz quiz = quizDAO.findQuizById(quizDTO.getId());
+//
+//        AuthUtils.checkDataAuth(user.getId(), quiz.getId(), "您无权创建该测试");
+//        checkSameName(0L, quizDTO.getSlideId(), quizDTO.getName());
+//
+//        Slide slide = quiz.getSlide();
+//        checkQuizTypeOkToSlideState(slide.getState(), quizDTO.getType());
+//
+//    }
+//
+//    @Override
+//    public String deleteQuiz(Long quizId) {
+//        Quiz quiz = quizDAO.findQuizById(quizId);
+//        if (quiz.getState() != QuizState.NOT_STARTED) {
+//            throw HelperException.of(ExceptionType.FORBIDDEN, "不能删除已经开始的测试!");
+//        }
+//        quizDAO.delete(quiz);
+//        return "delete success";
+//    }
+//
+//    @Override
+//    public Page<Quiz> getAllBasicQuizByUser(Pageable pageable, QuizState state, Long uid) {
+//        User user = userDAO.findUserById(uid);
+//        //todo: 这里写的太狗屎了,可以用重写sql或者用实例查询
+//        if (user.getType().equals(UserType.STUDENT)) {
+//            final Set<Long> courseIdsByStudentId = chooseDAO.findCourseIdsByStudentId(uid);
+//            final Set<Course> collect = courseIdsByStudentId.stream().map(i -> {
+//                Course c = new Course();
+//                c.setId(i);
+//                return c;
+//            }).collect(Collectors.toSet());
+//            if (state != null) {
+//                return quizDAO.findAllByCourseInAndState(collect, state, pageable);
+//            } else {
+//                return quizDAO.findAllByCourseIn(collect, pageable);
+//            }
+//        } else {
+//            if (state != null) {
+//                return quizDAO.findByTeacherAndState(user, state, pageable);
+//            } else {
+//                return quizDAO.findByTeacher(user, pageable);
+//            }
+//
+//        }
+//
+//    }
+//
+//    @Override
+//    public List<QuizResultVO> getQuizResult(Long quizId) {
+//        Assert.notNull(quizId, "错误的测试!");
+//        final Quiz quiz = quizDAO.findQuizById(quizId);
+//        if (quiz.getState() != QuizState.CLOSED) {
+//            throw new RuntimeException("测试未关闭,无法得到测试结果");
+//        }
+//        List<QuizResultVO> retList = new ArrayList<>();
+//        final List<StudentScore> studentScoreList = quiz.getStudentScore();
+//        Map<Long, List<QuizStudentAnswer>> idQuizStudentAnswerMap = new HashMap<>();
+//        for (QuizStudentAnswer qsa : quizStudentAnswerDAO.findAllByQuiz(quiz)) {
+//            idQuizStudentAnswerMap.computeIfAbsent(qsa.getStudent().getId(), k -> new ArrayList<>());
+//            idQuizStudentAnswerMap.get(qsa.getStudent().getId()).add(qsa);
+//        }
+//        for (StudentScore studentScore : studentScoreList) {
+//            final User student = studentScore.getStudent();
+//            final List<QuizStudentAnswer> list = idQuizStudentAnswerMap.get(student.getId());
+//            retList.add(new QuizResultVO(studentScore, student, list));
+//        }
+//        return retList;
+//    }
+//
+//    @Override
+//    public void modifySlideState(Slide slide) {
+//        final List<Quiz> quizzes = quizDAO.findAllBySlide(slide);
+//        quizzes.forEach(quiz -> checkQuizState(quiz, slide));
+//    }
+//
+//    @Override
+//    @Transactional(rollbackFor = Exception.class)
+//    public Integer upStudentAnswer(Long quizId, Long uid, List<QuestionStudentAnswerDTO> answers) {
+//        Assert.notNull(quizId, "错误的测试!");
+//        final Quiz quiz = quizDAO.findQuizById(quizId);
+//        if (quiz.getState() != QuizState.ONGOING) {
+//            throw HelperException.of(ExceptionType.FORBIDDEN, "不能提交尚未开始或已经结束的作业!");
+//        }
+//        User student = new User();
+//        student.setId(uid);
+//        Set<QuizStudentAnswer> quizAnswers = quizStudentAnswerDAO.findByStudentAndQuiz(student, quiz);
+//        Set<String> questionIdSet = new HashSet<>(quiz.getQuestions());
+//        Map<String, QuizStudentAnswer> qsaMap = new HashMap<>(questionIdSet.size());
+//        for (QuizStudentAnswer qsa : quizAnswers) {
+//            qsaMap.put(qsa.getQuestionId(), qsa);
+//        }
+//        //确定被更新或者新建的学生答案提交
+//        List<QuizStudentAnswer> quizStudentAnswers = new ArrayList<>();
+//        for (QuestionStudentAnswerDTO studentAnswer : answers) {
+//            String id = studentAnswer.getQuestionId();
+//            String answer = studentAnswer.getStudentAnswer().toString();
+//            if (!questionIdSet.contains(id)) {
+//                break;
+//            }
+//            if (qsaMap.get(id) != null) {
+//                if (qsaMap.get(id).getStudentAnswer().equals(answer)) {
+//                    continue;
+//                }
+//                qsaMap.get(id).setStudentAnswer(answer);
+//                System.out.println(answer);
+//                quizStudentAnswers.add(qsaMap.get(id));
+//            } else {
+//                QuizStudentAnswer qsa = QuizStudentAnswer.builder()
+//                        .questionId(id).quiz(quiz).student(student).studentAnswer(answer)
+//                        .build();
+//                quizStudentAnswers.add(qsa);
+//            }
+//
+//        }
+//        Integer savedNum = quizStudentAnswers.size();
+//        quizStudentAnswerDAO.saveAll(quizStudentAnswers);
+//        return savedNum;
+//    }
+//
+//    @Override
+//    public Page<Quiz> getAllBasicQuizBySlide(Long slideId, Pageable pageable, QuizState state, Long uid) {
+//        Assert.notNull(slideId, "错误的幻灯片!");
+//        Slide slide = new Slide();
+//        slide.setId(slideId);
+//        if (state != null) {
+//            return quizDAO.findAllBySlideAndState(slide, state, pageable);
+//        } else {
+//            return quizDAO.findAllBySlide(slide, pageable);
+//        }
+//    }
+//
+//    @Override
+//    @Transactional(rollbackFor = Exception.class)
+//    public QuizState checkQuizState(Quiz quiz, Slide slide) {
+//        int quizTime = quiz.getQuizTime().getNum();
+//        int slideTime = slide.getState().getNum();
+//        if (quiz.getId() == null) {
+//            //未持久化的quiz
+//            quiz.setState(slideTime < quizTime ? QuizState.NOT_STARTED : QuizState.ONGOING);
+//        } else {
+//            //持久化后,不仅仅需要推进状态,还需要判分,保存等步骤
+//            if (slideTime < quizTime) {
+//                if (quiz.getState().equals(QuizState.NOT_STARTED)) {
+//                    return QuizState.NOT_STARTED;
+//                }
+//                //未开始
+//                quiz.setState(QuizState.NOT_STARTED);
+//            } else if (slideTime == quizTime) {
+//                if (quiz.getState().equals(QuizState.ONGOING)) {
+//                    return QuizState.ONGOING;
+//                }
+//                quiz.setState(QuizState.ONGOING);
+//            } else {
+//                if (quiz.getState().equals(QuizState.CLOSED)) {
+//                    return QuizState.CLOSED;
+//                }
+//                quiz.setState(QuizState.CLOSED);
+//                Set<QuizStudentAnswer> quizAnswers = quizStudentAnswerDAO.findAllByQuiz(quiz);
+//                final Set<Long> studentIds = chooseDAO.findStudentIdsByCourseId(slide.getCourse().getId());
+//                Student2QuestionId2Answer triadMap = new Student2QuestionId2Answer(studentIds, quiz.getQuestions().size());
+//                //将已经作答的学生答案加入
+//                for (QuizStudentAnswer answers : quizAnswers) {
+//                    triadMap.addAnswer(answers);
+//                }
+//                //生成未作答的学生答案
+//                triadMap.fullAnswer(quiz);
+//                //检查答案,赋分
+//                triadMap.checkAnswerAndFullPass(bokUtil.bokFindByIdIn(quiz.getQuestions()), quiz);
+//                //保存现场
+//                quizStudentAnswerDAO.saveAll(triadMap.getAll());
+//            }
+//
+//            quizDAO.save(quiz);
+//        }
+//        return quiz.getState();
+//    }
+//
+//    @Override
+//    public QuizState checkQuizState(Long quizId, Long slideId) {
+//        Quiz quiz = quizDAO.findQuizById(quizId);
+//        Slide slide = slideDAO.findSlideById(slideId);
+//        return checkQuizState(quiz, slide);
+//    }
+//
+//    private class Student2QuestionId2Answer {
+//        Map<Long, Map<String, QuizStudentAnswer>> student2QuestionId2Answer;
+//
+//        Student2QuestionId2Answer(Set<Long> studentIds, Integer quizQuestionSize) {
+//            student2QuestionId2Answer = new LinkedHashMap<>(studentIds.size());
+//            for (Long studentId : studentIds) {
+//                Map<String, QuizStudentAnswer> questionId2Answer = new LinkedHashMap<>(quizQuestionSize);
+//                student2QuestionId2Answer.put(studentId, questionId2Answer);
+//            }
+//        }
+//
+//        void addAnswer(QuizStudentAnswer answers) {
+//            Map<String, QuizStudentAnswer> stringQuizStudentAnswerMap = student2QuestionId2Answer.get(answers.getStudent().getId());
+//            if (stringQuizStudentAnswerMap == null) {
+//                return;
+//            }
+//            stringQuizStudentAnswerMap.put(answers.getQuestionId(), answers);
+//        }
+//
+//        void fullAnswer(Quiz quiz) {
+//            List<String> questions = quiz.getQuestions();
+//            student2QuestionId2Answer.forEach((studentId, map) -> {
+//                if (questions.size() != map.size()) {
+//                    for (String questionId : questions) {
+//                        if (map.get(questionId) == null) {
+//                            User student = new User();
+//                            student.setId(studentId);
+//                            QuizStudentAnswer qsa = QuizStudentAnswer.builder()
+//                                    .questionId(questionId).quiz(quiz).student(student)
+//                                    .build();
+//                            map.put(questionId, qsa);
+//                        }
+//                    }
+//                }
+//            });
+//        }
+//
+//        void checkAnswerAndFullPass(List<BaseQuestionVO> questionVos, Quiz quiz) {
+//            if (quiz.getStudentScore() == null) {
+//                quiz.setStudentScore(new ArrayList<>(student2QuestionId2Answer.size()));
+//            }
+//            student2QuestionId2Answer.forEach((studentId, map) -> {
+//                int passCount = 0;
+//                for (BaseQuestionVO vo : questionVos) {
+//                    final String studentAnswer = map.get(vo.getQuestionId()).getStudentAnswer();
+//                    boolean pass = vo.checkAnswer(studentAnswer);
+//                    if (pass) {
+//                        passCount++;
+//                    }
+//                    map.get(vo.getQuestionId()).setPass(pass);
+//                }
+//                Double score = (100.0 * passCount) / questionVos.size();
+//                User student = new User();
+//                student.setId(studentId);
+//                StudentScore studentScore = new StudentScore();
+//                studentScore.setQuizId(quiz.getId());
+//                studentScore.setScore(Long.valueOf(Math.round(score)).intValue());
+//                studentScore.setStudent(student);
+//                quiz.getStudentScore().add(studentScore);
+//            });
+//        }
+//
+//        List<QuizStudentAnswer> getAll() {
+//            List<QuizStudentAnswer> list = new ArrayList<>();
+//            for (Long sid : student2QuestionId2Answer.keySet()) {
+//                list.addAll(student2QuestionId2Answer.get(sid).values());
+//            }
+//            return list;
+//        }
+//    }
+//
+//    @Override
+//    public QuizVO combineQuiz(Long quizId) {
+//        Assert.notNull(quizId, "错误的测试!");
+//        final Quiz quizById = quizDAO.findQuizById(quizId);
+//        final List<BaseQuestionVO> questionVoS = bokUtil.bokFindByIdIn(quizById.getQuestions());
+//        return new QuizVO(quizById, questionVoS);
+//    }
+//
+//    @Override
+//    public QuizVO combineQuizWithAnswer(Long quizId, Long uid, UserType userType) {
+//        Assert.notNull(quizId, "错误的测试!");
+//        final Quiz quizById = quizDAO.findQuizById(quizId);
+//        User student = new User();
+//        student.setId(uid);
+//
+//        if (userType == null || userType.equals(UserType.TEACHER)) {
+//            //向老师展示
+//            List<BaseQuestionVO> questionVoS = bokUtil.bokFindByIdIn(quizById.getQuestions());
+//            return new QuizVO(quizById, questionVoS);
+//        }
+//        if (quizById.getState().equals(QuizState.NOT_STARTED)) {
+//            //未开始看不到题目
+//            return new QuizVO(quizById);
+//        }
+//
+//        List<BaseQuestionVO> questionVos = bokUtil.bokFindByIdIn(quizById.getQuestions());
+//        final Set<QuizStudentAnswer> quizAnswers = quizStudentAnswerDAO.findByStudentAndQuiz(student, quizById);
+//        Map<String, QuizStudentAnswer> qsaMap = new HashMap<>(quizAnswers.size());
+//        for (QuizStudentAnswer qsa : quizAnswers) {
+//            qsaMap.put(qsa.getQuestionId(), qsa);
+//        }
+//        for (BaseQuestionVO vo : questionVos) {
+//            if (qsaMap.get(vo.getQuestionId()) != null) {
+//                vo.exAddAnswer(qsaMap.get(vo.getQuestionId()));
+//            }
+//        }
+//
+//        return new QuizVO(quizById, questionVos);
+//    }
+//
+//    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, "课件暂时不支持创建该类型的测试,请检查课件状态");
+//        }
+//    }
 }
 }

+ 2 - 2
src/main/java/nju/seec/helper/service/impl/SlideServiceImpl.java

@@ -129,8 +129,8 @@ public class SlideServiceImpl implements SlideService {
 
 
         slide.setState(slideStateDTO.getState());
         slide.setState(slideStateDTO.getState());
         slide = slideDAO.save(slide);
         slide = slideDAO.save(slide);
-        // 修改Slide状态同时推进quiz状态
-        quizService.modifySlideState(slide);
+//        // 修改Slide状态同时推进quiz状态
+//        quizService.modifySlideState(slide);
 
 
         // 增加通知
         // 增加通知
         if (slide.getState() == SlideState.IN_CLASS) {
         if (slide.getState() == SlideState.IN_CLASS) {

+ 283 - 283
src/main/java/nju/seec/helper/util/BokUtil.java

@@ -1,283 +1,283 @@
-package nju.seec.helper.util;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.google.common.collect.ImmutableMap;
-import lombok.Data;
-import nju.seec.helper.util.enums.ExceptionType;
-import nju.seec.helper.util.enums.QuestionKindState;
-import nju.seec.helper.util.exception.HelperException;
-import nju.seec.helper.vo.quiz.BaseQuestionVO;
-import nju.seec.helper.vo.quiz.ChoiceQuestionVO;
-import nju.seec.helper.vo.quiz.TrueOrFalseQuestionVO;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.data.domain.Pageable;
-import org.springframework.http.HttpStatus;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Isolation;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.client.HttpClientErrorException;
-
-import java.util.*;
-import java.util.stream.Collectors;
-
-/**
- * @author xst
- * <p>
- * updated by cst
- */
-@Component
-public class BokUtil {
-    private final RestRequestUtil restRequestUtil;
-    private final GuavaCacheUtil cacheUtils;
-    @Value("${bok.url}")
-    private String bokUrl = "http://bok.seecoder.cn";
-    private String searchUrl = bokUrl + "/api/tq/search/";
-    private String tqUrl = bokUrl + "/api/tq/";
-
-    public BokUtil(RestRequestUtil restRequestUtil, GuavaCacheUtil cacheUtils) {
-        this.restRequestUtil = restRequestUtil;
-        this.cacheUtils = cacheUtils;
-    }
-    
-    public void bokFindByStemLike(String stem, List<BaseQuestionVO> questions, Map page, Pageable pageable) {
-        Map<String, String> urlParams = new HashMap<>();
-        urlParams.put("content", stem);
-        urlParams.put("sort", pageable.getSort().toString().replaceAll(" ", "").replaceAll(":", ","));
-        urlParams.put("size", String.valueOf(pageable.getPageSize()));
-        urlParams.put("page", String.valueOf(1 + pageable.getPageNumber()));
-        try {
-            Map ret = (Map) restRequestUtil.sendGetRequest(
-                    searchUrl + "findByStemLike?content={content}&sort={sort}&size={size}&page={page}", urlParams);
-            List<Map> tqs = ((List) ((Map) ret.get("_embedded")).get("choiceQuestions"));
-
-            List collect = parseBody(tqs);
-            try {
-                page.putAll((Map) ret.get("page"));
-                questions.addAll(collect);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    private static String CACHE_NAME = "BOK";
-
-    public List<BaseQuestionVO> bokFindByIdIn(List<String> ids) {
-        //todo: 从缓存中取Ids
-        Set<String> requestIds = new HashSet<>(ids);
-        final ImmutableMap<Object, Object> bok = cacheUtils.multiGet(CACHE_NAME, requestIds);
-
-        Map<String, BaseQuestionVO> questionsMap = new HashMap<>(ids.size());
-        bok.values().forEach(vo -> {
-            if (vo instanceof BaseQuestionVO) {
-                BaseQuestionVO questionVO = (BaseQuestionVO) vo;
-                questionsMap.put(questionVO.getQuestionId(), questionVO);
-                requestIds.remove(questionVO.getQuestionId());
-            }
-        });
-        //未缓存的去这里拿
-        if (requestIds.size() > 0) {
-            Map<String, String> urlParams = new HashMap<>();
-            String idsStr = requestIds.stream().reduce((a, b) -> {
-                return a + "," + b;
-            }).orElse("");
-            urlParams.put("id", idsStr);
-            urlParams.put("size", String.valueOf(requestIds.size()));
-            urlParams.put("page", "1");
-            List<Map> tqs = null;
-            try {
-                Map ret = (Map) restRequestUtil.sendGetRequest(
-                        searchUrl + "findByIdIn?id={id}&size={size}&page={page}", urlParams);
-                tqs = ((List) ((Map) ret.get("_embedded")).get("choiceQuestions"));
-            } catch (Exception e) {
-                e.printStackTrace();
-                throw new RuntimeException("bok request error!for findByIdIn:" + Arrays.toString(requestIds.toArray()));
-            }
-            List<BaseQuestionVO> collect = parseBody(tqs);
-            Map<String, Object> newGet = new HashMap<>(collect.size());
-            for (BaseQuestionVO vo : collect) {
-                System.out.println(vo);
-                questionsMap.put(vo.getQuestionId(), vo);
-                newGet.put(vo.getQuestionId(), vo);
-            }
-            cacheUtils.setAll(CACHE_NAME, newGet);
-        }
-
-        // todo: 按照Ids重排序
-        List<BaseQuestionVO> ret = new ArrayList<>();
-        for (String id : ids) {
-            ret.add(questionsMap.get(id));
-        }
-        return (ret);
-    }
-
-    private List parseBody(List<Map> tqs) {
-        final List collect = tqs.stream().map(BokUtil::parseOneQuestion).collect(Collectors.toList());
-        return collect;
-    }
-
-    private static BaseQuestionVO parseOneQuestion(Map q) {
-        switch ((String) q.get("type")) {
-            case "choice":
-                return ChoiceQuestionVO.builder().stem((String) q.get("stem")).kind(QuestionKindState.CHOICE)
-                        .options((Map<String, String>) q.get("options")).answer(((String) q.get("answer")).replaceAll("【答案】", ""))
-                        .analysis((String) q.get("analysis")).questionId(String.valueOf((Integer) q.get("tq_id"))).build();
-
-            case "true_false":
-                return TrueOrFalseQuestionVO.builder().stem((String) q.get("stem")).kind(QuestionKindState.TRUE_FALSE)
-                        .answer(Boolean.valueOf((String) q.get("answer")))
-                        .analysis((String) q.get("analysis")).questionId(String.valueOf((Integer) q.get("tq_id"))).build();
-            default:
-        }
-        throw HelperException.of(ExceptionType.ERROR, "unknown type:" + (String) q.get("type"));
-    }
-
-    public BaseQuestionVO bokFindById(String questionId) {
-        Map<String, String> urlParams = new HashMap<>();
-        Object cachedVo = cacheUtils.get(CACHE_NAME, questionId);
-        if (cachedVo instanceof BaseQuestionVO) {
-            return (BaseQuestionVO) cachedVo;
-        }
-        try {
-            Map ret = (Map) restRequestUtil.sendGetRequest(tqUrl + questionId, urlParams);
-            final BaseQuestionVO vo = parseOneQuestion(ret);
-            cacheUtils.set(CACHE_NAME, vo.getQuestionId(), vo);
-            return vo;
-        } catch (JsonProcessingException e) {
-            throw HelperException.of(ExceptionType.ERROR, "请求BOK题库数据错误:" + e.getMessage());
-        } catch (HttpClientErrorException e) {
-            throw HelperException.of(ExceptionType.valueOf(e.getStatusCode()), "请求BOK题库数据错误:" + e.getMessage());
-        }
-    }
-
-    @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
-    public BaseQuestionVO postNewQuestion(BaseQuestionVO vo) throws JsonProcessingException {
-        if (vo.getQuestionId() != null) {
-            throw HelperException.of(ExceptionType.PARAM_ERROR, "should POST a new question");
-        }
-        String questionId = null;
-        //我当时应该用uuid的,但是线上已经部署了,只能下次再改了(如果有下次
-        //因为线上用的也是Long Id 并且es不提供自增主键,先这样尝试插入
-        //之后对于新增bok的题目,应该有某种限制,未补全知识点的题目不允许插入
-        int tryNumber = 100;
-        int randomLength = 4;
-        for (int i = 0; i < tryNumber; i++) {
-            Date date = new Date();
-            Calendar calendar = Calendar.getInstance();
-            int year = calendar.get(Calendar.YEAR);
-            String month = String.valueOf(1 + calendar.get(Calendar.MONTH));
-            String day = String.valueOf(calendar.get(Calendar.DATE));
-            if (month.length() < 2) {
-                month = "0" + month;
-            }
-            if (day.length() < 2) {
-                month = "0" + month;
-            }
-            Random randomGet = new Random();
-            StringBuilder random = new StringBuilder(String.valueOf(randomGet.nextInt(10000)));
-            while (random.length() < randomLength) {
-                random.insert(0, "0");
-            }
-            questionId = "" + (year - 2010) + (month) + day + (random);
-            try {
-                Map ret = (Map) restRequestUtil.sendGetRequest(tqUrl + questionId, new HashMap<>());
-            } catch (HttpClientErrorException e) {
-                if (e.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
-                    break;
-                }
-            }
-            questionId = null;
-        }
-        if (questionId == null) {
-            throw HelperException.of(ExceptionType.ERROR, "暂时无法保存题目,请重试!");
-        }
-
-        vo.setQuestionId(questionId);
-
-        BokTq bokTq = new BokTq(vo);
-        restRequestUtil.sendPutRequest(tqUrl + questionId, bokTq);
-
-        return vo;
-
-    }
-
-    @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
-    public BaseQuestionVO putQuestion(BaseQuestionVO vo) throws JsonProcessingException {
-        if (vo.getQuestionId() == null) {
-            throw HelperException.of(ExceptionType.PARAM_ERROR, "should POST a present question");
-        }
-        String questionId = vo.getQuestionId();
-        try {
-            restRequestUtil.sendGetRequest(tqUrl + questionId, new HashMap<>());
-        } catch (HttpClientErrorException e) {
-            if (e.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
-                throw HelperException.of(ExceptionType.PARAM_ERROR, "should POST a present question");
-            }
-        }
-        restRequestUtil.sendPutRequest(tqUrl + questionId, new BokTq(vo));
-
-        cacheUtils.remove(CACHE_NAME, questionId);
-        return vo;
-    }
-
-    public void deleteQuestion(String questionId) {
-        try {
-            restRequestUtil.sendDeleteRequest(tqUrl + questionId);
-        } catch (JsonProcessingException e) {
-            throw HelperException.of(ExceptionType.ERROR, "请求BOK题库数据错误:" + e.getMessage());
-        }
-        cacheUtils.remove(CACHE_NAME, questionId);
-    }
-
-    /**
-     * 来自restBok接口的对象
-     */
-    @JsonInclude(JsonInclude.Include.NON_NULL)
-    @Data
-    static class BokTq {
-        String id;
-        String type;
-        String answer;
-        @JsonProperty(value = "key_points")
-        String keyPoints;
-        String analysis;
-        String lastModified;
-        String stem;
-        Map options;
-        List tags;
-        List knowledgeId;
-
-        private BokTq(BaseQuestionVO vo) {
-            this.id = vo.getQuestionId();
-            this.stem = vo.getStem();
-            switch (vo.getKind()) {
-
-                case CHOICE:
-                    ChoiceQuestionVO cqvo = (ChoiceQuestionVO) vo;
-                    this.options = cqvo.getOptions();
-                    this.type = "choice";
-                    this.analysis = cqvo.getAnalysis();
-                    this.answer = cqvo.getAnswer();
-                    break;
-                case TRUE_FALSE:
-                    TrueOrFalseQuestionVO tfvo = (TrueOrFalseQuestionVO) vo;
-                    this.options = null;
-                    this.type = "true_false";
-                    this.analysis = tfvo.getAnalysis();
-                    this.answer = tfvo.getAnswer().toString();
-                    break;
-                default:
-            }
-
-            this.keyPoints = null;
-            this.lastModified = null;
-            this.tags = null;
-            this.knowledgeId = null;
-        }
-    }
-}
+//package nju.seec.helper.util;
+//
+//import com.fasterxml.jackson.annotation.JsonInclude;
+//import com.fasterxml.jackson.annotation.JsonProperty;
+//import com.fasterxml.jackson.core.JsonProcessingException;
+//import com.google.common.collect.ImmutableMap;
+//import lombok.Data;
+//import nju.seec.helper.util.enums.ExceptionType;
+//import nju.seec.helper.util.enums.QuestionKindState;
+//import nju.seec.helper.util.exception.HelperException;
+//import nju.seec.helper.vo.quiz.BaseQuestionVO;
+//import nju.seec.helper.vo.quiz.ChoiceQuestionVO;
+//import nju.seec.helper.vo.quiz.TrueOrFalseQuestionVO;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.data.domain.Pageable;
+//import org.springframework.http.HttpStatus;
+//import org.springframework.stereotype.Component;
+//import org.springframework.transaction.annotation.Isolation;
+//import org.springframework.transaction.annotation.Transactional;
+//import org.springframework.web.client.HttpClientErrorException;
+//
+//import java.util.*;
+//import java.util.stream.Collectors;
+//
+///**
+// * @author xst
+// * <p>
+// * updated by cst
+// */
+//@Component
+//public class BokUtil {
+//    private final RestRequestUtil restRequestUtil;
+//    private final GuavaCacheUtil cacheUtils;
+//    @Value("${bok.url}")
+//    private String bokUrl = "http://bok.seecoder.cn";
+//    private String searchUrl = bokUrl + "/api/tq/search/";
+//    private String tqUrl = bokUrl + "/api/tq/";
+//
+//    public BokUtil(RestRequestUtil restRequestUtil, GuavaCacheUtil cacheUtils) {
+//        this.restRequestUtil = restRequestUtil;
+//        this.cacheUtils = cacheUtils;
+//    }
+//
+//    public void bokFindByStemLike(String stem, List<BaseQuestionVO> questions, Map page, Pageable pageable) {
+//        Map<String, String> urlParams = new HashMap<>();
+//        urlParams.put("content", stem);
+//        urlParams.put("sort", pageable.getSort().toString().replaceAll(" ", "").replaceAll(":", ","));
+//        urlParams.put("size", String.valueOf(pageable.getPageSize()));
+//        urlParams.put("page", String.valueOf(1 + pageable.getPageNumber()));
+//        try {
+//            Map ret = (Map) restRequestUtil.sendGetRequest(
+//                    searchUrl + "findByStemLike?content={content}&sort={sort}&size={size}&page={page}", urlParams);
+//            List<Map> tqs = ((List) ((Map) ret.get("_embedded")).get("choiceQuestions"));
+//
+//            List collect = parseBody(tqs);
+//            try {
+//                page.putAll((Map) ret.get("page"));
+//                questions.addAll(collect);
+//            } catch (Exception e) {
+//                e.printStackTrace();
+//            }
+//
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//    }
+//
+//    private static String CACHE_NAME = "BOK";
+//
+//    public List<BaseQuestionVO> bokFindByIdIn(List<String> ids) {
+//        //todo: 从缓存中取Ids
+//        Set<String> requestIds = new HashSet<>(ids);
+//        final ImmutableMap<Object, Object> bok = cacheUtils.multiGet(CACHE_NAME, requestIds);
+//
+//        Map<String, BaseQuestionVO> questionsMap = new HashMap<>(ids.size());
+//        bok.values().forEach(vo -> {
+//            if (vo instanceof BaseQuestionVO) {
+//                BaseQuestionVO questionVO = (BaseQuestionVO) vo;
+//                questionsMap.put(questionVO.getQuestionId(), questionVO);
+//                requestIds.remove(questionVO.getQuestionId());
+//            }
+//        });
+//        //未缓存的去这里拿
+//        if (requestIds.size() > 0) {
+//            Map<String, String> urlParams = new HashMap<>();
+//            String idsStr = requestIds.stream().reduce((a, b) -> {
+//                return a + "," + b;
+//            }).orElse("");
+//            urlParams.put("id", idsStr);
+//            urlParams.put("size", String.valueOf(requestIds.size()));
+//            urlParams.put("page", "1");
+//            List<Map> tqs = null;
+//            try {
+//                Map ret = (Map) restRequestUtil.sendGetRequest(
+//                        searchUrl + "findByIdIn?id={id}&size={size}&page={page}", urlParams);
+//                tqs = ((List) ((Map) ret.get("_embedded")).get("choiceQuestions"));
+//            } catch (Exception e) {
+//                e.printStackTrace();
+//                throw new RuntimeException("bok request error!for findByIdIn:" + Arrays.toString(requestIds.toArray()));
+//            }
+//            List<BaseQuestionVO> collect = parseBody(tqs);
+//            Map<String, Object> newGet = new HashMap<>(collect.size());
+//            for (BaseQuestionVO vo : collect) {
+//                System.out.println(vo);
+//                questionsMap.put(vo.getQuestionId(), vo);
+//                newGet.put(vo.getQuestionId(), vo);
+//            }
+//            cacheUtils.setAll(CACHE_NAME, newGet);
+//        }
+//
+//        // todo: 按照Ids重排序
+//        List<BaseQuestionVO> ret = new ArrayList<>();
+//        for (String id : ids) {
+//            ret.add(questionsMap.get(id));
+//        }
+//        return (ret);
+//    }
+//
+//    private List parseBody(List<Map> tqs) {
+//        final List collect = tqs.stream().map(BokUtil::parseOneQuestion).collect(Collectors.toList());
+//        return collect;
+//    }
+//
+//    private static BaseQuestionVO parseOneQuestion(Map q) {
+//        switch ((String) q.get("type")) {
+//            case "choice":
+//                return ChoiceQuestionVO.builder().stem((String) q.get("stem")).kind(QuestionKindState.CHOICE)
+//                        .options((Map<String, String>) q.get("options")).answer(((String) q.get("answer")).replaceAll("【答案】", ""))
+//                        .analysis((String) q.get("analysis")).questionId(String.valueOf((Integer) q.get("tq_id"))).build();
+//
+//            case "true_false":
+//                return TrueOrFalseQuestionVO.builder().stem((String) q.get("stem")).kind(QuestionKindState.TRUE_FALSE)
+//                        .answer(Boolean.valueOf((String) q.get("answer")))
+//                        .analysis((String) q.get("analysis")).questionId(String.valueOf((Integer) q.get("tq_id"))).build();
+//            default:
+//        }
+//        throw HelperException.of(ExceptionType.ERROR, "unknown type:" + (String) q.get("type"));
+//    }
+//
+//    public BaseQuestionVO bokFindById(String questionId) {
+//        Map<String, String> urlParams = new HashMap<>();
+//        Object cachedVo = cacheUtils.get(CACHE_NAME, questionId);
+//        if (cachedVo instanceof BaseQuestionVO) {
+//            return (BaseQuestionVO) cachedVo;
+//        }
+//        try {
+//            Map ret = (Map) restRequestUtil.sendGetRequest(tqUrl + questionId, urlParams);
+//            final BaseQuestionVO vo = parseOneQuestion(ret);
+//            cacheUtils.set(CACHE_NAME, vo.getQuestionId(), vo);
+//            return vo;
+//        } catch (JsonProcessingException e) {
+//            throw HelperException.of(ExceptionType.ERROR, "请求BOK题库数据错误:" + e.getMessage());
+//        } catch (HttpClientErrorException e) {
+//            throw HelperException.of(ExceptionType.valueOf(e.getStatusCode()), "请求BOK题库数据错误:" + e.getMessage());
+//        }
+//    }
+//
+//    @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
+//    public BaseQuestionVO postNewQuestion(BaseQuestionVO vo) throws JsonProcessingException {
+//        if (vo.getQuestionId() != null) {
+//            throw HelperException.of(ExceptionType.PARAM_ERROR, "should POST a new question");
+//        }
+//        String questionId = null;
+//        //我当时应该用uuid的,但是线上已经部署了,只能下次再改了(如果有下次
+//        //因为线上用的也是Long Id 并且es不提供自增主键,先这样尝试插入
+//        //之后对于新增bok的题目,应该有某种限制,未补全知识点的题目不允许插入
+//        int tryNumber = 100;
+//        int randomLength = 4;
+//        for (int i = 0; i < tryNumber; i++) {
+//            Date date = new Date();
+//            Calendar calendar = Calendar.getInstance();
+//            int year = calendar.get(Calendar.YEAR);
+//            String month = String.valueOf(1 + calendar.get(Calendar.MONTH));
+//            String day = String.valueOf(calendar.get(Calendar.DATE));
+//            if (month.length() < 2) {
+//                month = "0" + month;
+//            }
+//            if (day.length() < 2) {
+//                month = "0" + month;
+//            }
+//            Random randomGet = new Random();
+//            StringBuilder random = new StringBuilder(String.valueOf(randomGet.nextInt(10000)));
+//            while (random.length() < randomLength) {
+//                random.insert(0, "0");
+//            }
+//            questionId = "" + (year - 2010) + (month) + day + (random);
+//            try {
+//                Map ret = (Map) restRequestUtil.sendGetRequest(tqUrl + questionId, new HashMap<>());
+//            } catch (HttpClientErrorException e) {
+//                if (e.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
+//                    break;
+//                }
+//            }
+//            questionId = null;
+//        }
+//        if (questionId == null) {
+//            throw HelperException.of(ExceptionType.ERROR, "暂时无法保存题目,请重试!");
+//        }
+//
+//        vo.setQuestionId(questionId);
+//
+//        BokTq bokTq = new BokTq(vo);
+//        restRequestUtil.sendPutRequest(tqUrl + questionId, bokTq);
+//
+//        return vo;
+//
+//    }
+//
+//    @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
+//    public BaseQuestionVO putQuestion(BaseQuestionVO vo) throws JsonProcessingException {
+//        if (vo.getQuestionId() == null) {
+//            throw HelperException.of(ExceptionType.PARAM_ERROR, "should POST a present question");
+//        }
+//        String questionId = vo.getQuestionId();
+//        try {
+//            restRequestUtil.sendGetRequest(tqUrl + questionId, new HashMap<>());
+//        } catch (HttpClientErrorException e) {
+//            if (e.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
+//                throw HelperException.of(ExceptionType.PARAM_ERROR, "should POST a present question");
+//            }
+//        }
+//        restRequestUtil.sendPutRequest(tqUrl + questionId, new BokTq(vo));
+//
+//        cacheUtils.remove(CACHE_NAME, questionId);
+//        return vo;
+//    }
+//
+//    public void deleteQuestion(String questionId) {
+//        try {
+//            restRequestUtil.sendDeleteRequest(tqUrl + questionId);
+//        } catch (JsonProcessingException e) {
+//            throw HelperException.of(ExceptionType.ERROR, "请求BOK题库数据错误:" + e.getMessage());
+//        }
+//        cacheUtils.remove(CACHE_NAME, questionId);
+//    }
+//
+//    /**
+//     * 来自restBok接口的对象
+//     */
+//    @JsonInclude(JsonInclude.Include.NON_NULL)
+//    @Data
+//    static class BokTq {
+//        String id;
+//        String type;
+//        String answer;
+//        @JsonProperty(value = "key_points")
+//        String keyPoints;
+//        String analysis;
+//        String lastModified;
+//        String stem;
+//        Map options;
+//        List tags;
+//        List knowledgeId;
+//
+//        private BokTq(BaseQuestionVO vo) {
+//            this.id = vo.getQuestionId();
+//            this.stem = vo.getStem();
+//            switch (vo.getKind()) {
+//
+//                case CHOICE:
+//                    ChoiceQuestionVO cqvo = (ChoiceQuestionVO) vo;
+//                    this.options = cqvo.getOptions();
+//                    this.type = "choice";
+//                    this.analysis = cqvo.getAnalysis();
+//                    this.answer = cqvo.getAnswer();
+//                    break;
+//                case TRUE_FALSE:
+//                    TrueOrFalseQuestionVO tfvo = (TrueOrFalseQuestionVO) vo;
+//                    this.options = null;
+//                    this.type = "true_false";
+//                    this.analysis = tfvo.getAnalysis();
+//                    this.answer = tfvo.getAnswer().toString();
+//                    break;
+//                default:
+//            }
+//
+//            this.keyPoints = null;
+//            this.lastModified = null;
+//            this.tags = null;
+//            this.knowledgeId = null;
+//        }
+//    }
+//}

+ 5 - 0
src/main/java/nju/seec/helper/util/JsonUtils.java

@@ -2,6 +2,7 @@ package nju.seec.helper.util;
 
 
 import com.google.gson.Gson;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
 import lombok.experimental.UtilityClass;
 import lombok.experimental.UtilityClass;
 import nju.seec.helper.util.serializer.LocalDateTimeSerializer;
 import nju.seec.helper.util.serializer.LocalDateTimeSerializer;
 
 
@@ -21,4 +22,8 @@ public class JsonUtils {
     public <T> T fromJson(String json, Class<T> classOfT) {
     public <T> T fromJson(String json, Class<T> classOfT) {
         return GSON.fromJson(json, classOfT);
         return GSON.fromJson(json, classOfT);
     }
     }
+
+    public <T> T fromJson(String json, TypeToken<T> type) {
+        return GSON.fromJson(json, type.getType());
+    }
 }
 }

+ 3 - 1
src/main/java/nju/seec/helper/util/enums/QuizState.java

@@ -1,7 +1,9 @@
 package nju.seec.helper.util.enums;
 package nju.seec.helper.util.enums;
 
 
 /**
 /**
- * @author cst
+ * @author xst
+ * <p>
+ * updated by cst
  */
  */
 public enum QuizState {
 public enum QuizState {
     NOT_STARTED("未开始"), ONGOING("正在进行"), CLOSED("已结束");
     NOT_STARTED("未开始"), ONGOING("正在进行"), CLOSED("已结束");

+ 27 - 0
src/main/java/nju/seec/helper/util/enums/QuizType.java

@@ -0,0 +1,27 @@
+package nju.seec.helper.util.enums;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author cst
+ */
+public enum QuizType {
+    BEFORE_CLASS, IN_CLASS, AFTER_CLASS;
+
+    private final static Map<SlideState, Set<QuizType>> SLIDE_QUIZ_MAP = ImmutableMap.of(
+            SlideState.DRAFT, ImmutableSet.of(BEFORE_CLASS, IN_CLASS, AFTER_CLASS),
+            SlideState.BEFORE_CLASS, ImmutableSet.of(BEFORE_CLASS, IN_CLASS, AFTER_CLASS),
+            SlideState.IN_CLASS, ImmutableSet.of(IN_CLASS, AFTER_CLASS),
+            SlideState.AFTER_CLASS, ImmutableSet.of(AFTER_CLASS),
+            SlideState.FINISH, Collections.emptySet()
+    );
+
+    public static Set<QuizType> getQuizTypesBySlideState(SlideState slideState) {
+        return SLIDE_QUIZ_MAP.get(slideState);
+    }
+}

+ 95 - 95
src/main/java/nju/seec/helper/vo/quiz/BaseQuestionVO.java

@@ -1,104 +1,104 @@
-package nju.seec.helper.vo.quiz;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.SuperBuilder;
-import nju.seec.helper.entity.QuizStudentAnswer;
-import nju.seec.helper.util.enums.ExceptionType;
-import nju.seec.helper.util.enums.QuestionKindState;
-import nju.seec.helper.util.exception.HelperException;
-
-import javax.validation.constraints.NotNull;
-import java.util.Map;
-
-/**
- * @author XuShengTao
- */
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-@SuperBuilder
-public abstract class BaseQuestionVO {
-    @NotNull
-    @JsonProperty(value = "id")
-    private String questionId;
-    @NotNull
-    @JsonProperty(value = "kind")
-    private QuestionKindState kind;
-    @JsonProperty(value = "stem")
-    private String stem;
-
-    public abstract void exAddAnswer(QuizStudentAnswer answer);
-
-    public abstract boolean checkAnswer(Object answer);
-
-    public abstract void excludeCorrectAnswer();
-
-    private static ObjectMapper objectMapper = new ObjectMapper();
-
-    public static BaseQuestionVO parse(Map question) {
-        String kind = (String) question.get("kind");
-        BaseQuestionVO newQuestion = null;
-        switch (kind) {
-            case "CHOICE":
-                newQuestion = (objectMapper.convertValue(question, ChoiceQuestionVO.class));
-                return newQuestion;
-            case "TRUE_FALSE":
-                newQuestion = (objectMapper.convertValue(question, TrueOrFalseQuestionVO.class));
-                return newQuestion;
-            default:
-        }
-        throw HelperException.of(ExceptionType.PARAM_ERROR, "parse failed:" + question.toString());
-    }
-}
-//QuestionSerializer
-//问题的详细定义
+//package nju.seec.helper.vo.quiz;
 //
 //
-//Attribute
-//type QuestionSerializer =
-//  | ChoiceQuestionSerializer
-//  | TrueOrFalseQuestionSerializer;
+//import com.fasterxml.jackson.annotation.JsonProperty;
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import lombok.AllArgsConstructor;
+//import lombok.Data;
+//import lombok.NoArgsConstructor;
+//import lombok.experimental.SuperBuilder;
+//import nju.seec.helper.entity.QuizStudentAnswer;
+//import nju.seec.helper.util.enums.ExceptionType;
+//import nju.seec.helper.util.enums.QuestionKindState;
+//import nju.seec.helper.util.exception.HelperException;
 //
 //
-//type QuestionWithoutAnswerSerializer = Omit<
-//  QuestionSerializer,
-//  "answer" | "analysis"
-//>;
+//import javax.validation.constraints.NotNull;
+//import java.util.Map;
 //
 //
-//type QuestionWithStudentAnswerSerializer =
-//  | ChoiceQuestionWithStudentAnswer
-//  | TrueOrFalseQuestionWithStudentAnswer;
+///**
+// * @author XuShengTao
+// */
+//@Data
+//@NoArgsConstructor
+//@AllArgsConstructor
+//@SuperBuilder
+//public abstract class BaseQuestionVO {
+//    @NotNull
+//    @JsonProperty(value = "id")
+//    private String questionId;
+//    @NotNull
+//    @JsonProperty(value = "kind")
+//    private QuestionKindState kind;
+//    @JsonProperty(value = "stem")
+//    private String stem;
 //
 //
-//interface Question {
-//  id: number; // 题目id
-//  kind: "CHOICE" | "TRUE_FALSE";
-//  stem: string; // 题干
-//}
+//    public abstract void exAddAnswer(QuizStudentAnswer answer);
 //
 //
-//interface ChoiceQuestionSerializer extends Question {
-//  kind: "CHOICE";
-//  options: {
-//    [key: string]: string;
-//  };
-//  answer: string; // 答案 [与 options 的 key 一致]
-//  analysis?: string; // 解析
-//}
+//    public abstract boolean checkAnswer(Object answer);
 //
 //
-//interface ChoiceQuestionWithStudentAnswer extends ChoiceQuestionSerializer {
-//  studentAnswer: string;
-//  pass: boolean; // 是否正确
-//}
+//    public abstract void excludeCorrectAnswer();
 //
 //
-//interface TrueOrFalseQuestionSerializer extends Question {
-//  kind: "TRUE_FALSE";
-//  answer: boolean; // 答案
-//  analysis?: string; // 解析
-//}
+//    private static ObjectMapper objectMapper = new ObjectMapper();
 //
 //
-//interface TrueOrFalseQuestionWithStudentAnswer
-//  extends TrueOrFalseQuestionSerializer {
-//  studentAnswer: boolean;
-//  pass: boolean; // 是否正确
+//    public static BaseQuestionVO parse(Map question) {
+//        String kind = (String) question.get("kind");
+//        BaseQuestionVO newQuestion = null;
+//        switch (kind) {
+//            case "CHOICE":
+//                newQuestion = (objectMapper.convertValue(question, ChoiceQuestionVO.class));
+//                return newQuestion;
+//            case "TRUE_FALSE":
+//                newQuestion = (objectMapper.convertValue(question, TrueOrFalseQuestionVO.class));
+//                return newQuestion;
+//            default:
+//        }
+//        throw HelperException.of(ExceptionType.PARAM_ERROR, "parse failed:" + question.toString());
+//    }
 //}
 //}
+////QuestionSerializer
+////问题的详细定义
+////
+////Attribute
+////type QuestionSerializer =
+////  | ChoiceQuestionSerializer
+////  | TrueOrFalseQuestionSerializer;
+////
+////type QuestionWithoutAnswerSerializer = Omit<
+////  QuestionSerializer,
+////  "answer" | "analysis"
+////>;
+////
+////type QuestionWithStudentAnswerSerializer =
+////  | ChoiceQuestionWithStudentAnswer
+////  | TrueOrFalseQuestionWithStudentAnswer;
+////
+////interface Question {
+////  id: number; // 题目id
+////  kind: "CHOICE" | "TRUE_FALSE";
+////  stem: string; // 题干
+////}
+////
+////interface ChoiceQuestionSerializer extends Question {
+////  kind: "CHOICE";
+////  options: {
+////    [key: string]: string;
+////  };
+////  answer: string; // 答案 [与 options 的 key 一致]
+////  analysis?: string; // 解析
+////}
+////
+////interface ChoiceQuestionWithStudentAnswer extends ChoiceQuestionSerializer {
+////  studentAnswer: string;
+////  pass: boolean; // 是否正确
+////}
+////
+////interface TrueOrFalseQuestionSerializer extends Question {
+////  kind: "TRUE_FALSE";
+////  answer: boolean; // 答案
+////  analysis?: string; // 解析
+////}
+////
+////interface TrueOrFalseQuestionWithStudentAnswer
+////  extends TrueOrFalseQuestionSerializer {
+////  studentAnswer: boolean;
+////  pass: boolean; // 是否正确
+////}

+ 26 - 26
src/main/java/nju/seec/helper/vo/quiz/BokQuestion.java

@@ -1,26 +1,26 @@
-package nju.seec.helper.vo.quiz;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * @author sheen
- */
-@Data
-public class BokQuestion {
-    @JsonProperty(value = "tq_id")
-    String tqId;
-    String type;
-    String stem;
-    Map<String, String> options;
-    String answer;
-    @JsonProperty(value = "key_points")
-    String keyPoints;
-    String analysis;
-    Collection<String> tags;
-    Collection<String> knowledgeId;
-    String lastModified;
-}
+//package nju.seec.helper.vo.quiz;
+//
+//import com.fasterxml.jackson.annotation.JsonProperty;
+//import lombok.Data;
+//
+//import java.util.Collection;
+//import java.util.Map;
+//
+///**
+// * @author sheen
+// */
+//@Data
+//public class BokQuestion {
+//    @JsonProperty(value = "tq_id")
+//    String tqId;
+//    String type;
+//    String stem;
+//    Map<String, String> options;
+//    String answer;
+//    @JsonProperty(value = "key_points")
+//    String keyPoints;
+//    String analysis;
+//    Collection<String> tags;
+//    Collection<String> knowledgeId;
+//    String lastModified;
+//}

+ 54 - 54
src/main/java/nju/seec/helper/vo/quiz/ChoiceQuestionVO.java

@@ -1,54 +1,54 @@
-package nju.seec.helper.vo.quiz;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.SuperBuilder;
-import nju.seec.helper.entity.QuizStudentAnswer;
-
-import java.util.Map;
-
-@Data
-@SuperBuilder
-@AllArgsConstructor
-@NoArgsConstructor
-public class ChoiceQuestionVO extends BaseQuestionVO {
-    @JsonProperty(value = "options")
-    private Map<String, String> options;
-    @JsonProperty(value = "answer")
-    private String answer;
-    @JsonProperty(value = "analysis")
-    private String analysis;
-    @JsonProperty(value = "studentAnswer")
-    private String studentAnswer;
-    @JsonProperty(value = "pass")
-    private Boolean pass;
-
-    @Override
-    public void exAddAnswer(QuizStudentAnswer answer) {
-        this.studentAnswer = answer.getStudentAnswer();
-        this.pass = answer.getPass();
-    }
-
-    @Override
-    public boolean checkAnswer(Object answer) {
-        if (answer == null) {
-            return false;
-        }
-        return this.answer.toLowerCase().equals(answer.toString().toLowerCase());
-    }
-
-    @Override
-    public void excludeCorrectAnswer() {
-        this.answer = null;
-        this.pass = null;
-        this.analysis = null;
-    }
-}
-//kind: "CHOICE";
-//  options: {
-//    [key: string]: string;
-//  };
-//  answer: string; // 答案 [与 options 的 key 一致]
-//  analysis?: string; // 解析
+//package nju.seec.helper.vo.quiz;
+//
+//import com.fasterxml.jackson.annotation.JsonProperty;
+//import lombok.AllArgsConstructor;
+//import lombok.Data;
+//import lombok.NoArgsConstructor;
+//import lombok.experimental.SuperBuilder;
+//import nju.seec.helper.entity.QuizStudentAnswer;
+//
+//import java.util.Map;
+//
+//@Data
+//@SuperBuilder
+//@AllArgsConstructor
+//@NoArgsConstructor
+//public class ChoiceQuestionVO extends BaseQuestionVO {
+//    @JsonProperty(value = "options")
+//    private Map<String, String> options;
+//    @JsonProperty(value = "answer")
+//    private String answer;
+//    @JsonProperty(value = "analysis")
+//    private String analysis;
+//    @JsonProperty(value = "studentAnswer")
+//    private String studentAnswer;
+//    @JsonProperty(value = "pass")
+//    private Boolean pass;
+//
+//    @Override
+//    public void exAddAnswer(QuizStudentAnswer answer) {
+//        this.studentAnswer = answer.getStudentAnswer();
+//        this.pass = answer.getPass();
+//    }
+//
+//    @Override
+//    public boolean checkAnswer(Object answer) {
+//        if (answer == null) {
+//            return false;
+//        }
+//        return this.answer.toLowerCase().equals(answer.toString().toLowerCase());
+//    }
+//
+//    @Override
+//    public void excludeCorrectAnswer() {
+//        this.answer = null;
+//        this.pass = null;
+//        this.analysis = null;
+//    }
+//}
+////kind: "CHOICE";
+////  options: {
+////    [key: string]: string;
+////  };
+////  answer: string; // 答案 [与 options 的 key 一致]
+////  analysis?: string; // 解析

+ 27 - 27
src/main/java/nju/seec/helper/vo/quiz/QuizResultVO.java

@@ -1,27 +1,27 @@
-package nju.seec.helper.vo.quiz;
-
-import com.fasterxml.jackson.annotation.JsonUnwrapped;
-import lombok.Data;
-import nju.seec.helper.entity.QuizStudentAnswer;
-import nju.seec.helper.entity.StudentScore;
-import nju.seec.helper.entity.User;
-import nju.seec.helper.vo.UserVO;
-
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-@Data
-public class QuizResultVO {
-    @JsonUnwrapped
-    UserVO student;
-    Integer score;
-    Map<String, Boolean> detail;
-
-    public QuizResultVO(StudentScore studentScore, User student, List<QuizStudentAnswer> list) {
-        this.student = new UserVO(student);
-        this.score = studentScore.getScore();
-        this.detail = list.stream().collect(
-                Collectors.toMap(QuizStudentAnswer::getQuestionId, QuizStudentAnswer::getPass));
-    }
-}
+//package nju.seec.helper.vo.quiz;
+//
+//import com.fasterxml.jackson.annotation.JsonUnwrapped;
+//import lombok.Data;
+//import nju.seec.helper.entity.QuizStudentAnswer;
+//import nju.seec.helper.entity.StudentScore;
+//import nju.seec.helper.entity.User;
+//import nju.seec.helper.vo.UserVO;
+//
+//import java.util.List;
+//import java.util.Map;
+//import java.util.stream.Collectors;
+//
+//@Data
+//public class QuizResultVO {
+//    @JsonUnwrapped
+//    UserVO student;
+//    Integer score;
+//    Map<String, Boolean> detail;
+//
+//    public QuizResultVO(StudentScore studentScore, User student, List<QuizStudentAnswer> list) {
+//        this.student = new UserVO(student);
+//        this.score = studentScore.getScore();
+//        this.detail = list.stream().collect(
+//                Collectors.toMap(QuizStudentAnswer::getQuestionId, QuizStudentAnswer::getPass));
+//    }
+//}

+ 84 - 93
src/main/java/nju/seec/helper/vo/quiz/QuizVO.java

@@ -1,96 +1,87 @@
-package nju.seec.helper.vo.quiz;
-
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import nju.seec.helper.entity.Quiz;
-import nju.seec.helper.util.enums.QuizState;
-import nju.seec.helper.util.enums.SlideState;
-import nju.seec.helper.vo.CourseVO;
-import nju.seec.helper.vo.SlideVO;
-
-import java.util.List;
-
-@Data
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class QuizVO {
-    @JsonProperty(value = "id")
-    private String quizId;
-    @JsonProperty(value = "name")
-    private String name;
-    @JsonProperty(value = "state")
-    private QuizState state;
-    @JsonProperty(value = "course")
-    private CourseVO courseVO;
-    @JsonProperty(value = "quizTime")
-    private SlideState quizTime;
-    @JsonProperty(value = "slide")
-    private SlideVO slide;
-    @JsonProperty(value = "questionNumber")
-    private Integer questionNumber;
-    @JsonProperty(value = "questions")
-    @JsonInclude(JsonInclude.Include.NON_NULL)
-    private List<BaseQuestionVO> questions;
-
-    public QuizVO(Quiz quiz, List<BaseQuestionVO> questions) {
-        this.quizId = quiz.getId().toString();
-        this.name = quiz.getName();
-        this.state = quiz.getState();
-        this.courseVO = new CourseVO(quiz.getCourse());
-        this.quizTime = quiz.getQuizTime();
-        this.slide = new SlideVO(quiz.getSlide());
-        this.questionNumber = questions.size();
-        this.questions = questions;
-    }
-
-    public QuizVO(Quiz quiz) {
-        this.quizId = quiz.getId().toString();
-        this.name = quiz.getName();
-        this.state = quiz.getState();
-        this.courseVO = new CourseVO(quiz.getCourse());
-        this.quizTime = quiz.getQuizTime();
-        this.slide = new SlideVO(quiz.getSlide());
-        this.questionNumber = quiz.getQuestions().size();
-    }
-
-    public void excludeCorrectAnswer() {
-        questions.forEach(BaseQuestionVO::excludeCorrectAnswer);
-    }
-}
-// http://47.100.18.120:3000/SEEC-BOK/API-DOC/src/master/helper/serializer/QuizSerializer.md
-// /** 已实现的枚举类 */
-//    type SlideState =
-//  | "DRAFT"
-//          | "BEFORE_CLASS" // 课前
-//          | "IN_CLASS" // 课中
-//          | "AFTER_CLASS" // 课后
-//          | "FINISH"; // 最终截止
+//package nju.seec.helper.vo.quiz;
 //
 //
-//          type QuizState =
-//          | "NOT_STARTED" // 未开始
-//          | "ONGOING" // 正在进行
-//          | "CLOSED"; // 已结束
 //
 //
-//interface QuizSerializer<T extends QuizState> {
-//    id: number;
-//    name: string; // 测试名
-//    state: T; // 考试状态
-//    course: CourseSerializer; // 课程详情
-//    quizTime: SlideState;
-//    slide: SlideSerializer;
-//    questions: Array<
-//            T extends "CLOSED"
-//            ? QuestionWithStudentAnswerSerializer
-//      : QuestionWithoutAnswerSerializer
-//  >;
-//}
+//import lombok.*;
+//import nju.seec.helper.entity.Quiz;
+//import nju.seec.helper.util.enums.QuizType;
+//
+//import java.time.LocalDateTime;
+//
+///**
+// * @author xst
+// * <p>
+// * updated by cst
+// */
+//@Data
+//@Builder
+//@NoArgsConstructor
+//@AllArgsConstructor
+//public class QuizVO {
+//    private Long id;
+//    private String name;
+//    private QuizType type;
+//    private Long slideId;
+//    private String slideName;
+//    private Long teacherId;
+//    private String teacherName;
+//    private LocalDateTime createAt;
+//    private LocalDateTime updateAt;
 //
 //
-//interface QuizBasicSerialzer extends Omit<QuizSerialzier, "questions"> {
-//        questionNumber: number; // 题目数量
-//        }
+////    public QuizVO(Quiz quiz, List<BaseQuestionVO> questions) {
+////        this.quizId = quiz.getId().toString();
+////        this.name = quiz.getName();
+////        this.state = quiz.getState();
+////        this.courseVO = new CourseVO(quiz.getCourse());
+////        this.quizTime = quiz.getQuizTime();
+////        this.slide = new SlideVO(quiz.getSlide());
+////        this.questionNumber = questions.size();
+////        this.questions = questions;
+////    }
+//
+//    public QuizVO(@NonNull Quiz quiz) {
+//        this.id = quiz.getId();
+//        this.name = quiz.getName();
+//        this.type = quiz.getType();
+//        this.slideId = quiz.getSlide().getId();
+//        this.slideName = quiz.getSlide().getName();
+//        this.teacherId = quiz.getTeacher().getId();
+//        this.teacherName = quiz.getTeacher().getName();
+//        this.createAt = quiz.getCreateAt();
+//        this.updateAt = quiz.getUpdateAt();
+//    }
+//
+////    public void excludeCorrectAnswer() {
+////        questions.forEach(BaseQuestionVO::excludeCorrectAnswer);
+////    }
+//}
+//// http://47.100.18.120:3000/SEEC-BOK/API-DOC/src/master/helper/serializer/QuizSerializer.md
+//// /** 已实现的枚举类 */
+////    type SlideState =
+////  | "DRAFT"
+////          | "BEFORE_CLASS" // 课前
+////          | "IN_CLASS" // 课中
+////          | "AFTER_CLASS" // 课后
+////          | "FINISH"; // 最终截止
+////
+////          type QuizState =
+////          | "NOT_STARTED" // 未开始
+////          | "ONGOING" // 正在进行
+////          | "CLOSED"; // 已结束
+////
+////interface QuizSerializer<T extends QuizState> {
+////    id: number;
+////    name: string; // 测试名
+////    state: T; // 考试状态
+////    course: CourseSerializer; // 课程详情
+////    quizTime: SlideState;
+////    slide: SlideSerializer;
+////    questions: Array<
+////            T extends "CLOSED"
+////            ? QuestionWithStudentAnswerSerializer
+////      : QuestionWithoutAnswerSerializer
+////  >;
+////}
+////
+////interface QuizBasicSerialzer extends Omit<QuizSerialzier, "questions"> {
+////        questionNumber: number; // 题目数量
+////        }

+ 44 - 44
src/main/java/nju/seec/helper/vo/quiz/TrueOrFalseQuestionVO.java

@@ -1,44 +1,44 @@
-package nju.seec.helper.vo.quiz;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.SuperBuilder;
-import nju.seec.helper.entity.QuizStudentAnswer;
-
-@Data
-@SuperBuilder
-@AllArgsConstructor
-@NoArgsConstructor
-public class TrueOrFalseQuestionVO extends BaseQuestionVO {
-    @JsonProperty(value = "answer")
-    private Boolean answer;
-    @JsonProperty(value = "analysis")
-    private String analysis;
-    @JsonProperty(value = "studentAnswer")
-    private Boolean studentAnswer;
-    @JsonProperty(value = "pass")
-    private Boolean pass;
-
-    @Override
-    public void exAddAnswer(QuizStudentAnswer answer) {
-        this.pass = answer.getPass();
-        this.studentAnswer = Boolean.valueOf(answer.getStudentAnswer());
-    }
-
-    @Override
-    public boolean checkAnswer(Object answer) {
-        if (answer == null) {
-            return false;
-        }
-        return this.answer.toString().toLowerCase().equals(answer.toString().toLowerCase());
-    }
-
-    @Override
-    public void excludeCorrectAnswer() {
-        this.answer = null;
-        this.pass = null;
-        this.analysis = null;
-    }
-}
+//package nju.seec.helper.vo.quiz;
+//
+//import com.fasterxml.jackson.annotation.JsonProperty;
+//import lombok.AllArgsConstructor;
+//import lombok.Data;
+//import lombok.NoArgsConstructor;
+//import lombok.experimental.SuperBuilder;
+//import nju.seec.helper.entity.QuizStudentAnswer;
+//
+//@Data
+//@SuperBuilder
+//@AllArgsConstructor
+//@NoArgsConstructor
+//public class TrueOrFalseQuestionVO extends BaseQuestionVO {
+//    @JsonProperty(value = "answer")
+//    private Boolean answer;
+//    @JsonProperty(value = "analysis")
+//    private String analysis;
+//    @JsonProperty(value = "studentAnswer")
+//    private Boolean studentAnswer;
+//    @JsonProperty(value = "pass")
+//    private Boolean pass;
+//
+//    @Override
+//    public void exAddAnswer(QuizStudentAnswer answer) {
+//        this.pass = answer.getPass();
+//        this.studentAnswer = Boolean.valueOf(answer.getStudentAnswer());
+//    }
+//
+//    @Override
+//    public boolean checkAnswer(Object answer) {
+//        if (answer == null) {
+//            return false;
+//        }
+//        return this.answer.toString().toLowerCase().equals(answer.toString().toLowerCase());
+//    }
+//
+//    @Override
+//    public void excludeCorrectAnswer() {
+//        this.answer = null;
+//        this.pass = null;
+//        this.analysis = null;
+//    }
+//}