Browse Source

Merge branch 'master' of https://git.proginn.com/zaixianjiaoyu/sourcecode

KaysonCui 5 years ago
parent
commit
f2046b5fa7
39 changed files with 1186 additions and 171 deletions
  1. 3 1
      server/data/src/main/java/com/qxgmat/data/constants/enums/user/PrepareExaminationTime.java
  2. 35 35
      server/data/src/main/java/com/qxgmat/data/dao/entity/ExercisePaper.java
  3. 51 16
      server/data/src/main/java/com/qxgmat/data/dao/entity/User.java
  4. 35 0
      server/data/src/main/java/com/qxgmat/data/dao/entity/UserPaper.java
  5. 52 0
      server/data/src/main/java/com/qxgmat/data/dao/entity/UserPay.java
  6. 35 0
      server/data/src/main/java/com/qxgmat/data/dao/entity/UserQuestion.java
  7. 26 0
      server/data/src/main/java/com/qxgmat/data/dao/entity/UserReport.java
  8. 2 2
      server/data/src/main/java/com/qxgmat/data/dao/mapping/ExercisePaperMapper.xml
  9. 5 3
      server/data/src/main/java/com/qxgmat/data/dao/mapping/UserMapper.xml
  10. 3 1
      server/data/src/main/java/com/qxgmat/data/dao/mapping/UserPaperMapper.xml
  11. 4 1
      server/data/src/main/java/com/qxgmat/data/dao/mapping/UserPayMapper.xml
  12. 2 1
      server/data/src/main/java/com/qxgmat/data/dao/mapping/UserQuestionMapper.xml
  13. 2 1
      server/data/src/main/java/com/qxgmat/data/dao/mapping/UserReportMapper.xml
  14. 22 0
      server/data/src/main/java/com/qxgmat/data/relation/UserRelationMapper.java
  15. 54 0
      server/data/src/main/java/com/qxgmat/data/relation/entity/UserPrepareRelation.java
  16. 44 0
      server/data/src/main/java/com/qxgmat/data/relation/mapping/UserRelationMapper.xml
  17. 0 1
      server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java
  18. 134 20
      server/gateway-api/src/main/java/com/qxgmat/controller/api/QuestionController.java
  19. 27 16
      server/gateway-api/src/main/java/com/qxgmat/controller/api/SentenceController.java
  20. 57 0
      server/gateway-api/src/main/java/com/qxgmat/controller/api/ShopController.java
  21. 10 0
      server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserHomeworkPreviewExtendDto.java
  22. 1 1
      server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserPaperExtendDto.java
  23. 38 0
      server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserPaperDetailExtendDto.java
  24. 10 0
      server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserReportExtendDto.java
  25. 3 3
      server/gateway-api/src/main/java/com/qxgmat/dto/request/UserPrepareDto.java
  26. 20 0
      server/gateway-api/src/main/java/com/qxgmat/dto/response/MyDto.java
  27. 47 0
      server/gateway-api/src/main/java/com/qxgmat/dto/response/PaperBaseDto.java
  28. 17 3
      server/gateway-api/src/main/java/com/qxgmat/dto/response/UserPrepareDetailDto.java
  29. 17 5
      server/gateway-api/src/main/java/com/qxgmat/dto/response/UserReportDto.java
  30. 101 0
      server/gateway-api/src/main/java/com/qxgmat/dto/response/UserReportDetailDto.java
  31. 4 0
      server/gateway-api/src/main/java/com/qxgmat/help/WechatHelp.java
  32. 29 12
      server/gateway-api/src/main/java/com/qxgmat/service/UserPaperService.java
  33. 139 4
      server/gateway-api/src/main/java/com/qxgmat/service/UsersService.java
  34. 22 0
      server/gateway-api/src/main/java/com/qxgmat/service/extend/QuestionFlowService.java
  35. 42 7
      server/gateway-api/src/main/java/com/qxgmat/service/extend/TradeService.java
  36. 1 13
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserClassService.java
  37. 1 16
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserServiceService.java
  38. 84 6
      server/gateway-api/src/main/java/com/qxgmat/task/ScheduledTask.java
  39. 7 3
      server/tools/src/main/java/com/nuliji/tools/third/wechat/WechatClient.java

+ 3 - 1
server/data/src/main/java/com/qxgmat/data/constants/enums/user/PrepareExaminationTime.java

@@ -4,7 +4,9 @@ public enum PrepareExaminationTime {
     ONE_MONTH("one_month"),
     TWO_MONTH("two_month"),
     THREE_MONTH("three_month"),
-    SIX_MONTH("six_month");
+    SIX_MONTH("six_month"),
+    ONE_YEAR("one_year")
+    ;
 
     public String key;
     private PrepareExaminationTime(String key){

+ 35 - 35
server/data/src/main/java/com/qxgmat/data/dao/entity/ExercisePaper.java

@@ -17,6 +17,12 @@ public class ExercisePaper implements Serializable {
     private String type;
 
     /**
+     * 组卷名称
+     */
+    @Column(name = "`title`")
+    private String title;
+
+    /**
      * 组卷序号
      */
     @Column(name = "`no`")
@@ -47,12 +53,6 @@ public class ExercisePaper implements Serializable {
     private Integer[] structParent;
 
     /**
-     * 组卷名称
-     */
-    @Column(name = "`title`")
-    private String title;
-
-    /**
      * 题目数量
      */
     @Column(name = "`question_number`")
@@ -105,6 +105,24 @@ public class ExercisePaper implements Serializable {
     }
 
     /**
+     * 获取组卷名称
+     *
+     * @return title - 组卷名称
+     */
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * 设置组卷名称
+     *
+     * @param title 组卷名称
+     */
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    /**
      * 获取组卷序号
      *
      * @return no - 组卷序号
@@ -195,24 +213,6 @@ public class ExercisePaper implements Serializable {
     }
 
     /**
-     * 获取组卷名称
-     *
-     * @return title - 组卷名称
-     */
-    public String getTitle() {
-        return title;
-    }
-
-    /**
-     * 设置组卷名称
-     *
-     * @param title 组卷名称
-     */
-    public void setTitle(String title) {
-        this.title = title;
-    }
-
-    /**
      * 获取题目数量
      *
      * @return question_number - 题目数量
@@ -274,12 +274,12 @@ public class ExercisePaper implements Serializable {
         sb.append("Hash = ").append(hashCode());
         sb.append(", id=").append(id);
         sb.append(", type=").append(type);
+        sb.append(", title=").append(title);
         sb.append(", no=").append(no);
         sb.append(", logic=").append(logic);
         sb.append(", logicExtend=").append(logicExtend);
         sb.append(", structId=").append(structId);
         sb.append(", structParent=").append(structParent);
-        sb.append(", title=").append(title);
         sb.append(", questionNumber=").append(questionNumber);
         sb.append(", questionNoIds=").append(questionNoIds);
         sb.append(", status=").append(status);
@@ -317,6 +317,16 @@ public class ExercisePaper implements Serializable {
         }
 
         /**
+         * 设置组卷名称
+         *
+         * @param title 组卷名称
+         */
+        public Builder title(String title) {
+            obj.setTitle(title);
+            return this;
+        }
+
+        /**
          * 设置组卷序号
          *
          * @param no 组卷序号
@@ -367,16 +377,6 @@ public class ExercisePaper implements Serializable {
         }
 
         /**
-         * 设置组卷名称
-         *
-         * @param title 组卷名称
-         */
-        public Builder title(String title) {
-            obj.setTitle(title);
-            return this;
-        }
-
-        /**
          * 设置题目数量
          *
          * @param questionNumber 题目数量

+ 51 - 16
server/data/src/main/java/com/qxgmat/data/dao/entity/User.java

@@ -127,7 +127,7 @@ public class User implements Serializable {
      * 备考:考试时间
      */
     @Column(name = "`prepare_examination_time`")
-    private Integer prepareExaminationTime;
+    private String prepareExaminationTime;
 
     /**
      * 备考:出分时间
@@ -138,8 +138,14 @@ public class User implements Serializable {
     /**
      * 上次做题
      */
-    @Column(name = "`last_exercise`")
-    private Integer lastExercise;
+    @Column(name = "`latest_exercise`")
+    private Integer latestExercise;
+
+    /**
+     * 上一次错题组卷
+     */
+    @Column(name = "`latest_error`")
+    private Integer latestError;
 
     /**
      * 邀请用户
@@ -527,7 +533,7 @@ public class User implements Serializable {
      *
      * @return prepare_examination_time - 备考:考试时间
      */
-    public Integer getPrepareExaminationTime() {
+    public String getPrepareExaminationTime() {
         return prepareExaminationTime;
     }
 
@@ -536,7 +542,7 @@ public class User implements Serializable {
      *
      * @param prepareExaminationTime 备考:考试时间
      */
-    public void setPrepareExaminationTime(Integer prepareExaminationTime) {
+    public void setPrepareExaminationTime(String prepareExaminationTime) {
         this.prepareExaminationTime = prepareExaminationTime;
     }
 
@@ -561,19 +567,37 @@ public class User implements Serializable {
     /**
      * 获取上次做题
      *
-     * @return last_exercise - 上次做题
+     * @return latest_exercise - 上次做题
      */
-    public Integer getLastExercise() {
-        return lastExercise;
+    public Integer getLatestExercise() {
+        return latestExercise;
     }
 
     /**
      * 设置上次做题
      *
-     * @param lastExercise 上次做题
+     * @param latestExercise 上次做题
+     */
+    public void setLatestExercise(Integer latestExercise) {
+        this.latestExercise = latestExercise;
+    }
+
+    /**
+     * 获取上一次错题组卷
+     *
+     * @return latest_error - 上一次错题组卷
      */
-    public void setLastExercise(Integer lastExercise) {
-        this.lastExercise = lastExercise;
+    public Integer getLatestError() {
+        return latestError;
+    }
+
+    /**
+     * 设置上一次错题组卷
+     *
+     * @param latestError 上一次错题组卷
+     */
+    public void setLatestError(Integer latestError) {
+        this.latestError = latestError;
     }
 
     /**
@@ -690,7 +714,8 @@ public class User implements Serializable {
         sb.append(", prepareGoal=").append(prepareGoal);
         sb.append(", prepareExaminationTime=").append(prepareExaminationTime);
         sb.append(", prepareScoreTime=").append(prepareScoreTime);
-        sb.append(", lastExercise=").append(lastExercise);
+        sb.append(", latestExercise=").append(latestExercise);
+        sb.append(", latestError=").append(latestError);
         sb.append(", originId=").append(originId);
         sb.append(", inviteCode=").append(inviteCode);
         sb.append(", totalMoney=").append(totalMoney);
@@ -912,7 +937,7 @@ public class User implements Serializable {
          *
          * @param prepareExaminationTime 备考:考试时间
          */
-        public Builder prepareExaminationTime(Integer prepareExaminationTime) {
+        public Builder prepareExaminationTime(String prepareExaminationTime) {
             obj.setPrepareExaminationTime(prepareExaminationTime);
             return this;
         }
@@ -930,10 +955,20 @@ public class User implements Serializable {
         /**
          * 设置上次做题
          *
-         * @param lastExercise 上次做题
+         * @param latestExercise 上次做题
+         */
+        public Builder latestExercise(Integer latestExercise) {
+            obj.setLatestExercise(latestExercise);
+            return this;
+        }
+
+        /**
+         * 设置上一次错题组卷
+         *
+         * @param latestError 上一次错题组卷
          */
-        public Builder lastExercise(Integer lastExercise) {
-            obj.setLastExercise(lastExercise);
+        public Builder latestError(Integer latestError) {
+            obj.setLatestError(latestError);
             return this;
         }
 

+ 35 - 0
server/data/src/main/java/com/qxgmat/data/dao/entity/UserPaper.java

@@ -48,6 +48,12 @@ public class UserPaper implements Serializable {
     private Integer[] questionNoIds;
 
     /**
+     * 题目数量
+     */
+    @Column(name = "`question_number`")
+    private Integer questionNumber;
+
+    /**
      * 练习次数
      */
     @Column(name = "`times`")
@@ -214,6 +220,24 @@ public class UserPaper implements Serializable {
     }
 
     /**
+     * 获取题目数量
+     *
+     * @return question_number - 题目数量
+     */
+    public Integer getQuestionNumber() {
+        return questionNumber;
+    }
+
+    /**
+     * 设置题目数量
+     *
+     * @param questionNumber 题目数量
+     */
+    public void setQuestionNumber(Integer questionNumber) {
+        this.questionNumber = questionNumber;
+    }
+
+    /**
      * 获取练习次数
      *
      * @return times - 练习次数
@@ -352,6 +376,7 @@ public class UserPaper implements Serializable {
         sb.append(", moduleExtend=").append(moduleExtend);
         sb.append(", moduleId=").append(moduleId);
         sb.append(", questionNoIds=").append(questionNoIds);
+        sb.append(", questionNumber=").append(questionNumber);
         sb.append(", times=").append(times);
         sb.append(", time=").append(time);
         sb.append(", totalTime=").append(totalTime);
@@ -443,6 +468,16 @@ public class UserPaper implements Serializable {
         }
 
         /**
+         * 设置题目数量
+         *
+         * @param questionNumber 题目数量
+         */
+        public Builder questionNumber(Integer questionNumber) {
+            obj.setQuestionNumber(questionNumber);
+            return this;
+        }
+
+        /**
          * 设置单次时间:系统时间
          *
          * @param time 单次时间:系统时间

+ 52 - 0
server/data/src/main/java/com/qxgmat/data/dao/entity/UserPay.java

@@ -44,6 +44,12 @@ public class UserPay implements Serializable {
     @Column(name = "`use_time`")
     private Date useTime;
 
+    @Column(name = "`start_time`")
+    private Date startTime;
+
+    @Column(name = "`expire_time`")
+    private Date expireTime;
+
     private static final long serialVersionUID = 1L;
 
     /**
@@ -164,6 +170,34 @@ public class UserPay implements Serializable {
         this.useTime = useTime;
     }
 
+    /**
+     * @return start_time
+     */
+    public Date getStartTime() {
+        return startTime;
+    }
+
+    /**
+     * @param startTime
+     */
+    public void setStartTime(Date startTime) {
+        this.startTime = startTime;
+    }
+
+    /**
+     * @return expire_time
+     */
+    public Date getExpireTime() {
+        return expireTime;
+    }
+
+    /**
+     * @param expireTime
+     */
+    public void setExpireTime(Date expireTime) {
+        this.expireTime = expireTime;
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
@@ -177,6 +211,8 @@ public class UserPay implements Serializable {
         sb.append(", createTime=").append(createTime);
         sb.append(", isUse=").append(isUse);
         sb.append(", useTime=").append(useTime);
+        sb.append(", startTime=").append(startTime);
+        sb.append(", expireTime=").append(expireTime);
         sb.append("]");
         return sb.toString();
     }
@@ -258,6 +294,22 @@ public class UserPay implements Serializable {
             return this;
         }
 
+        /**
+         * @param startTime
+         */
+        public Builder startTime(Date startTime) {
+            obj.setStartTime(startTime);
+            return this;
+        }
+
+        /**
+         * @param expireTime
+         */
+        public Builder expireTime(Date expireTime) {
+            obj.setExpireTime(expireTime);
+            return this;
+        }
+
         public UserPay build() {
             return this.obj;
         }

+ 35 - 0
server/data/src/main/java/com/qxgmat/data/dao/entity/UserQuestion.java

@@ -37,6 +37,12 @@ public class UserQuestion implements Serializable {
     private Integer questionNoId;
 
     /**
+     * 做题序号
+     */
+    @Column(name = "`no`")
+    private Integer no;
+
+    /**
      * 系统定义时间
      */
     @Column(name = "`time`")
@@ -152,6 +158,24 @@ public class UserQuestion implements Serializable {
     }
 
     /**
+     * 获取做题序号
+     *
+     * @return no - 做题序号
+     */
+    public Integer getNo() {
+        return no;
+    }
+
+    /**
+     * 设置做题序号
+     *
+     * @param no 做题序号
+     */
+    public void setNo(Integer no) {
+        this.no = no;
+    }
+
+    /**
      * 获取系统定义时间
      *
      * @return time - 系统定义时间
@@ -248,6 +272,7 @@ public class UserQuestion implements Serializable {
         sb.append(", reportId=").append(reportId);
         sb.append(", questionId=").append(questionId);
         sb.append(", questionNoId=").append(questionNoId);
+        sb.append(", no=").append(no);
         sb.append(", time=").append(time);
         sb.append(", userTime=").append(userTime);
         sb.append(", createTime=").append(createTime);
@@ -317,6 +342,16 @@ public class UserQuestion implements Serializable {
         }
 
         /**
+         * 设置做题序号
+         *
+         * @param no 做题序号
+         */
+        public Builder no(Integer no) {
+            obj.setNo(no);
+            return this;
+        }
+
+        /**
          * 设置系统定义时间
          *
          * @param time 系统定义时间

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

@@ -90,6 +90,9 @@ public class UserReport implements Serializable {
     @Column(name = "`create_time`")
     private Date createTime;
 
+    @Column(name = "`update_time`")
+    private Date updateTime;
+
     private static final long serialVersionUID = 1L;
 
     /**
@@ -350,6 +353,20 @@ public class UserReport implements Serializable {
         this.createTime = createTime;
     }
 
+    /**
+     * @return update_time
+     */
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    /**
+     * @param updateTime
+     */
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
@@ -371,6 +388,7 @@ public class UserReport implements Serializable {
         sb.append(", setting=").append(setting);
         sb.append(", detail=").append(detail);
         sb.append(", createTime=").append(createTime);
+        sb.append(", updateTime=").append(updateTime);
         sb.append("]");
         return sb.toString();
     }
@@ -530,6 +548,14 @@ public class UserReport implements Serializable {
             return this;
         }
 
+        /**
+         * @param updateTime
+         */
+        public Builder updateTime(Date updateTime) {
+            obj.setUpdateTime(updateTime);
+            return this;
+        }
+
         public UserReport build() {
             return this.obj;
         }

+ 2 - 2
server/data/src/main/java/com/qxgmat/data/dao/mapping/ExercisePaperMapper.xml

@@ -7,12 +7,12 @@
     -->
     <id column="id" jdbcType="INTEGER" property="id" />
     <result column="type" jdbcType="VARCHAR" property="type" />
+    <result column="title" jdbcType="VARCHAR" property="title" />
     <result column="no" jdbcType="INTEGER" property="no" />
     <result column="logic" jdbcType="VARCHAR" property="logic" />
     <result column="logic_extend" jdbcType="VARCHAR" property="logicExtend" />
     <result column="struct_id" jdbcType="INTEGER" property="structId" />
     <result column="struct_parent" jdbcType="VARCHAR" property="structParent" typeHandler="com.nuliji.tools.mybatis.handler.IntegerArrayHandler" />
-    <result column="title" jdbcType="VARCHAR" property="title" />
     <result column="question_number" jdbcType="INTEGER" property="questionNumber" />
     <result column="question_no_ids" jdbcType="VARCHAR" property="questionNoIds" typeHandler="com.nuliji.tools.mybatis.handler.IntegerArrayWithJsonHandler" />
     <result column="status" jdbcType="INTEGER" property="status" />
@@ -21,7 +21,7 @@
     <!--
       WARNING - @mbg.generated
     -->
-    `id`, `type`, `no`, `logic`, `logic_extend`, `struct_id`, `struct_parent`, `title`, 
+    `id`, `type`, `title`, `no`, `logic`, `logic_extend`, `struct_id`, `struct_parent`, 
     `question_number`, `question_no_ids`, `status`
   </sql>
 </mapper>

+ 5 - 3
server/data/src/main/java/com/qxgmat/data/dao/mapping/UserMapper.xml

@@ -25,9 +25,10 @@
     <result column="real_status" jdbcType="INTEGER" property="realStatus" />
     <result column="prepare_status" jdbcType="VARCHAR" property="prepareStatus" />
     <result column="prepare_goal" jdbcType="INTEGER" property="prepareGoal" />
-    <result column="prepare_examination_time" jdbcType="INTEGER" property="prepareExaminationTime" />
+    <result column="prepare_examination_time" jdbcType="VARCHAR" property="prepareExaminationTime" />
     <result column="prepare_score_time" jdbcType="TIMESTAMP" property="prepareScoreTime" />
-    <result column="last_exercise" jdbcType="INTEGER" property="lastExercise" />
+    <result column="latest_exercise" jdbcType="INTEGER" property="latestExercise" />
+    <result column="latest_error" jdbcType="INTEGER" property="latestError" />
     <result column="origin_id" jdbcType="INTEGER" property="originId" />
     <result column="invite_code" jdbcType="VARCHAR" property="inviteCode" />
     <result column="total_money" jdbcType="DECIMAL" property="totalMoney" />
@@ -42,6 +43,7 @@
     `wechat_openid_wechat`, `wechat_unionid`, `wechat_access_token`, `wechat_refresh_token`, 
     `wechat_expire_time`, `real_name`, `real_address`, `real_identity`, `real_photo`, 
     `real_status`, `prepare_status`, `prepare_goal`, `prepare_examination_time`, `prepare_score_time`, 
-    `last_exercise`, `origin_id`, `invite_code`, `total_money`, `invite_number`, `create_time`
+    `latest_exercise`, `latest_error`, `origin_id`, `invite_code`, `total_money`, `invite_number`, 
+    `create_time`
   </sql>
 </mapper>

+ 3 - 1
server/data/src/main/java/com/qxgmat/data/dao/mapping/UserPaperMapper.xml

@@ -12,6 +12,7 @@
     <result column="module_extend" jdbcType="VARCHAR" property="moduleExtend" />
     <result column="module_id" jdbcType="INTEGER" property="moduleId" />
     <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="times" jdbcType="INTEGER" property="times" />
     <result column="time" jdbcType="INTEGER" property="time" />
     <result column="total_time" jdbcType="INTEGER" property="totalTime" />
@@ -25,6 +26,7 @@
       WARNING - @mbg.generated
     -->
     `id`, `user_id`, `title`, `module`, `module_extend`, `module_id`, `question_no_ids`, 
-    `times`, `time`, `total_time`, `total_number`, `total_correct`, `delete_time`, `is_reset`
+    `question_number`, `times`, `time`, `total_time`, `total_number`, `total_correct`, 
+    `delete_time`, `is_reset`
   </sql>
 </mapper>

+ 4 - 1
server/data/src/main/java/com/qxgmat/data/dao/mapping/UserPayMapper.xml

@@ -12,11 +12,14 @@
     <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
     <result column="is_use" jdbcType="INTEGER" property="isUse" />
     <result column="use_time" jdbcType="TIMESTAMP" property="useTime" />
+    <result column="start_time" jdbcType="TIMESTAMP" property="startTime" />
+    <result column="expire_time" jdbcType="TIMESTAMP" property="expireTime" />
   </resultMap>
   <sql id="Base_Column_List">
     <!--
       WARNING - @mbg.generated
     -->
-    `id`, `user_id`, `module`, `module_extend`, `create_time`, `is_use`, `use_time`
+    `id`, `user_id`, `module`, `module_extend`, `create_time`, `is_use`, `use_time`, 
+    `start_time`, `expire_time`
   </sql>
 </mapper>

+ 2 - 1
server/data/src/main/java/com/qxgmat/data/dao/mapping/UserQuestionMapper.xml

@@ -10,6 +10,7 @@
     <result column="report_id" jdbcType="INTEGER" property="reportId" />
     <result column="question_id" jdbcType="INTEGER" property="questionId" />
     <result column="question_no_id" jdbcType="INTEGER" property="questionNoId" />
+    <result column="no" jdbcType="INTEGER" property="no" />
     <result column="time" jdbcType="INTEGER" property="time" />
     <result column="user_time" jdbcType="INTEGER" property="userTime" />
     <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
@@ -20,7 +21,7 @@
     <!--
       WARNING - @mbg.generated
     -->
-    `id`, `user_id`, `report_id`, `question_id`, `question_no_id`, `time`, `user_time`, 
+    `id`, `user_id`, `report_id`, `question_id`, `question_no_id`, `no`, `time`, `user_time`, 
     `create_time`, `user_answer`, `is_correct`
   </sql>
 </mapper>

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

@@ -20,6 +20,7 @@
     <result column="setting" jdbcType="VARCHAR" property="setting" typeHandler="com.nuliji.tools.mybatis.handler.JsonObjectHandler" />
     <result column="detail" jdbcType="VARCHAR" property="detail" typeHandler="com.nuliji.tools.mybatis.handler.JsonObjectHandler" />
     <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
+    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
   </resultMap>
   <sql id="Base_Column_List">
     <!--
@@ -27,6 +28,6 @@
     -->
     `id`, `user_id`, `paper_id`, `module`, `module_id`, `question_no_ids`, `question_number`, 
     `time`, `user_number`, `user_time`, `user_correct`, `finish_time`, `setting`, `detail`, 
-    `create_time`
+    `create_time`, `update_time`
   </sql>
 </mapper>

+ 22 - 0
server/data/src/main/java/com/qxgmat/data/relation/UserRelationMapper.java

@@ -0,0 +1,22 @@
+package com.qxgmat.data.relation;
+
+import com.qxgmat.data.dao.entity.UserReport;
+import com.qxgmat.data.relation.entity.UserPrepareRelation;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Created by gaojie on 2017/11/9.
+ */
+public interface UserRelationMapper {
+    List<UserPrepareRelation> groupPrepareString(
+            @Param("field") String field
+    );
+
+    List<UserPrepareRelation> groupPrepareInteger(
+            @Param("field") String field
+    );
+
+}

+ 54 - 0
server/data/src/main/java/com/qxgmat/data/relation/entity/UserPrepareRelation.java

@@ -0,0 +1,54 @@
+package com.qxgmat.data.relation.entity;
+
+import com.qxgmat.data.dao.entity.UserPaper;
+import com.qxgmat.data.dao.entity.UserReport;
+
+import javax.persistence.Column;
+
+/**
+ * Created by gaojie on 2017/11/9.
+ */
+// 备考统计
+public class UserPrepareRelation {
+
+    /**
+     * 数字字段
+     */
+    @Column(name = "`i`")
+    private Integer i;
+
+    /**
+     * 字符串字段
+     */
+    @Column(name = "`s`")
+    private String s;
+    /**
+     * 统计值
+     */
+    @Column(name = "`user_id`")
+    private Integer number;
+
+    public Integer getI() {
+        return i;
+    }
+
+    public void setI(Integer i) {
+        this.i = i;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public String getS() {
+        return s;
+    }
+
+    public void setS(String s) {
+        this.s = s;
+    }
+}

+ 44 - 0
server/data/src/main/java/com/qxgmat/data/relation/mapping/UserRelationMapper.xml

@@ -0,0 +1,44 @@
+<?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.UserRelationMapper">
+  <resultMap id="IdMap" type="com.qxgmat.data.relation.entity.UserPrepareRelation">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="i" jdbcType="INTEGER" property="i" />
+    <id column="s" jdbcType="VARCHAR" property="s" />
+    <id column="number" jdbcType="INTEGER" property="number" />
+  </resultMap>
+  <sql id="Id_Column_List">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    ur.`id`
+  </sql>
+
+  <!--
+    字符串字段统计
+  -->
+  <select id="groupPrepareString" resultMap="IdMap">
+    select
+      `${field}` as `s`, count(*) as `number`
+    from `user`
+    where
+      `prepare_goal` > 0
+    and `${field}` != null and `${field}` != ""
+    group by `${field}`
+  </select>
+
+  <!--
+    数字字段统计
+  -->
+  <select id="groupPrepareInteger" resultMap="IdMap">
+    select
+    `${field}` as `i`, count(*) as `number`
+    from `user`
+    where
+    `prepare_goal` > 0
+    and `${field}` > 0
+    group by `${field}`
+  </select>
+</mapper>

+ 0 - 1
server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java

@@ -200,7 +200,6 @@ public class MyController {
         User entity = usersService.get(user.getId());
         UserPrepareDetailDto dto = Transform.convert(entity, UserPrepareDetailDto.class);
 
-        // todo 获取备考统计
         Setting setting = settingService.getByKey(SettingKey.PREPARE_INFO);
         JSONObject value = setting.getValue();
         return ResponseHelp.success(dto);

+ 134 - 20
server/gateway-api/src/main/java/com/qxgmat/controller/api/QuestionController.java

@@ -4,6 +4,7 @@ package com.qxgmat.controller.api;
 import com.alibaba.fastjson.JSONObject;
 import com.github.pagehelper.Page;
 import com.nuliji.tools.*;
+import com.nuliji.tools.exception.ParameterException;
 import com.qxgmat.data.constants.enums.logic.ExerciseLogic;
 import com.qxgmat.data.constants.enums.module.PaperModule;
 import com.qxgmat.data.constants.enums.module.PayModule;
@@ -18,10 +19,7 @@ import com.qxgmat.dto.extend.UserHomeworkPreviewExtendDto;
 import com.qxgmat.dto.request.*;
 import com.qxgmat.dto.response.*;
 import com.qxgmat.help.ShiroHelp;
-import com.qxgmat.service.ExercisePaperService;
-import com.qxgmat.service.HomeworkPreviewService;
-import com.qxgmat.service.UserCollectQuestionService;
-import com.qxgmat.service.UserQuestionService;
+import com.qxgmat.service.*;
 import com.qxgmat.service.extend.QuestionFlowService;
 import com.qxgmat.service.inline.*;
 import io.swagger.annotations.Api;
@@ -69,6 +67,12 @@ public class QuestionController {
     private UserPayService userPayService;
 
     @Autowired
+    private UserReportService userReportService;
+
+    @Autowired
+    private UserPaperService userPaperService;
+
+    @Autowired
     private QuestionFlowService questionFlowService;
 
     @RequestMapping(value = "/class/process", method = RequestMethod.GET)
@@ -144,7 +148,7 @@ public class QuestionController {
         return ResponseHelp.success(exercisePaperService.groupPlace());
     }
 
-    @RequestMapping(value = "/exercise/paper", method = RequestMethod.GET)
+    @RequestMapping(value = "/exercise/list", method = RequestMethod.GET)
     @ApiOperation(value = "练习组卷列表", httpMethod = "GET")
     public Response<PageMessage<UserExercisePaperExtendDto>> listExercisePaper(
             @RequestParam(required = false, defaultValue = "1") int page,
@@ -186,7 +190,7 @@ public class QuestionController {
         return ResponseHelp.success(p, page, size, p.getTotal());
     }
 
-    @RequestMapping(value = "/examination/paper", method = RequestMethod.GET)
+    @RequestMapping(value = "/examination/list", method = RequestMethod.GET)
     @ApiOperation(value = "模考组卷列表", httpMethod = "GET")
     public Response<PageMessage<ExercisePaper>> examinationPaperList(
             @RequestParam(required = false, defaultValue = "1") int page,
@@ -199,56 +203,168 @@ public class QuestionController {
         return ResponseHelp.success(p, page, size, p.getTotal());
     }
 
-    @RequestMapping(value = "/detail", method = RequestMethod.GET)
+    @RequestMapping(value = "/question/detail", method = RequestMethod.GET)
     @ApiOperation(value = "获取题目详情", notes = "获取题目详情", httpMethod = "GET")
     public Response<UserQuestionDetailDto> detail(
-            @RequestParam(required = false) String userQuestionId
+            @RequestParam(required = true, name="id") Integer userQuestionId
     )  {
         User user = (User) shiroHelp.getLoginUser();
+        // todo 获取数据
+
         return ResponseHelp.success(null);
     }
 
+    @RequestMapping(value = "/exercise/paper", method = RequestMethod.GET)
+    @ApiOperation(value = "获取练习卷", notes = "获取练习卷", httpMethod = "GET")
+    public Response<PaperBaseDto> detailExercise(
+            @RequestParam(required = true, name="id") Integer paperId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        ExercisePaper paper = exercisePaperService.get(paperId);
+        PaperBaseDto paperDto = Transform.convert(paper, PaperBaseDto.class);
+
+        return ResponseHelp.success(paperDto);
+    }
+
+    @RequestMapping(value = "/report/base", method = RequestMethod.GET)
+    @ApiOperation(value = "获取练习记录", notes = "获取练习卷", httpMethod = "GET")
+    public Response<UserReportBaseDto> baseReport(
+            @RequestParam(required = true, name="id") Integer userReportId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        UserReportRelation report = questionFlowService.baseReport(user.getId(), userReportId);
+
+        UserReportBaseDto userReportDto = Transform.convert(report, UserReportBaseDto.class);
+
+        return ResponseHelp.success(userReportDto);
+    }
+
+    @RequestMapping(value = "/report/detail", method = RequestMethod.GET)
+    @ApiOperation(value = "获取练习详细记录", notes = "获取练习卷", httpMethod = "GET")
+    public Response<UserReportDetailDto> detailReport(
+            @RequestParam(required = true, name="id") Integer userReportId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        UserReportRelation report = questionFlowService.baseReport(user.getId(), userReportId);
+
+        UserReportDetailDto userReportDto = Transform.convert(report, UserReportDetailDto.class);
+
+        return ResponseHelp.success(userReportDto);
+    }
+
     @RequestMapping(value = "/exercise/start", method = RequestMethod.POST)
     @ApiOperation(value = "开始: 练习", notes = "提交考试设置", httpMethod = "POST")
-    public Response<UserReportDto> startExercise(@RequestBody @Validated ExerciseStartDto dto)  {
+    public Response<UserReportBaseDto> startExercise(@RequestBody @Validated ExerciseStartDto dto)  {
         User user = (User) shiroHelp.getLoginUser();
         JSONObject setting = new JSONObject();
         setting.put("disorder", dto.getDisorder());
         UserReport report = questionFlowService.start(user.getId(), PaperModule.HOMEWORK_PREVIEW, dto.getPaperId(), setting);
 
-        return ResponseHelp.success(Transform.convert(report, UserReportDto.class));
+        return ResponseHelp.success(Transform.convert(report, UserReportBaseDto.class));
+    }
+
+    @RequestMapping(value = "/preview/paper", method = RequestMethod.GET)
+    @ApiOperation(value = "获取预习作业", notes = "获取预习作业", httpMethod = "GET")
+    public Response<PaperBaseDto> detailPreview(
+            @RequestParam(required = true, name="id") Integer paperId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        HomeworkPreview preview = homeworkPreviewService.get(paperId);
+        PaperBaseDto paperDto = Transform.convert(preview, PaperBaseDto.class);
+
+        return ResponseHelp.success(paperDto);
     }
 
     @RequestMapping(value = "/preview/start", method = RequestMethod.POST)
     @ApiOperation(value = "开始: 预习作业", notes = "提交考试设置", httpMethod = "POST")
-    public Response<UserReportDto> startPreview(@RequestBody @Validated PreviewStartDto dto)  {
+    public Response<UserReportBaseDto> startPreview(@RequestBody @Validated PreviewStartDto dto)  {
         User user = (User) shiroHelp.getLoginUser();
         JSONObject setting = new JSONObject();
         setting.put("disorder", dto.getDisorder());
         UserReportRelation report = questionFlowService.start(user.getId(), PaperModule.HOMEWORK_PREVIEW, dto.getPaperId(), setting);
 
-        UserReportDto userReportDto = Transform.convert(report, UserReportDto.class);
+        UserReportBaseDto userReportBaseDto = Transform.convert(report, UserReportBaseDto.class);
 
-        return ResponseHelp.success(userReportDto);
+        return ResponseHelp.success(userReportBaseDto);
+    }
+
+    @RequestMapping(value = "/error/paper", method = RequestMethod.GET)
+    @ApiOperation(value = "获取错题组卷", notes = "获取错题组卷", httpMethod = "GET")
+    public Response<PaperBaseDto> detailError(
+            @RequestParam(required = true, name="id") Integer paperId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        UserPaper paper = userPaperService.get(paperId);
+        if (!paper.getModule().equals(PaperModule.ERROR.key)){
+            throw new ParameterException("试卷不存在");
+        }
+        if (!paper.getUserId().equals(user.getId())){
+            throw new ParameterException("试卷不存在");
+        }
+        PaperBaseDto paperDto = Transform.convert(paper, PaperBaseDto.class);
+
+        return ResponseHelp.success(paperDto);
+    }
+
+    @RequestMapping(value = "/error/start", method = RequestMethod.POST)
+    @ApiOperation(value = "开始: 错题组卷", notes = "提交考试设置", httpMethod = "POST")
+    public Response<UserReportBaseDto> startError(@RequestBody @Validated PreviewStartDto dto)  {
+        User user = (User) shiroHelp.getLoginUser();
+        JSONObject setting = new JSONObject();
+        setting.put("disorder", dto.getDisorder());
+        UserReportRelation report = questionFlowService.start(user.getId(), PaperModule.ERROR, dto.getPaperId(), setting);
+
+        UserReportBaseDto userReportBaseDto = Transform.convert(report, UserReportBaseDto.class);
+
+        return ResponseHelp.success(userReportBaseDto);
+    }
+
+    @RequestMapping(value = "/collect/paper", method = RequestMethod.GET)
+    @ApiOperation(value = "获取收藏组卷", notes = "获取收藏组卷", httpMethod = "GET")
+    public Response<PaperBaseDto> detailCollect(
+            @RequestParam(required = true, name="id") Integer paperId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        UserPaper paper = userPaperService.get(paperId);
+        if (!paper.getModule().equals(PaperModule.COLLECT.key)){
+            throw new ParameterException("试卷不存在");
+        }
+        if (!paper.getUserId().equals(user.getId())){
+            throw new ParameterException("试卷不存在");
+        }
+        PaperBaseDto paperDto = Transform.convert(paper, PaperBaseDto.class);
+
+        return ResponseHelp.success(paperDto);
+    }
+
+    @RequestMapping(value = "/collect/start", method = RequestMethod.POST)
+    @ApiOperation(value = "开始: 收藏组卷", notes = "提交考试设置", httpMethod = "POST")
+    public Response<UserReportBaseDto> startCollect(@RequestBody @Validated PreviewStartDto dto)  {
+        User user = (User) shiroHelp.getLoginUser();
+        JSONObject setting = new JSONObject();
+        setting.put("disorder", dto.getDisorder());
+        UserReportRelation report = questionFlowService.start(user.getId(), PaperModule.COLLECT, dto.getPaperId(), setting);
+
+        UserReportBaseDto userReportBaseDto = Transform.convert(report, UserReportBaseDto.class);
+
+        return ResponseHelp.success(userReportBaseDto);
     }
 
     @RequestMapping(value = "/continue", method = RequestMethod.POST)
     @ApiOperation(value = "继续做题", notes = "获取报告信息", httpMethod = "POST")
-    public Response<UserReportDto> continueReport(@RequestBody @Validated ReportContinueDto dto)  {
+    public Response<UserReportBaseDto> continueReport(@RequestBody @Validated ReportContinueDto dto)  {
         User user = (User) shiroHelp.getLoginUser();
         UserReportRelation report = questionFlowService.continueReport(user.getId(), dto.getUserReportId());
 
-        UserReportDto userReportDto = Transform.convert(report, UserReportDto.class);
+        UserReportBaseDto userReportBaseDto = Transform.convert(report, UserReportBaseDto.class);
 
-        return ResponseHelp.success(userReportDto);
+        return ResponseHelp.success(userReportBaseDto);
     }
 
     @RequestMapping(value = "/next", method = RequestMethod.POST)
     @ApiOperation(value = "获取下一题", notes = "获取下一题", httpMethod = "POST")
     public Response<UserQuestionBaseDto> next(@RequestBody @Validated ReportNextDto dto)  {
         User user = (User) shiroHelp.getLoginUser();
-        // 根据对应paper获取,以及设定的setting获取下一题
-
         UserQuestion userQuestion = questionFlowService.next(user.getId(), dto.getUserReportId());
         UserQuestionBaseDto baseDto = Transform.convert(userQuestion, UserQuestionBaseDto.class);
 
@@ -264,7 +380,6 @@ public class QuestionController {
         // 绑定collect
         baseDto.setCollect(userCollectQuestionService.getByUserAndQuestion(user.getId(), userQuestion.getQuestionId()) != null);
 
-
         return ResponseHelp.success(baseDto);
     }
 
@@ -291,7 +406,6 @@ public class QuestionController {
         User user = (User) shiroHelp.getLoginUser();
 
         questionFlowService.restart(dto.getUserPaperId(), user.getId());
-
         return ResponseHelp.success(true);
     }
 }

+ 27 - 16
server/gateway-api/src/main/java/com/qxgmat/controller/api/SentenceController.java

@@ -12,7 +12,6 @@ import com.qxgmat.data.dao.entity.*;
 import com.qxgmat.data.relation.entity.UserReportRelation;
 import com.qxgmat.dto.extend.QuestionExtendDto;
 import com.qxgmat.dto.extend.SentenceQuestionBaseExtendDto;
-import com.qxgmat.dto.extend.SentenceQuestionDetailExtendDto;
 import com.qxgmat.dto.request.*;
 import com.qxgmat.dto.response.*;
 import com.qxgmat.help.ShiroHelp;
@@ -170,38 +169,50 @@ public class SentenceController
 
     @RequestMapping(value = "/question/detail", method = RequestMethod.GET)
     @ApiOperation(value = "获取题目详情", notes = "获取题目详情", httpMethod = "GET")
-    public Response<UserSentenceQuestionDetailDto> detail(
-            @RequestParam(required = false) String questionNoId
+    public Response<UserSentenceQuestionDetailDto> detailQuestion(
+            @RequestParam(required = true, name="id") Integer questionNoId
     )  {
         User user = (User) shiroHelp.getLoginUser();
         return ResponseHelp.success(null);
     }
 
-    @RequestMapping(value = "/paper/start", method = RequestMethod.POST)
+    @RequestMapping(value = "/paper", method = RequestMethod.GET)
+    @ApiOperation(value = "获取练习卷", notes = "获取练习卷", httpMethod = "GET")
+    public Response<PaperBaseDto> detailPaper(
+            @RequestParam(required = true, name="id") Integer paperId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        SentencePaper paper = sentencePaperService.get(paperId);
+
+        PaperBaseDto paperDto = Transform.convert(paper, PaperBaseDto.class);
+
+        return ResponseHelp.success(paperDto);
+    }
+
+    @RequestMapping(value = "/start", method = RequestMethod.POST)
     @ApiOperation(value = "开始做题", notes = "提交考试设置", httpMethod = "POST")
-    public Response<UserReportDto> start(@RequestBody @Validated SentenceStartDto dto)  {
+    public Response<UserReportBaseDto> start(@RequestBody @Validated SentenceStartDto dto)  {
         User user = (User) shiroHelp.getLoginUser();
         JSONObject setting = new JSONObject();
         UserReportRelation report = questionFlowService.start(user.getId(), PaperModule.SENTENCE, dto.getPaperId(), setting);
 
-        UserReportDto userReportDto = Transform.convert(report, UserReportDto.class);
+        UserReportBaseDto userReportBaseDto = Transform.convert(report, UserReportBaseDto.class);
 
-        return ResponseHelp.success(userReportDto);
+        return ResponseHelp.success(userReportBaseDto);
     }
 
-
-    @RequestMapping(value = "/paper/continue", method = RequestMethod.POST)
+    @RequestMapping(value = "/continue", method = RequestMethod.POST)
     @ApiOperation(value = "继续做题", notes = "获取报告信息", httpMethod = "POST")
-    public Response<UserReportDto> continueReport(@RequestBody @Validated ReportContinueDto dto)  {
+    public Response<UserReportBaseDto> continueReport(@RequestBody @Validated ReportContinueDto dto)  {
         User user = (User) shiroHelp.getLoginUser();
         UserReportRelation report = questionFlowService.continueReport(user.getId(), dto.getUserReportId());
 
-        UserReportDto userReportDto = Transform.convert(report, UserReportDto.class);
+        UserReportBaseDto userReportBaseDto = Transform.convert(report, UserReportBaseDto.class);
 
-        return ResponseHelp.success(userReportDto);
+        return ResponseHelp.success(userReportBaseDto);
     }
 
-    @RequestMapping(value = "/paper/next", method = RequestMethod.POST)
+    @RequestMapping(value = "/next", method = RequestMethod.POST)
     @ApiOperation(value = "获取下一题", notes = "获取下一题", httpMethod = "POST")
     public Response<UserSentenceQuestionBaseDto> next(@RequestBody @Validated ReportNextDto dto)  {
         User user = (User) shiroHelp.getLoginUser();
@@ -222,7 +233,7 @@ public class SentenceController
         return ResponseHelp.success(null);
     }
 
-    @RequestMapping(value = "/paper/submit", method = RequestMethod.POST)
+    @RequestMapping(value = "/submit", method = RequestMethod.POST)
     @ApiOperation(value = "提交题目答案", notes = "提交题目", httpMethod = "POST")
     public Response<Boolean> submit(@RequestBody @Validated QuestionSubmitDto dto)  {
         User user = (User) shiroHelp.getLoginUser();
@@ -230,7 +241,7 @@ public class SentenceController
         return ResponseHelp.success(result);
     }
 
-    @RequestMapping(value = "/paper/finish", method = RequestMethod.POST)
+    @RequestMapping(value = "/finish", method = RequestMethod.POST)
     @ApiOperation(value = "完成考试", notes = "完成考试", httpMethod = "POST")
     public Response<Boolean> finish(@RequestBody @Validated ReportFinishDto dto)  {
         User user = (User) shiroHelp.getLoginUser();
@@ -239,7 +250,7 @@ public class SentenceController
         return ResponseHelp.success(result);
     }
 
-    @RequestMapping(value = "/paper/restart", method = RequestMethod.POST)
+    @RequestMapping(value = "/restart", method = RequestMethod.POST)
     @ApiOperation(value = "重置考试", notes = "重置考试", httpMethod = "POST")
     public Response<Boolean> restart(@RequestBody @Validated PaperRestartDto dto)  {
         User user = (User) shiroHelp.getLoginUser();

+ 57 - 0
server/gateway-api/src/main/java/com/qxgmat/controller/api/ShopController.java

@@ -0,0 +1,57 @@
+package com.qxgmat.controller.api;
+
+import com.alibaba.fastjson.JSONObject;
+import com.nuliji.tools.Response;
+import com.nuliji.tools.ResponseHelp;
+import com.qxgmat.data.constants.enums.SettingKey;
+import com.qxgmat.data.dao.entity.*;
+import com.qxgmat.service.inline.*;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpSession;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api/base")
+@Api(tags = "商城接口", description = "商城相关接口", produces = MediaType.APPLICATION_JSON_VALUE)
+public class ShopController {
+
+    @Autowired
+    private SettingService settingService;
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    @ApiOperation(value = "商品信息", httpMethod = "GET")
+    private Response<JSONObject> index(){
+        Setting entity = settingService.getByKey(SettingKey.INDEX);
+        return ResponseHelp.success(entity.getValue());
+    }
+
+    @RequestMapping(value = "/pay/wechat", method = RequestMethod.POST)
+    @ApiOperation(value = "通过微信支付", notes = "通过微信支付", httpMethod = "POST")
+    public Response<Boolean> wechat() {
+        return ResponseHelp.success(null);
+    }
+
+    @RequestMapping(value = "/pay/alipay", method = RequestMethod.POST)
+    @ApiOperation(value = "通过支付宝支付", notes = "通过支付宝支付", httpMethod = "POST")
+    public Response<Boolean> alipay() {
+        return ResponseHelp.success(null);
+    }
+
+    @RequestMapping(value = "/pay/query", method = RequestMethod.GET)
+    @ApiOperation(value = "支付结果查询", notes = "支付结果查询", httpMethod = "GET")
+    public Response<Boolean> response(
+            @RequestParam(required = true, name="id") Long payId
+    ) {
+        return ResponseHelp.success(null);
+    }
+}

+ 10 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserHomeworkPreviewExtendDto.java

@@ -13,6 +13,8 @@ public class UserHomeworkPreviewExtendDto {
 
     private Integer times;
 
+    private Integer time;
+
     private String title;
 
     private PaperStat stat;
@@ -56,4 +58,12 @@ public class UserHomeworkPreviewExtendDto {
     public void setTimes(Integer times) {
         this.times = times;
     }
+
+    public Integer getTime() {
+        return time;
+    }
+
+    public void setTime(Integer time) {
+        this.time = time;
+    }
 }

+ 1 - 1
server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserPaperExtendDto.java

@@ -5,7 +5,7 @@ import com.qxgmat.data.dao.entity.UserPaper;
 import com.qxgmat.data.inline.PaperStat;
 
 @Dto(entity = UserPaper.class)
-public class UserPaperExtendDto {
+public class UserPaperBaseExtendDto {
 
     private Integer id;
 

+ 38 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserPaperDetailExtendDto.java

@@ -0,0 +1,38 @@
+package com.qxgmat.dto.extend;
+
+import com.nuliji.tools.annotation.Dto;
+import com.qxgmat.data.dao.entity.UserPaper;
+
+@Dto(entity = UserPaper.class)
+public class UserPaperDetailExtendDto {
+
+    private Integer id;
+
+    private Integer times;
+
+    private String title;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public Integer getTimes() {
+        return times;
+    }
+
+    public void setTimes(Integer times) {
+        this.times = times;
+    }
+}

+ 10 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/extend/UserReportExtendDto.java

@@ -23,6 +23,8 @@ public class UserReportExtendDto {
 
     private Date finishTime;
 
+    private Date updateTime;
+
     public Integer getId() {
         return id;
     }
@@ -78,4 +80,12 @@ public class UserReportExtendDto {
     public void setFinishTime(Date finishTime) {
         this.finishTime = finishTime;
     }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
 }

+ 3 - 3
server/gateway-api/src/main/java/com/qxgmat/dto/request/UserPrepareDto.java

@@ -20,7 +20,7 @@ public class UserPrepareDto {
     /**
      * 备考:考试时间
      */
-    private Integer prepareExaminationTime;
+    private String prepareExaminationTime;
 
     /**
      * 备考:出分时间
@@ -51,11 +51,11 @@ public class UserPrepareDto {
         this.prepareScoreTime = prepareScoreTime;
     }
 
-    public Integer getPrepareExaminationTime() {
+    public String getPrepareExaminationTime() {
         return prepareExaminationTime;
     }
 
-    public void setPrepareExaminationTime(Integer prepareExaminationTime) {
+    public void setPrepareExaminationTime(String prepareExaminationTime) {
         this.prepareExaminationTime = prepareExaminationTime;
     }
 }

+ 20 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/response/MyDto.java

@@ -24,6 +24,10 @@ public class MyDto extends UserDto {
 
     private Boolean bindMobile;
 
+    private Integer latestError;
+
+    private Integer latestExercise;
+
     @ApiModelProperty(value = "未读消息数", required = true)
     private int messageNum;
 
@@ -100,4 +104,20 @@ public class MyDto extends UserDto {
     public void setBindMobile(Boolean bindMobile) {
         this.bindMobile = bindMobile;
     }
+
+    public Integer getLatestError() {
+        return latestError;
+    }
+
+    public void setLatestError(Integer latestError) {
+        this.latestError = latestError;
+    }
+
+    public Integer getLatestExercise() {
+        return latestExercise;
+    }
+
+    public void setLatestExercise(Integer latestExercise) {
+        this.latestExercise = latestExercise;
+    }
 }

+ 47 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/response/PaperBaseDto.java

@@ -0,0 +1,47 @@
+package com.qxgmat.dto.response;
+
+import com.nuliji.tools.annotation.Dto;
+import com.qxgmat.data.dao.entity.UserClass;
+import com.qxgmat.dto.extend.UserHomeworkPreviewExtendDto;
+
+import java.util.Date;
+import java.util.List;
+
+public class PaperBaseDto {
+    private String title;
+    private Integer paperId;
+    private Integer time;
+    private Integer questionNumber;
+
+    public Integer getPaperId() {
+        return paperId;
+    }
+
+    public void setPaperId(Integer paperId) {
+        this.paperId = paperId;
+    }
+
+    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 String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+}

+ 17 - 3
server/gateway-api/src/main/java/com/qxgmat/dto/response/UserPrepareDetailDto.java

@@ -1,5 +1,6 @@
 package com.qxgmat.dto.response;
 
+import com.alibaba.fastjson.JSONObject;
 import com.nuliji.tools.annotation.Dto;
 import com.qxgmat.data.dao.entity.User;
 
@@ -20,13 +21,18 @@ public class UserPrepareDetailDto {
     /**
      * 备考:考试时间
      */
-    private Integer prepareExaminationTime;
+    private String prepareExaminationTime;
 
     /**
      * 备考:出分时间
      */
     private Date prepareScoreTime;
 
+    /**
+     * 总的统计信息:{status: [], goal: [], examinationTime: [], scoreTime: []}
+     */
+    private JSONObject stat;
+
 
     public String getPrepareStatus() {
         return prepareStatus;
@@ -52,11 +58,19 @@ public class UserPrepareDetailDto {
         this.prepareScoreTime = prepareScoreTime;
     }
 
-    public Integer getPrepareExaminationTime() {
+    public String getPrepareExaminationTime() {
         return prepareExaminationTime;
     }
 
-    public void setPrepareExaminationTime(Integer prepareExaminationTime) {
+    public void setPrepareExaminationTime(String prepareExaminationTime) {
         this.prepareExaminationTime = prepareExaminationTime;
     }
+
+    public JSONObject getStat() {
+        return stat;
+    }
+
+    public void setStat(JSONObject stat) {
+        this.stat = stat;
+    }
 }

+ 17 - 5
server/gateway-api/src/main/java/com/qxgmat/dto/response/UserReportDto.java

@@ -2,15 +2,17 @@ package com.qxgmat.dto.response;
 
 import com.nuliji.tools.annotation.Dto;
 import com.qxgmat.data.dao.entity.UserReport;
-import com.qxgmat.dto.extend.UserPaperExtendDto;
+import com.qxgmat.dto.extend.UserPaperBaseExtendDto;
+
+import java.util.Date;
 
 @Dto(entity = UserReport.class)
-public class UserReportDto {
+public class UserReportBaseDto {
     private Integer id;
 
     private Integer paperId;
 
-    private UserPaperExtendDto paper;
+    private UserPaperBaseExtendDto paper;
 
     private String module;
 
@@ -22,6 +24,8 @@ public class UserReportDto {
 
     private Integer userNumber;
 
+    private Date updateTime;
+
     public Integer getId() {
         return id;
     }
@@ -78,11 +82,19 @@ public class UserReportDto {
         this.userNumber = userNumber;
     }
 
-    public UserPaperExtendDto getPaper() {
+    public UserPaperBaseExtendDto getPaper() {
         return paper;
     }
 
-    public void setPaper(UserPaperExtendDto paper) {
+    public void setPaper(UserPaperBaseExtendDto paper) {
         this.paper = paper;
     }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
 }

+ 101 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/response/UserReportDetailDto.java

@@ -0,0 +1,101 @@
+package com.qxgmat.dto.response;
+
+import com.nuliji.tools.annotation.Dto;
+import com.qxgmat.data.dao.entity.UserReport;
+import com.qxgmat.dto.extend.UserPaperBaseExtendDto;
+import com.qxgmat.dto.extend.UserPaperDetailExtendDto;
+
+import java.util.Date;
+
+@Dto(entity = UserReport.class)
+public class UserReportDetailDto {
+    private Integer id;
+
+    private Integer paperId;
+
+    private UserPaperDetailExtendDto paper;
+
+    private String module;
+
+    private Integer time;
+
+    private Integer questionNumber;
+
+    private Integer userTime;
+
+    private Integer userNumber;
+
+    private Date updateTime;
+
+    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;
+    }
+
+    public UserPaperDetailExtendDto getPaper() {
+        return paper;
+    }
+
+    public void setPaper(UserPaperDetailExtendDto paper) {
+        this.paper = paper;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+}

+ 4 - 0
server/gateway-api/src/main/java/com/qxgmat/help/WechatHelp.java

@@ -33,6 +33,10 @@ public class WechatHelp {
         return wechat.webAuthorize(code);
     }
 
+    public OauthData refreshNative(String refreshToken) {
+        return wechat.refreshWebAccessToken(refreshToken);
+    }
+
     public String redirectPc(String redirectUrl, String state){
         return wechatPc.getOAuthUrl(redirectUrl, state);
     }

+ 29 - 12
server/gateway-api/src/main/java/com/qxgmat/service/UserPaperService.java

@@ -63,19 +63,36 @@ public class UserPaperService extends AbstractService {
     public UserPaper getByPaper(Integer userId, PaperModule module, Integer paperId, InitPaper IInitPaper){
         // 查找对应的paper是否有,没有则添加
         Example example = new Example(UserPaper.class);
-        example.and(
-                example.createCriteria()
-                        .andEqualTo("userId", userId)
-                        .andEqualTo("module", module.key)
-                        .andEqualTo("module_id", paperId)
-        );
-        UserPaper paper = one(userPaperMapper, example);
-        if (paper == null){
-            paper = UserPaper.builder().userId(userId).module(module.key).moduleId(paperId).build();
-            // 回调,根据模块更新设置
-            IInitPaper.callback(paper, paperId);
-            paper = add(paper);
+        UserPaper paper;
+        if (module.equals(PaperModule.ERROR) || module.equals(PaperModule.COLLECT)){
+            // 错题和收藏组卷,paper即为userPaper的id
+            example.and(
+                    example.createCriteria()
+                            .andEqualTo("userId", userId)
+                            .andEqualTo("module", module.key)
+                            .andEqualTo("id", paperId)
+            );
+            paper = one(userPaperMapper, example);
+            if (paper == null){
+                throw new ParameterException("试卷");
+            }
+        }else{
+            example.and(
+                    example.createCriteria()
+                            .andEqualTo("userId", userId)
+                            .andEqualTo("module", module.key)
+                            .andEqualTo("module_id", paperId)
+            );
+
+            paper = one(userPaperMapper, example);
+            if (paper == null){
+                paper = UserPaper.builder().userId(userId).module(module.key).moduleId(paperId).build();
+                // 回调,根据模块更新设置
+                IInitPaper.callback(paper, paperId);
+                paper = add(paper);
+            }
         }
+
         return paper;
     }
 

+ 139 - 4
server/gateway-api/src/main/java/com/qxgmat/service/UsersService.java

@@ -11,9 +11,12 @@ import com.nuliji.tools.mybatis.Example;
 import com.nuliji.tools.mybatis.NativeJsonHandler;
 import com.nuliji.tools.third.OauthData;
 import com.qxgmat.data.constants.enums.status.DirectionStatus;
+import com.qxgmat.data.constants.enums.user.PrepareExaminationTime;
 import com.qxgmat.data.dao.UserMapper;
 import com.qxgmat.data.dao.entity.User;
 import com.qxgmat.data.inline.UserToken;
+import com.qxgmat.data.relation.UserRelationMapper;
+import com.qxgmat.data.relation.entity.UserPrepareRelation;
 import com.qxgmat.help.WechatHelp;
 import com.qxgmat.service.inline.UserClassService;
 import com.qxgmat.service.inline.UserMessageService;
@@ -24,10 +27,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 
 /**
  * Created by GaoJie on 2017/11/1.
@@ -61,6 +61,9 @@ public class UsersService extends AbstractService {
     @Resource
     private UserServiceService userServiceService;
 
+    @Resource
+    private UserRelationMapper userRelationMapper;
+
     /**
      * 生成有效期token
      * @param user
@@ -256,6 +259,11 @@ public class UsersService extends AbstractService {
         return one(userMapper, example);
     }
 
+    /**
+     * 通过邀请码或者手机好获取邀请人
+     * @param inviteCode
+     * @return
+     */
     public User getByInviteCode(String inviteCode){
         User user = new User();
         Example example = new Example(User.class);
@@ -268,6 +276,133 @@ public class UsersService extends AbstractService {
         return one(userMapper, example);
     }
 
+    public List<UserPrepareRelation> statPrepareStatus(){
+        return userRelationMapper.groupPrepareString("prepare_status");
+    }
+
+    public List<UserPrepareRelation> statPrepareGoal(){
+        List<UserPrepareRelation> relations =  userRelationMapper.groupPrepareInteger("prepare_goal");
+        // 按考分分组
+        List<UserPrepareRelation> userPrepareRelationList = new ArrayList<>();
+        Integer[] goalGroup = new Integer[]{600, 650, 700, 750};
+        for(Integer goal : goalGroup){
+            UserPrepareRelation real = new UserPrepareRelation();
+            real.setI(goal);
+            real.setNumber(0);
+            userPrepareRelationList.add(real);
+        }
+
+        for(UserPrepareRelation relation : relations){
+            int goal = -1;
+            for(int i = 0; i < goalGroup.length; i++){
+                // 根据考分判断层级
+                if (goalGroup[i] > relation.getI()){
+                    // 属于上一层
+                    goal = i - 1;
+                    break;
+                }
+            }
+            if (goal > 0){
+                // 按层级归类
+                UserPrepareRelation real = userPrepareRelationList.get(goal);
+                real.setNumber(real.getNumber()+real.getNumber());
+            }
+        }
+
+        return userPrepareRelationList;
+    }
+
+    public List<UserPrepareRelation> statPrepareExaminationTime(){
+        return userRelationMapper.groupPrepareString("prepare_examination_time");
+    }
+
+    public List<UserPrepareRelation> statPrepareScoreTime(){
+        // 直接按不同时间段统计
+        Example example;
+        List<UserPrepareRelation> userPrepareRelationList = new ArrayList<>();
+        Calendar calendar = Calendar.getInstance();
+
+        // 一个月内
+        calendar.setTime(new Date());
+        calendar.add(Calendar.MONTH, 1);
+        example = new Example(User.class);
+        example.and(
+                example.createCriteria()
+                        .andLessThan("prepareScoreTime", calendar.getTime())
+        );
+        UserPrepareRelation oneMonth = new UserPrepareRelation();
+        oneMonth.setS(PrepareExaminationTime.ONE_MONTH.key);
+        oneMonth.setNumber(count(userMapper, example));
+        userPrepareRelationList.add(oneMonth);
+
+        // 两个月内
+        calendar.setTime(new Date());
+        calendar.add(Calendar.MONTH, 2);
+        example = new Example(User.class);
+        example.and(
+                example.createCriteria()
+                        .andLessThan("prepareScoreTime", calendar.getTime())
+        );
+        UserPrepareRelation twoMonth = new UserPrepareRelation();
+        twoMonth.setS(PrepareExaminationTime.TWO_MONTH.key);
+        twoMonth.setNumber(count(userMapper, example) - oneMonth.getNumber());
+        userPrepareRelationList.add(twoMonth);
+
+        // 三个月内
+        calendar.setTime(new Date());
+        calendar.add(Calendar.MONTH, 3);
+        example = new Example(User.class);
+        example.and(
+                example.createCriteria()
+                        .andLessThan("prepareScoreTime", calendar.getTime())
+        );
+        UserPrepareRelation threeMonth = new UserPrepareRelation();
+        threeMonth.setS(PrepareExaminationTime.THREE_MONTH.key);
+        threeMonth.setNumber(count(userMapper, example) - twoMonth.getNumber());
+        userPrepareRelationList.add(twoMonth);
+
+        // 半年
+        calendar.setTime(new Date());
+        calendar.add(Calendar.MONTH, 6);
+        example = new Example(User.class);
+        example.and(
+                example.createCriteria()
+                        .andLessThan("prepareScoreTime", calendar.getTime())
+        );
+        UserPrepareRelation sixMonth = new UserPrepareRelation();
+        sixMonth.setS(PrepareExaminationTime.SIX_MONTH.key);
+        sixMonth.setNumber(count(userMapper, example) - threeMonth.getNumber());
+        userPrepareRelationList.add(sixMonth);
+
+        // 一年
+        calendar.setTime(new Date());
+        calendar.add(Calendar.MONTH, 12);
+        example = new Example(User.class);
+        example.and(
+                example.createCriteria()
+                        .andLessThan("prepareScoreTime", calendar.getTime())
+        );
+        UserPrepareRelation oneYear = new UserPrepareRelation();
+        oneYear.setS(PrepareExaminationTime.ONE_YEAR.key);
+        oneYear.setNumber(count(userMapper, example) - sixMonth.getNumber());
+        userPrepareRelationList.add(oneYear);
+
+        // 其他
+        example = new Example(User.class);
+        example.and(
+                example.createCriteria()
+                        // 设置过备考信息的人:mapper中做为基本条件
+                        .andGreaterThan("prepareGoal", 0)
+                        .andIsNull("prepareScoreTime")
+        );
+        UserPrepareRelation other = new UserPrepareRelation();
+        other.setS(PrepareExaminationTime.ONE_YEAR.key);
+        other.setNumber(count(userMapper, example));
+        userPrepareRelationList.add(other);
+
+        return userPrepareRelationList;
+    }
+
     public boolean equalsPassword(User user, String password){
         return Objects.equals(user.getPassword(), Tools.stringMD5(Tools.stringMD5(password)));
     }

+ 22 - 0
server/gateway-api/src/main/java/com/qxgmat/service/extend/QuestionFlowService.java

@@ -48,6 +48,9 @@ public class QuestionFlowService {
     private SentencePaperService sentencePaperService;
 
     @Resource
+    private UsersService usersService;
+
+    @Resource
     private UserReportService userReportService;
 
     @Resource
@@ -134,6 +137,8 @@ public class QuestionFlowService {
             Integer questionNoId = this.nextId(report.getQuestionNoIds(), lastQuestion!=null ? lastQuestion.getQuestionNoId():null);
             if (questionNoId == 0) return false;
             this.bindQuestionNo(question, questionNoId, SettingKey.EXERCISE_TIME);
+            // 设定最后一次练习记录
+            usersService.edit(User.builder().id(question.getUserId()).latestExercise(report.getPaperId()).build());
             return true;
         });
         nextCallback.put(PaperModule.HOMEWORK_PREVIEW, (question, report, lastQuestion)->{
@@ -156,6 +161,8 @@ public class QuestionFlowService {
             // 根据扩展确定exercise还是examination
             UserPaper paper = userPaperService.get(report.getPaperId());
             this.bindQuestionNo(question, questionNoId, SettingKey.getTimeByPaperModule(PaperModule.ValueOf(paper.getModuleExtend())));
+            // 设定最后一次错题记录
+            usersService.edit(User.builder().id(question.getUserId()).latestError(report.getPaperId()).build());
             return true;
         });
         nextCallback.put(PaperModule.SENTENCE, (question, report, lastQuestion)->{
@@ -250,6 +257,21 @@ public class QuestionFlowService {
     }
 
     /**
+     * 获取单个report信息:基础
+     * @param userId
+     * @param userReportId
+     * @return
+     */
+    public UserReportRelation baseReport(Integer userId, Integer userReportId){
+        UserReport userReport = userReportService.get(userReportId);
+        if (!userReport.getUserId().equals(userId)){
+            throw new ParameterException("试卷不存在");
+        }
+
+        return relationReport(userReport);
+    }
+
+    /**
      * 获取report的下一道题
      * @param userId
      * @param userReportId

+ 42 - 7
server/gateway-api/src/main/java/com/qxgmat/service/extend/TradeService.java

@@ -9,7 +9,9 @@ import com.qxgmat.data.constants.enums.trade.PayType;
 import com.qxgmat.data.constants.enums.trade.TradeStatus;
 import com.qxgmat.data.dao.PayMapper;
 import com.qxgmat.data.dao.entity.Pay;
+import com.qxgmat.data.dao.entity.UserPay;
 import com.qxgmat.service.inline.UserClassService;
+import com.qxgmat.service.inline.UserPayService;
 import com.qxgmat.service.inline.UserServiceService;
 import com.qxgmat.util.annotation.Callback;
 import org.springframework.stereotype.Service;
@@ -32,25 +34,58 @@ public class TradeService extends AbstractService {
 
     @Resource
     private UserServiceService userServiceService;
+
     @Resource
     private UserClassService userClassService;
 
-    private Map<PayModule, Callback> payCallback;
+    private Map<PayModule, Callback> payCallback = new HashMap<>();;
+
+    @Resource
+    private UserPayService userPayService;
 
     public TradeService(){
-        payCallback = new HashMap<>();
-        payCallback.put(PayModule.SERVICE, (pay)->{
-            return userServiceService.payed((Pay)pay);
+        payCallback.put(PayModule.SERVICE, (obj)->{
+            Pay pay = (Pay) obj;
+            String[] extend = pay.getModuleExtend().split(":");
+            Integer userId = Integer.valueOf(extend[0]);
+            // 写入用户购买
+            userPayService.add(UserPay.builder().module(pay.getModule()).moduleExtend(extend[1]).isUse(0).userId(userId).build());
+            return true;
         });
-        payCallback.put(PayModule.CLASS, (pay)->{
-            return userClassService.payed((Pay)pay);
+        payCallback.put(PayModule.CLASS, (obj)->{
+            Pay pay = (Pay) obj;
+            String[] extend = pay.getModuleExtend().split(":");
+            Integer userId = Integer.valueOf(extend[0]);
+            // 写入用户购买
+            userPayService.add(UserPay.builder().module(pay.getModule()).moduleExtend(extend[1]).isUse(0).userId(userId).build());
+            return true;
+        });
+        payCallback.put(PayModule.DATA, (obj)->{
+            Pay pay = (Pay) obj;
+            String[] extend = pay.getModuleExtend().split(":");
+            Integer userId = Integer.valueOf(extend[0]);
+            // 写入用户购买
+            userPayService.add(UserPay.builder().module(pay.getModule()).moduleExtend(extend[1]).isUse(0).userId(userId).build());
+            return true;
         });
     }
 
+    /**
+     * 对于用户的支付方式
+     * @param userId
+     * @param subject
+     * @param body
+     * @param module
+     * @param moduleExtend
+     * @param money
+     * @param payType
+     * @param request
+     * @return
+     */
     public Pay pay(Number userId, String subject, String body, String module, String moduleExtend, BigDecimal money, PayType payType, HttpServletRequest request){
         if(!payCallback.containsKey(module))
             throw new ParameterException("不支持的支付模块");
-
+        moduleExtend = String.valueOf(userId)+":"+moduleExtend;
         Pay pay = Pay.builder()
                 .subject(subject)
                 .body(body)

+ 1 - 13
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserClassService.java

@@ -28,22 +28,10 @@ public class UserClassService extends AbstractService {
     @Resource
     private UserPayService userPayService;
 
-    // 完成服务支付
-    public boolean payed(Pay pay){
-        String[] extend = pay.getModuleExtend().split(":");
-        Integer userId = Integer.valueOf(extend[0]);
-        // 写入用户购买
-        userPayService.add(UserPay.builder().module(pay.getModule()).moduleExtend("").isUse(0).userId(userId).build());
-        return true;
-    }
-
     // 开通服务
     public boolean used(UserPay pay){
-        String[] extend = pay.getModuleExtend().split(":");
-        Integer userId = Integer.valueOf(extend[0]);
-        Integer category = Integer.valueOf(extend[1]);
         // todo 分析时长
-        add(UserClass.builder().userId(userId).category(category).build());
+        add(UserClass.builder().userId(pay.getUserId()).category(Integer.valueOf(pay.getModuleExtend())).build());
         return true;
     }
 

+ 1 - 16
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserServiceService.java

@@ -23,25 +23,10 @@ public class UserServiceService extends AbstractService {
     @Resource
     private UserServiceMapper userServiceMapper;
 
-    @Resource
-    private UserPayService userPayService;
-
-    // 完成服务支付
-    public boolean payed(Pay pay){
-        String[] extend = pay.getModuleExtend().split(":");
-        Integer userId = Integer.valueOf(extend[0]);
-        // 写入用户购买
-        userPayService.add(UserPay.builder().module(pay.getModule()).moduleExtend("").isUse(0).userId(userId).build());
-        return true;
-    }
 
     // 开通服务
     public boolean used(UserPay pay){
-        String[] extend = pay.getModuleExtend().split(":");
-        Integer userId = Integer.valueOf(extend[0]);
-        String category = extend[1];
-        // todo 分析时长
-        add(UserService.builder().userId(userId).service(category).build());
+        add(UserService.builder().userId(pay.getUserId()).service(pay.getModuleExtend()).build());
         return true;
     }
 

+ 84 - 6
server/gateway-api/src/main/java/com/qxgmat/task/ScheduledTask.java

@@ -1,9 +1,15 @@
 package com.qxgmat.task;
 
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.github.pagehelper.Page;
+import com.nuliji.tools.third.OauthData;
 import com.qxgmat.data.constants.enums.SettingKey;
 import com.qxgmat.data.dao.entity.Setting;
+import com.qxgmat.data.dao.entity.User;
 import com.qxgmat.data.dao.entity.UserService;
+import com.qxgmat.data.relation.entity.UserPrepareRelation;
+import com.qxgmat.help.WechatHelp;
 import com.qxgmat.service.UsersService;
 import com.qxgmat.service.inline.SettingService;
 import org.slf4j.Logger;
@@ -12,10 +18,12 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
+import javax.annotation.Resource;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.List;
 
 /**
  * Created by gaojie on 2017/11/20.
@@ -33,28 +41,98 @@ public class ScheduledTask {
     @Autowired
     private UsersService usersService;
 
+    @Autowired
+    private WechatHelp wechatHelp;
+
     /**
      * cron表达式:* * * * * *(共6位,使用空格隔开,具体如下)
      * cron表达式:*(秒0-59) *(分钟0-59) *(小时0-23) *(日期1-31) *(月份1-12或是JAN-DEC) *(星期1-7或是SUN-SAT)
      * 注意: 30 * * * * * 表示每分钟的第30秒执行,而(*斜杠30)表示每30秒执行
      *
      * */
-    @Scheduled(cron="0 0 * * * *")
-    public void refreshToken(){
-        // 每小时刷新快过期用户的accessToken
 
+
+    // 每小时刷新快过期用户的accessToken
+    @Scheduled(cron="0 0 * * * *")
+    public void refreshWechatToken(){
+        logger.info("Start refresh Wechat token");
+        int page = 1;
+        int size = 100;
+        Date date = new Date();
+        Page<User> userList;
+        do{
+            userList = usersService.listByWechatExpire(page, size, date);
+            for(User user : userList){
+                OauthData data = wechatHelp.refreshNative(user.getWechatRefreshToken());
+                usersService.edit(User.builder()
+                        .id(user.getId())
+                        .wechatAccessToken(data.getAccessToken())
+                        .wechatRefreshToken(data.getRefreshToken())
+                        .wechatExpireTime(data.getExpiresTime())
+                        .build()
+                );
+            }
+        }while(userList.size() >= size);
     }
 
+    // 每小时刷新备考统计信息
     @Scheduled(cron="0 0 * * * *")
     public void refreshPrepare(){
-        // 每小时刷新备考统计信息
-        Setting setting = Setting.builder().value(new JSONObject()).build();
+        logger.info("Start refresh Prepare");
+        JSONObject value = new JSONObject();
+        // 分别统计不同信息
+        List<UserPrepareRelation> relations = null;
+        // 身份
+        relations = usersService.statPrepareStatus();
+        JSONArray status = new JSONArray();
+        for(UserPrepareRelation relation : relations){
+            JSONObject one = new JSONObject();
+            one.put("key", relation.getS());
+            one.put("value", relation.getNumber());
+            status.add(one);
+        }
+        value.put("status", status);
+
+        // 考分
+        relations = usersService.statPrepareGoal();
+        JSONArray goal = new JSONArray();
+        for(UserPrepareRelation relation : relations){
+            JSONObject one = new JSONObject();
+            one.put("key", relation.getI());
+            one.put("value", relation.getNumber());
+            goal.add(one);
+        }
+        value.put("goal", goal);
+
+        // 考试时间
+        relations = usersService.statPrepareExaminationTime();
+        JSONArray examinationTime = new JSONArray();
+        for(UserPrepareRelation relation : relations){
+            JSONObject one = new JSONObject();
+            one.put("key", relation.getS());
+            one.put("value", relation.getNumber());
+            examinationTime.add(one);
+        }
+        value.put("examinationTime", examinationTime);
+
+        // 出分时间
+        relations = usersService.statPrepareScoreTime();
+        JSONArray scoreTime = new JSONArray();
+        for(UserPrepareRelation relation : relations){
+            JSONObject one = new JSONObject();
+            one.put("key", relation.getS());
+            one.put("value", relation.getNumber());
+            scoreTime.add(one);
+        }
+        value.put("scoreTime", scoreTime);
+
+        Setting setting = Setting.builder().value(value).build();
         settingService.editByKey(SettingKey.PREPARE_INFO, setting);
     }
 
+    // 每天判断是否自动组卷
     @Scheduled(cron="0 1 0 * * *")
     public void autoExercisePaper() throws ParseException {
-        // 每天判断是否自动组卷
         Setting setting = settingService.getByKey(SettingKey.EXERCISE_PAPER_AUTO);
         JSONObject value = setting.getValue();
         String dateString = value.getString("date");

+ 7 - 3
server/tools/src/main/java/com/nuliji/tools/third/wechat/WechatClient.java

@@ -143,14 +143,18 @@ public class WechatClient {
         return object;
     }
 
-    public JSONObject refreshWebAccessToken(String refreshToken){
+    public OauthData refreshWebAccessToken(String refreshToken){
         Map<String, String> params = new HashMap<>();
         params.put("appid", appId);
         params.put("refresh_token", refreshToken);
         params.put("grant_type", "refresh_token");
-        JSONObject object = execute("https://api.weixin.qq.com/sns/oauth2/refresh_token", params, null);
+        JSONObject result = execute("https://api.weixin.qq.com/sns/oauth2/refresh_token", params, null);
+        OauthData data = new OauthData();
+        data.setRefreshToken(result.getString("refresh_token"));
+        data.setAccessToken(result.getString("access_token"));
+        data.setExpiresTime(new Date(new Date().getTime() + result.getInteger("expires_in")));
 
-        return object;
+        return data;
     }
 
     /**