Browse Source

feat(server): 添加前端接口

Go 5 years ago
parent
commit
a416512077
20 changed files with 915 additions and 95 deletions
  1. 32 32
      server/data/src/main/java/com/qxgmat/data/dao/entity/UserCollect.java
  2. 35 0
      server/data/src/main/java/com/qxgmat/data/dao/entity/UserNote.java
  3. 3 3
      server/data/src/main/java/com/qxgmat/data/dao/mapping/UserCollectMapper.xml
  4. 2 1
      server/data/src/main/java/com/qxgmat/data/dao/mapping/UserNoteMapper.xml
  5. 33 0
      server/gateway-api/src/main/java/com/qxgmat/controller/api/AuthController.java
  6. 0 8
      server/gateway-api/src/main/java/com/qxgmat/controller/api/BaseController.java
  7. 97 19
      server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java
  8. 120 0
      server/gateway-api/src/main/java/com/qxgmat/controller/api/QuestionController.java
  9. 194 0
      server/gateway-api/src/main/java/com/qxgmat/controller/api/SentenceController.java
  10. 0 30
      server/gateway-api/src/main/java/com/qxgmat/controller/gateway/OauthController.java
  11. 17 0
      server/gateway-api/src/main/java/com/qxgmat/dto/request/UserCollectDto.java
  12. 28 0
      server/gateway-api/src/main/java/com/qxgmat/dto/request/UserNoteDto.java
  13. 17 0
      server/gateway-api/src/main/java/com/qxgmat/dto/request/UserSentenceCodeDto.java
  14. 38 0
      server/gateway-api/src/main/java/com/qxgmat/dto/request/UserSentenceProcessDto.java
  15. 47 0
      server/gateway-api/src/main/java/com/qxgmat/dto/response/UserSentenceArticleDto.java
  16. 45 0
      server/gateway-api/src/main/java/com/qxgmat/service/inline/SentenceArticleService.java
  17. 17 2
      server/gateway-api/src/main/java/com/qxgmat/service/inline/SentenceCodeService.java
  18. 43 0
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserCollectService.java
  19. 23 0
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserNoteService.java
  20. 124 0
      server/gateway-api/src/main/java/com/qxgmat/service/inline/UserSentenceProcessService.java

+ 32 - 32
server/data/src/main/java/com/qxgmat/data/dao/entity/UserCollect.java

@@ -18,16 +18,16 @@ public class UserCollect implements Serializable {
     private Integer userId;
 
     /**
-     * 模块:question,article
+     * 题目id
      */
-    @Column(name = "`module`")
-    private String module;
+    @Column(name = "`question_id`")
+    private Integer questionId;
 
     /**
-     * 对应模块id
+     * 题目编号id
      */
-    @Column(name = "`module_id`")
-    private Integer moduleId;
+    @Column(name = "`question_no_id`")
+    private Integer questionNoId;
 
     @Column(name = "`create_time`")
     private Date createTime;
@@ -67,39 +67,39 @@ public class UserCollect implements Serializable {
     }
 
     /**
-     * 获取模块:question,article
+     * 获取题目id
      *
-     * @return module - 模块:question,article
+     * @return question_id - 题目id
      */
-    public String getModule() {
-        return module;
+    public Integer getQuestionId() {
+        return questionId;
     }
 
     /**
-     * 设置模块:question,article
+     * 设置题目id
      *
-     * @param module 模块:question,article
+     * @param questionId 题目id
      */
-    public void setModule(String module) {
-        this.module = module;
+    public void setQuestionId(Integer questionId) {
+        this.questionId = questionId;
     }
 
     /**
-     * 获取对应模块id
+     * 获取题目编号id
      *
-     * @return module_id - 对应模块id
+     * @return question_no_id - 题目编号id
      */
-    public Integer getModuleId() {
-        return moduleId;
+    public Integer getQuestionNoId() {
+        return questionNoId;
     }
 
     /**
-     * 设置对应模块id
+     * 设置题目编号id
      *
-     * @param moduleId 对应模块id
+     * @param questionNoId 题目编号id
      */
-    public void setModuleId(Integer moduleId) {
-        this.moduleId = moduleId;
+    public void setQuestionNoId(Integer questionNoId) {
+        this.questionNoId = questionNoId;
     }
 
     /**
@@ -124,8 +124,8 @@ public class UserCollect implements Serializable {
         sb.append("Hash = ").append(hashCode());
         sb.append(", id=").append(id);
         sb.append(", userId=").append(userId);
-        sb.append(", module=").append(module);
-        sb.append(", moduleId=").append(moduleId);
+        sb.append(", questionId=").append(questionId);
+        sb.append(", questionNoId=").append(questionNoId);
         sb.append(", createTime=").append(createTime);
         sb.append("]");
         return sb.toString();
@@ -161,22 +161,22 @@ public class UserCollect implements Serializable {
         }
 
         /**
-         * 设置模块:question,article
+         * 设置题目id
          *
-         * @param module 模块:question,article
+         * @param questionId 题目id
          */
-        public Builder module(String module) {
-            obj.setModule(module);
+        public Builder questionId(Integer questionId) {
+            obj.setQuestionId(questionId);
             return this;
         }
 
         /**
-         * 设置对应模块id
+         * 设置题目编号id
          *
-         * @param moduleId 对应模块id
+         * @param questionNoId 题目编号id
          */
-        public Builder moduleId(Integer moduleId) {
-            obj.setModuleId(moduleId);
+        public Builder questionNoId(Integer questionNoId) {
+            obj.setQuestionNoId(questionNoId);
             return this;
         }
 

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

@@ -23,6 +23,12 @@ public class UserNote implements Serializable {
     @Column(name = "`question_id`")
     private Integer questionId;
 
+    /**
+     * 题目编号id
+     */
+    @Column(name = "`question_no_id`")
+    private Integer questionNoId;
+
     @Column(name = "`create_time`")
     private Date createTime;
 
@@ -88,6 +94,24 @@ public class UserNote implements Serializable {
     }
 
     /**
+     * 获取题目编号id
+     *
+     * @return question_no_id - 题目编号id
+     */
+    public Integer getQuestionNoId() {
+        return questionNoId;
+    }
+
+    /**
+     * 设置题目编号id
+     *
+     * @param questionNoId 题目编号id
+     */
+    public void setQuestionNoId(Integer questionNoId) {
+        this.questionNoId = questionNoId;
+    }
+
+    /**
      * @return create_time
      */
     public Date getCreateTime() {
@@ -142,6 +166,7 @@ public class UserNote implements Serializable {
         sb.append(", id=").append(id);
         sb.append(", userId=").append(userId);
         sb.append(", questionId=").append(questionId);
+        sb.append(", questionNoId=").append(questionNoId);
         sb.append(", createTime=").append(createTime);
         sb.append(", updateTime=").append(updateTime);
         sb.append(", content=").append(content);
@@ -189,6 +214,16 @@ public class UserNote implements Serializable {
         }
 
         /**
+         * 设置题目编号id
+         *
+         * @param questionNoId 题目编号id
+         */
+        public Builder questionNoId(Integer questionNoId) {
+            obj.setQuestionNoId(questionNoId);
+            return this;
+        }
+
+        /**
          * @param createTime
          */
         public Builder createTime(Date createTime) {

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

@@ -7,14 +7,14 @@
     -->
     <id column="id" jdbcType="INTEGER" property="id" />
     <result column="user_id" jdbcType="INTEGER" property="userId" />
-    <result column="module" jdbcType="VARCHAR" property="module" />
-    <result column="module_id" jdbcType="INTEGER" property="moduleId" />
+    <result column="question_id" jdbcType="INTEGER" property="questionId" />
+    <result column="question_no_id" jdbcType="INTEGER" property="questionNoId" />
     <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
   </resultMap>
   <sql id="Base_Column_List">
     <!--
       WARNING - @mbg.generated
     -->
-    `id`, `user_id`, `module`, `module_id`, `create_time`
+    `id`, `user_id`, `question_id`, `question_no_id`, `create_time`
   </sql>
 </mapper>

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

@@ -8,6 +8,7 @@
     <id column="id" jdbcType="INTEGER" property="id" />
     <result column="user_id" jdbcType="INTEGER" property="userId" />
     <result column="question_id" jdbcType="INTEGER" property="questionId" />
+    <result column="question_no_id" jdbcType="INTEGER" property="questionNoId" />
     <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
     <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
   </resultMap>
@@ -21,7 +22,7 @@
     <!--
       WARNING - @mbg.generated
     -->
-    `id`, `user_id`, `question_id`, `create_time`, `update_time`
+    `id`, `user_id`, `question_id`, `question_no_id`, `create_time`, `update_time`
   </sql>
   <sql id="Blob_Column_List">
     <!--

+ 33 - 0
server/gateway-api/src/main/java/com/qxgmat/controller/api/AuthController.java

@@ -1,5 +1,6 @@
 package com.qxgmat.controller.api;
 
+import com.nuliji.tools.MessageHelp;
 import com.nuliji.tools.Response;
 import com.nuliji.tools.ResponseHelp;
 import com.nuliji.tools.Transform;
@@ -21,6 +22,7 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 import javax.validation.Validator;
 
@@ -74,6 +76,37 @@ public class AuthController {
         return ResponseHelp.success(Transform.convert(shiroHelp.getLoginUser(), MyDto.class));
     }
 
+
+    @RequestMapping(value = "/wechat_pc", method = RequestMethod.GET)
+    @ApiOperation(value = "直接微信二维码登录", httpMethod = "GET")
+    public Response<Boolean> directWechatPc(
+            @RequestParam(required = false, defaultValue = "") String code,
+            HttpSession session, HttpServletResponse response) {
+        User user = (User) shiroHelp.getLoginUser();
+        if (user!=null){
+            // 已登录用户,绑定
+            usersService.Oauth(user, code, "wechat_pc");
+        }else{
+            shiroHelp.getSession().login(shiroHelp.oauth(code, "wechat_pc"));
+        }
+        return MessageHelp.success(true);
+    }
+
+    @RequestMapping(value = "/wechat", method = RequestMethod.GET)
+    @ApiOperation(value = "直接微信二维码登录", httpMethod = "GET")
+    public Response<Boolean> directWechat(
+            @RequestParam(required = false, defaultValue = "") String code,
+            HttpSession session, HttpServletResponse response) {
+        User user = (User) shiroHelp.getLoginUser();
+        if (user!=null){
+            // 已登录用户,绑定
+            usersService.Oauth(user, code, "wechat_native");
+        }else{
+            shiroHelp.getSession().login(shiroHelp.oauth(code, "wechat_native"));
+        }
+        return MessageHelp.success(true);
+    }
+
     @RequestMapping(value = "/logout", method = RequestMethod.POST)
     @ApiOperation(value = "登出", httpMethod = "POST")
     public Response<Boolean> logout(HttpSession session, HttpServletRequest request) {

+ 0 - 8
server/gateway-api/src/main/java/com/qxgmat/controller/api/BaseController.java

@@ -75,12 +75,4 @@ public class BaseController {
         List<ExaminationStruct> p = examinationStructService.all();
         return ResponseHelp.success(p);
     }
-
-    @RequestMapping(value = "/sentence/struct", method = RequestMethod.GET)
-    @ApiOperation(value = "所有长难句结构", httpMethod = "GET")
-    public Response<JSONObject> sentenceStruct(HttpSession session) {
-        Setting entity = settingService.getByKey(SettingKey.SENTENCE);
-
-        return ResponseHelp.success(entity.getValue());
-    }
 }

+ 97 - 19
server/gateway-api/src/main/java/com/qxgmat/controller/api/MyController.java

@@ -9,24 +9,17 @@ import com.nuliji.tools.Transform;
 import com.nuliji.tools.exception.ParameterException;
 import com.nuliji.tools.exception.SystemException;
 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.UserMessage;
+import com.qxgmat.data.dao.entity.*;
 import com.qxgmat.data.relation.entity.UserHomeworkPreviewRelation;
 import com.qxgmat.dto.extend.UserHomeworkPreviewExtendDto;
-import com.qxgmat.dto.request.UserEmailDto;
-import com.qxgmat.dto.request.UserInfoDto;
-import com.qxgmat.dto.request.UserPrepareDto;
+import com.qxgmat.dto.request.*;
 import com.qxgmat.dto.response.UserClassDetailDto;
 import com.qxgmat.dto.response.UserPrepareDetailDto;
 import com.qxgmat.dto.response.UserRealDto;
 import com.qxgmat.help.ShiroHelp;
 import com.qxgmat.service.HomeworkPreviewService;
 import com.qxgmat.service.UsersService;
-import com.qxgmat.service.inline.SettingService;
-import com.qxgmat.service.inline.StatDayService;
-import com.qxgmat.service.inline.UserClassService;
-import com.qxgmat.service.inline.UserMessageService;
+import com.qxgmat.service.inline.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -83,7 +76,16 @@ public class MyController {
     private UserClassService userClassService;
 
     @Autowired
-    private HomeworkPreviewService homeworkPreviewService;
+    private UserServiceService userServiceService;
+
+    @Autowired
+    private UserCollectService userCollectService;
+
+    @Autowired
+    private UserNoteService userNoteService;
+
+    @Autowired
+    private UserQuestionService userQuestionService;
 
     @RequestMapping(value = "/email", method = RequestMethod.POST)
     @ApiOperation(value = "绑定邮箱", httpMethod = "POST")
@@ -203,26 +205,102 @@ public class MyController {
         return ResponseHelp.success(dto);
     }
 
+    @RequestMapping(value = "/collect", method = RequestMethod.PUT)
+    @ApiOperation(value = "添加收藏", notes = "添加收藏", httpMethod = "PUT")
+    public Response<Boolean> collectAdd(@RequestBody @Validated UserCollectDto dto)  {
+        UserCollect entity = Transform.dtoToEntity(dto);
+        User user = (User) shiroHelp.getLoginUser();
+        userCollectService.addQuestion(user.getId(), entity.getQuestionNoId());
+
+        return ResponseHelp.success(true);
+    }
+
+    @RequestMapping(value = "/collect", method = RequestMethod.DELETE)
+    @ApiOperation(value = "移除收藏", notes = "移除收藏", httpMethod = "DELETE")
+    public Response<Boolean> collectDelete(int id)  {
+        User user = (User) shiroHelp.getLoginUser();
+        Boolean result = userCollectService.deleteQuestion(user.getId(), id);
+
+        return ResponseHelp.success(result);
+    }
+
+    @RequestMapping(value = "/collect/list", method = RequestMethod.GET)
+    @ApiOperation(value = "获取收藏列表", notes = "获取收藏列表", httpMethod = "GET")
+    public Response<PageMessage<UserHomeworkPreviewExtendDto>> collectList(
+            @RequestParam(required = false, defaultValue = "1") int page,
+            @RequestParam(required = false, defaultValue = "100") int size,
+            @RequestParam(required = true) String module,
+            @RequestParam(required = false) Number category,
+            @RequestParam(required = false) String endTime,
+            @RequestParam(required = false) Boolean finish
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        Page<UserHomeworkPreviewRelation> p = userCollectService.list(page, size, category, user.getId(), endTime, finish);
+
+        List<UserHomeworkPreviewExtendDto> pr = Transform.convert(p, UserHomeworkPreviewExtendDto.class);
+
+        return ResponseHelp.success(pr, page, size, p.getTotal());
+    }
+
+    @RequestMapping(value = "/error/list", method = RequestMethod.GET)
+    @ApiOperation(value = "获取错题列表", notes = "获取错题列表", httpMethod = "GET")
+    public Response<PageMessage<UserHomeworkPreviewExtendDto>> errorList(
+            @RequestParam(required = false, defaultValue = "1") int page,
+            @RequestParam(required = false, defaultValue = "100") int size,
+            @RequestParam(required = true) String module,
+            @RequestParam(required = false) Number category,
+            @RequestParam(required = false) String endTime,
+            @RequestParam(required = false) Boolean finish
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        Page<UserHomeworkPreviewRelation> p = userQuestionService.list(page, size, category, user.getId(), endTime, finish);
+
+        List<UserHomeworkPreviewExtendDto> pr = Transform.convert(p, UserHomeworkPreviewExtendDto.class);
 
-    @RequestMapping(value = "/class/list", method = RequestMethod.GET)
-    @ApiOperation(value = "获取课程", notes = "获取所有课程及状态", httpMethod = "GET")
-    public Response<List<UserClassDetailDto>> classList()  {
+        return ResponseHelp.success(pr, page, size, p.getTotal());
+    }
+
+    @RequestMapping(value = "/note", method = RequestMethod.PUT)
+    @ApiOperation(value = "更新笔记", notes = "更新笔记", httpMethod = "PUT")
+    public Response<Boolean> noteUpdate(@RequestBody @Validated UserNoteDto dto)  {
+        UserNote entity = Transform.dtoToEntity(dto);
         User user = (User) shiroHelp.getLoginUser();
+        entity.setUserId(user.getId());
+        userNoteService.update(entity);
 
-        return ResponseHelp.success(null);
+        return ResponseHelp.success(true);
+    }
+
+    @RequestMapping(value = "/note/list", method = RequestMethod.GET)
+    @ApiOperation(value = "获取笔记列表", notes = "获取笔记列表", httpMethod = "GET")
+    public Response<PageMessage<UserHomeworkPreviewExtendDto>> noteList(
+            @RequestParam(required = false, defaultValue = "1") int page,
+            @RequestParam(required = false, defaultValue = "100") int size,
+            @RequestParam(required = true) String module,
+            @RequestParam(required = false) Number category,
+            @RequestParam(required = false) String endTime,
+            @RequestParam(required = false) Boolean finish
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        Page<UserHomeworkPreviewRelation> p = userNoteService.list(page, size, category, user.getId(), endTime, finish);
+
+        List<UserHomeworkPreviewExtendDto> pr = Transform.convert(p, UserHomeworkPreviewExtendDto.class);
+
+        return ResponseHelp.success(pr, page, size, p.getTotal());
     }
 
-    @RequestMapping(value = "/preview/list", method = RequestMethod.GET)
-    @ApiOperation(value = "获取预习作业列表", notes = "获取预习作业列表", httpMethod = "GET")
-    public Response<PageMessage<UserHomeworkPreviewExtendDto>> previewList(
+    @RequestMapping(value = "/report/list", method = RequestMethod.GET)
+    @ApiOperation(value = "获取报告列表", notes = "获取报告列表", httpMethod = "GET")
+    public Response<PageMessage<UserHomeworkPreviewExtendDto>> reportList(
             @RequestParam(required = false, defaultValue = "1") int page,
             @RequestParam(required = false, defaultValue = "100") int size,
+            @RequestParam(required = true) String module,
             @RequestParam(required = false) Number category,
             @RequestParam(required = false) String endTime,
             @RequestParam(required = false) Boolean finish
     )  {
         User user = (User) shiroHelp.getLoginUser();
-        Page<UserHomeworkPreviewRelation> p = homeworkPreviewService.list(page, size, category, user.getId(), endTime, finish);
+        Page<UserHomeworkPreviewRelation> p = userNoteService.list(page, size, category, user.getId(), endTime, finish);
 
         List<UserHomeworkPreviewExtendDto> pr = Transform.convert(p, UserHomeworkPreviewExtendDto.class);
 

+ 120 - 0
server/gateway-api/src/main/java/com/qxgmat/controller/api/QuestionController.java

@@ -1,15 +1,26 @@
 package com.qxgmat.controller.api;
 
 
+import com.github.pagehelper.Page;
+import com.nuliji.tools.PageMessage;
 import com.nuliji.tools.Response;
 import com.nuliji.tools.ResponseHelp;
+import com.nuliji.tools.Transform;
+import com.qxgmat.data.dao.entity.ExercisePaper;
 import com.qxgmat.data.dao.entity.ExerciseStruct;
+import com.qxgmat.data.dao.entity.User;
+import com.qxgmat.data.relation.entity.UserHomeworkPreviewRelation;
+import com.qxgmat.dto.extend.UserHomeworkPreviewExtendDto;
+import com.qxgmat.dto.response.UserClassDetailDto;
+import com.qxgmat.help.ShiroHelp;
+import com.qxgmat.service.HomeworkPreviewService;
 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.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;
@@ -19,6 +30,10 @@ import java.util.List;
 @RequestMapping("/api/question")
 @Api(tags = "题目", description = "题目接口")
 public class QuestionController {
+
+    @Autowired
+    private ShiroHelp shiroHelp;
+
     @Autowired
     private QuestionNoService questionNoService;
 
@@ -31,5 +46,110 @@ public class QuestionController {
     @Autowired
     private UserQuestionService userQuestionService;
 
+    @Autowired
+    private HomeworkPreviewService homeworkPreviewService;
+
+    @RequestMapping(value = "/class/list", method = RequestMethod.GET)
+    @ApiOperation(value = "获取课程", notes = "获取所有课程及状态进度", httpMethod = "GET")
+    public Response<List<UserClassDetailDto>> classList()  {
+        User user = (User) shiroHelp.getLoginUser();
+
+        return ResponseHelp.success(null);
+    }
+
+    @RequestMapping(value = "/exercise/process", method = RequestMethod.GET)
+    @ApiOperation(value = "练习组卷列表", httpMethod = "GET")
+    public Response<PageMessage<ExercisePaper>> exerciseProcess(
+            @RequestParam(required = false, defaultValue = "1") int page,
+            @RequestParam(required = false, defaultValue = "100") int size,
+            HttpSession session) {
+        Page<ExercisePaper> p=null;
+
+        return ResponseHelp.success(p, page, size, p.getTotal());
+    }
+
+    @RequestMapping(value = "/examination/process", method = RequestMethod.GET)
+    @ApiOperation(value = "练习组卷列表", httpMethod = "GET")
+    public Response<PageMessage<ExercisePaper>> examinationProcess(
+            @RequestParam(required = false, defaultValue = "1") int page,
+            @RequestParam(required = false, defaultValue = "100") int size,
+            HttpSession session) {
+        Page<ExercisePaper> p=null;
+
+        return ResponseHelp.success(p, page, size, p.getTotal());
+    }
+
+    @RequestMapping(value = "/examination/paper", method = RequestMethod.GET)
+    @ApiOperation(value = "模考组卷列表", httpMethod = "GET")
+    public Response<PageMessage<ExercisePaper>> examinationPaperList(
+            @RequestParam(required = false, defaultValue = "1") int page,
+            @RequestParam(required = false, defaultValue = "100") int size,
+            HttpSession session) {
+        Page<ExercisePaper> p = null;
+
+        return ResponseHelp.success(p, page, size, p.getTotal());
+    }
+
+
+    @RequestMapping(value = "/preview/list", method = RequestMethod.GET)
+    @ApiOperation(value = "获取预习作业列表", notes = "获取预习作业列表", httpMethod = "GET")
+    public Response<PageMessage<UserHomeworkPreviewExtendDto>> previewList(
+            @RequestParam(required = false, defaultValue = "1") int page,
+            @RequestParam(required = false, defaultValue = "100") int size,
+            @RequestParam(required = false) Number category,
+            @RequestParam(required = false) String endTime,
+            @RequestParam(required = false) Boolean finish
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        Page<UserHomeworkPreviewRelation> p = homeworkPreviewService.list(page, size, category, user.getId(), endTime, finish);
+
+        List<UserHomeworkPreviewExtendDto> pr = Transform.convert(p, UserHomeworkPreviewExtendDto.class);
+
+        return ResponseHelp.success(pr, page, size, p.getTotal());
+    }
+
+    @RequestMapping(value = "/detail", method = RequestMethod.GET)
+    @ApiOperation(value = "获取题目详情", notes = "获取题目详情", httpMethod = "GET")
+    public Response<User> detail(
+            @RequestParam(required = false) String questionNoId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        return ResponseHelp.success(null);
+    }
+
+    @RequestMapping(value = "/start", method = RequestMethod.POST)
+    @ApiOperation(value = "开始考试", notes = "提交考试设置", httpMethod = "POST")
+    public Response<User> start(
+            @RequestParam(required = false) String paperId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        return ResponseHelp.success(null);
+    }
+
+    @RequestMapping(value = "/next", method = RequestMethod.POST)
+    @ApiOperation(value = "获取下一题", notes = "获取下一题", httpMethod = "POST")
+    public Response<User> next(
+            @RequestParam(required = false) String reportId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        return ResponseHelp.success(null);
+    }
+
+    @RequestMapping(value = "/submit", method = RequestMethod.POST)
+    @ApiOperation(value = "提交题目答案", notes = "提交题目", httpMethod = "POST")
+    public Response<User> submit(
+            @RequestParam(required = false) String questionNoId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        return ResponseHelp.success(null);
+    }
 
+    @RequestMapping(value = "/finish", method = RequestMethod.POST)
+    @ApiOperation(value = "完成考试", notes = "完成考试", httpMethod = "POST")
+    public Response<User> finish(
+            @RequestParam(required = false) String paperId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        return ResponseHelp.success(null);
+    }
 }

+ 194 - 0
server/gateway-api/src/main/java/com/qxgmat/controller/api/SentenceController.java

@@ -0,0 +1,194 @@
+package com.qxgmat.controller.api;
+
+import com.alibaba.fastjson.JSONObject;
+import com.nuliji.tools.Response;
+import com.nuliji.tools.ResponseHelp;
+import com.nuliji.tools.Transform;
+import com.qxgmat.data.constants.enums.SettingKey;
+import com.qxgmat.data.dao.entity.*;
+import com.qxgmat.dto.request.UserSentenceCodeDto;
+import com.qxgmat.dto.request.UserSentenceProcessDto;
+import com.qxgmat.dto.response.UserSentenceArticleDto;
+import com.qxgmat.help.ShiroHelp;
+import com.qxgmat.service.SentencePaperService;
+import com.qxgmat.service.UsersService;
+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.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpSession;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api/sentence")
+@Api(tags = "长难句", description = "长难句接口")
+public class SentenceController
+{
+    @Autowired
+    private ShiroHelp shiroHelp;
+
+    @Autowired
+    private UserPaperService userPaperService;
+
+    @Autowired
+    private UserReportService userReportService;
+
+    @Autowired
+    private UserQuestionService userQuestionService;
+
+    @Autowired
+    private SentenceArticleService sentenceArticleService;
+
+    @Autowired
+    private SentenceQuestionService sentenceQuestionService;
+
+    @Autowired
+    private SentencePaperService sentencePaperService;
+
+    @Autowired
+    private UserSentenceProcessService userSentenceProcessService;
+
+    @Autowired
+    private UsersService usersService;
+
+    @Autowired
+    private SentenceCodeService sentenceCodeService;
+
+    @Autowired
+    private SettingService settingService;
+
+    @RequestMapping(value = "/info", method = RequestMethod.GET)
+    @ApiOperation(value = "所有长难句信息", httpMethod = "GET")
+    public Response<JSONObject> sentenceInfo(HttpSession session) {
+        Setting entity = settingService.getByKey(SettingKey.SENTENCE);
+        JSONObject value = entity.getValue();
+
+        // 用户code状态
+        User user = (User) shiroHelp.getLoginUser();
+        SentenceCode code = sentenceCodeService.isActive(user.getId());
+        if (code != null){
+            value.put("code", code.getCode());
+        }
+        // 查询用户进度
+        List<UserSentenceProcess> processList = userSentenceProcessService.listTotal(user.getId());
+        Map process = Transform.getMap(processList,UserSentenceProcess.class, "chapter", "process");
+        value.put("process", process);
+
+        return ResponseHelp.success(value);
+    }
+
+    @RequestMapping(value = "/active", method = RequestMethod.PUT)
+    @ApiOperation(value = "激活长难句", httpMethod = "PUT")
+    public Response<Boolean> active(@RequestBody @Validated UserSentenceCodeDto dto) {
+        UserSentenceProcess entity = Transform.dtoToEntity(dto);
+        User user = (User) shiroHelp.getLoginUser();
+
+        if (sentenceCodeService.isActive(user.getId()) == null){
+            sentenceCodeService.active(user.getId(), dto.getCode());
+        }
+
+        return ResponseHelp.success(true);
+    }
+
+    @RequestMapping(value = "/article/list", method = RequestMethod.GET)
+    @ApiOperation(value = "长难句文章列表", httpMethod = "GET")
+    public Response<List<UserSentenceArticleDto>> articleList(
+            @RequestParam(required = true) Integer chapter,
+            HttpSession session) {
+        User user = (User) shiroHelp.getLoginUser();
+        // 查询用户code
+
+        if (sentenceCodeService.isActive(user.getId()) != null){
+            List<SentenceArticle> p = sentenceArticleService.listByChapter(chapter);
+            List<UserSentenceArticleDto> pr = Transform.convert(p, UserSentenceArticleDto.class);
+
+            // 查询文章进度
+            List<UserSentenceProcess> processList = userSentenceProcessService.listByChapter(user.getId(), chapter);
+            Map process = Transform.getMap(processList,UserSentenceProcess.class, "part", "process");
+            Transform.combine(pr, process, UserSentenceArticleDto.class, "part", "process");
+            return ResponseHelp.success(pr);
+        } else {
+            List<SentenceArticle> p = sentenceArticleService.listByTrail();
+            List<UserSentenceArticleDto> pr = Transform.convert(p, UserSentenceArticleDto.class);
+
+            List<UserSentenceProcess> processList = userSentenceProcessService.listAllByTrail(user.getId());
+
+            return ResponseHelp.success(pr);
+        }
+    }
+
+    @RequestMapping(value = "/article/process", method = RequestMethod.PUT)
+    @ApiOperation(value = "更新长难句文章进度", httpMethod = "PUT")
+    public Response<Boolean> articleProcess(@RequestBody @Validated UserSentenceProcessDto dto) {
+        UserSentenceProcess entity = Transform.dtoToEntity(dto);
+        User user = (User) shiroHelp.getLoginUser();
+        // 获取本章节的最大part数
+        Integer max = sentenceArticleService.maxPart(dto.getChapter());
+
+        userSentenceProcessService.updateProcess(user.getId(), dto.getChapter(), dto.getPart(), dto.getProcess(), max);
+        return ResponseHelp.success(true);
+    }
+
+    @RequestMapping(value = "/paper/list", method = RequestMethod.GET)
+    @ApiOperation(value = "长难句组卷列表", httpMethod = "GET")
+    public Response<List<UserSentenceArticleDto>> paperList(
+            HttpSession session) {
+        User user = (User) shiroHelp.getLoginUser();
+        // 查询用户code
+        if (sentenceCodeService.isActive(user.getId()) != null){
+
+        } else {
+
+        }
+        return ResponseHelp.success(null);
+    }
+
+    @RequestMapping(value = "/question/detail", method = RequestMethod.GET)
+    @ApiOperation(value = "获取题目详情", notes = "获取题目详情", httpMethod = "GET")
+    public Response<User> detail(
+            @RequestParam(required = false) String questionNoId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        return ResponseHelp.success(null);
+    }
+
+    @RequestMapping(value = "/paper/start", method = RequestMethod.POST)
+    @ApiOperation(value = "开始做题", notes = "提交考试设置", httpMethod = "POST")
+    public Response<User> start(
+            @RequestParam(required = false) String paperId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        return ResponseHelp.success(null);
+    }
+
+    @RequestMapping(value = "/paper/next", method = RequestMethod.POST)
+    @ApiOperation(value = "获取下一题", notes = "获取下一题", httpMethod = "POST")
+    public Response<User> next(
+            @RequestParam(required = false) String reportId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        return ResponseHelp.success(null);
+    }
+
+    @RequestMapping(value = "/paper/submit", method = RequestMethod.POST)
+    @ApiOperation(value = "提交题目答案", notes = "提交题目", httpMethod = "POST")
+    public Response<User> submit(
+            @RequestParam(required = false) String questionNoId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        return ResponseHelp.success(null);
+    }
+
+    @RequestMapping(value = "/paper/finish", method = RequestMethod.POST)
+    @ApiOperation(value = "完成考试", notes = "完成考试", httpMethod = "POST")
+    public Response<User> finish(
+            @RequestParam(required = false) String paperId
+    )  {
+        User user = (User) shiroHelp.getLoginUser();
+        return ResponseHelp.success(null);
+    }
+}

+ 0 - 30
server/gateway-api/src/main/java/com/qxgmat/controller/gateway/OauthController.java

@@ -61,34 +61,4 @@ public class OauthController {
         }
         response.sendRedirect(jump.toString());
     }
-
-    @RequestMapping(value = "/direct/wechat_pc", method = RequestMethod.GET)
-    @ApiOperation(value = "直接微信二维码登录", httpMethod = "GET")
-    public Response<Boolean> directWechatPc(
-            @RequestParam(required = false, defaultValue = "") String code,
-            HttpSession session, HttpServletResponse response) {
-        User user = (User) shiroHelp.getLoginUser();
-        if (user!=null){
-            // 已登录用户,绑定
-            usersService.Oauth(user, code, "wechat_pc");
-        }else{
-            shiroHelp.getSession().login(shiroHelp.oauth(code, "wechat_pc"));
-        }
-        return MessageHelp.success(true);
-    }
-
-    @RequestMapping(value = "/direct/wechat", method = RequestMethod.GET)
-    @ApiOperation(value = "直接微信二维码登录", httpMethod = "GET")
-    public Response<Boolean> directWechat(
-            @RequestParam(required = false, defaultValue = "") String code,
-            HttpSession session, HttpServletResponse response) {
-        User user = (User) shiroHelp.getLoginUser();
-        if (user!=null){
-            // 已登录用户,绑定
-            usersService.Oauth(user, code, "wechat_native");
-        }else{
-            shiroHelp.getSession().login(shiroHelp.oauth(code, "wechat_native"));
-        }
-        return MessageHelp.success(true);
-    }
 }

+ 17 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/request/UserCollectDto.java

@@ -0,0 +1,17 @@
+package com.qxgmat.dto.request;
+
+import com.nuliji.tools.annotation.Dto;
+import com.qxgmat.data.dao.entity.UserCollect;
+
+@Dto(entity = UserCollect.class)
+public class UserCollectDto {
+    private Integer questionNoId;
+
+    public Integer getQuestionNoId() {
+        return questionNoId;
+    }
+
+    public void setQuestionNoId(Integer questionNoId) {
+        this.questionNoId = questionNoId;
+    }
+}

+ 28 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/request/UserNoteDto.java

@@ -0,0 +1,28 @@
+package com.qxgmat.dto.request;
+
+import com.nuliji.tools.annotation.Dto;
+import com.qxgmat.data.dao.entity.UserNote;
+
+@Dto(entity = UserNote.class)
+public class UserNoteDto {
+
+    private Integer questionNoId;
+
+    private String content;
+
+    public Integer getQuestionNoId() {
+        return questionNoId;
+    }
+
+    public void setQuestionNoId(Integer questionNoId) {
+        this.questionNoId = questionNoId;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+}

+ 17 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/request/UserSentenceCodeDto.java

@@ -0,0 +1,17 @@
+package com.qxgmat.dto.request;
+
+import com.nuliji.tools.annotation.Dto;
+import com.qxgmat.data.dao.entity.SentenceCode;
+
+@Dto(entity = SentenceCode.class)
+public class UserSentenceCodeDto {
+    private String code;
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+}

+ 38 - 0
server/gateway-api/src/main/java/com/qxgmat/dto/request/UserSentenceProcessDto.java

@@ -0,0 +1,38 @@
+package com.qxgmat.dto.request;
+
+import com.nuliji.tools.annotation.Dto;
+import com.qxgmat.data.dao.entity.UserSentenceProcess;
+
+@Dto(entity = UserSentenceProcess.class)
+public class UserSentenceProcessDto {
+
+    private Integer chapter;
+
+    private Integer part;
+
+    private Integer process;
+
+    public Integer getChapter() {
+        return chapter;
+    }
+
+    public void setChapter(Integer chapter) {
+        this.chapter = chapter;
+    }
+
+    public Integer getPart() {
+        return part;
+    }
+
+    public void setPart(Integer part) {
+        this.part = part;
+    }
+
+    public Integer getProcess() {
+        return process;
+    }
+
+    public void setProcess(Integer process) {
+        this.process = process;
+    }
+}

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

@@ -0,0 +1,47 @@
+package com.qxgmat.dto.response;
+
+import com.nuliji.tools.annotation.Dto;
+import com.qxgmat.data.dao.entity.SentenceArticle;
+
+@Dto(entity = SentenceArticle.class)
+public class UserSentenceArticleDto {
+    private Integer process;
+
+    private String title;
+
+    private Integer isTrail;
+
+    private Integer part;
+
+    public Integer getProcess() {
+        return process;
+    }
+
+    public void setProcess(Integer process) {
+        this.process = process;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public Integer getIsTrail() {
+        return isTrail;
+    }
+
+    public void setIsTrail(Integer isTrail) {
+        this.isTrail = isTrail;
+    }
+
+    public Integer getPart() {
+        return part;
+    }
+
+    public void setPart(Integer part) {
+        this.part = part;
+    }
+}

+ 45 - 0
server/gateway-api/src/main/java/com/qxgmat/service/inline/SentenceArticleService.java

@@ -23,6 +23,51 @@ public class SentenceArticleService extends AbstractService {
     @Resource
     private SentenceArticleMapper sentenceArticleMapper;
 
+    /**
+     * 获取长难句单个章节所有文章
+     * @param chapter
+     * @return
+     */
+    public List<SentenceArticle> listByChapter(Number chapter){
+        Example example = new Example(SentenceArticle.class);
+        example.and(
+                example.createCriteria()
+                        .andEqualTo("chapter", chapter)
+        );
+        example.orderBy("part").asc();
+        return select(sentenceArticleMapper, example);
+    }
+
+    /**
+     * 获取所有试用章节文章
+     * @return
+     */
+    public List<SentenceArticle> listByTrail(){
+        Example example = new Example(SentenceArticle.class);
+        example.and(
+                example.createCriteria()
+                        .andEqualTo("isTrail", 1)
+        );
+        example.setOrderByClause("chapter asc,part asc");
+        return select(sentenceArticleMapper, example);
+    }
+
+    /**
+     * 获取章节下最大
+     * @param chapter
+     * @return
+     */
+    public Integer maxPart(Integer chapter){
+        Example example = new Example(SentenceArticle.class);
+        example.and(
+                example.createCriteria()
+                        .andEqualTo("chapter", chapter)
+        );
+        example.selectProperties("part");
+        example.setOrderByClause("part desc");
+        SentenceArticle entity = one(sentenceArticleMapper, example);
+        return entity != null ? entity.getPart() : 0;
+    }
 
     public SentenceArticle add(SentenceArticle article){
         int result = insert(sentenceArticleMapper, article);

+ 17 - 2
server/gateway-api/src/main/java/com/qxgmat/service/inline/SentenceCodeService.java

@@ -27,13 +27,14 @@ public class SentenceCodeService extends AbstractService {
 
     /**
      * 查询并激活
+     * @param userId
      * @param code
      * @return
      */
     @Transactional
-    public SentenceCode active(String code, Integer userId){
+    public SentenceCode active(Integer userId, String code){
         Example example = new Example(SentenceCode.class);
-        example.or(
+        example.and(
                 example.createCriteria()
                         .andEqualTo("code", code)
         );
@@ -49,6 +50,20 @@ public class SentenceCodeService extends AbstractService {
         return entity;
     }
 
+    /**
+     * 获取用户code激活
+     * @param userId
+     * @return
+     */
+    public SentenceCode isActive(Integer userId){
+        Example example = new Example(SentenceCode.class);
+        example.and(
+                example.createCriteria()
+                        .andEqualTo("userId", userId)
+        );
+        return one(sentenceCodeMapper, example);
+    }
+
     public SentenceCode add(SentenceCode code){
         int result = insert(sentenceCodeMapper, code);
         code = one(sentenceCodeMapper, code.getId());

+ 43 - 0
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserCollectService.java

@@ -4,13 +4,16 @@ import com.github.pagehelper.Page;
 import com.nuliji.tools.AbstractService;
 import com.nuliji.tools.exception.ParameterException;
 import com.nuliji.tools.exception.SystemException;
+import com.nuliji.tools.mybatis.Example;
 import com.qxgmat.data.dao.UserAskMapper;
 import com.qxgmat.data.dao.UserCollectMapper;
+import com.qxgmat.data.dao.entity.QuestionNo;
 import com.qxgmat.data.dao.entity.UserAsk;
 import com.qxgmat.data.dao.entity.UserCollect;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.util.Collection;
@@ -23,6 +26,46 @@ public class UserCollectService extends AbstractService {
     @Resource
     private UserCollectMapper userCollectMapper;
 
+    @Resource
+    private QuestionNoService questionNoService;
+
+    @Transactional
+    public UserCollect addQuestion(Integer userId, Integer questionNoId){
+        Example example = new Example(UserCollect.class);
+        example.and(
+                example.createCriteria()
+                        .andEqualTo("userId", userId)
+                        .andEqualTo("questionNoId", questionNoId)
+        );
+        UserCollect in = one(userCollectMapper, example);
+        if (in != null){
+            return in;
+        }
+        QuestionNo no = questionNoService.get(questionNoId);
+        UserCollect collect = add(UserCollect.builder()
+                .userId(userId)
+                .questionNoId(questionNoId)
+                .questionId(no.getQuestionId()).build());
+        int result = insert(userCollectMapper, collect);
+        return collect;
+    }
+
+    @Transactional
+    public boolean deleteQuestion(Integer userId, Integer questionNoId){
+        Example example = new Example(UserCollect.class);
+        example.and(
+                example.createCriteria()
+                .andEqualTo("userId", userId)
+                .andEqualTo("questionNoId", questionNoId)
+        );
+        UserCollect in = one(userCollectMapper, example);
+        if (in == null){
+            return true;
+        }
+        int result = delete(userCollectMapper, example);
+        return result > 0;
+    }
+
     public UserCollect add(UserCollect collect){
         int result = insert(userCollectMapper, collect);
         collect = one(userCollectMapper, collect.getId());

+ 23 - 0
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserNoteService.java

@@ -4,6 +4,7 @@ import com.github.pagehelper.Page;
 import com.nuliji.tools.AbstractService;
 import com.nuliji.tools.exception.ParameterException;
 import com.nuliji.tools.exception.SystemException;
+import com.nuliji.tools.mybatis.Example;
 import com.qxgmat.data.dao.UserCollectMapper;
 import com.qxgmat.data.dao.UserNoteMapper;
 import com.qxgmat.data.dao.entity.UserCollect;
@@ -11,6 +12,7 @@ import com.qxgmat.data.dao.entity.UserNote;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.util.Collection;
@@ -23,6 +25,27 @@ public class UserNoteService extends AbstractService {
     @Resource
     private UserNoteMapper userNoteMapper;
 
+    @Transactional
+    public UserNote update(UserNote note){
+        Example example = new Example(UserCollect.class);
+        example.and(
+                example.createCriteria()
+                        .andEqualTo("userId", note.getUserId())
+        );
+        example.and(
+                example.createCriteria()
+                        .orEqualTo("questionId", note.getQuestionId())
+                        .orEqualTo("questionNoId", note.getQuestionNoId())
+        );
+        UserNote in = one(userNoteMapper, example);
+        if(in == null){
+            return add(note);
+        }else{
+            note.setId(in.getId());
+            return edit(note);
+        }
+    }
+
     public UserNote add(UserNote note){
         int result = insert(userNoteMapper, note);
         note = one(userNoteMapper, note.getId());

+ 124 - 0
server/gateway-api/src/main/java/com/qxgmat/service/inline/UserSentenceProcessService.java

@@ -4,13 +4,16 @@ import com.github.pagehelper.Page;
 import com.nuliji.tools.AbstractService;
 import com.nuliji.tools.exception.ParameterException;
 import com.nuliji.tools.exception.SystemException;
+import com.nuliji.tools.mybatis.Example;
 import com.qxgmat.data.dao.SentenceQuestionMapper;
 import com.qxgmat.data.dao.UserSentenceProcessMapper;
 import com.qxgmat.data.dao.entity.SentenceQuestion;
+import com.qxgmat.data.dao.entity.User;
 import com.qxgmat.data.dao.entity.UserSentenceProcess;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.util.Collection;
@@ -23,6 +26,127 @@ public class UserSentenceProcessService extends AbstractService {
     @Resource
     private UserSentenceProcessMapper userSentenceProcessMapper;
 
+    /**
+     * 更新长难句文章进度
+     * @param userId
+     * @param chapter
+     * @param part
+     * @param process
+     * @return
+     */
+    @Transactional
+    public UserSentenceProcess updateProcess(Integer userId, Integer chapter, Integer part, Integer process, Integer maxPart){
+        Example example = new Example(UserSentenceProcess.class);
+        example.and(
+                example.createCriteria()
+                        .andEqualTo("userId", userId)
+                        .andEqualTo("chapter", chapter)
+                        .andEqualTo("part", part)
+        );
+        UserSentenceProcess entity;
+        UserSentenceProcess in = one(userSentenceProcessMapper, example);
+        if (in != null){
+            if (in.getProcess() <= process){
+                in.setProcess(process);
+                entity = edit(in);
+                return entity;
+            }else{
+                entity = in;
+            }
+        }else{
+            entity = add(UserSentenceProcess.builder()
+            .userId(userId)
+            .chapter(chapter)
+            .part(part)
+            .process(process).build());
+        }
+        // 计算本章节的总体进度
+        List<UserSentenceProcess> list = listByChapter(userId, chapter);
+        Integer total = 0;
+        for (UserSentenceProcess p: list) {
+            total += p.getProcess();
+        }
+        updateTotalProcess(userId, chapter, (total * 100) / (maxPart * 100));
+        return entity;
+    }
+
+    /**
+     * 更新单个章节总体进度
+     * @param userId
+     * @param chapter
+     * @param process
+     */
+    private void updateTotalProcess(Integer userId, Integer chapter, Integer process){
+        Example example = new Example(UserSentenceProcess.class);
+        example.and(
+                example.createCriteria()
+                        .andEqualTo("userId", userId)
+                        .andEqualTo("chapter", chapter)
+                        .andEqualTo("part", 0)
+        );
+        UserSentenceProcess in = one(userSentenceProcessMapper, example);
+        if (in != null){
+            if (in.getProcess() <= process){
+                in.setProcess(process);
+                edit(in);
+            }
+        }else{
+            add(UserSentenceProcess.builder()
+                    .userId(userId)
+                    .chapter(chapter)
+                    .part(0)
+                    .process(process).build());
+        }
+
+    }
+
+    /**
+     * 获取用户单个章节的所有进度
+     * @param userId
+     * @param chapter
+     * @return
+     */
+    public List<UserSentenceProcess> listByChapter(Integer userId, Integer chapter){
+        Example example = new Example(UserSentenceProcess.class);
+        example.and(
+                example.createCriteria()
+                        .andEqualTo("userId", userId)
+                        .andEqualTo("chapter", chapter)
+                        .andNotEqualTo("part", 0)
+        );
+        return select(userSentenceProcessMapper, example);
+    }
+
+    /**
+     * 获取用户所有章节进度:试用情况下
+     * @param userId
+     * @return
+     */
+    public List<UserSentenceProcess> listAllByTrail(Integer userId){
+        Example example = new Example(UserSentenceProcess.class);
+        example.and(
+                example.createCriteria()
+                        .andEqualTo("userId", userId)
+                        .andNotEqualTo("part", 0)
+        );
+        return select(userSentenceProcessMapper, example);
+    }
+
+    /**
+     * 获取用户所有章节总体进度
+     * @param userId
+     * @return
+     */
+    public List<UserSentenceProcess> listTotal(Integer userId){
+        Example example = new Example(UserSentenceProcess.class);
+        example.and(
+                example.createCriteria()
+                        .andEqualTo("userId", userId)
+                        .andEqualTo("part", 0)
+        );
+        return select(userSentenceProcessMapper, example);
+    }
+
     public UserSentenceProcess add(UserSentenceProcess process){
         int result = insert(userSentenceProcessMapper, process);
         process = one(userSentenceProcessMapper, process.getId());