Browse Source

feat(server): 完成做题流程

Go 5 years ago
parent
commit
3b3f0f9835
29 changed files with 579 additions and 154 deletions
  1. 63 63
      server/data/src/main/java/com/qxgmat/data/dao/entity/UserReport.java
  2. 6 6
      server/data/src/main/java/com/qxgmat/data/dao/mapping/UserReportMapper.xml
  3. 6 0
      server/data/src/main/java/com/qxgmat/data/relation/QuestionNoRelationMapper.java
  4. 6 0
      server/data/src/main/java/com/qxgmat/data/relation/QuestionRelationMapper.java
  5. 16 0
      server/data/src/main/java/com/qxgmat/data/relation/SentenceQuestionRelationMapper.java
  6. 8 0
      server/data/src/main/java/com/qxgmat/data/relation/UserPaperRelationMapper.java
  7. 7 0
      server/data/src/main/java/com/qxgmat/data/relation/UserReportRelationMapper.java
  8. 11 0
      server/data/src/main/java/com/qxgmat/data/relation/mapping/QuestionNoRelationMapper.xml
  9. 10 0
      server/data/src/main/java/com/qxgmat/data/relation/mapping/QuestionRelationMapper.xml
  10. 28 0
      server/data/src/main/java/com/qxgmat/data/relation/mapping/SentenceQuestionRelationMapper.xml
  11. 12 0
      server/data/src/main/java/com/qxgmat/data/relation/mapping/UserPaperRelationMapper.xml
  12. 11 0
      server/data/src/main/java/com/qxgmat/data/relation/mapping/UserReportRelationMapper.xml
  13. 12 3
      server/gateway-api/src/main/java/com/qxgmat/controller/api/QuestionController.java
  14. 11 1
      server/gateway-api/src/main/java/com/qxgmat/controller/api/SentenceController.java
  15. 32 20
      server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserReportExtendDto.java
  16. 10 0
      server/gateway-api/src/main/java/com/qxgmat/dto/request/QuestionSubmitDto.java
  17. 13 0
      server/gateway-api/src/main/java/com/qxgmat/dto/request/ReportContinueDto.java
  18. 69 0
      server/gateway-api/src/main/java/com/qxgmat/dto/response/UserReportDto.java
  19. 8 0
      server/gateway-api/src/main/java/com/qxgmat/service/UserPaperService.java
  20. 17 0
      server/gateway-api/src/main/java/com/qxgmat/service/UserQuestionService.java
  21. 16 0
      server/gateway-api/src/main/java/com/qxgmat/service/annotation/StatReport.java
  22. 12 0
      server/gateway-api/src/main/java/com/qxgmat/service/annotation/SubmitAfterQuestion.java
  23. 13 0
      server/gateway-api/src/main/java/com/qxgmat/service/annotation/SubmitQuestion.java
  24. 131 53
      server/gateway-api/src/main/java/com/qxgmat/service/extend/QuestionFlowService.java
  25. 14 0
      server/gateway-api/src/main/java/com/qxgmat/service/extend/ToolsService.java
  26. 8 5
      server/gateway-api/src/main/java/com/qxgmat/service/inline/QuestionNoService.java
  27. 9 0
      server/gateway-api/src/main/java/com/qxgmat/service/inline/QuestionService.java
  28. 10 3
      server/gateway-api/src/main/java/com/qxgmat/service/inline/SentenceQuestionService.java
  29. 10 0
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserReportService.java

+ 63 - 63
server/data/src/main/java/com/qxgmat/data/dao/entity/UserReport.java

@@ -34,16 +34,22 @@ public class UserReport implements Serializable {
     private Integer moduleId;
 
     /**
-     * 总题目数
+     * 题目编号id列表:json
      */
-    @Column(name = "`total_number`")
-    private Integer totalNumber;
+    @Column(name = "`question_no_ids`")
+    private Integer[] questionNoIds;
+
+    /**
+     * 总题数
+     */
+    @Column(name = "`question_number`")
+    private Integer questionNumber;
 
     /**
      * 预计时常/总时长
      */
-    @Column(name = "`total_time`")
-    private Integer totalTime;
+    @Column(name = "`time`")
+    private Integer time;
 
     /**
      * 已做题目数
@@ -58,12 +64,6 @@ public class UserReport implements Serializable {
     private Integer userTime;
 
     /**
-     * 题目编号id列表:json
-     */
-    @Column(name = "`question_no_ids`")
-    private Integer[] questionNoIds;
-
-    /**
      * 正确题目数
      */
     @Column(name = "`correct_number`")
@@ -175,39 +175,57 @@ public class UserReport implements Serializable {
     }
 
     /**
-     * 获取总题目数
+     * 获取题目编号id列表:json
      *
-     * @return total_number - 总题目数
+     * @return question_no_ids - 题目编号id列表:json
      */
-    public Integer getTotalNumber() {
-        return totalNumber;
+    public Integer[] getQuestionNoIds() {
+        return questionNoIds;
     }
 
     /**
-     * 设置总题目数
+     * 设置题目编号id列表:json
      *
-     * @param totalNumber 总题目数
+     * @param questionNoIds 题目编号id列表:json
      */
-    public void setTotalNumber(Integer totalNumber) {
-        this.totalNumber = totalNumber;
+    public void setQuestionNoIds(Integer[] questionNoIds) {
+        this.questionNoIds = questionNoIds;
+    }
+
+    /**
+     * 获取总题数
+     *
+     * @return question_number - 总题数
+     */
+    public Integer getQuestionNumber() {
+        return questionNumber;
+    }
+
+    /**
+     * 设置总题数
+     *
+     * @param questionNumber 总题数
+     */
+    public void setQuestionNumber(Integer questionNumber) {
+        this.questionNumber = questionNumber;
     }
 
     /**
      * 获取预计时常/总时长
      *
-     * @return total_time - 预计时常/总时长
+     * @return time - 预计时常/总时长
      */
-    public Integer getTotalTime() {
-        return totalTime;
+    public Integer getTime() {
+        return time;
     }
 
     /**
      * 设置预计时常/总时长
      *
-     * @param totalTime 预计时常/总时长
+     * @param time 预计时常/总时长
      */
-    public void setTotalTime(Integer totalTime) {
-        this.totalTime = totalTime;
+    public void setTime(Integer time) {
+        this.time = time;
     }
 
     /**
@@ -247,24 +265,6 @@ public class UserReport implements Serializable {
     }
 
     /**
-     * 获取题目编号id列表:json
-     *
-     * @return question_no_ids - 题目编号id列表:json
-     */
-    public Integer[] getQuestionNoIds() {
-        return questionNoIds;
-    }
-
-    /**
-     * 设置题目编号id列表:json
-     *
-     * @param questionNoIds 题目编号id列表:json
-     */
-    public void setQuestionNoIds(Integer[] questionNoIds) {
-        this.questionNoIds = questionNoIds;
-    }
-
-    /**
      * 获取正确题目数
      *
      * @return correct_number - 正确题目数
@@ -361,11 +361,11 @@ public class UserReport implements Serializable {
         sb.append(", paperId=").append(paperId);
         sb.append(", module=").append(module);
         sb.append(", moduleId=").append(moduleId);
-        sb.append(", totalNumber=").append(totalNumber);
-        sb.append(", totalTime=").append(totalTime);
+        sb.append(", questionNoIds=").append(questionNoIds);
+        sb.append(", questionNumber=").append(questionNumber);
+        sb.append(", time=").append(time);
         sb.append(", userNumber=").append(userNumber);
         sb.append(", userTime=").append(userTime);
-        sb.append(", questionNoIds=").append(questionNoIds);
         sb.append(", correctNumber=").append(correctNumber);
         sb.append(", finishTime=").append(finishTime);
         sb.append(", setting=").append(setting);
@@ -433,22 +433,32 @@ public class UserReport implements Serializable {
         }
 
         /**
-         * 设置总题目数
+         * 设置题目编号id列表:json
          *
-         * @param totalNumber 总题目数
+         * @param questionNoIds 题目编号id列表:json
          */
-        public Builder totalNumber(Integer totalNumber) {
-            obj.setTotalNumber(totalNumber);
+        public Builder questionNoIds(Integer[] questionNoIds) {
+            obj.setQuestionNoIds(questionNoIds);
+            return this;
+        }
+
+        /**
+         * 设置总题数
+         *
+         * @param questionNumber 总题数
+         */
+        public Builder questionNumber(Integer questionNumber) {
+            obj.setQuestionNumber(questionNumber);
             return this;
         }
 
         /**
          * 设置预计时常/总时长
          *
-         * @param totalTime 预计时常/总时长
+         * @param time 预计时常/总时长
          */
-        public Builder totalTime(Integer totalTime) {
-            obj.setTotalTime(totalTime);
+        public Builder time(Integer time) {
+            obj.setTime(time);
             return this;
         }
 
@@ -473,16 +483,6 @@ public class UserReport implements Serializable {
         }
 
         /**
-         * 设置题目编号id列表:json
-         *
-         * @param questionNoIds 题目编号id列表:json
-         */
-        public Builder questionNoIds(Integer[] questionNoIds) {
-            obj.setQuestionNoIds(questionNoIds);
-            return this;
-        }
-
-        /**
          * 设置正确题目数
          *
          * @param correctNumber 正确题目数

+ 6 - 6
server/data/src/main/java/com/qxgmat/data/dao/mapping/UserReportMapper.xml

@@ -10,11 +10,11 @@
     <result column="paper_id" jdbcType="INTEGER" property="paperId" />
     <result column="module" jdbcType="VARCHAR" property="module" />
     <result column="module_id" jdbcType="INTEGER" property="moduleId" />
-    <result column="total_number" jdbcType="INTEGER" property="totalNumber" />
-    <result column="total_time" jdbcType="INTEGER" property="totalTime" />
+    <result column="question_no_ids" jdbcType="VARCHAR" property="questionNoIds" typeHandler="com.nuliji.tools.mybatis.handler.IntegerArrayWithJsonHandler" />
+    <result column="question_number" jdbcType="INTEGER" property="questionNumber" />
+    <result column="time" jdbcType="INTEGER" property="time" />
     <result column="user_number" jdbcType="INTEGER" property="userNumber" />
     <result column="user_time" jdbcType="INTEGER" property="userTime" />
-    <result column="question_no_ids" jdbcType="VARCHAR" property="questionNoIds" typeHandler="com.nuliji.tools.mybatis.handler.IntegerArrayWithJsonHandler" />
     <result column="correct_number" jdbcType="INTEGER" property="correctNumber" />
     <result column="finish_time" jdbcType="TIMESTAMP" property="finishTime" />
     <result column="setting" jdbcType="VARCHAR" property="setting" typeHandler="com.nuliji.tools.mybatis.handler.JsonObjectHandler" />
@@ -25,8 +25,8 @@
     <!--
       WARNING - @mbg.generated
     -->
-    `id`, `user_id`, `paper_id`, `module`, `module_id`, `total_number`, `total_time`, 
-    `user_number`, `user_time`, `question_no_ids`, `correct_number`, `finish_time`, `setting`, 
-    `detail`, `create_time`
+    `id`, `user_id`, `paper_id`, `module`, `module_id`, `question_no_ids`, `question_number`, 
+    `time`, `user_number`, `user_time`, `correct_number`, `finish_time`, `setting`, `detail`, 
+    `create_time`
   </sql>
 </mapper>

+ 6 - 0
server/data/src/main/java/com/qxgmat/data/relation/QuestionNoRelationMapper.java

@@ -11,4 +11,10 @@ import java.util.List;
  */
 public interface QuestionNoRelationMapper {
 
+    void accumulation(
+            @Param("id") Number questionNoId,
+            @Param("number") Integer number,
+            @Param("time") Integer time,
+            @Param("current") Integer current
+    );
 }

+ 6 - 0
server/data/src/main/java/com/qxgmat/data/relation/QuestionRelationMapper.java

@@ -10,4 +10,10 @@ import java.util.List;
  */
 public interface QuestionRelationMapper {
 
+    void accumulation(
+            @Param("id") Number questionId,
+            @Param("number") Integer number,
+            @Param("time") Integer time,
+            @Param("current") Integer current
+    );
 }

+ 16 - 0
server/data/src/main/java/com/qxgmat/data/relation/SentenceQuestionRelationMapper.java

@@ -0,0 +1,16 @@
+package com.qxgmat.data.relation;
+
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * Created by gaojie on 2017/11/9.
+ */
+public interface SentenceQuestionRelationMapper {
+
+    void accumulation(
+            @Param("id") Number sentenceQuestionId,
+            @Param("number") Integer number,
+            @Param("time") Integer time,
+            @Param("current") Integer current
+    );
+}

+ 8 - 0
server/data/src/main/java/com/qxgmat/data/relation/UserPaperRelationMapper.java

@@ -38,4 +38,12 @@ public interface UserPaperRelationMapper {
             @Param("logicExtend") String logicExtend,
             @Param("times") Integer times
     );
+
+    void accumulation(
+            @Param("id") Number userPaperId,
+            @Param("number") Integer number,
+            @Param("time") Integer time,
+            @Param("current") Integer current,
+            @Param("times") Integer times
+    );
 }

+ 7 - 0
server/data/src/main/java/com/qxgmat/data/relation/UserReportRelationMapper.java

@@ -19,4 +19,11 @@ public interface UserReportRelationMapper {
     List<UserReport> listLast(
             @Param("paperIds") Collection paperIds
     );
+
+    void accumulation(
+            @Param("id") Number reportId,
+            @Param("number") Integer number,
+            @Param("time") Integer time,
+            @Param("current") Integer current
+    );
 }

+ 11 - 0
server/data/src/main/java/com/qxgmat/data/relation/mapping/QuestionNoRelationMapper.xml

@@ -14,4 +14,15 @@
     qn.`id`
   </sql>
 
+  <!--累加做题记录-->
+  <update id="accumulation">
+    UPDATE `question_no`
+    <trim prefix="set" suffixOverrides=",">
+      `total_number`=`total_number`+#{number, jdbcType=INTEGER},
+      `total_time`=`total_time`+#{time, jdbcType=INTEGER},
+      `total_correct`=`total_correct`+#{correct, jdbcType=INTEGER},
+    </trim>
+    WHERE `id` = #{id, jdbcType=VARCHAR}
+  </update>
+
 </mapper>

+ 10 - 0
server/data/src/main/java/com/qxgmat/data/relation/mapping/QuestionRelationMapper.xml

@@ -14,4 +14,14 @@
     q.`id`
   </sql>
 
+  <!--累加做题记录-->
+  <update id="accumulation">
+    UPDATE `question_no`
+    <trim prefix="set" suffixOverrides=",">
+      `total_number`=`total_number`+#{number, jdbcType=INTEGER},
+      `total_time`=`total_time`+#{time, jdbcType=INTEGER},
+      `total_correct`=`total_correct`+#{correct, jdbcType=INTEGER},
+    </trim>
+    WHERE `id` = #{id, jdbcType=VARCHAR}
+  </update>
 </mapper>

+ 28 - 0
server/data/src/main/java/com/qxgmat/data/relation/mapping/SentenceQuestionRelationMapper.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qxgmat.data.relation.SentenceQuestionRelationMapper">
+  <resultMap id="IdMap" type="com.qxgmat.data.dao.entity.SentenceQuestion">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="id" jdbcType="INTEGER" property="id" />
+  </resultMap>
+  <sql id="Id_Column_List">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    sq.`id`
+  </sql>
+
+  <!--累加做题记录-->
+  <update id="accumulation">
+    UPDATE `sentence_question`
+    <trim prefix="set" suffixOverrides=",">
+      `total_number`=`total_number`+#{number, jdbcType=INTEGER},
+      `total_time`=`total_time`+#{time, jdbcType=INTEGER},
+      `total_correct`=`total_correct`+#{correct, jdbcType=INTEGER},
+    </trim>
+    WHERE `id` = #{id, jdbcType=VARCHAR}
+  </update>
+
+</mapper>

+ 12 - 0
server/data/src/main/java/com/qxgmat/data/relation/mapping/UserPaperRelationMapper.xml

@@ -14,6 +14,18 @@
     up.`id`
   </sql>
 
+  <!--累加做题记录-->
+  <update id="accumulation">
+    UPDATE `user_paper`
+    <trim prefix="set" suffixOverrides=",">
+      `total_number`=`total_number`+#{number, jdbcType=INTEGER},
+      `total_time`=`total_time`+#{time, jdbcType=INTEGER},
+      `total_correct`=`total_correct`+#{correct, jdbcType=INTEGER},
+      `times` = `times`+#{times, jdbcType=INTEGER},
+    </trim>
+    WHERE `id` = #{id, jdbcType=VARCHAR}
+  </update>
+
   <!--
     用户预习作业列表: 后台
     https://blog.csdn.net/t_1007/article/details/52369261

+ 11 - 0
server/data/src/main/java/com/qxgmat/data/relation/mapping/UserReportRelationMapper.xml

@@ -14,6 +14,17 @@
     ur.`id`
   </sql>
 
+  <!--累加做题记录-->
+  <update id="accumulation">
+    UPDATE `user_report`
+    <trim prefix="set" suffixOverrides=",">
+      `user_number`=`user_number`+#{number, jdbcType=INTEGER},
+      `user_time`=`user_time`+#{time, jdbcType=INTEGER},
+      `user_correct`=`user_correct`+#{correct, jdbcType=INTEGER},
+    </trim>
+    WHERE `id` = #{id, jdbcType=VARCHAR}
+  </update>
+
   <!--
     用户完成度最高的最后一次
     https://blog.csdn.net/t_1007/article/details/52369261

+ 12 - 3
server/gateway-api/src/main/java/com/qxgmat/controller/api/QuestionController.java

@@ -196,7 +196,7 @@ public class QuestionController {
 
     @RequestMapping(value = "/exercise/start", method = RequestMethod.POST)
     @ApiOperation(value = "开始: 练习", notes = "提交考试设置", httpMethod = "POST")
-    public Response<UserReportDto> start(@RequestBody @Validated ExerciseStartDto dto)  {
+    public Response<UserReportDto> startExercise(@RequestBody @Validated ExerciseStartDto dto)  {
         User user = (User) shiroHelp.getLoginUser();
         JSONObject setting = new JSONObject();
         setting.put("disorder", dto.getDisorder());
@@ -207,7 +207,7 @@ public class QuestionController {
 
     @RequestMapping(value = "/preview/start", method = RequestMethod.POST)
     @ApiOperation(value = "开始: 预习作业", notes = "提交考试设置", httpMethod = "POST")
-    public Response<UserReportDto> start(@RequestBody @Validated PreviewStartDto dto)  {
+    public Response<UserReportDto> startPreview(@RequestBody @Validated PreviewStartDto dto)  {
         User user = (User) shiroHelp.getLoginUser();
         JSONObject setting = new JSONObject();
         setting.put("disorder", dto.getDisorder());
@@ -216,6 +216,15 @@ public class QuestionController {
         return ResponseHelp.success(Transform.convert(report, UserReportDto.class));
     }
 
+    @RequestMapping(value = "/continue", method = RequestMethod.POST)
+    @ApiOperation(value = "继续做题", notes = "获取报告信息", httpMethod = "POST")
+    public Response<UserReportDto> continueReport(@RequestBody @Validated ReportContinueDto dto)  {
+        User user = (User) shiroHelp.getLoginUser();
+        UserReport report = questionFlowService.continueReport(user.getId(), dto.getUserReportId());
+
+        return ResponseHelp.success(Transform.convert(report, UserReportDto.class));
+    }
+
     @RequestMapping(value = "/next", method = RequestMethod.POST)
     @ApiOperation(value = "获取下一题", notes = "获取下一题", httpMethod = "POST")
     public Response<UserQuestionBaseDto> next(@RequestBody @Validated ReportNextDto dto)  {
@@ -237,7 +246,7 @@ public class QuestionController {
     @ApiOperation(value = "提交题目答案", notes = "提交题目", httpMethod = "POST")
     public Response<Boolean> submit(@RequestBody @Validated QuestionSubmitDto dto)  {
         User user = (User) shiroHelp.getLoginUser();
-        Boolean result = questionFlowService.submit(user.getId(), dto.getUserQuestionId(), dto.getAnswer());
+        Boolean result = questionFlowService.submit(user.getId(), dto.getUserQuestionId(), dto.getTime(), dto.getAnswer());
         return ResponseHelp.success(result);
     }
 

+ 11 - 1
server/gateway-api/src/main/java/com/qxgmat/controller/api/SentenceController.java

@@ -175,6 +175,16 @@ public class SentenceController
         return ResponseHelp.success(Transform.convert(report, UserReportDto.class));
     }
 
+
+    @RequestMapping(value = "/paper/continue", method = RequestMethod.POST)
+    @ApiOperation(value = "继续做题", notes = "获取报告信息", httpMethod = "POST")
+    public Response<UserReportDto> continueReport(@RequestBody @Validated ReportContinueDto dto)  {
+        User user = (User) shiroHelp.getLoginUser();
+        UserReport report = questionFlowService.continueReport(user.getId(), dto.getUserReportId());
+
+        return ResponseHelp.success(Transform.convert(report, UserReportDto.class));
+    }
+
     @RequestMapping(value = "/paper/next", method = RequestMethod.POST)
     @ApiOperation(value = "获取下一题", notes = "获取下一题", httpMethod = "POST")
     public Response<UserSentenceQuestionBaseDto> next(@RequestBody @Validated ReportNextDto dto)  {
@@ -195,7 +205,7 @@ public class SentenceController
     @ApiOperation(value = "提交题目答案", notes = "提交题目", httpMethod = "POST")
     public Response<Boolean> submit(@RequestBody @Validated QuestionSubmitDto dto)  {
         User user = (User) shiroHelp.getLoginUser();
-        Boolean result = questionFlowService.submit(user.getId(), dto.getUserQuestionId(), dto.getAnswer());
+        Boolean result = questionFlowService.submit(user.getId(), dto.getUserQuestionId(), dto.getTime(), dto.getAnswer());
         return ResponseHelp.success(result);
     }
 

+ 32 - 20
server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserReportExtendDto.java

@@ -4,20 +4,24 @@ import com.nuliji.tools.annotation.Dto;
 import com.qxgmat.data.dao.entity.UserPaper;
 import com.qxgmat.data.dao.entity.UserReport;
 
+import java.util.Date;
+
 @Dto(entity = UserReport.class)
 public class UserReportExtendDto {
 
     private Integer id;
 
-    private Integer totalNumber;
+    private Integer time;
+
+    private Integer questionNumber;
 
     private Integer userNumber;
 
-    private Integer correctNumber;
+    private Integer userTime;
 
-    private Integer totalTime;
+    private Integer correctNumber;
 
-    private Integer userTime;
+    private Date finishTime;
 
     public Integer getId() {
         return id;
@@ -27,14 +31,6 @@ public class UserReportExtendDto {
         this.id = id;
     }
 
-    public Integer getTotalNumber() {
-        return totalNumber;
-    }
-
-    public void setTotalNumber(Integer totalNumber) {
-        this.totalNumber = totalNumber;
-    }
-
     public Integer getUserNumber() {
         return userNumber;
     }
@@ -51,14 +47,6 @@ public class UserReportExtendDto {
         this.correctNumber = correctNumber;
     }
 
-    public Integer getTotalTime() {
-        return totalTime;
-    }
-
-    public void setTotalTime(Integer totalTime) {
-        this.totalTime = totalTime;
-    }
-
     public Integer getUserTime() {
         return userTime;
     }
@@ -66,4 +54,28 @@ public class UserReportExtendDto {
     public void setUserTime(Integer userTime) {
         this.userTime = userTime;
     }
+
+    public Integer getQuestionNumber() {
+        return questionNumber;
+    }
+
+    public void setQuestionNumber(Integer questionNumber) {
+        this.questionNumber = questionNumber;
+    }
+
+    public Integer getTime() {
+        return time;
+    }
+
+    public void setTime(Integer time) {
+        this.time = time;
+    }
+
+    public Date getFinishTime() {
+        return finishTime;
+    }
+
+    public void setFinishTime(Date finishTime) {
+        this.finishTime = finishTime;
+    }
 }

+ 10 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/request/QuestionSubmitDto.java

@@ -5,6 +5,8 @@ import com.alibaba.fastjson.JSONObject;
 public class QuestionSubmitDto {
     private Integer userQuestionId;
 
+    private Integer time;
+
     private JSONObject answer;
 
     public Integer getUserQuestionId() {
@@ -22,4 +24,12 @@ public class QuestionSubmitDto {
     public void setAnswer(JSONObject answer) {
         this.answer = answer;
     }
+
+    public Integer getTime() {
+        return time;
+    }
+
+    public void setTime(Integer time) {
+        this.time = time;
+    }
 }

+ 13 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/request/ReportContinueDto.java

@@ -0,0 +1,13 @@
+package com.qxgmat.dto.request;
+
+public class ReportContinueDto {
+    private Integer userReportId;
+
+    public Integer getUserReportId() {
+        return userReportId;
+    }
+
+    public void setUserReportId(Integer userReportId) {
+        this.userReportId = userReportId;
+    }
+}

+ 69 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/response/UserReportDto.java

@@ -5,4 +5,73 @@ import com.qxgmat.data.dao.entity.UserReport;
 
 @Dto(entity = UserReport.class)
 public class UserReportDto {
+    private Integer id;
+
+    private Integer paperId;
+
+    private String module;
+
+    private Integer time;
+
+    private Integer questionNumber;
+
+    private Integer userTime;
+
+    private Integer userNumber;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getPaperId() {
+        return paperId;
+    }
+
+    public void setPaperId(Integer paperId) {
+        this.paperId = paperId;
+    }
+
+    public String getModule() {
+        return module;
+    }
+
+    public void setModule(String module) {
+        this.module = module;
+    }
+
+    public Integer getTime() {
+        return time;
+    }
+
+    public void setTime(Integer time) {
+        this.time = time;
+    }
+
+    public Integer getQuestionNumber() {
+        return questionNumber;
+    }
+
+    public void setQuestionNumber(Integer questionNumber) {
+        this.questionNumber = questionNumber;
+    }
+
+    public Integer getUserTime() {
+        return userTime;
+    }
+
+    public void setUserTime(Integer userTime) {
+        this.userTime = userTime;
+    }
+
+    public Integer getUserNumber() {
+        return userNumber;
+    }
+
+    public void setUserNumber(Integer userNumber) {
+        this.userNumber = userNumber;
+    }
 }

+ 8 - 0
server/gateway-api/src/main/java/com/qxgmat/service/UserPaperService.java

@@ -95,6 +95,14 @@ public class UserPaperService extends AbstractService {
     }
 
     /**
+     * 累加做题记录到paper
+     * @param report
+     */
+    public void accumulation(UserReport report){
+        userPaperRelationMapper.accumulation(report.getPaperId(), report.getUserNumber(), report.getUserTime(), report.getCorrectNumber(), 1);
+    }
+
+    /**
      * 批量删除用户记录:homework切换可用学生
      * @param userIds
      * @param module

+ 17 - 0
server/gateway-api/src/main/java/com/qxgmat/service/UserQuestionService.java

@@ -83,6 +83,23 @@ public class UserQuestionService extends AbstractService {
         return add(question);
     }
 
+    /**
+     * 获取报告的所有做题记录
+     * @param userId
+     * @param userReportId
+     * @return
+     */
+    public List<UserQuestion> listByReport(Integer userId, Integer userReportId){
+        Example example = new Example(UserQuestion.class);
+        example.and(
+                example.createCriteria()
+                        .andEqualTo("userId", userId)
+                        .andEqualTo("paper_id", userReportId)
+        );
+        example.orderBy("id").asc();
+        return select(userQuestionMapper, example);
+    }
+
     public UserQuestion add(UserQuestion question){
         int result = insert(userQuestionMapper, question);
         question = one(userQuestionMapper, question.getId());

+ 16 - 0
server/gateway-api/src/main/java/com/qxgmat/service/annotation/StatReport.java

@@ -0,0 +1,16 @@
+package com.qxgmat.service.annotation;
+
+
+import com.qxgmat.data.dao.entity.UserPaper;
+import com.qxgmat.data.dao.entity.UserQuestion;
+import com.qxgmat.data.dao.entity.UserReport;
+
+import java.util.List;
+
+/**
+ * Created by gaojie on 2017/11/20.
+ */
+@FunctionalInterface
+public interface StatReport {
+    void callback(UserReport report, List<UserQuestion> userQuestionList);
+}

+ 12 - 0
server/gateway-api/src/main/java/com/qxgmat/service/annotation/SubmitAfterQuestion.java

@@ -0,0 +1,12 @@
+package com.qxgmat.service.annotation;
+
+
+import com.qxgmat.data.dao.entity.UserQuestion;
+
+/**
+ * Created by gaojie on 2017/11/20.
+ */
+@FunctionalInterface
+public interface SubmitAfterQuestion {
+    void callback(UserQuestion question);
+}

+ 13 - 0
server/gateway-api/src/main/java/com/qxgmat/service/annotation/SubmitQuestion.java

@@ -0,0 +1,13 @@
+package com.qxgmat.service.annotation;
+
+
+import com.qxgmat.data.dao.entity.UserQuestion;
+import com.qxgmat.data.dao.entity.UserReport;
+
+/**
+ * Created by gaojie on 2017/11/20.
+ */
+@FunctionalInterface
+public interface SubmitQuestion {
+    boolean callback(UserQuestion question);
+}

+ 131 - 53
server/gateway-api/src/main/java/com/qxgmat/service/extend/QuestionFlowService.java

@@ -5,16 +5,12 @@ import com.nuliji.tools.exception.ParameterException;
 import com.qxgmat.data.constants.enums.SettingKey;
 import com.qxgmat.data.constants.enums.module.PaperModule;
 import com.qxgmat.data.constants.enums.module.QuestionModule;
-import com.qxgmat.data.dao.entity.QuestionNo;
-import com.qxgmat.data.dao.entity.UserPaper;
-import com.qxgmat.data.dao.entity.UserQuestion;
-import com.qxgmat.data.dao.entity.UserReport;
+import com.qxgmat.data.dao.entity.*;
 import com.qxgmat.data.relation.entity.QuestionNoRelation;
 import com.qxgmat.service.*;
-import com.qxgmat.service.annotation.InitPaper;
-import com.qxgmat.service.annotation.InitQuestion;
-import com.qxgmat.service.annotation.InitReport;
+import com.qxgmat.service.annotation.*;
 import com.qxgmat.service.inline.QuestionNoService;
+import com.qxgmat.service.inline.QuestionService;
 import com.qxgmat.service.inline.SentenceQuestionService;
 import com.qxgmat.service.inline.UserReportService;
 import com.qxgmat.util.annotation.Callback;
@@ -41,6 +37,9 @@ public class QuestionFlowService {
     private QuestionNoService questionNoService;
 
     @Resource
+    private QuestionService questionService;
+
+    @Resource
     private SentenceQuestionService sentenceQuestionService;
 
     @Resource
@@ -64,14 +63,17 @@ public class QuestionFlowService {
     // 初始化报告的callback,根据试卷模块进行后续处理
     private Map<PaperModule, InitReport> initReportCallback = new HashMap<>();
 
-    // 根据
+    // 初始化题目,根据试卷模块进行选题处理
     private Map<PaperModule, InitQuestion> nextCallback = new HashMap<>();
 
-    // 完成试卷的callback,根据试卷模块进行后续处理
-    private Map<PaperModule, Callback> finishCallback = new HashMap<>();
+    // 提交答题的callback,根据试题模块正确判断
+    private Map<QuestionModule, SubmitQuestion> submitCallback = new HashMap<>();
 
-    // 提交答题的callback,根据试题模块进行后续处理
-    private Map<QuestionModule, Callback> submitCallback;
+    // 提交答题的callback,根据试题模块后续统计,会过滤满足剔除条件
+    private Map<QuestionModule, SubmitAfterQuestion> submitAfterCallback = new HashMap<>();
+
+    // 完成试卷的callback,根据试卷模块进行后续处理
+    private Map<PaperModule, StatReport> finishCallback = new HashMap<>();
 
     public QuestionFlowService(){
         initPaperCallback.put(PaperModule.EXERCISE, (paper, id)->{
@@ -129,71 +131,75 @@ public class QuestionFlowService {
         nextCallback.put(PaperModule.EXERCISE, (question, report, lastQuestion)->{
             Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
             if (questionNoId == 0) return false;
-            QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId);
-            question.setQuestionNoId(relation.getId());
-            question.setQuestionId(relation.getQuestionId());
-            Integer time = toolsService.computerTime(SettingKey.EXERCISE_TIME, relation);
-            question.setTime(time);
+            this.bindQuestionNo(question, questionNoId, SettingKey.EXERCISE_TIME);
             return true;
         });
         nextCallback.put(PaperModule.HOMEWORK_PREVIEW, (question, report, lastQuestion)->{
             Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
             if (questionNoId == 0) return false;
-            QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId);
-            question.setQuestionNoId(relation.getId());
-            question.setQuestionId(relation.getQuestionId());
-            Integer time = toolsService.computerTime(SettingKey.EXERCISE_TIME, relation);
-            question.setTime(time);
+            this.bindQuestionNo(question, questionNoId, SettingKey.EXERCISE_TIME);
             return true;
         });
         nextCallback.put(PaperModule.COLLECT, (question, report, lastQuestion)->{
             Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
             if (questionNoId == 0) return false;
-            QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId);
-            question.setQuestionNoId(relation.getId());
-            question.setQuestionId(relation.getQuestionId());
-            Integer time = toolsService.computerTime(SettingKey.getTimeByPaperModule(PaperModule.ValueOf(relation.getModule())), relation);
-            question.setTime(time);
+            // 根据扩展确定exercise还是examination
+            UserPaper paper = userPaperService.get(report.getPaperId());
+            this.bindQuestionNo(question, questionNoId, SettingKey.getTimeByPaperModule(PaperModule.ValueOf(paper.getModuleExtend())));
             return true;
         });
         nextCallback.put(PaperModule.ERROR, (question, report, lastQuestion)->{
             Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
             if (questionNoId == 0) return false;
-            QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId);
-            question.setQuestionNoId(relation.getId());
-            question.setQuestionId(relation.getQuestionId());
-            Integer time = toolsService.computerTime(SettingKey.getTimeByPaperModule(PaperModule.ValueOf(relation.getModule())), relation);
-            question.setTime(time);
+            // 根据扩展确定exercise还是examination
+            UserPaper paper = userPaperService.get(report.getPaperId());
+            this.bindQuestionNo(question, questionNoId, SettingKey.getTimeByPaperModule(PaperModule.ValueOf(paper.getModuleExtend())));
             return true;
         });
         nextCallback.put(PaperModule.SENTENCE, (question, report, lastQuestion)->{
             Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
             if (questionNoId == 0) return false;
-            QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId);
+            SentenceQuestion relation = sentenceQuestionService.get(questionNoId);
             question.setQuestionNoId(relation.getId());
             question.setQuestionId(relation.getQuestionId());
             question.setTime(0);
             return true;
         });
 
-        finishCallback.put(PaperModule.EXERCISE, (obj)->{
-            return exercisePaperService.finished((UserPaper) obj);
-        });
-        finishCallback.put(PaperModule.HOMEWORK_PREVIEW, (obj)->{
-            return homeworkPreviewService.finished((UserPaper) obj);
+        submitCallback.put(QuestionModule.BASE, (userQuestion)->{
+            // 判断答题情况
+            JSONObject answer = userQuestion.getUserAnswer();
+            Question question = questionService.get(userQuestion.getQuestionId());
+
+            return true;
         });
-        finishCallback.put(PaperModule.EXAMINATION, (obj)->{
-            return homeworkPreviewService.finished((UserPaper) obj);
+        submitCallback.put(QuestionModule.SENTENCE, (userQuestion)->{
+            // 判断答题情况
+            JSONObject answer = userQuestion.getUserAnswer();
+            Question question = questionService.get(userQuestion.getQuestionId());
+
+            return true;
         });
 
-        submitCallback = new HashMap<>();
-        submitCallback.put(QuestionModule.BASE, (obj)->{
+        submitAfterCallback.put(QuestionModule.BASE, (userQuestion)->{
             // 更新题目及题目编号统计
-            return questionNoService.submit((UserQuestion) obj);
+            questionNoService.accumulation(userQuestion);
+            questionService.accumulation(userQuestion);
         });
-        submitCallback.put(QuestionModule.SENTENCE, (obj)->{
+        submitAfterCallback.put(QuestionModule.SENTENCE, (userQuestion)->{
             // 更新题目及题目编号统计
-            return sentenceQuestionService.submit((UserQuestion) obj);
+            questionService.accumulation(userQuestion);
+            sentenceQuestionService.accumulation(userQuestion);
+        });
+
+        finishCallback.put(PaperModule.EXERCISE, (report, questionList)->{
+            // report
+        });
+        finishCallback.put(PaperModule.HOMEWORK_PREVIEW, (report, questionList)->{
+
+        });
+        finishCallback.put(PaperModule.EXAMINATION, (report, questionList)->{
+
         });
     }
 
@@ -220,6 +226,28 @@ public class QuestionFlowService {
     }
 
     /**
+     * 继续做题:判断是否可以继续
+     * @param userId
+     * @param userReportId
+     * @return
+     */
+    public UserReport continueReport(Integer userId, Integer userReportId){
+        UserReport userReport = userReportService.get(userReportId);
+        if (!userReport.getUserId().equals(userId)){
+            throw new ParameterException("试卷不存在");
+        }
+        if (userReport.getDetail() != null && userReport.getFinishTime() != null){
+            throw new ParameterException("做题结束");
+        }
+        if (userReport.getUserNumber()>=userReport.getQuestionNumber()){
+            throw new ParameterException("答题结束,请提交完成");
+        }
+
+
+        return userReport;
+    }
+
+    /**
      * 获取report的下一道题
      * @param userId
      * @param userReportId
@@ -231,6 +259,9 @@ public class QuestionFlowService {
         if (userQuestion==null || userQuestion.getUserTime() >0){
             // 创建新的question
             UserReport report = userReportService.get(userReportId);
+            if (!report.getUserId().equals(userId)){
+                throw new ParameterException("试卷不存在");
+            }
             userQuestion = userQuestionService.addByReport(report, userQuestion, nextCallback.get(PaperModule.ValueOf(report.getModule())));
         }
 
@@ -245,18 +276,31 @@ public class QuestionFlowService {
      * @return
      */
     @Transactional
-    public Boolean submit(Integer userId, Integer userQuestionId, JSONObject answer){
+    public Boolean submit(Integer userId, Integer userQuestionId, Integer time, JSONObject answer){
         UserQuestion userQuestion = userQuestionService.get(userQuestionId);
         if (!userQuestion.getUserId().equals(userId)){
             throw new ParameterException("题目不存在");
         }
+        userQuestion.setTime(time);
+        userQuestion.setUserAnswer(answer);
+
         UserReport userReport = userReportService.get(userQuestion.getReportId());
-        // 判断题目是否正确
-        // 更新做题记录
 
+        // 根据report模块获取试题所属模块
         QuestionModule module = QuestionModule.WithPaper(PaperModule.ValueOf(userReport.getModule()));
-        Callback callback = submitCallback.get(module);
-        callback.callback(userQuestion);
+        SubmitQuestion callback = submitCallback.get(module);
+        boolean result = callback.callback(userQuestion);
+        userQuestion.setIsCorrect(result ? 1 : 0);
+        userQuestionService.edit(userQuestion);
+
+        // 根据剔除逻辑判断是否统计
+        if (toolsService.filterTime(userQuestion)){
+            SubmitAfterQuestion afterCallback = submitAfterCallback.get(module);
+            afterCallback.callback(userQuestion);
+        }
+
+        // 更新对应report记录
+        userReportService.accumulation(userQuestion);
         return true;
     }
 
@@ -268,9 +312,24 @@ public class QuestionFlowService {
      */
     @Transactional
     public Boolean finish(Integer userId, Integer userReportId){
-        // 设定paper完成次数加1
-
-        // 统计
+        UserReport userReport = userReportService.get(userReportId);
+        if (!userReport.getUserId().equals(userId)){
+            throw new ParameterException("试卷不存在");
+        }
+        if (!userReport.getQuestionNumber().equals(userReport.getUserNumber())){
+            throw new ParameterException("试卷未完成");
+        }
+        if (userReport.getDetail() != null && userReport.getFinishTime() != null){
+            throw new ParameterException("做题结束");
+        }
+        userReport.setFinishTime(new Date());
+        List<UserQuestion> userQuestionList = userQuestionService.listByReport(userId, userReportId);
+        // 分析做题结果
+        StatReport callback = finishCallback.get(PaperModule.ValueOf(userReport.getModule()));
+        callback.callback(userReport, userQuestionList);
+
+        // 统计: 更新对应paper记录
+        userPaperService.accumulation(userReport);
         return true;
     }
 
@@ -320,4 +379,23 @@ public class QuestionFlowService {
         }
         return 0;
     }
+
+    /**
+     * 关联绑定questionNo类型试题
+     * @param question
+     * @param questionNoId
+     * @param settingKey
+     */
+    private void bindQuestionNo(UserQuestion question, Integer questionNoId, SettingKey settingKey){
+        QuestionNoRelation relation = questionNoService.getWithRelation(questionNoId);
+        question.setQuestionNoId(relation.getId());
+        question.setQuestionId(relation.getQuestionId());
+        if (settingKey != null) {
+            // 根据试题模块信息,获取对应时间key
+            settingKey = SettingKey.getTimeByPaperModule(PaperModule.ValueOf(relation.getModule()));
+        }
+
+        Integer time = toolsService.computerTime(settingKey, relation);
+        question.setTime(time);
+    }
 }

+ 14 - 0
server/gateway-api/src/main/java/com/qxgmat/service/extend/ToolsService.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.qxgmat.data.constants.enums.SettingKey;
 import com.qxgmat.data.dao.entity.QuestionNo;
 import com.qxgmat.data.dao.entity.Setting;
+import com.qxgmat.data.dao.entity.UserQuestion;
 import com.qxgmat.data.relation.entity.QuestionNoRelation;
 import com.qxgmat.service.inline.SettingService;
 import org.springframework.stereotype.Service;
@@ -68,4 +69,17 @@ public class ToolsService {
         if (t == null || t.isEmpty()) return 0;
         return Integer.valueOf(t);
     }
+
+    /**
+     * 根据后台设置剔除时间,判断试题统计情况
+     * @param question
+     * @return
+     */
+    public boolean filterTime(UserQuestion question){
+        Setting setting = settingService.getByKey(SettingKey.FILTER_TIME);
+        JSONObject value = setting.getValue();
+        if (value.getInteger("min")> question.getTime()) return false;
+        if (value.getInteger("max") < question.getTime()) return false;
+        return  true;
+    }
 }

+ 8 - 5
server/gateway-api/src/main/java/com/qxgmat/service/inline/QuestionNoService.java

@@ -37,11 +37,6 @@ public class QuestionNoService extends AbstractService {
     @Resource
     private QuestionService questionService;
 
-    // 完成一次
-    public boolean submit(UserQuestion userQuestion){
-
-        return true;
-    }
     /**
      * 根据题干搜索相似题目
      * @param page
@@ -180,6 +175,14 @@ public class QuestionNoService extends AbstractService {
     }
 
     /**
+     * 累加做题记录到questionNo
+     * @param question
+     */
+    public void accumulation(UserQuestion question){
+        questionNoRelationMapper.accumulation(question.getQuestionNoId(), 1, question.getTime(), question.getIsCorrect());
+    }
+
+    /**
      * 根据试卷分组获取统计信息
      * @param questionNoIdsMap
      * @return

+ 9 - 0
server/gateway-api/src/main/java/com/qxgmat/service/inline/QuestionService.java

@@ -10,6 +10,7 @@ import com.qxgmat.data.dao.HomeworkPreviewMapper;
 import com.qxgmat.data.dao.QuestionMapper;
 import com.qxgmat.data.dao.entity.HomeworkPreview;
 import com.qxgmat.data.dao.entity.Question;
+import com.qxgmat.data.dao.entity.UserQuestion;
 import com.qxgmat.data.inline.PaperStat;
 import com.qxgmat.data.relation.QuestionRelationMapper;
 import org.slf4j.Logger;
@@ -76,6 +77,14 @@ public class QuestionService extends AbstractService {
         return relationMap;
     }
 
+    /**
+     * 累加做题记录到questionNo
+     * @param question
+     */
+    public void accumulation(UserQuestion question){
+        questionRelationMapper.accumulation(question.getQuestionId(), 1, question.getTime(), question.getIsCorrect());
+    }
+
     public Question add(Question question){
         int result = insert(questionMapper, question);
         question = one(questionMapper, question.getId());

+ 10 - 3
server/gateway-api/src/main/java/com/qxgmat/service/inline/SentenceQuestionService.java

@@ -11,6 +11,7 @@ import com.qxgmat.data.dao.entity.Manager;
 import com.qxgmat.data.dao.entity.Question;
 import com.qxgmat.data.dao.entity.SentenceQuestion;
 import com.qxgmat.data.dao.entity.UserQuestion;
+import com.qxgmat.data.relation.SentenceQuestionRelationMapper;
 import com.qxgmat.data.relation.entity.SentenceQuestionRelation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,11 +31,17 @@ public class SentenceQuestionService extends AbstractService {
     @Resource
     private QuestionService questionService;
 
-    // 完成一次
-    public boolean submit(UserQuestion userQuestion){
+    @Resource
+    private SentenceQuestionRelationMapper sentenceQuestionRelationMapper;
 
-        return true;
+    /**
+     * 累加做题记录到sentenceQuestion
+     * @param question
+     */
+    public void accumulation(UserQuestion question){
+        sentenceQuestionRelationMapper.accumulation(question.getQuestionNoId(), 1, question.getTime(), question.getIsCorrect());
     }
+
     /**
      * 根据长难句题目关系,获取完整题目:列表
      * @param p

+ 10 - 0
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserReportService.java

@@ -77,12 +77,22 @@ public class UserReportService extends AbstractService {
                 .userId(paper.getUserId())
                 .paperId(paper.getId())
                 .questionNoIds(paper.getQuestionNoIds())
+                .questionNumber(paper.getQuestionNoIds().length)
+                .time(paper.getTime())
                 .build();
         // 回调,根据模块更新设置
         IInitReport.callback(report, paper);
         return add(report);
     }
 
+    /**
+     * 累加做题记录到report
+     * @param question
+     */
+    public void accumulation(UserQuestion question){
+        userReportRelationMapper.accumulation(question.getReportId(), 1, question.getTime(), question.getIsCorrect());
+    }
+
     public UserReport add(UserReport report){
         int result = insert(userReportMapper, report);
         report = one(userReportMapper, report.getId());