فهرست منبع

fix: 修复slide部分方法Specification语句错误

ChenSiTong 6 سال پیش
والد
کامیت
b1168faa47
33فایلهای تغییر یافته به همراه398 افزوده شده و 319 حذف شده
  1. 1 1
      src/main/java/nju/seec/helper/HelperApplication.java
  2. 9 5
      src/main/java/nju/seec/helper/controller/QuestionController.java
  3. 18 22
      src/main/java/nju/seec/helper/controller/QuizController.java
  4. 9 4
      src/main/java/nju/seec/helper/dao/QuizDAO.java
  5. 4 2
      src/main/java/nju/seec/helper/dao/QuizStudentAnswerDAO.java
  6. 1 1
      src/main/java/nju/seec/helper/dao/StudentScoreDAO.java
  7. 3 2
      src/main/java/nju/seec/helper/dto/QuestionStudentAnswerDTO.java
  8. 0 1
      src/main/java/nju/seec/helper/dto/QuizDTO.java
  9. 0 2
      src/main/java/nju/seec/helper/dto/QuizUpdateDTO.java
  10. 8 11
      src/main/java/nju/seec/helper/entity/Quiz.java
  11. 7 7
      src/main/java/nju/seec/helper/entity/QuizStudentAnswer.java
  12. 1 2
      src/main/java/nju/seec/helper/entity/StudentScore.java
  13. 5 3
      src/main/java/nju/seec/helper/service/QuizService.java
  14. 1 1
      src/main/java/nju/seec/helper/service/impl/CodeServiceImpl.java
  15. 3 3
      src/main/java/nju/seec/helper/service/impl/CourseFileServiceImpl.java
  16. 4 4
      src/main/java/nju/seec/helper/service/impl/QuestionServiceImpl.java
  17. 148 110
      src/main/java/nju/seec/helper/service/impl/QuizServiceImpl.java
  18. 6 6
      src/main/java/nju/seec/helper/service/impl/SlideServiceImpl.java
  19. 1 1
      src/main/java/nju/seec/helper/service/impl/UserServiceImpl.java
  20. 96 76
      src/main/java/nju/seec/helper/util/BokUtil.java
  21. 12 14
      src/main/java/nju/seec/helper/util/GuavaCacheUtil.java
  22. 3 1
      src/main/java/nju/seec/helper/util/RedisCacheUtils.java
  23. 5 1
      src/main/java/nju/seec/helper/util/RestRequestUtil.java
  24. 4 4
      src/main/java/nju/seec/helper/util/enums/ExceptionType.java
  25. 3 2
      src/main/java/nju/seec/helper/util/enums/QuestionKindState.java
  26. 3 2
      src/main/java/nju/seec/helper/util/enums/QuizState.java
  27. 3 2
      src/main/java/nju/seec/helper/util/enums/SlideState.java
  28. 12 7
      src/main/java/nju/seec/helper/vo/quiz/BaseQuestionVO.java
  29. 1 1
      src/main/java/nju/seec/helper/vo/quiz/BokQuestion.java
  30. 9 7
      src/main/java/nju/seec/helper/vo/quiz/ChoiceQuestionVO.java
  31. 5 7
      src/main/java/nju/seec/helper/vo/quiz/QuizResultVO.java
  32. 5 3
      src/main/java/nju/seec/helper/vo/quiz/QuizVO.java
  33. 8 4
      src/main/java/nju/seec/helper/vo/quiz/TrueOrFalseQuestionVO.java

+ 1 - 1
src/main/java/nju/seec/helper/HelperApplication.java

@@ -3,8 +3,8 @@ package nju.seec.helper;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
-import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
 
 /**

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

@@ -60,9 +60,11 @@ public class QuestionController {
      * 创建题目
      */
     @Auth(roles = {UserType.TEACHER}, message = "创建题目")
-    @PostMapping("")
+    @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 +75,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 +91,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;
     }
 }

+ 18 - 22
src/main/java/nju/seec/helper/controller/QuizController.java

@@ -2,19 +2,16 @@ 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.*;
-import org.springframework.beans.factory.annotation.Autowired;
+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 org.springframework.data.web.PageableDefault;
@@ -82,7 +79,6 @@ public class QuizController {
     @Auth(roles = {UserType.TEACHER}, message = "创建测试")
     @PostMapping("")
     public QuizVO createQuiz(LoginUser user, @RequestBody QuizDTO newQuiz) {
-        System.out.println(newQuiz);
         final Quiz quiz = quizService.createQuiz(newQuiz.getName(), user.getId(), newQuiz.getQuizTime(),
                 Long.valueOf(newQuiz.getSlideId()), newQuiz.getQuestions());
         return quizService.combineQuiz(quiz.getId());
@@ -94,9 +90,8 @@ public class QuizController {
     @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());
+        Quiz ret = quizService.modifyQuiz(Long.valueOf(quizId), newQuiz.getName(),
+                newQuiz.getQuestions(), newQuiz.getQuizTime(), newQuiz.getSlideId());
         return quizService.combineQuiz(ret.getId());
     }
 
@@ -106,9 +101,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 +113,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 +133,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 - 4
src/main/java/nju/seec/helper/dao/QuizDAO.java

@@ -13,19 +13,24 @@ import org.springframework.data.jpa.repository.JpaRepository;
 
 import java.util.Collection;
 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 - 2
src/main/java/nju/seec/helper/dao/QuizStudentAnswerDAO.java

@@ -5,12 +5,14 @@ import nju.seec.helper.entity.QuizStudentAnswer;
 import nju.seec.helper.entity.User;
 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> {
 }

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

@@ -3,12 +3,13 @@ package nju.seec.helper.dto;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.Data;
-import nju.seec.helper.util.enums.QuestionKindState;
 
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
-import java.util.Map;
 
+/**
+ * @author sheen
+ */
 @Data
 public class QuestionStudentAnswerDTO {
     @JsonProperty(value = "id")

+ 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

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

@@ -3,8 +3,6 @@ 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;
 
 /**

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

@@ -1,6 +1,5 @@
 package nju.seec.helper.entity;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.Data;
 import nju.seec.helper.util.enums.QuizState;
 import nju.seec.helper.util.enums.SlideState;
@@ -10,12 +9,10 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
 import javax.persistence.*;
 import java.time.LocalDateTime;
 import java.util.List;
-import java.util.Map;
-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 +26,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 - 2
src/main/java/nju/seec/helper/entity/StudentScore.java

@@ -4,7 +4,6 @@ import lombok.Data;
 
 import javax.persistence.*;
 import java.io.Serializable;
-import java.util.Map;
 
 @Data
 @Entity
@@ -16,7 +15,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")

+ 5 - 3
src/main/java/nju/seec/helper/service/QuizService.java

@@ -10,12 +10,14 @@ 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 org.springframework.transaction.annotation.Transactional;
 
-import java.util.Collection;
 import java.util.List;
-import java.util.Map;
 
+/**
+ * @author xst
+ * <p>
+ * updated by cst
+ */
 public interface QuizService {
 
     /**

+ 1 - 1
src/main/java/nju/seec/helper/service/impl/CodeServiceImpl.java

@@ -1,9 +1,9 @@
 package nju.seec.helper.service.impl;
 
 import nju.seec.helper.service.CodeService;
-import nju.seec.helper.util.RedisCacheUtils;
 import nju.seec.helper.util.Consts;
 import nju.seec.helper.util.MailUtils;
+import nju.seec.helper.util.RedisCacheUtils;
 import nju.seec.helper.util.SmsUtils;
 import org.springframework.stereotype.Service;
 

+ 3 - 3
src/main/java/nju/seec/helper/service/impl/CourseFileServiceImpl.java

@@ -10,9 +10,9 @@ import nju.seec.helper.entity.Course;
 import nju.seec.helper.entity.CourseFile;
 import nju.seec.helper.service.CourseFileService;
 import nju.seec.helper.service.util.AuthUtils;
-import nju.seec.helper.util.CacheUtils;
 import nju.seec.helper.util.Consts;
 import nju.seec.helper.util.FileUtils;
+import nju.seec.helper.util.RedisCacheUtils;
 import nju.seec.helper.util.enums.ExceptionType;
 import nju.seec.helper.util.exception.HelperException;
 import nju.seec.helper.vo.CourseFileVO;
@@ -39,9 +39,9 @@ public class CourseFileServiceImpl implements CourseFileService {
 
 
     private final FileUtils fileUtils;
-    private final CacheUtils cacheUtils;
+    private final RedisCacheUtils cacheUtils;
 
-    public CourseFileServiceImpl(CourseDAO courseDAO, CourseFileDAO courseFileDAO, ChooseDAO chooseDAO, FileUtils fileUtils, CacheUtils cacheUtils) {
+    public CourseFileServiceImpl(CourseDAO courseDAO, CourseFileDAO courseFileDAO, ChooseDAO chooseDAO, FileUtils fileUtils, RedisCacheUtils cacheUtils) {
         this.courseDAO = courseDAO;
         this.courseFileDAO = courseFileDAO;
         this.chooseDAO = chooseDAO;

+ 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());
         }
     }
 

+ 148 - 110
src/main/java/nju/seec/helper/service/impl/QuizServiceImpl.java

@@ -23,6 +23,12 @@ import org.springframework.util.Assert;
 import java.util.*;
 import java.util.stream.Collectors;
 
+
+/**
+ * @author xst
+ * <p>
+ * updated by cst
+ */
 @Service
 public class QuizServiceImpl implements QuizService {
     private final SlideDAO slideDAO;
@@ -47,12 +53,12 @@ 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();
-        course.setId(slide.getCourseId());
+        course.setId(slide.getCourse().getId());
         Quiz quiz = new Quiz();
 
         quiz.setCourse(course);
@@ -62,15 +68,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 +88,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 +108,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 +135,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,83 +158,93 @@ 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());
+                final Set<Long> studentIds = chooseDAO.findStudentIdsByCourseId(slide.getCourse().getId());
                 Student2QuestionId2Answer triadMap = new Student2QuestionId2Answer(studentIds, quiz.getQuestions().size());
                 //将已经作答的学生答案加入
                 for (QuizStudentAnswer answers : quizAnswers) {
@@ -239,108 +262,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);
     }
 
 

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

@@ -18,9 +18,9 @@ import nju.seec.helper.service.QuizService;
 import nju.seec.helper.service.SlideService;
 import nju.seec.helper.service.util.AuthUtils;
 import nju.seec.helper.service.util.StringUtils;
-import nju.seec.helper.util.RedisCacheUtils;
 import nju.seec.helper.util.Consts;
 import nju.seec.helper.util.FileUtils;
+import nju.seec.helper.util.RedisCacheUtils;
 import nju.seec.helper.util.enums.ExceptionType;
 import nju.seec.helper.util.enums.MessageType;
 import nju.seec.helper.util.enums.SlideState;
@@ -245,8 +245,8 @@ public class SlideServiceImpl implements SlideService {
     private void checkSameName(Long slideId, Long courseId, String name) {
         long exists = slideDAO.count((Specification<Slide>) (root, query, cb) -> cb.and(
                 cb.notEqual(root.get("id"), slideId),
+                cb.equal(root.get("course").get("Id"), courseId),
                 cb.equal(root.get("deleteAt"), 0L),
-                cb.equal(root.get("courseId"), courseId),
                 cb.equal(root.get("name"), name)));
 
         if (exists > 0) {
@@ -257,8 +257,8 @@ public class SlideServiceImpl implements SlideService {
     private Page<Slide> findByTeacherIdAndKey(Long teacherId, String key, Pageable pageable) {
         return slideDAO.findAll(
                 (Specification<Slide>) (root, query, cb) -> cb.and(
-                        cb.equal(root.get("deleteAt"), 0L),
                         cb.equal(root.get("teacher").get("id"), teacherId),
+                        cb.equal(root.get("deleteAt"), 0L),
                         cb.like(root.get("name"), StringUtils.keyPattern(key))),
                 pageable);
     }
@@ -266,9 +266,9 @@ public class SlideServiceImpl implements SlideService {
     private Page<Slide> findByCourseIdAndTeacherIdAndKey(Long courseId, Long teacherId, String key, Pageable pageable) {
         return slideDAO.findAll(
                 (Specification<Slide>) (root, query, cb) -> cb.and(
-                        cb.equal(root.get("deleteAt"), 0L),
-                        cb.equal(root.get("courseId"), courseId),
+                        cb.equal(root.get("course").get("Id"), courseId),
                         cb.equal(root.get("teacher").get("id"), teacherId),
+                        cb.equal(root.get("deleteAt"), 0L),
                         cb.like(root.get("name"), StringUtils.keyPattern(key))),
                 pageable);
     }
@@ -276,8 +276,8 @@ public class SlideServiceImpl implements SlideService {
     private Page<Slide> findByCourseIdAndKeyAndStateNotIn(Long courseId, Set<SlideState> exclusiveStates, String key, Pageable pageable) {
         return slideDAO.findAll(
                 (Specification<Slide>) (root, query, cb) -> cb.and(
+                        cb.equal(root.get("course").get("Id"), courseId),
                         cb.equal(root.get("deleteAt"), 0L),
-                        cb.equal(root.get("courseId"), courseId),
                         cb.not(root.get("state").in(exclusiveStates)),
                         cb.like(root.get("name"), StringUtils.keyPattern(key))
                 ),

+ 1 - 1
src/main/java/nju/seec/helper/service/impl/UserServiceImpl.java

@@ -8,9 +8,9 @@ import nju.seec.helper.dto.UserDTO;
 import nju.seec.helper.entity.User;
 import nju.seec.helper.service.UserService;
 import nju.seec.helper.service.util.AuthUtils;
-import nju.seec.helper.util.RedisCacheUtils;
 import nju.seec.helper.util.Consts;
 import nju.seec.helper.util.EncryptUtils;
+import nju.seec.helper.util.RedisCacheUtils;
 import nju.seec.helper.util.enums.ExceptionType;
 import nju.seec.helper.util.enums.UserType;
 import nju.seec.helper.util.exception.HelperException;

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

@@ -11,7 +11,6 @@ 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.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.domain.Pageable;
 import org.springframework.http.HttpStatus;
@@ -23,46 +22,55 @@ import org.springframework.web.client.HttpClientErrorException;
 import java.util.*;
 import java.util.stream.Collectors;
 
+/**
+ * @author xst
+ * <p>
+ * updated by cst
+ */
 @Component
 public class BokUtil {
-    @Autowired
-    private RestRequestUtil restRequestUtil;
-    @Autowired
-    private GuavaCacheUtil cacheUtils;
+    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/";
+    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) {
+    public BokUtil(RestRequestUtil restRequestUtil, GuavaCacheUtil cacheUtils) {
+        this.restRequestUtil = restRequestUtil;
+        this.cacheUtils = cacheUtils;
+    }
 
-        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()));
+    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"));
+            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 +81,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;
@@ -91,17 +99,17 @@ public class BokUtil {
                 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());
+            Map<String, Object> newGet = new HashMap<>(collect.size());
             for (BaseQuestionVO vo : collect) {
                 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);
@@ -112,7 +120,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)
@@ -125,92 +133,104 @@ public class BokUtil {
                         .analysis((String) q.get("analysis")).questionId(String.valueOf((Integer) q.get("tqId"))).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);
     }
 
     /**
@@ -218,7 +238,7 @@ public class BokUtil {
      */
     @JsonInclude(JsonInclude.Include.NON_NULL)
     @Data
-    class BokTq {
+    static class BokTq {
         String id;
         String type;
         String answer;
@@ -234,21 +254,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 - 14
src/main/java/nju/seec/helper/util/GuavaCacheUtil.java

@@ -3,29 +3,26 @@ package nju.seec.helper.util;
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.collect.ImmutableMap;
-import org.springframework.beans.factory.BeanNameAware;
-import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
-import org.springframework.util.StringUtils;
 
 import java.util.Collection;
-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 +33,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 - 4
src/main/java/nju/seec/helper/util/enums/ExceptionType.java

@@ -1,6 +1,5 @@
 package nju.seec.helper.util.enums;
 
-import lombok.AllArgsConstructor;
 import lombok.Getter;
 import org.springframework.http.HttpStatus;
 
@@ -18,9 +17,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() {

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

@@ -27,23 +27,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
@@ -93,4 +98,4 @@ public abstract class BaseQuestionVO {
 //  extends TrueOrFalseQuestionSerializer {
 //  studentAnswer: boolean;
 //  pass: boolean; // 是否正确
-//}
+//}

+ 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;

+ 9 - 7
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";
@@ -49,4 +51,4 @@ public class ChoiceQuestionVO extends BaseQuestionVO {
 //    [key: string]: string;
 //  };
 //  answer: string; // 答案 [与 options 的 key 一致]
-//  analysis?: string; // 解析
+//  analysis?: string; // 解析

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

@@ -1,6 +1,5 @@
 package nju.seec.helper.vo.quiz;
 
-import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonUnwrapped;
 import lombok.Data;
 import nju.seec.helper.entity.QuizStudentAnswer;
@@ -8,7 +7,6 @@ import nju.seec.helper.entity.StudentScore;
 import nju.seec.helper.entity.User;
 import nju.seec.helper.vo.UserVO;
 
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -18,12 +16,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));
     }
 }

+ 5 - 3
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);
     }
 }
@@ -91,4 +93,4 @@ public class QuizVO {
 //
 //interface QuizBasicSerialzer extends Omit<QuizSerialzier, "questions"> {
 //        questionNumber: number; // 题目数量
-//        }
+//        }

+ 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;
     }
 }