Jelajahi Sumber

fix : Reformat code

XuShengTao 6 tahun lalu
induk
melakukan
206acf36ab
25 mengubah file dengan 369 tambahan dan 282 penghapusan
  1. 15 9
      src/main/java/nju/seec/helper/controller/QuestionController.java
  2. 27 26
      src/main/java/nju/seec/helper/controller/QuizController.java
  3. 9 2
      src/main/java/nju/seec/helper/dao/QuizDAO.java
  4. 4 1
      src/main/java/nju/seec/helper/dao/QuizStudentAnswerDAO.java
  5. 1 1
      src/main/java/nju/seec/helper/dao/StudentScoreDAO.java
  6. 0 1
      src/main/java/nju/seec/helper/dto/QuizDTO.java
  7. 8 8
      src/main/java/nju/seec/helper/entity/Quiz.java
  8. 7 7
      src/main/java/nju/seec/helper/entity/QuizStudentAnswer.java
  9. 1 1
      src/main/java/nju/seec/helper/entity/StudentScore.java
  10. 4 4
      src/main/java/nju/seec/helper/service/impl/QuestionServiceImpl.java
  11. 140 108
      src/main/java/nju/seec/helper/service/impl/QuizServiceImpl.java
  12. 83 69
      src/main/java/nju/seec/helper/util/BokUtil.java
  13. 12 10
      src/main/java/nju/seec/helper/util/GuavaCacheUtil.java
  14. 3 1
      src/main/java/nju/seec/helper/util/RedisCacheUtils.java
  15. 5 1
      src/main/java/nju/seec/helper/util/RestRequestUtil.java
  16. 4 3
      src/main/java/nju/seec/helper/util/enums/ExceptionType.java
  17. 3 2
      src/main/java/nju/seec/helper/util/enums/QuestionKindState.java
  18. 3 2
      src/main/java/nju/seec/helper/util/enums/QuizState.java
  19. 3 2
      src/main/java/nju/seec/helper/util/enums/SlideState.java
  20. 11 6
      src/main/java/nju/seec/helper/vo/quiz/BaseQuestionVO.java
  21. 1 1
      src/main/java/nju/seec/helper/vo/quiz/BokQuestion.java
  22. 8 6
      src/main/java/nju/seec/helper/vo/quiz/ChoiceQuestionVO.java
  23. 5 5
      src/main/java/nju/seec/helper/vo/quiz/QuizResultVO.java
  24. 4 2
      src/main/java/nju/seec/helper/vo/quiz/QuizVO.java
  25. 8 4
      src/main/java/nju/seec/helper/vo/quiz/TrueOrFalseQuestionVO.java

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

@@ -18,6 +18,7 @@ import org.springframework.data.web.PageableDefault;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.*;
+
 /**
  * 题库
  *
@@ -32,17 +33,18 @@ public class QuestionController {
     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 {
+    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()));
+        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;
     }
 
@@ -51,7 +53,7 @@ public class QuestionController {
      */
     @Auth(roles = {UserType.TEACHER}, message = "获得题目详情")
     @GetMapping("/{questionId}")
-        public BaseQuestionVO getQuestion(LoginUser user, @PathVariable("questionId") String questionId) throws JsonProcessingException {
+    public BaseQuestionVO getQuestion(LoginUser user, @PathVariable("questionId") String questionId) throws JsonProcessingException {
         return questionService.getQuestion(questionId);
     }
 
@@ -62,7 +64,9 @@ public class QuestionController {
     @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,"无类型");}
+        if (question.get("kind") == null) {
+            throw HelperException.of(ExceptionType.PARAM_ERROR, "无类型");
+        }
 
         return questionService.newQuestion(BaseQuestionVO.parse(question));
     }
@@ -73,7 +77,9 @@ public class QuestionController {
     @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,"无类型");}
+        if (question.get("kind") == null) {
+            throw HelperException.of(ExceptionType.PARAM_ERROR, "无类型");
+        }
 
         return questionService.updateQuestion(BaseQuestionVO.parse(question));
     }
@@ -87,8 +93,8 @@ public class QuestionController {
     public Map deleteQuestion(LoginUser user, @PathVariable("questionId") String questionId) {
 
         questionService.deleteQuestion(questionId);
-        Map map=new HashMap();
-        map.put("message","success");
+        Map map = new HashMap();
+        map.put("message", "success");
         return map;
     }
 }

+ 27 - 26
src/main/java/nju/seec/helper/controller/QuizController.java

@@ -44,33 +44,33 @@ public class QuizController {
     /**
      * 获得测试列表
      */
-    @Auth(roles = {UserType.STUDENT,UserType.TEACHER}, message = "获得测试列表")
+    @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);
+                                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){
+        if (slideId != null) {
             page = quizService.getAllBasicQuizBySlide(Long.valueOf(slideId), pageable, state, user.getId());
-           }else{
-            page = quizService.getAllBasicQuizByUser( 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);
+        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 = "获得某一测试的详细内容")
+    @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)){
+        if (user.getType().equals(UserType.STUDENT) && !quizVO.getState().equals(QuizState.CLOSED)) {
             quizVO.excludeCorrectAnswer();
         }
         return quizVO;
@@ -95,8 +95,8 @@ public class QuizController {
     @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());
+        Quiz ret = quizService.modifyQuiz(Long.valueOf(quizId), newQuiz.getName(),
+                newQuiz.getQuestions(), newQuiz.getQuizTime(), newQuiz.getSlideId());
         return quizService.combineQuiz(ret.getId());
     }
 
@@ -106,9 +106,9 @@ public class QuizController {
     @Auth(roles = {UserType.TEACHER}, message = "删除测试")
     @DeleteMapping("/{quizId}")
     public Map deleteQuiz(LoginUser user, @PathVariable("quizId") String quizId) {
-        Map map=new HashMap();
+        Map map = new HashMap();
         String message = quizService.deleteQuiz(Long.valueOf(quizId));
-        map.put("message",message);
+        map.put("message", message);
         return map;
     }
 
@@ -118,17 +118,18 @@ public class QuizController {
     @Auth(roles = {UserType.TEACHER}, message = "获得测试结果统计")
     @GetMapping("/{quizId}/result")
     public Map getQuizResult(LoginUser user, @PathVariable("quizId") String quizId) {
-        if(quizId==null){
+        if (quizId == null) {
             throw new EntityNotFoundException("quiz can't be null");
         }
-        Map map=new HashMap();
+        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);
+        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;
     }
+
     /**
      * 提交答案
      */
@@ -137,13 +138,13 @@ public class QuizController {
     @PutMapping("/{quizId}/student-answer")
     public Map putStudentAnswer(LoginUser user, @PathVariable("quizId") String quizId, @RequestBody QuizAnswerDTO quizAnswerDTO) {
 
-        if(quizId==null){
+        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);
+        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;
     }
 }

+ 9 - 2
src/main/java/nju/seec/helper/dao/QuizDAO.java

@@ -16,16 +16,23 @@ import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 
-public interface QuizDAO extends JpaRepository<Quiz,Long> {
+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> findAllByCourseInAndState(Collection<Course> course, QuizState state, Pageable pageable);
+
     Page<Quiz> findByTeacher(User teacher, Pageable pageable);
+
     Page<Quiz> findByTeacherAndState(User teacher, QuizState state, Pageable pageable);
 }

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

@@ -8,9 +8,12 @@ import org.springframework.data.jpa.repository.JpaRepository;
 import java.util.Optional;
 import java.util.Set;
 
-public interface QuizStudentAnswerDAO extends JpaRepository<QuizStudentAnswer,Long> {
+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);
 }

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

@@ -3,5 +3,5 @@ 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> {
+public interface StudentScoreDAO extends JpaRepository<StudentScore, Long> {
 }

+ 0 - 1
src/main/java/nju/seec/helper/dto/QuizDTO.java

@@ -8,7 +8,6 @@ import javax.validation.constraints.NotNull;
 import java.util.List;
 
 /**
- *
  * @author sheen
  */
 @Data

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

@@ -15,7 +15,7 @@ import java.util.Set;
 
 @Data
 @Entity
-@Table(name = "quiz",indexes = {@Index(columnList = "course"),@Index(columnList = "slide")}
+@Table(name = "quiz", indexes = {@Index(columnList = "course"), @Index(columnList = "slide")}
         , uniqueConstraints = @UniqueConstraint(name = "测试名约束", columnNames = {"teacher", "name"}))
 @EntityListeners(AuditingEntityListener.class)
 public class Quiz {
@@ -29,38 +29,38 @@ public class Quiz {
     private String name;
 
     @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
-    @JoinColumn(name="slide",referencedColumnName="id")
+    @JoinColumn(name = "slide", referencedColumnName = "id")
     private Slide slide;
 
     @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
-    @JoinColumn(name="course",referencedColumnName="id")
+    @JoinColumn(name = "course", referencedColumnName = "id")
     private Course course;
 
     @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
-    @JoinColumn(name="teacher",referencedColumnName="id")
+    @JoinColumn(name = "teacher", referencedColumnName = "id")
     private User teacher;
 
     @ElementCollection
     private List<String> questions;
 
     @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
-    @JoinColumn(name="studentScore")
+    @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)
+    @Column(name = "state", nullable = false)
     private QuizState state;
 
     @Basic
-    @Column(name = "create_at",nullable = false)
+    @Column(name = "create_at", nullable = false)
     @CreatedDate
     private LocalDateTime createAt;
 
     @Basic
-    @Column(name = "modified_at",nullable = false)
+    @Column(name = "modified_at", nullable = false)
     @CreatedDate
     private LocalDateTime modifiedAt;
 }

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

@@ -16,7 +16,7 @@ import java.time.LocalDateTime;
 @Builder
 @Table(name = "quiz_student_answer",
         indexes = {@Index(columnList = "quiz"),
-                    @Index(columnList = "student ,quiz")})
+                @Index(columnList = "student ,quiz")})
 @EntityListeners(AuditingEntityListener.class)
 @AllArgsConstructor
 @NoArgsConstructor
@@ -27,29 +27,29 @@ public class QuizStudentAnswer {
     private Long id;
 
     @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
-    @JoinColumn(name="quiz",referencedColumnName="id")
+    @JoinColumn(name = "quiz", referencedColumnName = "id")
     private Quiz quiz;
 
     @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
-    @JoinColumn(name="student",referencedColumnName="id")
+    @JoinColumn(name = "student", referencedColumnName = "id")
     private User student;
 
     @Basic
-    @Column(name = "questionId",nullable = false)
+    @Column(name = "questionId", nullable = false)
     private String questionId;
 
     @Basic
-    @Column(name = "create_at",nullable = false)
+    @Column(name = "create_at", nullable = false)
     @CreatedDate
     private LocalDateTime createAt;
 
     @Basic
-    @Column(name = "modified_at",nullable = false)
+    @Column(name = "modified_at", nullable = false)
     @CreatedDate
     private LocalDateTime modifiedAt;
 
     @Basic
-    @Column(name = "student_answer",nullable = true)
+    @Column(name = "student_answer", nullable = true)
     private String studentAnswer;
 
     @Basic

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

@@ -16,7 +16,7 @@ public class StudentScore implements Serializable {
     private Long id;
 
     @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
-    @JoinColumn(name="student",referencedColumnName="id")
+    @JoinColumn(name = "student", referencedColumnName = "id")
     private User student;
 
     @Column(name = "quiz_id")

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

@@ -33,8 +33,8 @@ public class QuestionServiceImpl implements QuestionService {
         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")));
+        bokUtil.bokFindByStemLike(stem, questions, page, pageable);
+        return new PageImpl<>(questions, pageable, Long.valueOf((Integer) page.get("totalElements")));
     }
 
     @Override
@@ -47,7 +47,7 @@ public class QuestionServiceImpl implements QuestionService {
         try {
             return bokUtil.postNewQuestion(newQuestion);
         } catch (JsonProcessingException e) {
-            throw HelperException.of(ExceptionType.ERROR,"请求BOK题库数据错误:"+e.getMessage());
+            throw HelperException.of(ExceptionType.ERROR, "请求BOK题库数据错误:" + e.getMessage());
         }
     }
 
@@ -56,7 +56,7 @@ public class QuestionServiceImpl implements QuestionService {
         try {
             return bokUtil.putQuestion(newQuestion);
         } catch (JsonProcessingException e) {
-            throw HelperException.of(ExceptionType.ERROR,"请求BOK题库数据错误:"+e.getMessage());
+            throw HelperException.of(ExceptionType.ERROR, "请求BOK题库数据错误:" + e.getMessage());
         }
     }
 

+ 140 - 108
src/main/java/nju/seec/helper/service/impl/QuizServiceImpl.java

@@ -47,8 +47,8 @@ public class QuizServiceImpl implements QuizService {
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Quiz createQuiz(String name, Long uid, SlideState quizTime,
-                           Long slideId, List<String> questions){
-        User teacher =new User();
+                           Long slideId, List<String> questions) {
+        User teacher = new User();
         teacher.setId(uid);
         Slide slide = slideDAO.findSlideById(slideId);
         Course course = new Course();
@@ -62,15 +62,18 @@ public class QuizServiceImpl implements QuizService {
         quiz.setSlide(slide);
         quiz.setTeacher(teacher);
 
-        checkQuizState(quiz,slide);
+        checkQuizState(quiz, slide);
 
-        quiz=quizDAO.saveAndFlush(quiz);
+        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,"不能删除已经开始的测试!");}
+        Quiz quiz = quizDAO.findQuizById(quizId);
+        if (quiz.getState() != QuizState.NOT_STARTED) {
+            throw HelperException.of(ExceptionType.FORBIDDEN, "不能删除已经开始的测试!");
+        }
         quizDAO.delete(quiz);
         return "delete success";
     }
@@ -79,17 +82,19 @@ public class QuizServiceImpl implements QuizService {
     @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 quiz = quizDAO.findQuizById(quizId);
+        if (quiz.getState() != QuizState.NOT_STARTED) {
+            throw HelperException.of(ExceptionType.FORBIDDEN, "不能修改已经开始的测试!");
+        }
+        if (name != null) {
             quiz.setName(name);
         }
-        if(questions!=null) {
+        if (questions != null) {
             quiz.setQuestions(questions);
         }
-        if(quizTime!=null) {
+        if (quizTime != null) {
             quiz.setQuizTime(quizTime);
-            checkQuizState(quiz,quiz.getSlide());
+            checkQuizState(quiz, quiz.getSlide());
         }
         return quizDAO.saveAndFlush(quiz);
 
@@ -97,25 +102,25 @@ public class QuizServiceImpl implements QuizService {
 
     @Override
     public Page<Quiz> getAllBasicQuizByUser(Pageable pageable, QuizState state, Long uid) {
-        User user=userDAO.findUserById(uid);
+        User user = userDAO.findUserById(uid);
         //todo: 这里写的太狗屎了,可以用重写sql或者用实例查询
-        if(user.getType().equals(UserType.STUDENT)){
+        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);
+            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);
+        } else {
+            if (state != null) {
+                return quizDAO.findByTeacherAndState(user, state, pageable);
+            } else {
+                return quizDAO.findByTeacher(user, pageable);
             }
 
         }
@@ -124,20 +129,22 @@ public class QuizServiceImpl implements QuizService {
 
     @Override
     public List<QuizResultVO> getQuizResult(Long quizId) {
-        Assert.notNull(quizId,"错误的测试!");
+        Assert.notNull(quizId, "错误的测试!");
         final Quiz quiz = quizDAO.findQuizById(quizId);
-        if(quiz.getState()!=QuizState.CLOSED){throw new RuntimeException("测试未关闭,无法得到测试结果");}
-        List<QuizResultVO> retList=new ArrayList<>();
+        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)){
+        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){
+        for (StudentScore studentScore : studentScoreList) {
             final User student = studentScore.getStudent();
             final List<QuizStudentAnswer> list = idQuizStudentAnswerMap.get(student.getId());
-            retList.add(new QuizResultVO(studentScore,student,list));
+            retList.add(new QuizResultVO(studentScore, student, list));
         }
         return retList;
     }
@@ -145,80 +152,90 @@ public class QuizServiceImpl implements QuizService {
     @Override
     public void modifySlideState(Slide slide) {
         final List<Quiz> quizzes = quizDAO.findAllBySlide(slide);
-        quizzes.forEach(quiz->checkQuizState(quiz,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,"错误的测试!");
+        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);
+        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);
+        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){
+        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)){
+            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()
+            } else {
+                QuizStudentAnswer qsa = QuizStudentAnswer.builder()
                         .questionId(id).quiz(quiz).student(student).studentAnswer(answer)
                         .build();
                 quizStudentAnswers.add(qsa);
             }
 
         }
-        Integer savedNum=quizStudentAnswers.size();
+        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();
+        Assert.notNull(slideId, "错误的幻灯片!");
+        Slide slide = new Slide();
         slide.setId(slideId);
-        if(state!=null) {
+        if (state != null) {
             return quizDAO.findAllBySlideAndState(slide, state, pageable);
-        }
-        else {
+        } 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){
+        if (quiz.getId() == null) {
             //未持久化的quiz
             quiz.setState(slideTime < quizTime ? QuizState.NOT_STARTED : QuizState.ONGOING);
-        }
-        else {
+        } else {
             //持久化后,不仅仅需要推进状态,还需要判分,保存等步骤
             if (slideTime < quizTime) {
-                if(quiz.getState().equals(QuizState.NOT_STARTED)){return QuizState.NOT_STARTED;}
+                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;}
+                if (quiz.getState().equals(QuizState.ONGOING)) {
+                    return QuizState.ONGOING;
+                }
                 quiz.setState(QuizState.ONGOING);
             } else {
-                if(quiz.getState().equals(QuizState.CLOSED)){return QuizState.CLOSED;}
+                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.getCourseId());
@@ -239,108 +256,123 @@ public class QuizServiceImpl implements QuizService {
         }
         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);
+    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;
+        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);
+            student2QuestionId2Answer = new LinkedHashMap<>(studentIds.size());
+            for (Long studentId : studentIds) {
+                Map<String, QuizStudentAnswer> questionId2Answer = new LinkedHashMap<>(quizQuestionSize);
+                student2QuestionId2Answer.put(studentId, questionId2Answer);
             }
         }
-        void addAnswer(QuizStudentAnswer answers){
+
+        void addAnswer(QuizStudentAnswer answers) {
             Map<String, QuizStudentAnswer> stringQuizStudentAnswerMap = student2QuestionId2Answer.get(answers.getStudent().getId());
-            if(stringQuizStudentAnswerMap==null){
-                return ;
+            if (stringQuizStudentAnswerMap == null) {
+                return;
             }
-            stringQuizStudentAnswerMap.put(answers.getQuestionId(),answers);
+            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()
+
+        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);
+                            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){
+
+        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++;}
+                    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();
+                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<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,"错误的测试!");
+    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);
+        return new QuizVO(quizById, questionVoS);
     }
+
     @Override
-    public QuizVO combineQuizWithAnswer(Long quizId, Long uid,UserType userType){
-        Assert.notNull(quizId,"错误的测试!");
+    public QuizVO combineQuizWithAnswer(Long quizId, Long uid, UserType userType) {
+        Assert.notNull(quizId, "错误的测试!");
         final Quiz quizById = quizDAO.findQuizById(quizId);
-        User student =new User();
+        User student = new User();
         student.setId(uid);
 
-        if(userType==null||userType.equals(UserType.TEACHER)){
+        if (userType == null || userType.equals(UserType.TEACHER)) {
             //向老师展示
             List<BaseQuestionVO> questionVoS = bokUtil.bokFindByIdIn(quizById.getQuestions());
-            return new QuizVO(quizById,questionVoS);
+            return new QuizVO(quizById, questionVoS);
         }
-        if(quizById.getState().equals(QuizState.NOT_STARTED)){
+        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);
+        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){
+        for (BaseQuestionVO vo : questionVos) {
+            if (qsaMap.get(vo.getQuestionId()) != null) {
                 vo.exAddAnswer(qsaMap.get(vo.getQuestionId()));
             }
         }
 
-        return new QuizVO(quizById,questionVos);
+        return new QuizVO(quizById, questionVos);
     }
 
 

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

@@ -30,39 +30,41 @@ public class BokUtil {
     @Autowired
     private 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/";
+    private String bokUrl = "http://bok.seecoder.cn";
+    private String searchUrl = bokUrl + "/api/tq/search/";
+    private String tqUrl = bokUrl + "/api/tq/";
 
     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()));
+        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"));
+            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"));
+                page.putAll((Map) ret.get("page"));
                 questions.addAll(collect);
-            }catch (Exception e){
+            } catch (Exception e) {
                 e.printStackTrace();
             }
 
-        }catch (Exception e){
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
-    private static String CACHE_NAME="BOK";
+
+    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 );
+        final ImmutableMap<Object, Object> bok = cacheUtils.multiGet(CACHE_NAME, requestIds);
 
         Map<String, BaseQuestionVO> questionsMap = new HashMap<>(ids.size());
         bok.values().forEach(vo -> {
@@ -73,7 +75,7 @@ public class BokUtil {
             }
         });
         //未缓存的去这里拿
-        if(requestIds.size()>0){
+        if (requestIds.size() > 0) {
             Map<String, String> urlParams = new HashMap<>();
             String idsStr = requestIds.stream().reduce((a, b) -> {
                 return a + "," + b;
@@ -92,18 +94,18 @@ public class BokUtil {
             }
             List<BaseQuestionVO> collect = parseBody(tqs);
 
-            Map<String,Object> newGet=new HashMap<>(collect.size());
+            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);
+                newGet.put(vo.getQuestionId(), vo);
             }
-            cacheUtils.setAll(CACHE_NAME,newGet);
+            cacheUtils.setAll(CACHE_NAME, newGet);
         }
 
         // todo: 按照Ids重排序
-        List<BaseQuestionVO> ret=new ArrayList<>();
-        for (String id:ids){
+        List<BaseQuestionVO> ret = new ArrayList<>();
+        for (String id : ids) {
             ret.add(questionsMap.get(id));
         }
         return (ret);
@@ -114,7 +116,7 @@ public class BokUtil {
         return collect;
     }
 
-    private static BaseQuestionVO parseOneQuestion(Map q){
+    private static BaseQuestionVO parseOneQuestion(Map q) {
         switch ((String) q.get("type")) {
             case "choice":
                 return ChoiceQuestionVO.builder().stem((String) q.get("stem")).kind(QuestionKindState.CHOICE)
@@ -127,92 +129,104 @@ public class BokUtil {
                         .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"));
+        throw HelperException.of(ExceptionType.ERROR, "unknown type:" + (String) q.get("type"));
     }
-    public BaseQuestionVO bokFindById(String questionId)  {
-        Map<String,String> urlParams=new HashMap<>();
+
+    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);
+            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());
+            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)
+
+    @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
     public BaseQuestionVO postNewQuestion(BaseQuestionVO vo) throws JsonProcessingException {
-        if(vo.getQuestionId()!=null) {
+        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();
+        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){
+            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);
+            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)){
+                Map ret = (Map) restRequestUtil.sendGetRequest(tqUrl + questionId, new HashMap<>());
+            } catch (HttpClientErrorException e) {
+                if (e.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
                     break;
                 }
             }
-            questionId=null;
+            questionId = null;
+        }
+        if (questionId == null) {
+            throw HelperException.of(ExceptionType.ERROR, "暂时无法保存题目,请重试!");
         }
-        if(questionId==null){throw HelperException.of(ExceptionType.ERROR,"暂时无法保存题目,请重试!");}
 
         vo.setQuestionId(questionId);
 
-        BokTq bokTq=new BokTq(vo);
-        restRequestUtil.sendPutRequest(tqUrl+questionId, bokTq);
+        BokTq bokTq = new BokTq(vo);
+        restRequestUtil.sendPutRequest(tqUrl + questionId, bokTq);
 
         return vo;
 
     }
-    @Transactional(isolation=Isolation.SERIALIZABLE,rollbackFor = Exception.class)
+
+    @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
     public BaseQuestionVO putQuestion(BaseQuestionVO vo) throws JsonProcessingException {
-        if(vo.getQuestionId()==null ){
+        if (vo.getQuestionId() == null) {
             throw HelperException.of(ExceptionType.PARAM_ERROR, "should POST a present question");
         }
-        String questionId=vo.getQuestionId();
+        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.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));
+        restRequestUtil.sendPutRequest(tqUrl + questionId, new BokTq(vo));
 
-        cacheUtils.remove(CACHE_NAME,questionId);
+        cacheUtils.remove(CACHE_NAME, questionId);
         return vo;
     }
+
     public void deleteQuestion(String questionId) {
         try {
-            restRequestUtil.sendDeleteRequest(tqUrl+questionId);
+            restRequestUtil.sendDeleteRequest(tqUrl + questionId);
         } catch (JsonProcessingException e) {
-            throw HelperException.of(ExceptionType.ERROR,"请求BOK题库数据错误:"+e.getMessage());
+            throw HelperException.of(ExceptionType.ERROR, "请求BOK题库数据错误:" + e.getMessage());
         }
-        cacheUtils.remove(CACHE_NAME,questionId);
+        cacheUtils.remove(CACHE_NAME, questionId);
     }
 
     /**
@@ -236,21 +250,21 @@ public class BokUtil {
         private BokTq(BaseQuestionVO vo) {
             this.id = vo.getQuestionId();
             this.stem = vo.getStem();
-            switch(vo.getKind()){
+            switch (vo.getKind()) {
 
                 case CHOICE:
-                    ChoiceQuestionVO cqvo= (ChoiceQuestionVO) vo;
+                    ChoiceQuestionVO cqvo = (ChoiceQuestionVO) vo;
                     this.options = cqvo.getOptions();
                     this.type = "choice";
-                    this.analysis=cqvo.getAnalysis();
-                    this.answer=cqvo.getAnswer();
+                    this.analysis = cqvo.getAnalysis();
+                    this.answer = cqvo.getAnswer();
                     break;
                 case TRUE_FALSE:
-                    TrueOrFalseQuestionVO tfvo= (TrueOrFalseQuestionVO) vo;
+                    TrueOrFalseQuestionVO tfvo = (TrueOrFalseQuestionVO) vo;
                     this.options = null;
                     this.type = "true_false";
-                    this.analysis=tfvo.getAnalysis();
-                    this.answer=tfvo.getAnswer().toString();
+                    this.analysis = tfvo.getAnalysis();
+                    this.answer = tfvo.getAnswer().toString();
                     break;
                 default:
             }

+ 12 - 10
src/main/java/nju/seec/helper/util/GuavaCacheUtil.java

@@ -14,18 +14,19 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
+
 @Component
 public class GuavaCacheUtil {
     private Cache<Object, Object> cache;
 
     @Value("${guavaCache.maximumSize}")
-    private Long maximumSize=1000L;
+    private Long maximumSize = 1000L;
 
     @Value("${guavaCache.expireAfterAccessInSeconds}")
-    private Long expireAfterAccessInSeconds=1800L;
+    private Long expireAfterAccessInSeconds = 1800L;
 
     @Value("${guavaCache.expireAfterWriteInSeconds}")
-    private Long expireAfterWriteInSeconds=3600L;
+    private Long expireAfterWriteInSeconds = 3600L;
 
     public GuavaCacheUtil() {
         CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder();
@@ -36,29 +37,30 @@ public class GuavaCacheUtil {
     }
 
     public void set(String cacheName, String key, Object value) {
-        cache.put(combineKey(cacheName,key),value);
+        cache.put(combineKey(cacheName, key), value);
     }
 
-    public void setAll(String cacheName, Map<String,Object> putAll) {
+    public void setAll(String cacheName, Map<String, Object> putAll) {
         final Map<String, Object> all = putAll.entrySet().stream().collect(Collectors.toMap(entry -> {
-            return combineKey(cacheName , entry.getKey());
+            return combineKey(cacheName, entry.getKey());
         }, Map.Entry::getValue));
         cache.putAll(all);
     }
+
     public Object get(String cacheName, String key) {
-        return cache.getIfPresent(combineKey(cacheName,key));
+        return cache.getIfPresent(combineKey(cacheName, key));
     }
 
     public ImmutableMap<Object, Object> multiGet(String cacheName, Collection<String> keys) {
-        Collection<String> body=keys.stream().map(s->combineKey(cacheName,s)).collect(Collectors.toList());
+        Collection<String> body = keys.stream().map(s -> combineKey(cacheName, s)).collect(Collectors.toList());
         return cache.getAllPresent(body);
     }
 
     public void remove(String cacheName, String key) {
-        cache.invalidate(combineKey(cacheName,key));
+        cache.invalidate(combineKey(cacheName, key));
     }
 
-    private String combineKey(String cacheName, String key){
+    private String combineKey(String cacheName, String key) {
         return cacheName + ":" + key;
     }
 }

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

@@ -24,15 +24,17 @@ public class RedisCacheUtils {
     public void set(String cacheName, String key, String value, long expireTime, TimeUnit timeUnit) {
         redisTemplate.opsForValue().set(cacheName + ":" + key, value, expireTime, timeUnit);
     }
+
     public void setAll(String cacheName, String key, String value, long expireTime, TimeUnit timeUnit) {
         throw new NotImplementedException();
     }
+
     public String get(String cacheName, String key) {
         return redisTemplate.opsForValue().get(cacheName + ":" + key);
     }
 
     public List<String> multiGet(String cacheName, List<String> keys) {
-        List<String> body=keys.stream().map(s->cacheName + ":" + s).collect(Collectors.toList());
+        List<String> body = keys.stream().map(s -> cacheName + ":" + s).collect(Collectors.toList());
         return redisTemplate.opsForValue().multiGet(body);
     }
 

+ 5 - 1
src/main/java/nju/seec/helper/util/RestRequestUtil.java

@@ -7,6 +7,7 @@ import org.springframework.web.client.RestTemplate;
 
 import java.util.List;
 import java.util.Map;
+
 @Component
 public class RestRequestUtil {
 
@@ -19,20 +20,23 @@ public class RestRequestUtil {
         ResponseEntity ret = client.postForEntity(url, requestEntity, List.class);
         return (List) ret.getBody();
     }
+
     public void sendPutRequest(String url, Object params) throws JsonProcessingException {
         RestTemplate client = new RestTemplate();
         client.put(url, params);
     }
+
     public void sendDeleteRequest(String url) throws JsonProcessingException {
         RestTemplate client = new RestTemplate();
         client.delete(url);
     }
+
     public Object sendGetRequest(String url, Map<String, String> urlParams) throws JsonProcessingException {
         RestTemplate client = new RestTemplate();
         HttpHeaders headers = new HttpHeaders();
         HttpMethod method = HttpMethod.GET;
         headers.setContentType(MediaType.APPLICATION_JSON);
-        ResponseEntity ret = client.getForEntity(url,Object.class,urlParams);
+        ResponseEntity ret = client.getForEntity(url, Object.class, urlParams);
         return ret.getBody();
     }
 }

+ 4 - 3
src/main/java/nju/seec/helper/util/enums/ExceptionType.java

@@ -18,9 +18,10 @@ public enum ExceptionType {
     ExceptionType(HttpStatus status) {
         this.status = status;
     }
-    public static ExceptionType valueOf(HttpStatus status){
-        for(ExceptionType exceptionType:ExceptionType.values()){
-            if(exceptionType.getStatus().equals(status)){
+
+    public static ExceptionType valueOf(HttpStatus status) {
+        for (ExceptionType exceptionType : ExceptionType.values()) {
+            if (exceptionType.getStatus().equals(status)) {
                 return exceptionType;
             }
         }

+ 3 - 2
src/main/java/nju/seec/helper/util/enums/QuestionKindState.java

@@ -6,8 +6,9 @@ package nju.seec.helper.util.enums;
 public enum QuestionKindState {
     CHOICE("选择题"), TRUE_FALSE("判断题");
     private String name;
-    QuestionKindState(String name){
-        this.name=name;
+
+    QuestionKindState(String name) {
+        this.name = name;
     }
 
     public String getName() {

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

@@ -6,8 +6,9 @@ package nju.seec.helper.util.enums;
 public enum QuizState {
     NOT_STARTED("未开始"), ONGOING("正在进行"), CLOSED("已结束");
     private String name;
-    QuizState(String name){
-        this.name=name;
+
+    QuizState(String name) {
+        this.name = name;
     }
 
     public String getName() {

+ 3 - 2
src/main/java/nju/seec/helper/util/enums/SlideState.java

@@ -6,8 +6,9 @@ package nju.seec.helper.util.enums;
 public enum SlideState {
     DRAFT(1), BEFORE_CLASS(2), IN_CLASS(3), AFTER_CLASS(4), FINISH(5);
     private Integer num;
-    SlideState(Integer num){
-        this.num=num;
+
+    SlideState(Integer num) {
+        this.num = num;
     }
 
     public Integer getNum() {

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

@@ -30,23 +30,28 @@ public abstract class BaseQuestionVO {
     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){
+
+    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));
+                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());
+        throw HelperException.of(ExceptionType.PARAM_ERROR, "parse failed:" + question.toString());
     }
 }
 //QuestionSerializer

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

@@ -15,7 +15,7 @@ public class BokQuestion {
     String tqId;
     String type;
     String stem;
-    Map<String,String> options;
+    Map<String, String> options;
     String answer;
     @JsonProperty(value = "key_points")
     String keyPoints;

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

@@ -15,7 +15,7 @@ import java.util.Map;
 @NoArgsConstructor
 public class ChoiceQuestionVO extends BaseQuestionVO {
     @JsonProperty(value = "options")
-    private Map<String,String> options;
+    private Map<String, String> options;
     @JsonProperty(value = "answer")
     private String answer;
     @JsonProperty(value = "analysis")
@@ -27,21 +27,23 @@ public class ChoiceQuestionVO extends BaseQuestionVO {
 
     @Override
     public void exAddAnswer(QuizStudentAnswer answer) {
-        this.studentAnswer=answer.getStudentAnswer();
+        this.studentAnswer = answer.getStudentAnswer();
         this.pass = answer.getPass();
     }
 
     @Override
     public boolean checkAnswer(Object answer) {
-        if(answer==null){return false;}
+        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;
+        this.answer = null;
+        this.pass = null;
+        this.analysis = null;
     }
 }
 //kind: "CHOICE";

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

@@ -18,12 +18,12 @@ public class QuizResultVO {
     @JsonUnwrapped
     UserVO student;
     Integer score;
-    Map<String,Boolean> detail;
+    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));
+        this.student = new UserVO(student);
+        this.score = studentScore.getScore();
+        this.detail = list.stream().collect(
+                Collectors.toMap(QuizStudentAnswer::getQuestionId, QuizStudentAnswer::getPass));
     }
 }

+ 4 - 2
src/main/java/nju/seec/helper/vo/quiz/QuizVO.java

@@ -38,7 +38,7 @@ public class QuizVO {
     @JsonInclude(JsonInclude.Include.NON_NULL)
     private List<BaseQuestionVO> questions;
 
-    public QuizVO(Quiz quiz,List<BaseQuestionVO> questions) {
+    public QuizVO(Quiz quiz, List<BaseQuestionVO> questions) {
         this.quizId = quiz.getId().toString();
         this.name = quiz.getName();
         this.state = quiz.getState();
@@ -48,6 +48,7 @@ public class QuizVO {
         this.questionNumber = questions.size();
         this.questions = questions;
     }
+
     public QuizVO(Quiz quiz) {
         this.quizId = quiz.getId().toString();
         this.name = quiz.getName();
@@ -57,7 +58,8 @@ public class QuizVO {
         this.slide = new SlideVO(quiz.getSlide());
         this.questionNumber = quiz.getQuestions().size();
     }
-    public void excludeCorrectAnswer(){
+
+    public void excludeCorrectAnswer() {
         questions.forEach(BaseQuestionVO::excludeCorrectAnswer);
     }
 }

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

@@ -26,15 +26,19 @@ public class TrueOrFalseQuestionVO extends BaseQuestionVO {
         this.pass = answer.getPass();
         this.studentAnswer = Boolean.valueOf(answer.getStudentAnswer());
     }
+
     @Override
     public boolean checkAnswer(Object answer) {
-        if(answer==null){return false;}
+        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;
+        this.answer = null;
+        this.pass = null;
+        this.analysis = null;
     }
 }