Procházet zdrojové kódy

feat: 增加新增、修改、删除题目功能(未测试)

ChenSiTong před 6 roky
rodič
revize
50ce9050f2
37 změnil soubory, kde provedl 329 přidání a 414 odebrání
  1. 1 1
      src/main/java/nju/seec/helper/aspect/auth/Auth.java
  2. 2 2
      src/main/java/nju/seec/helper/controller/CommentController.java
  3. 2 2
      src/main/java/nju/seec/helper/controller/CourseController.java
  4. 1 1
      src/main/java/nju/seec/helper/controller/NoticeController.java
  5. 20 54
      src/main/java/nju/seec/helper/controller/QuestionController.java
  6. 2 2
      src/main/java/nju/seec/helper/controller/ReplyController.java
  7. 2 2
      src/main/java/nju/seec/helper/controller/SlideController.java
  8. 21 0
      src/main/java/nju/seec/helper/dao/QuestionRecordDAO.java
  9. 2 2
      src/main/java/nju/seec/helper/dto/question/BaseQuestionDTO.java
  10. 0 21
      src/main/java/nju/seec/helper/dto/question/SubjectiveQuestionDTO.java
  11. 37 0
      src/main/java/nju/seec/helper/entity/QuestionRecord.java
  12. 3 3
      src/main/java/nju/seec/helper/entity/Quiz.java
  13. 2 2
      src/main/java/nju/seec/helper/entity/QuizStudentAnswer.java
  14. 1 1
      src/main/java/nju/seec/helper/service/CommentService.java
  15. 1 1
      src/main/java/nju/seec/helper/service/CourseFileService.java
  16. 1 1
      src/main/java/nju/seec/helper/service/CourseService.java
  17. 1 1
      src/main/java/nju/seec/helper/service/MessageService.java
  18. 1 1
      src/main/java/nju/seec/helper/service/NoticeService.java
  19. 28 0
      src/main/java/nju/seec/helper/service/QuestionService.java
  20. 1 1
      src/main/java/nju/seec/helper/service/QuizService.java
  21. 1 1
      src/main/java/nju/seec/helper/service/ReplyService.java
  22. 1 1
      src/main/java/nju/seec/helper/service/SlideService.java
  23. 2 2
      src/main/java/nju/seec/helper/service/impl/CommentServiceImpl.java
  24. 1 1
      src/main/java/nju/seec/helper/service/impl/CourseFileServiceImpl.java
  25. 1 1
      src/main/java/nju/seec/helper/service/impl/CourseServiceImpl.java
  26. 1 1
      src/main/java/nju/seec/helper/service/impl/NoticeServiceImpl.java
  27. 50 6
      src/main/java/nju/seec/helper/service/impl/QuestionServiceImpl.java
  28. 1 1
      src/main/java/nju/seec/helper/service/impl/ReplyServiceImpl.java
  29. 1 1
      src/main/java/nju/seec/helper/service/impl/SlideServiceImpl.java
  30. 98 154
      src/main/java/nju/seec/helper/util/BokUtil.java
  31. 12 16
      src/main/java/nju/seec/helper/util/RestRequestUtil.java
  32. 30 1
      src/main/java/nju/seec/helper/util/enums/QuestionType.java
  33. 0 13
      src/main/java/nju/seec/helper/vo/question/BaseQuestionVO.java
  34. 0 18
      src/main/java/nju/seec/helper/vo/question/ChoiceQuestionVO.java
  35. 0 27
      src/main/java/nju/seec/helper/vo/question/SubjectiveQuestionVO.java
  36. 1 37
      src/main/java/nju/seec/helper/vo/question/TrueOrFalseQuestionVO.java
  37. 0 35
      src/main/java/nju/seec/helper/vo/quiz/QuizVO.java

+ 1 - 1
src/main/java/nju/seec/helper/aspect/auth/Auth.java

@@ -13,5 +13,5 @@ import java.lang.annotation.*;
 public @interface Auth {
     UserType[] roles() default {};
 
-    String message();
+    String message() default "";
 }

+ 2 - 2
src/main/java/nju/seec/helper/controller/CommentController.java

@@ -44,9 +44,9 @@ public class CommentController {
      */
     @Auth(roles = {UserType.TEACHER, UserType.STUDENT}, message = "删除评论")
     @DeleteMapping("/{commentId}")
-    public void removeComment(LoginUser user,
+    public void deleteComment(LoginUser user,
                               @PathVariable Long commentId) {
-        commentService.removeComment(user, commentId);
+        commentService.deleteComment(user, commentId);
     }
 
     /**

+ 2 - 2
src/main/java/nju/seec/helper/controller/CourseController.java

@@ -45,9 +45,9 @@ public class CourseController {
      */
     @Auth(roles = UserType.TEACHER, message = "删除课程")
     @DeleteMapping("/{courseId}")
-    public void removeCourse(LoginUser user,
+    public void deleteCourse(LoginUser user,
                              @PathVariable Long courseId) {
-        courseService.removeCourse(user, courseId);
+        courseService.deleteCourse(user, courseId);
     }
 
     /**

+ 1 - 1
src/main/java/nju/seec/helper/controller/NoticeController.java

@@ -43,7 +43,7 @@ public class NoticeController {
 
     @Auth(roles = UserType.TEACHER, message = "删除公告")
     @DeleteMapping("/{noticeId}")
-    public void removeNotice(LoginUser user,
+    public void deleteNotice(LoginUser user,
                              @PathVariable Long noticeId) {
         noticeService.deleteNotice(user, noticeId);
     }

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

@@ -2,12 +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.dto.groups.Create;
+import nju.seec.helper.dto.groups.Modify;
+import nju.seec.helper.dto.question.BaseQuestionDTO;
 import nju.seec.helper.dto.user.LoginUser;
 import nju.seec.helper.service.QuestionService;
 import nju.seec.helper.util.enums.UserType;
 import nju.seec.helper.vo.question.BaseQuestionVO;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.web.PageableDefault;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
@@ -49,63 +53,25 @@ public class QuestionController {
 
     @Auth(roles = UserType.TEACHER, message = "获取题目信息")
     @GetMapping("/{questionId}")
-    public BaseQuestionVO getOneQuestion(LoginUser user, @PathVariable("questionId") String questionId) {
+    public BaseQuestionVO getOneQuestion(LoginUser user, @PathVariable String questionId) {
         return questionService.getOneQuestion(user, questionId);
     }
 
-//    @Auth(roles = UserType.TEACHER, message = "创建题目")
-//    @PostMapping
-//    public BaseQuestionVO createQuestion(LoginUser user, @Validated @RequestBody BaseQuestionDTO baseQuestionDTO) {
-//        return questionService.createQuestion(user, baseQuestionDTO);
-//    }
-
-//    /**
-//     * 获得题目列表
-//     */
-//    @Auth(roles = {UserType.TEACHER}, message = "获得题目详情")
-//    @GetMapping("/{questionId}")
-//    public BaseQuestionVO getQuestion(LoginUser user, @PathVariable("questionId") String questionId) throws JsonProcessingException {
-//        return questionService.getQuestion(questionId);
-//    }
-
-
-//    /**
-//     * 创建题目
-//     */
-//    @Auth(roles = {UserType.TEACHER}, message = "创建题目")
-//    @PostMapping
-//    public BaseQuestionVO postQuestion(LoginUser user, @RequestBody Map question) {
-//        if (question.get("kind") == null) {
-//            throw HelperException.of(ExceptionType.PARAM_ERROR, "无类型");
-//        }
-//
-//        return questionService.newQuestion(BaseQuestionVO.parse(question));
-//    }
-
-//    /**
-//     * 更新题目
-//     */
-//    @Auth(roles = {UserType.TEACHER}, message = "更新题目")
-//    @PutMapping("/{questionId}")
-//    public BaseQuestionVO updateQuestion(LoginUser user, @RequestBody Map question, @PathVariable("questionId") String questionId) {
-//        if (question.get("kind") == null) {
-//            throw HelperException.of(ExceptionType.PARAM_ERROR, "无类型");
-//        }
-//
-//        return questionService.updateQuestion(BaseQuestionVO.parse(question));
-//    }
+    @Auth(roles = UserType.TEACHER, message = "创建题目")
+    @PostMapping
+    public BaseQuestionVO createQuestion(LoginUser user, @Validated(Create.class) @RequestBody BaseQuestionDTO baseQuestionDTO) {
+        return questionService.createQuestion(user, baseQuestionDTO);
+    }
 
+    @Auth(roles = UserType.TEACHER, message = "修改题目")
+    @PutMapping("/{questionId}")
+    public BaseQuestionVO modifyQuestion(LoginUser user, @PathVariable String questionId, @Validated(Modify.class) @RequestBody BaseQuestionDTO baseQuestionDTO) {
+        return questionService.modifyQuestion(user, questionId, baseQuestionDTO);
+    }
 
-//    /**
-//     * 删除题目
-//     */
-//    @Auth(roles = {UserType.TEACHER}, message = "删除题目")
-//    @DeleteMapping("/{questionId}")
-//    public Map deleteQuestion(LoginUser user, @PathVariable("questionId") String questionId) {
-//
-//        questionService.deleteQuestion(questionId);
-//        Map map = new HashMap();
-//        map.put("message", "success");
-//        return map;
-//    }
+    @Auth(roles = UserType.TEACHER, message = "删除题目")
+    @DeleteMapping("/{questionId}")
+    public void deleteQuestion(LoginUser user, @PathVariable String questionId) {
+        questionService.deleteQuestion(user, questionId);
+    }
 }

+ 2 - 2
src/main/java/nju/seec/helper/controller/ReplyController.java

@@ -36,8 +36,8 @@ public class ReplyController {
      */
     @Auth(roles = UserType.TEACHER, message = "删除回复")
     @DeleteMapping("/{replyId}")
-    public void removeReply(LoginUser user,
+    public void deleteReply(LoginUser user,
                             @PathVariable Long replyId) {
-        replyService.removeReply(user, replyId);
+        replyService.deleteReply(user, replyId);
     }
 }

+ 2 - 2
src/main/java/nju/seec/helper/controller/SlideController.java

@@ -80,9 +80,9 @@ public class SlideController {
      */
     @Auth(roles = UserType.TEACHER, message = "删除课件")
     @DeleteMapping("/{slideId}")
-    public void removeSlide(LoginUser user,
+    public void deleteSlide(LoginUser user,
                             @PathVariable Long slideId) {
-        slideService.removeSlide(user, slideId);
+        slideService.deleteSlide(user, slideId);
     }
 
     /**

+ 21 - 0
src/main/java/nju/seec/helper/dao/QuestionRecordDAO.java

@@ -0,0 +1,21 @@
+package nju.seec.helper.dao;
+
+import nju.seec.helper.entity.QuestionRecord;
+import nju.seec.helper.entity.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+/**
+ * @author cst
+ */
+public interface QuestionRecordDAO extends JpaRepository<QuestionRecord, Long> {
+    /**
+     * 基于老师和问题查询
+     *
+     * @param user
+     * @param questionId
+     * @return
+     */
+    Optional<QuestionRecord> findByTeacherAndQuestionId(User user, String questionId);
+}

+ 2 - 2
src/main/java/nju/seec/helper/dto/question/BaseQuestionDTO.java

@@ -24,8 +24,8 @@ import javax.validation.constraints.NotNull;
         @JsonSubTypes.Type(value = TrueOrFalseQuestionDTO.class, name = BaseQuestionDTO.TRUE_FALSE)
 })
 public abstract class BaseQuestionDTO {
-    protected static final String CHOICE = "CHOICE";
-    protected static final String TRUE_FALSE = "TRUE_FALSE";
+    protected static final String CHOICE = "choice";
+    protected static final String TRUE_FALSE = "true_false";
 
     @NotBlank(message = "题干不能为空")
     @Length(max = 1000, message = "题干长度不能超过1000")

+ 0 - 21
src/main/java/nju/seec/helper/dto/question/SubjectiveQuestionDTO.java

@@ -1,21 +0,0 @@
-//package nju.seec.helper.dto.question;
-//
-//import lombok.Data;
-//import lombok.EqualsAndHashCode;
-//import nju.seec.helper.util.enums.QuestionType;
-//
-//import java.io.Serializable;
-//
-///**
-// * @author cst
-// */
-//@EqualsAndHashCode(callSuper = true)
-//@Data
-//public class SubjectiveQuestionDTO extends BaseQuestionDTO implements Serializable {
-//    private static final long serialVersionUID = -4391297345486351815L;
-//
-//    @Override
-//    public QuestionType getQuestionType() {
-//        return QuestionType.SUBJECTIVE;
-//    }
-//}

+ 37 - 0
src/main/java/nju/seec/helper/entity/QuestionRecord.java

@@ -0,0 +1,37 @@
+package nju.seec.helper.entity;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+/**
+ * @author cst
+ */
+@Data
+@Accessors(chain = true)
+@Entity
+@Table(name = "question_record", uniqueConstraints = @UniqueConstraint(name = "teacher_question_unique", columnNames = {"teacher_id", "question_id"}))
+public class QuestionRecord {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.LAZY)
+    @JoinColumn(name = "teacher_id", foreignKey = @ForeignKey(name = "question_teacher"))
+    private User teacher;
+
+    @Column(name = "question_id", nullable = false)
+    private String questionId;
+
+    @Column(name = "create_at", nullable = false, updatable = false)
+    @CreationTimestamp
+    private LocalDateTime createAt;
+
+    @Column(name = "update_at", nullable = false)
+    @UpdateTimestamp
+    private LocalDateTime updateAt;
+}

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

@@ -36,15 +36,15 @@ public class Quiz {
     private String name;
 
     @ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.LAZY)
-    @JoinColumn(name = "course_id", referencedColumnName = "id", foreignKey = @ForeignKey(name = "quiz_course"))
+    @JoinColumn(name = "course_id", foreignKey = @ForeignKey(name = "quiz_course"))
     private Course course;
 
     @ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.LAZY)
-    @JoinColumn(name = "slide_id", referencedColumnName = "id", foreignKey = @ForeignKey(name = "quiz_slide"))
+    @JoinColumn(name = "slide_id", foreignKey = @ForeignKey(name = "quiz_slide"))
     private Slide slide;
 
     @ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.LAZY)
-    @JoinColumn(name = "teacher_id", referencedColumnName = "id", foreignKey = @ForeignKey(name = "quiz_teacher"))
+    @JoinColumn(name = "teacher_id", foreignKey = @ForeignKey(name = "quiz_teacher"))
     private User teacher;
 
     @Convert(converter = ListConverter.class)

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

@@ -31,11 +31,11 @@ public class QuizStudentAnswer {
     private Long id;
 
     @ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.LAZY)
-    @JoinColumn(name = "quiz_id", referencedColumnName = "id", foreignKey = @ForeignKey(name = "answer_quiz"))
+    @JoinColumn(name = "quiz_id", foreignKey = @ForeignKey(name = "answer_quiz"))
     private Quiz quiz;
 
     @ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.LAZY)
-    @JoinColumn(name = "student_id", referencedColumnName = "id", foreignKey = @ForeignKey(name = "answer_student"))
+    @JoinColumn(name = "student_id", foreignKey = @ForeignKey(name = "answer_student"))
     private User student;
 
     @SuppressWarnings("all")

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

@@ -25,7 +25,7 @@ public interface CommentService {
      * @param user
      * @param commentId
      */
-    void removeComment(LoginUser user, Long commentId);
+    void deleteComment(LoginUser user, Long commentId);
 
     /**
      * 置顶评论

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

@@ -24,7 +24,7 @@ public interface CourseFileService {
      * @param user
      * @param courseFileId
      */
-    void deleteCourseFile(LoginUser user, Long courseFileId);
+    void  deleteCourseFile(LoginUser user, Long courseFileId);
 
     /**
      * 取得课程附件

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

@@ -37,7 +37,7 @@ public interface CourseService {
      * @param user
      * @param courseId
      */
-    void removeCourse(LoginUser user, Long courseId);
+    void deleteCourse(LoginUser user, Long courseId);
 
     /**
      * 学生选课

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

@@ -29,7 +29,7 @@ public interface MessageService {
      * @param user
      * @param messageDTO
      */
-    void deleteMessages(LoginUser user, MessageDTO messageDTO);
+    void  deleteMessages(LoginUser user, MessageDTO messageDTO);
 
     /**
      * 设置消息已阅

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

@@ -46,7 +46,7 @@ public interface NoticeService {
      * @param user
      * @param noticeId
      */
-    void deleteNotice(LoginUser user, Long noticeId);
+    void  deleteNotice(LoginUser user, Long noticeId);
 
     /**
      * 取得某一公告

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

@@ -1,5 +1,6 @@
 package nju.seec.helper.service;
 
+import nju.seec.helper.dto.question.BaseQuestionDTO;
 import nju.seec.helper.dto.user.LoginUser;
 import nju.seec.helper.entity.Quiz;
 import nju.seec.helper.vo.question.BaseQuestionVO;
@@ -49,4 +50,31 @@ public interface QuestionService {
      * @return
      */
     BaseQuestionVO getOneQuestion(LoginUser user, String questionId);
+
+    /**
+     * 创建题目
+     *
+     * @param user
+     * @param baseQuestionDTO
+     * @return
+     */
+    BaseQuestionVO createQuestion(LoginUser user, BaseQuestionDTO baseQuestionDTO);
+
+    /**
+     * 修改题目
+     *
+     * @param user
+     * @param questionId
+     * @param baseQuestionDTO
+     * @return
+     */
+    BaseQuestionVO modifyQuestion(LoginUser user, String questionId, BaseQuestionDTO baseQuestionDTO);
+
+    /**
+     * 删除题目
+     *
+     * @param user
+     * @param questionId
+     */
+    void deleteQuestion(LoginUser user, String questionId);
 }

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

@@ -44,7 +44,7 @@ public interface QuizService {
      * @param quizId
      * @return
      */
-    void deleteQuiz(LoginUser user, Long quizId);
+    void  deleteQuiz(LoginUser user, Long quizId);
 
     /**
      * 教师基于课件获取测试

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

@@ -23,5 +23,5 @@ public interface ReplyService {
      * @param user
      * @param replyId
      */
-    void removeReply(LoginUser user, Long replyId);
+    void deleteReply(LoginUser user, Long replyId);
 }

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

@@ -55,7 +55,7 @@ public interface SlideService {
      * @param user
      * @param slideId
      */
-    void removeSlide(LoginUser user, Long slideId);
+    void deleteSlide(LoginUser user, Long slideId);
 
     /**
      * 教师获取课件列表

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

@@ -61,13 +61,13 @@ public class CommentServiceImpl implements CommentService {
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public void removeComment(LoginUser user, Long commentId) {
+    public void deleteComment(LoginUser user, Long commentId) {
         Comment comment = commentDAO.findCommentById(commentId);
 
         AuthUtils.checkDataAuth(user.getId(), comment.getUser().getId(), "您无权删除该评论");
 
         unTopComment(comment);
-        commentDAO.deleteById(commentId);
+        commentDAO.delete(comment);
     }
 
     @Transactional(rollbackFor = Exception.class)

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

@@ -81,7 +81,7 @@ public class CourseFileServiceImpl implements CourseFileService {
     public void deleteCourseFile(LoginUser user, Long courseFileId) {
         CourseFile courseFile = courseFileDAO.findCourseFileById(courseFileId);
         AuthUtils.checkDataAuth(user.getId(), courseFile.getTeacherId(), "您无权删除该附件");
-        courseFileDAO.deleteById(courseFileId);
+        courseFileDAO.delete(courseFile);
         fileUtils.delete(courseFile.getObjectName());
     }
 

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

@@ -73,7 +73,7 @@ public class CourseServiceImpl implements CourseService {
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public void removeCourse(LoginUser user, Long courseId) {
+    public void deleteCourse(LoginUser user, Long courseId) {
         Course course = courseDAO.findCourseById(courseId);
         AuthUtils.checkDataAuth(user.getId(), course.getTeacher().getId(), "您无权删除该课程");
 

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

@@ -76,7 +76,7 @@ public class NoticeServiceImpl implements NoticeService {
     public void deleteNotice(LoginUser user, Long noticeId) {
         Notice notice = noticeDAO.findNoticeById(noticeId);
         AuthUtils.checkDataAuth(user.getId(), notice.getTeacherId(), "您无权删除该公告");
-        noticeDAO.deleteById(noticeId);
+        noticeDAO.delete(notice);
     }
 
     @Transactional(readOnly = true)

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

@@ -1,14 +1,20 @@
 package nju.seec.helper.service.impl;
 
+import nju.seec.helper.dao.QuestionRecordDAO;
 import nju.seec.helper.dao.QuizDAO;
 import nju.seec.helper.dao.UserDAO;
+import nju.seec.helper.dto.question.BaseQuestionDTO;
 import nju.seec.helper.dto.user.LoginUser;
+import nju.seec.helper.entity.QuestionRecord;
 import nju.seec.helper.entity.Quiz;
 import nju.seec.helper.service.QuestionService;
 import nju.seec.helper.util.BokUtil;
+import nju.seec.helper.util.enums.ExceptionType;
 import nju.seec.helper.util.enums.QuizState;
 import nju.seec.helper.util.enums.UserType;
+import nju.seec.helper.util.exception.HelperException;
 import nju.seec.helper.vo.question.BaseQuestionVO;
+import nju.seec.helper.vo.question.BokQuestion;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
@@ -16,6 +22,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * @author xst
@@ -26,21 +33,23 @@ import java.util.List;
 public class QuestionServiceImpl implements QuestionService {
     private final QuizDAO quizDAO;
     private final UserDAO userDAO;
+    private final QuestionRecordDAO questionRecordDAO;
 
     private final BokUtil bokUtil;
 
     @Autowired
     public QuestionServiceImpl(QuizDAO quizDAO
             , UserDAO userDAO
-            , BokUtil bokUtil) {
+            , QuestionRecordDAO questionRecordDAO, BokUtil bokUtil) {
         this.quizDAO = quizDAO;
         this.userDAO = userDAO;
+        this.questionRecordDAO = questionRecordDAO;
         this.bokUtil = bokUtil;
     }
 
     @Override
     public Page<BaseQuestionVO> getQuestions(LoginUser user, String stem, Pageable pageable) {
-        return bokUtil.bokFindByStemLike(stem, pageable, true);
+        return bokUtil.bokFindByStemLike(stem, pageable).map(bokQuestion -> BaseQuestionVO.convertBokQuestionToVO(bokQuestion, true));
     }
 
     @Transactional(readOnly = true)
@@ -48,19 +57,54 @@ public class QuestionServiceImpl implements QuestionService {
     public List<BaseQuestionVO> getQuestionsByQuiz(LoginUser user, Long quizId) {
         Quiz quiz = quizDAO.findQuizById(quizId);
         List<String> questionIds = quiz.getQuestions();
-        return bokUtil.bokFindByIdIn(questionIds, quiz.getState() == QuizState.CLOSED || user.getType() == UserType.TEACHER);
+        return bokUtil.bokFindByIdIn(questionIds)
+                .stream()
+                .map(bokQuestion -> BaseQuestionVO.convertBokQuestionToVO(bokQuestion, quiz.getState() == QuizState.CLOSED || user.getType() == UserType.TEACHER))
+                .collect(Collectors.toList());
     }
 
     @Transactional(readOnly = true)
     @Override
     public List<BaseQuestionVO> getQuestionsByQuiz(Quiz quiz) {
         List<String> questionIds = quiz.getQuestions();
-        return bokUtil.bokFindByIdIn(questionIds, true);
+        return bokUtil.bokFindByIdIn(questionIds)
+                .stream()
+                .map(bokQuestion -> BaseQuestionVO.convertBokQuestionToVO(bokQuestion, true))
+                .collect(Collectors.toList());
     }
 
-    @Transactional(readOnly = true)
     @Override
     public BaseQuestionVO getOneQuestion(LoginUser user, String questionId) {
-        return bokUtil.bokFindById(questionId, true);
+        return BaseQuestionVO.convertBokQuestionToVO(bokUtil.bokFindById(questionId), true);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public BaseQuestionVO createQuestion(LoginUser user, BaseQuestionDTO baseQuestionDTO) {
+        BokQuestion bokQuestion = bokUtil.createQuestion(baseQuestionDTO);
+        QuestionRecord questionRecord = new QuestionRecord()
+                .setTeacher(userDAO.findUserById(user.getId()))
+                .setQuestionId(bokQuestion.getTqId());
+        questionRecordDAO.save(questionRecord);
+        return BaseQuestionVO.convertBokQuestionToVO(bokUtil.createQuestion(baseQuestionDTO), true);
+    }
+
+    @Transactional(readOnly = true)
+    @Override
+    public BaseQuestionVO modifyQuestion(LoginUser user, String questionId, BaseQuestionDTO baseQuestionDTO) {
+        QuestionRecord questionRecord = questionRecordDAO.findByTeacherAndQuestionId(userDAO.findUserById(user.getId()), questionId)
+                .orElseThrow(() -> HelperException.of(ExceptionType.FORBIDDEN, "您无权修改该问题"));
+        BokQuestion bokQuestion = bokUtil.modifyQuestion(questionId, baseQuestionDTO);
+        questionRecordDAO.save(questionRecord);
+        return BaseQuestionVO.convertBokQuestionToVO(bokQuestion, true);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void deleteQuestion(LoginUser user, String questionId) {
+        QuestionRecord questionRecord = questionRecordDAO.findByTeacherAndQuestionId(userDAO.findUserById(user.getId()), questionId)
+                .orElseThrow(() -> HelperException.of(ExceptionType.FORBIDDEN, "您无权删除该问题"));
+        bokUtil.deleteQuestion(questionId);
+        questionRecordDAO.delete(questionRecord);
     }
 }

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

@@ -71,7 +71,7 @@ public class ReplyServiceImpl implements ReplyService {
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public void removeReply(LoginUser user, Long replyId) {
+    public void deleteReply(LoginUser user, Long replyId) {
         Reply reply = replyDAO.findReplyById(replyId);
         AuthUtils.checkDataAuth(user.getId(), reply.getTeacher().getId(), "您无权删除该评论");
 

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

@@ -179,7 +179,7 @@ public class SlideServiceImpl implements SlideService {
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public void removeSlide(LoginUser user, Long slideId) {
+    public void deleteSlide(LoginUser user, Long slideId) {
         Slide slide = slideDAO.findSlideById(slideId);
         AuthUtils.checkDataAuth(user.getId(), slide.getTeacher().getId(), "您无权删除该课件");
 

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

@@ -1,12 +1,16 @@
 package nju.seec.helper.util;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
+import nju.seec.helper.dto.question.BaseQuestionDTO;
+import nju.seec.helper.dto.question.ChoiceQuestionDTO;
+import nju.seec.helper.dto.question.TrueOrFalseQuestionDTO;
 import nju.seec.helper.util.enums.ExceptionType;
+import nju.seec.helper.util.enums.QuestionType;
 import nju.seec.helper.util.exception.HelperException;
-import nju.seec.helper.vo.question.BaseQuestionVO;
 import nju.seec.helper.vo.question.BokQuestion;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.domain.Page;
@@ -14,10 +18,7 @@ import org.springframework.data.domain.PageImpl;
 import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Component;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -40,168 +41,111 @@ public class BokUtil {
         this.cacheUtils = cacheUtils;
     }
 
-    public Page<BaseQuestionVO> bokFindByStemLike(String stem, Pageable pageable, boolean withAnswer) {
-        try {
-            Map<String, String> urlParams = ImmutableMap.of(
-                    "content", stem,
-                    "page", String.valueOf(1 + pageable.getPageNumber()),
-                    "size", String.valueOf(pageable.getPageSize()),
-                    "sort", pageable.getSort().toString().replaceAll(" ", "").replaceAll(":", ",")
-            );
-            BokSearchResult result = restRequestUtil.sendGetRequest(
-                    searchUrl + "findByStemLike?content={content}&sort={sort}&size={size}&page={page}", BokSearchResult.class, urlParams);
-
-            List<BokQuestion> questions = result.get_embedded().getChoiceQuestions();
-            List<BaseQuestionVO> questionVOList =
-                    questions.stream()
-                            .map(question -> {
-                                cacheUtils.set(CACHE_NAME, question.getTqId(), question);
-                                return BaseQuestionVO.convertBokQuestionToVO(question, withAnswer);
-                            })
-                            .collect(Collectors.toList());
-            return new PageImpl<>(questionVOList, pageable, result.getPage().getTotalElements());
-        } catch (Exception e) {
-            log.error(e.getLocalizedMessage(), e);
-            throw HelperException.of(ExceptionType.ERROR, "获取题目失败");
-        }
+    public Page<BokQuestion> bokFindByStemLike(String stem, Pageable pageable) {
+        Map<String, String> urlParams = ImmutableMap.of(
+                "content", stem,
+                "page", String.valueOf(1 + pageable.getPageNumber()),
+                "size", String.valueOf(pageable.getPageSize()),
+                "sort", pageable.getSort().toString().replaceAll(" ", "").replaceAll(":", ",")
+        );
+        BokSearchResult result = restRequestUtil.sendGetRequest(
+                searchUrl + "findByStemLike?content={content}&sort={sort}&size={size}&page={page}", BokSearchResult.class, urlParams);
+
+        List<BokQuestion> questions = result.getEmbedded().getChoiceQuestions();
+        cacheUtils.setAll(BOK_CACHE_NAME,
+                questions.parallelStream()
+                        .collect(Collectors.toMap(BokQuestion::getTqId, bokQuestion -> bokQuestion)));
+        return new PageImpl<>(questions, pageable, result.getPage().getTotalElements());
     }
 
-    private static String CACHE_NAME = "BOK";
-
-    public List<BaseQuestionVO> bokFindByIdIn(final List<String> ids, boolean withAnswer) {
-        try {
-            final ImmutableMap<Object, Object> bokQuestionsMap = cacheUtils.multiGet(CACHE_NAME, ids);
-
-            List<String> requestIds = new ArrayList<>(ids);
-            Map<String, BaseQuestionVO> questionVOMap = Maps.newHashMapWithExpectedSize(ids.size());
-
-            bokQuestionsMap
-                    .values()
-                    .forEach(value -> {
-                        BokQuestion bokQuestion = (BokQuestion) value;
-                        BaseQuestionVO questionVO = BaseQuestionVO.convertBokQuestionToVO(bokQuestion, withAnswer);
-                        questionVOMap.put(questionVO.getId(), questionVO);
-                        requestIds.remove(bokQuestion.getTqId());
-                    });
-            //未缓存的去这里拿
-            if (!requestIds.isEmpty()) {
-                Map<String, String> urlParams = ImmutableMap.of("id", requestIds.stream().reduce((a, b) -> a + "," + b).orElse(""));
-
-                BokSearchResult result = restRequestUtil.sendGetRequest(searchUrl + "findByIdIn?id={id}", BokSearchResult.class, urlParams);
-                List<BokQuestion> questions = result.get_embedded().getChoiceQuestions();
-                questions.forEach(question -> {
-                    cacheUtils.set(CACHE_NAME, question.getTqId(), question);
-                    BaseQuestionVO questionVO = BaseQuestionVO.convertBokQuestionToVO(question, withAnswer);
-                    questionVOMap.put(questionVO.getId(), questionVO);
+    private static String BOK_CACHE_NAME = "BOK";
+
+    public List<BokQuestion> bokFindByIdIn(final List<String> ids) {
+        final ImmutableMap<Object, Object> bokQuestionsMap = cacheUtils.multiGet(BOK_CACHE_NAME, ids);
+
+        List<String> requestIds = new ArrayList<>(ids);
+        Map<String, BokQuestion> bokQuestionMap = Maps.newHashMapWithExpectedSize(ids.size());
+
+        bokQuestionsMap
+                .values()
+                .forEach(value -> {
+                    BokQuestion bokQuestion = (BokQuestion) value;
+                    bokQuestionMap.put(bokQuestion.getTqId(), bokQuestion);
+                    requestIds.remove(bokQuestion.getTqId());
                 });
-            }
-
-            return ids.stream()
-                    .map(questionVOMap::get)
-                    .collect(Collectors.toList());
-        } catch (Exception e) {
-            log.error(e.getLocalizedMessage(), e);
-            throw HelperException.of(ExceptionType.ERROR, "获取题目失败");
+        //未缓存的去这里拿
+        if (!requestIds.isEmpty()) {
+            Map<String, String> urlParams = ImmutableMap.of("id", requestIds.stream().reduce((a, b) -> a + "," + b).orElse(""));
+
+            BokSearchResult result = restRequestUtil.sendGetRequest(searchUrl + "findByIdIn?id={id}", BokSearchResult.class, urlParams);
+            List<BokQuestion> bokQuestions = result.getEmbedded().getChoiceQuestions();
+            bokQuestions.forEach(bokQuestion -> {
+                cacheUtils.set(BOK_CACHE_NAME, bokQuestion.getTqId(), bokQuestion);
+                bokQuestionMap.put(bokQuestion.getTqId(), bokQuestion);
+            });
         }
+
+        return ids.stream()
+                .map(bokQuestionMap::get)
+                .collect(Collectors.toList());
     }
 
-    public BaseQuestionVO bokFindById(String questionId, boolean withAnswer) {
-        Object cachedBokQuestion = cacheUtils.get(CACHE_NAME, questionId);
+    public BokQuestion bokFindById(String questionId) {
+        Object cachedBokQuestion = cacheUtils.get(BOK_CACHE_NAME, questionId);
         if (cachedBokQuestion instanceof BokQuestion) {
-            return BaseQuestionVO.convertBokQuestionToVO((BokQuestion) cachedBokQuestion, withAnswer);
-        }
-        try {
-            BokQuestion bokQuestion = restRequestUtil.sendGetRequest(tqUrl + questionId, BokQuestion.class, Collections.emptyMap());
-            cacheUtils.set(CACHE_NAME, bokQuestion.getTqId(), bokQuestion);
-            return BaseQuestionVO.convertBokQuestionToVO(bokQuestion, withAnswer);
-        } catch (Exception e) {
-            log.error(e.getLocalizedMessage(), e);
-            throw HelperException.of(ExceptionType.ERROR, "获取题目失败");
+            return (BokQuestion) cachedBokQuestion;
         }
+        BokQuestion bokQuestion = restRequestUtil.sendGetRequest(tqUrl + questionId, BokQuestion.class, Collections.emptyMap());
+        cacheUtils.set(BOK_CACHE_NAME, bokQuestion.getTqId(), bokQuestion);
+        return bokQuestion;
+    }
+
+    public BokQuestion createQuestion(BaseQuestionDTO baseQuestionDTO) {
+        BokQuestion bokQuestion = getQuestion(baseQuestionDTO);
+        bokQuestion.setTqId(UUID.randomUUID().toString());
+        bokQuestion = restRequestUtil.sendPostRequest(tqUrl, bokQuestion, BokQuestion.class);
+        return bokQuestion;
+    }
+
+    public BokQuestion modifyQuestion(String questionId, BaseQuestionDTO baseQuestionDTO) {
+        BokQuestion bokQuestion = getQuestion(baseQuestionDTO);
+        bokQuestion.setTqId(questionId);
+        restRequestUtil.sendPutRequest(tqUrl, bokQuestion);
+        return bokFindById(questionId);
     }
 
-//    @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
-//    public BaseQuestionVO postNewQuestion(BaseQuestionVO vo) throws JsonProcessingException {
-//        if (vo.getQuestionId() != null) {
-//            throw HelperException.of(ExceptionType.PARAM_ERROR, "should POST a new question");
-//        }
-//        String questionId = null;
-//        //我当时应该用uuid的,但是线上已经部署了,只能下次再改了(如果有下次
-//        //因为线上用的也是Long Id 并且es不提供自增主键,先这样尝试插入
-//        //之后对于新增bok的题目,应该有某种限制,未补全知识点的题目不允许插入
-//        int tryNumber = 100;
-//        int randomLength = 4;
-//        for (int i = 0; i < tryNumber; i++) {
-//            Date date = new Date();
-//            Calendar calendar = Calendar.getInstance();
-//            int year = calendar.get(Calendar.YEAR);
-//            String month = String.valueOf(1 + calendar.get(Calendar.MONTH));
-//            String day = String.valueOf(calendar.get(Calendar.DATE));
-//            if (month.length() < 2) {
-//                month = "0" + month;
-//            }
-//            if (day.length() < 2) {
-//                month = "0" + month;
-//            }
-//            Random randomGet = new Random();
-//            StringBuilder random = new StringBuilder(String.valueOf(randomGet.nextInt(10000)));
-//            while (random.length() < randomLength) {
-//                random.insert(0, "0");
-//            }
-//            questionId = "" + (year - 2010) + (month) + day + (random);
-//            try {
-//                Map ret = (Map) restRequestUtil.sendGetRequest(tqUrl + questionId, new HashMap<>());
-//            } catch (HttpClientErrorException e) {
-//                if (e.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
-//                    break;
-//                }
-//            }
-//            questionId = null;
-//        }
-//        if (questionId == null) {
-//            throw HelperException.of(ExceptionType.ERROR, "暂时无法保存题目,请重试!");
-//        }
-//
-//        vo.setQuestionId(questionId);
-//
-//        BokTq bokTq = new BokTq(vo);
-//        restRequestUtil.sendPutRequest(tqUrl + questionId, bokTq);
-//
-//        return vo;
-//
-//    }
-//
-//    @Transactional(isolation = Isolation.SERIALIZABLE, rollbackFor = Exception.class)
-//    public BaseQuestionVO putQuestion(BaseQuestionVO vo) throws JsonProcessingException {
-//        if (vo.getQuestionId() == null) {
-//            throw HelperException.of(ExceptionType.PARAM_ERROR, "should POST a present question");
-//        }
-//        String questionId = vo.getQuestionId();
-//        try {
-//            restRequestUtil.sendGetRequest(tqUrl + questionId, new HashMap<>());
-//        } catch (HttpClientErrorException e) {
-//            if (e.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
-//                throw HelperException.of(ExceptionType.PARAM_ERROR, "should POST a present question");
-//            }
-//        }
-//        restRequestUtil.sendPutRequest(tqUrl + questionId, new BokTq(vo));
-//
-//        cacheUtils.remove(CACHE_NAME, questionId);
-//        return vo;
-//    }
-//
-//    public void deleteQuestion(String questionId) {
-//        try {
-//            restRequestUtil.sendDeleteRequest(tqUrl + questionId);
-//        } catch (JsonProcessingException e) {
-//            throw HelperException.of(ExceptionType.ERROR, "请求BOK题库数据错误:" + e.getMessage());
-//        }
-//        cacheUtils.remove(CACHE_NAME, questionId);
-//    }
+    public void deleteQuestion(String questionId) {
+        restRequestUtil.sendDeleteRequest(tqUrl + questionId);
+    }
+
+    private BokQuestion getQuestion(BaseQuestionDTO baseQuestionDTO) {
+        BokQuestion bokQuestion = new BokQuestion();
+        bokQuestion.setType(baseQuestionDTO.getType());
+        bokQuestion.setStem(baseQuestionDTO.getStem());
+
+        final QuestionType questionType = QuestionType.getQuestionType(baseQuestionDTO.getType());
+        switch (Objects.requireNonNull(questionType)) {
+            case CHOICE:
+                ChoiceQuestionDTO choiceQuestionDTO = (ChoiceQuestionDTO) baseQuestionDTO;
+                bokQuestion.setOptions(choiceQuestionDTO.getOptions());
+                bokQuestion.setAnswer(choiceQuestionDTO.getAnswer());
+                bokQuestion.setAnalysis(choiceQuestionDTO.getAnalysis());
+                break;
+            case TRUE_FALSE:
+                TrueOrFalseQuestionDTO trueOrFalseQuestionDTO = (TrueOrFalseQuestionDTO) baseQuestionDTO;
+                bokQuestion.setAnswer(String.valueOf(trueOrFalseQuestionDTO.getAnswer()));
+                bokQuestion.setAnalysis(trueOrFalseQuestionDTO.getAnalysis());
+                break;
+            default:
+                throw HelperException.of(ExceptionType.ERROR, "不支持的题目类型");
+        }
+        return bokQuestion;
+    }
 
     @Data
     private static class BokSearchResult {
-        private Embedded _embedded;
+        @JsonProperty("_embedded")
+        private Embedded embedded;
         private Page page;
 
         @Data

+ 12 - 16
src/main/java/nju/seec/helper/util/RestRequestUtil.java

@@ -1,38 +1,34 @@
 package nju.seec.helper.util;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
-import org.springframework.http.*;
 import org.springframework.stereotype.Component;
 import org.springframework.web.client.RestTemplate;
 
-import java.util.List;
 import java.util.Map;
 
+/**
+ * @author xst
+ * <p>
+ * updated by cst
+ */
 @Component
 public class RestRequestUtil {
-
-    public List sendPostRequest(String url, Object params) throws JsonProcessingException {
+    public <T> T sendPostRequest(String url, Object request, Class<T> responseType) {
         RestTemplate client = new RestTemplate();
-        HttpHeaders headers = new HttpHeaders();
-        HttpMethod method = HttpMethod.POST;
-        headers.setContentType(MediaType.APPLICATION_JSON);
-        HttpEntity<Object> requestEntity = new HttpEntity<>(params, headers);
-        ResponseEntity ret = client.postForEntity(url, requestEntity, List.class);
-        return (List) ret.getBody();
+        return client.postForObject(url, request, responseType);
     }
 
-    public void sendPutRequest(String url, Object params) throws JsonProcessingException {
+    public void sendPutRequest(String url, Object request) {
         RestTemplate client = new RestTemplate();
-        client.put(url, params);
+        client.put(url, request);
     }
 
-    public void sendDeleteRequest(String url) throws JsonProcessingException {
+    public void sendDeleteRequest(String url) {
         RestTemplate client = new RestTemplate();
         client.delete(url);
     }
 
-    public <T> T sendGetRequest(String url, Class<T> responseType, Map<String, String> urlParams) {
+    public <T> T sendGetRequest(String url, Class<T> responseType, Map<String, ?> uriVariables) {
         RestTemplate client = new RestTemplate();
-        return client.getForObject(url, responseType, urlParams);
+        return client.getForObject(url, responseType, uriVariables);
     }
 }

+ 30 - 1
src/main/java/nju/seec/helper/util/enums/QuestionType.java

@@ -1,8 +1,37 @@
 package nju.seec.helper.util.enums;
 
+import com.fasterxml.jackson.annotation.JsonValue;
+
 /**
  * @author cst
  */
 public enum QuestionType {
-    CHOICE, TRUE_FALSE, SUBJECTIVE
+    /**
+     * 单选
+     */
+    CHOICE("choice"),
+    /**
+     * 判断
+     */
+    TRUE_FALSE("true_false");
+
+    private String value;
+
+    QuestionType(String value) {
+        this.value = value;
+    }
+
+    @JsonValue
+    public String getValue() {
+        return value;
+    }
+
+    public static QuestionType getQuestionType(String value) {
+        for (QuestionType questionType : QuestionType.values()) {
+            if (questionType.getValue().equals(value)) {
+                return questionType;
+            }
+        }
+        return null;
+    }
 }

+ 0 - 13
src/main/java/nju/seec/helper/vo/question/BaseQuestionVO.java

@@ -24,24 +24,11 @@ public abstract class BaseQuestionVO {
                 return new ChoiceQuestionVO(bokQuestion, withAnswer);
             case "true_false":
                 return new TrueOrFalseQuestionVO(bokQuestion, withAnswer);
-//            case "subjective":
-//                return new SubjectiveQuestionVO(bokQuestion, withAnswer);
             default:
                 throw HelperException.of(ExceptionType.ERROR, "无法解析该题目");
         }
     }
 
-//    public static BaseQuestionVO convertBaseQuestionToVO(@NonNull BaseQuestion baseQuestion, boolean withAnswer) {
-//        switch (baseQuestion.getType()) {
-//            case CHOICE:
-//                return new ChoiceQuestionVO((ChoiceQuestion) baseQuestion, withAnswer);
-//            case TRUE_FALSE:
-//                return new TrueOrFalseQuestionVO((TrueOrFalseQuestion) baseQuestion, withAnswer);
-//            default:
-//                throw HelperException.of(ExceptionType.ERROR,"暂不支持该类型的题目");
-//        }
-//    }
-
     /**
      * 检查答案是否正确
      *

+ 0 - 18
src/main/java/nju/seec/helper/vo/question/ChoiceQuestionVO.java

@@ -30,26 +30,8 @@ public class ChoiceQuestionVO extends BaseQuestionVO {
         }
     }
 
-//    public ChoiceQuestionVO(ChoiceQuestion baseQuestion, boolean withAnswer) {
-//        this.id = String.valueOf(baseQuestion.getId());
-//        this.type = QuestionType.CHOICE;
-//        this.stem = baseQuestion.getStem();
-//        this.options = baseQuestion.getOptions();
-//
-//        if (withAnswer) {
-//            this.answer = baseQuestion.getAnswer();
-//            this.analysis = baseQuestion.getAnalysis();
-//        }
-//    }
-
     @Override
     public boolean pass(Object answer) {
         return this.answer.equals(String.valueOf(answer));
     }
 }
-//kind: "CHOICE";
-//  options: {
-//    [key: string]: string;
-//  };
-//  answer: string; // 答案 [与 options 的 key 一致]
-//  analysis?: string; // 解析

+ 0 - 27
src/main/java/nju/seec/helper/vo/question/SubjectiveQuestionVO.java

@@ -1,27 +0,0 @@
-//package nju.seec.helper.vo.question;
-//
-//import lombok.Data;
-//import lombok.EqualsAndHashCode;
-//import lombok.NonNull;
-//import nju.seec.helper.util.enums.QuestionType;
-//
-//import java.io.Serializable;
-//
-///**
-// * @author cst
-// */
-//@EqualsAndHashCode(callSuper = true)
-//@Data
-//public class SubjectiveQuestionVO extends BaseQuestionVO implements Serializable {
-//    private static final long serialVersionUID = -7173121632346669906L;
-//
-//    public SubjectiveQuestionVO(@NonNull BokQuestion bokQuestion, boolean withAnswer) {
-//        this.id = bokQuestion.getTqId();
-//        this.type = QuestionType.SUBJECTIVE;
-//        this.stem = bokQuestion.getStem();
-//
-//        if (withAnswer) {
-//            this.analysis = bokQuestion.getAnalysis();
-//        }
-//    }
-//}

+ 1 - 37
src/main/java/nju/seec/helper/vo/question/TrueOrFalseQuestionVO.java

@@ -4,7 +4,6 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NonNull;
 import nju.seec.helper.util.enums.QuestionType;
-//import nju.seec.helper.entity.QuizStudentAnswer;
 
 /**
  * @author xst
@@ -15,17 +14,7 @@ import nju.seec.helper.util.enums.QuestionType;
 @Data
 public class TrueOrFalseQuestionVO extends BaseQuestionVO {
     private Boolean answer;
-
-//    public TrueOrFalseQuestionVO(TrueOrFalseQuestion baseQuestion, boolean withAnswer) {
-//        this.id = String.valueOf(baseQuestion.getId());
-//        this.type = QuestionType.TRUE_FALSE;
-//        this.stem = baseQuestion.getStem();
-//
-//        if (withAnswer) {
-//            this.answer = baseQuestion.getAnswer();
-//            this.analysis = baseQuestion.getAnalysis();
-//        }
-//    }
+    private String analysis;
 
     @Override
     public boolean pass(Object answer) {
@@ -42,29 +31,4 @@ public class TrueOrFalseQuestionVO extends BaseQuestionVO {
             this.analysis = bokQuestion.getAnalysis();
         }
     }
-//    @JsonProperty(value = "studentAnswer")
-//    private Boolean studentAnswer;
-//    @JsonProperty(value = "pass")
-//    private Boolean pass;
-
-//    @Override
-//    public void exAddAnswer(QuizStudentAnswer answer) {
-//        this.pass = answer.getPass();
-//        this.studentAnswer = Boolean.valueOf(answer.getStudentAnswer());
-//    }
-//
-//    @Override
-//    public boolean checkAnswer(Object answer) {
-//        if (answer == null) {
-//            return false;
-//        }
-//        return this.answer.toString().toLowerCase().equals(answer.toString().toLowerCase());
-//    }
-//
-//    @Override
-//    public void excludeCorrectAnswer() {
-//        this.answer = null;
-//        this.pass = null;
-//        this.analysis = null;
-//    }
 }

+ 0 - 35
src/main/java/nju/seec/helper/vo/quiz/QuizVO.java

@@ -43,39 +43,4 @@ public class QuizVO {
         this.createAt = quiz.getCreateAt();
         this.updateAt = quiz.getUpdateAt();
     }
-
-//    public void excludeCorrectAnswer() {
-//        questions.forEach(BaseQuestionVO::excludeCorrectAnswer);
-//    }
 }
-// http://47.100.18.120:3000/SEEC-BOK/API-DOC/src/master/helper/serializer/QuizSerializer.md
-// /** 已实现的枚举类 */
-//    type SlideState =
-//  | "DRAFT"
-//          | "BEFORE_CLASS" // 课前
-//          | "IN_CLASS" // 课中
-//          | "AFTER_CLASS" // 课后
-//          | "FINISH"; // 最终截止
-//
-//          type QuizState =
-//          | "NOT_STARTED" // 未开始
-//          | "ONGOING" // 正在进行
-//          | "CLOSED"; // 已结束
-//
-//interface QuizSerializer<T extends QuizState> {
-//    id: number;
-//    name: string; // 测试名
-//    state: T; // 考试状态
-//    course: CourseSerializer; // 课程详情
-//    quizTime: SlideState;
-//    slide: SlideSerializer;
-//    questions: Array<
-//            T extends "CLOSED"
-//            ? QuestionWithStudentAnswerSerializer
-//      : QuestionWithoutAnswerSerializer
-//  >;
-//}
-//
-//interface QuizBasicSerialzer extends Omit<QuizSerialzier, "questions"> {
-//        questionNumber: number; // 题目数量
-//        }