diff --git a/.idea/dictionaries/23778.xml b/.idea/dictionaries/23778.xml index 798db79..e80f33f 100644 --- a/.idea/dictionaries/23778.xml +++ b/.idea/dictionaries/23778.xml @@ -1,6 +1,7 @@ + lxjf tencent diff --git a/src/main/java/com/ccsens/braintraining/api/BrainController.java b/src/main/java/com/ccsens/braintraining/api/BrainController.java index 5779fe8..ba38e3b 100644 --- a/src/main/java/com/ccsens/braintraining/api/BrainController.java +++ b/src/main/java/com/ccsens/braintraining/api/BrainController.java @@ -32,6 +32,15 @@ public class BrainController { @Resource private IBrainService brainService; + @ApiOperation(value = "脑力测评排名") + @RequestMapping(value = "/rank", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) + public JsonResponse rank(@ApiParam @Validated @RequestBody QueryDto params) { + log.info("脑力测评排名:{}", params); + + log.info("脑力测评排名结束:{}"); + return JsonResponse.newInstance().ok(); + } + @MustLogin @ApiOperation(value = "脑力测评生成") @RequestMapping(value = "/generate", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) @@ -50,4 +59,14 @@ public class BrainController { log.info("查询指定类型题目结束:{}", classify); return JsonResponse.newInstance().ok(classify); } + + @MustLogin + @ApiOperation(value = "保存答案") + @RequestMapping(value = "/saveAnswer", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) + public JsonResponse saveAnswer(@ApiParam @Validated @RequestBody QueryDto params) { + log.info("保存答案:{}", params); + brainService.saveAnswer(params.getParam(), params.getUserId()); + log.info("保存答案结束"); + return JsonResponse.newInstance().ok(); + } } diff --git a/src/main/java/com/ccsens/braintraining/bean/dto/BrainDto.java b/src/main/java/com/ccsens/braintraining/bean/dto/BrainDto.java index aade24a..9119add 100644 --- a/src/main/java/com/ccsens/braintraining/bean/dto/BrainDto.java +++ b/src/main/java/com/ccsens/braintraining/bean/dto/BrainDto.java @@ -4,7 +4,10 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; +import java.util.List; /** * @description: @@ -14,7 +17,7 @@ import javax.validation.constraints.NotNull; public class BrainDto { @Data @ApiModel("脑力训练活动-请求") - public class Equipment { + public static class Equipment { @NotNull(message="请输入设备信息") @ApiModelProperty("设备ID") private Long equipmentId; @@ -22,12 +25,68 @@ public class BrainDto { @Data @ApiModel("脑力训练活动-请求") - public class Question { + public static class Question { @ApiModelProperty("活动用户ID") private Long activeUserId; @ApiModelProperty("分类ID") private Long classifyId; -// @ApiModelProperty("上一题结束的原因 0:无上一题 1:完成切换 2:到时切换") -// private Byte finishReason = 0; + } + + @Data + @ApiModel("脑力训练答案保存-请求") + public static class Answer { + @NotNull + @ApiModelProperty("活动用户ID") + private Long activeUserId; + @NotNull + @ApiModelProperty("分类ID") + private Long classifyId; + @ApiModelProperty("结束的原因 2:完成切换 3:到时切换") + @Min(2) + @Max(3) + private byte finishReason = 2; + @ApiModelProperty("题目") + @NotNull + private List questions; + } + + @Data + @ApiModel("题目和选项-请求") + public static class UserAnswer { + @ApiModelProperty("活动题目ID") + private Long questionId; + @ApiModelProperty("题目内容,连续减法需要传值") + private String questionContent; + @ApiModelProperty("分类ID") + private List timeAndOptions; + } + + @Data + @ApiModel("选项和操作时间-请求") + public static class OptionTime { + @NotNull + @ApiModelProperty("操作ID") + private Long operateTime; + @ApiModelProperty("答案内容") + private String content; + } + + @Data + @ApiModel("脑力测评活动排名-请求") + public static class Rank { + @NotNull(message="请输入设备信息") + @ApiModelProperty("设备ID") + private Long equipmentId; + @ApiModelProperty("前多少名") + private Integer levelSeveral = 20; + } + + @Data + @ApiModel("脑力测评活动排名-请求") + public static class QuestionAnswer { + @ApiModelProperty("活动题目ID") + private Long questionId; + @ApiModelProperty("答案") + private String answer; } } diff --git a/src/main/java/com/ccsens/braintraining/bean/po/TrainActiveScore.java b/src/main/java/com/ccsens/braintraining/bean/po/TrainActiveScore.java index 22a090b..e75365a 100644 --- a/src/main/java/com/ccsens/braintraining/bean/po/TrainActiveScore.java +++ b/src/main/java/com/ccsens/braintraining/bean/po/TrainActiveScore.java @@ -1,6 +1,7 @@ package com.ccsens.braintraining.bean.po; import java.io.Serializable; +import java.math.BigDecimal; import java.util.Date; public class TrainActiveScore implements Serializable { @@ -12,7 +13,7 @@ public class TrainActiveScore implements Serializable { private Long questionId; - private Integer score; + private BigDecimal score; private Long operator; @@ -56,11 +57,11 @@ public class TrainActiveScore implements Serializable { this.questionId = questionId; } - public Integer getScore() { + public BigDecimal getScore() { return score; } - public void setScore(Integer score) { + public void setScore(BigDecimal score) { this.score = score; } diff --git a/src/main/java/com/ccsens/braintraining/bean/po/TrainActiveScoreExample.java b/src/main/java/com/ccsens/braintraining/bean/po/TrainActiveScoreExample.java index cbdd9cf..a5e9289 100644 --- a/src/main/java/com/ccsens/braintraining/bean/po/TrainActiveScoreExample.java +++ b/src/main/java/com/ccsens/braintraining/bean/po/TrainActiveScoreExample.java @@ -1,5 +1,6 @@ package com.ccsens.braintraining.bean.po; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -355,52 +356,52 @@ public class TrainActiveScoreExample { return (Criteria) this; } - public Criteria andScoreEqualTo(Integer value) { + public Criteria andScoreEqualTo(BigDecimal value) { addCriterion("score =", value, "score"); return (Criteria) this; } - public Criteria andScoreNotEqualTo(Integer value) { + public Criteria andScoreNotEqualTo(BigDecimal value) { addCriterion("score <>", value, "score"); return (Criteria) this; } - public Criteria andScoreGreaterThan(Integer value) { + public Criteria andScoreGreaterThan(BigDecimal value) { addCriterion("score >", value, "score"); return (Criteria) this; } - public Criteria andScoreGreaterThanOrEqualTo(Integer value) { + public Criteria andScoreGreaterThanOrEqualTo(BigDecimal value) { addCriterion("score >=", value, "score"); return (Criteria) this; } - public Criteria andScoreLessThan(Integer value) { + public Criteria andScoreLessThan(BigDecimal value) { addCriterion("score <", value, "score"); return (Criteria) this; } - public Criteria andScoreLessThanOrEqualTo(Integer value) { + public Criteria andScoreLessThanOrEqualTo(BigDecimal value) { addCriterion("score <=", value, "score"); return (Criteria) this; } - public Criteria andScoreIn(List values) { + public Criteria andScoreIn(List values) { addCriterion("score in", values, "score"); return (Criteria) this; } - public Criteria andScoreNotIn(List values) { + public Criteria andScoreNotIn(List values) { addCriterion("score not in", values, "score"); return (Criteria) this; } - public Criteria andScoreBetween(Integer value1, Integer value2) { + public Criteria andScoreBetween(BigDecimal value1, BigDecimal value2) { addCriterion("score between", value1, value2, "score"); return (Criteria) this; } - public Criteria andScoreNotBetween(Integer value1, Integer value2) { + public Criteria andScoreNotBetween(BigDecimal value1, BigDecimal value2) { addCriterion("score not between", value1, value2, "score"); return (Criteria) this; } diff --git a/src/main/java/com/ccsens/braintraining/bean/po/TrainQuestionOption.java b/src/main/java/com/ccsens/braintraining/bean/po/TrainQuestionOption.java index 0c99dba..58a06b4 100644 --- a/src/main/java/com/ccsens/braintraining/bean/po/TrainQuestionOption.java +++ b/src/main/java/com/ccsens/braintraining/bean/po/TrainQuestionOption.java @@ -12,8 +12,6 @@ public class TrainQuestionOption implements Serializable { private Byte showType; - private Byte pageType; - private Integer sort; private Long operator; @@ -58,14 +56,6 @@ public class TrainQuestionOption implements Serializable { this.showType = showType; } - public Byte getPageType() { - return pageType; - } - - public void setPageType(Byte pageType) { - this.pageType = pageType; - } - public Integer getSort() { return sort; } @@ -116,7 +106,6 @@ public class TrainQuestionOption implements Serializable { sb.append(", questionId=").append(questionId); sb.append(", content=").append(content); sb.append(", showType=").append(showType); - sb.append(", pageType=").append(pageType); sb.append(", sort=").append(sort); sb.append(", operator=").append(operator); sb.append(", createdAt=").append(createdAt); diff --git a/src/main/java/com/ccsens/braintraining/bean/po/TrainQuestionOptionExample.java b/src/main/java/com/ccsens/braintraining/bean/po/TrainQuestionOptionExample.java index e11f73f..0291366 100644 --- a/src/main/java/com/ccsens/braintraining/bean/po/TrainQuestionOptionExample.java +++ b/src/main/java/com/ccsens/braintraining/bean/po/TrainQuestionOptionExample.java @@ -355,66 +355,6 @@ public class TrainQuestionOptionExample { return (Criteria) this; } - public Criteria andPageTypeIsNull() { - addCriterion("page_type is null"); - return (Criteria) this; - } - - public Criteria andPageTypeIsNotNull() { - addCriterion("page_type is not null"); - return (Criteria) this; - } - - public Criteria andPageTypeEqualTo(Byte value) { - addCriterion("page_type =", value, "pageType"); - return (Criteria) this; - } - - public Criteria andPageTypeNotEqualTo(Byte value) { - addCriterion("page_type <>", value, "pageType"); - return (Criteria) this; - } - - public Criteria andPageTypeGreaterThan(Byte value) { - addCriterion("page_type >", value, "pageType"); - return (Criteria) this; - } - - public Criteria andPageTypeGreaterThanOrEqualTo(Byte value) { - addCriterion("page_type >=", value, "pageType"); - return (Criteria) this; - } - - public Criteria andPageTypeLessThan(Byte value) { - addCriterion("page_type <", value, "pageType"); - return (Criteria) this; - } - - public Criteria andPageTypeLessThanOrEqualTo(Byte value) { - addCriterion("page_type <=", value, "pageType"); - return (Criteria) this; - } - - public Criteria andPageTypeIn(List values) { - addCriterion("page_type in", values, "pageType"); - return (Criteria) this; - } - - public Criteria andPageTypeNotIn(List values) { - addCriterion("page_type not in", values, "pageType"); - return (Criteria) this; - } - - public Criteria andPageTypeBetween(Byte value1, Byte value2) { - addCriterion("page_type between", value1, value2, "pageType"); - return (Criteria) this; - } - - public Criteria andPageTypeNotBetween(Byte value1, Byte value2) { - addCriterion("page_type not between", value1, value2, "pageType"); - return (Criteria) this; - } - public Criteria andSortIsNull() { addCriterion("sort is null"); return (Criteria) this; diff --git a/src/main/java/com/ccsens/braintraining/bean/po/TrainRuleScore.java b/src/main/java/com/ccsens/braintraining/bean/po/TrainRuleScore.java index 5612ca9..2fee4a1 100644 --- a/src/main/java/com/ccsens/braintraining/bean/po/TrainRuleScore.java +++ b/src/main/java/com/ccsens/braintraining/bean/po/TrainRuleScore.java @@ -6,7 +6,7 @@ import java.util.Date; public class TrainRuleScore implements Serializable { private Long id; - private String code; + private Long activeId; private Long classifyId; @@ -32,12 +32,12 @@ public class TrainRuleScore implements Serializable { this.id = id; } - public String getCode() { - return code; + public Long getActiveId() { + return activeId; } - public void setCode(String code) { - this.code = code == null ? null : code.trim(); + public void setActiveId(Long activeId) { + this.activeId = activeId; } public Long getClassifyId() { @@ -103,7 +103,7 @@ public class TrainRuleScore implements Serializable { sb.append(" ["); sb.append("Hash = ").append(hashCode()); sb.append(", id=").append(id); - sb.append(", code=").append(code); + sb.append(", activeId=").append(activeId); sb.append(", classifyId=").append(classifyId); sb.append(", calculateType=").append(calculateType); sb.append(", calculateParam=").append(calculateParam); diff --git a/src/main/java/com/ccsens/braintraining/bean/po/TrainRuleScoreExample.java b/src/main/java/com/ccsens/braintraining/bean/po/TrainRuleScoreExample.java index de03a46..7d12b4a 100644 --- a/src/main/java/com/ccsens/braintraining/bean/po/TrainRuleScoreExample.java +++ b/src/main/java/com/ccsens/braintraining/bean/po/TrainRuleScoreExample.java @@ -165,73 +165,63 @@ public class TrainRuleScoreExample { return (Criteria) this; } - public Criteria andCodeIsNull() { - addCriterion("code is null"); + public Criteria andActiveIdIsNull() { + addCriterion("active_id is null"); return (Criteria) this; } - public Criteria andCodeIsNotNull() { - addCriterion("code is not null"); + public Criteria andActiveIdIsNotNull() { + addCriterion("active_id is not null"); return (Criteria) this; } - public Criteria andCodeEqualTo(String value) { - addCriterion("code =", value, "code"); + public Criteria andActiveIdEqualTo(Long value) { + addCriterion("active_id =", value, "activeId"); return (Criteria) this; } - public Criteria andCodeNotEqualTo(String value) { - addCriterion("code <>", value, "code"); + public Criteria andActiveIdNotEqualTo(Long value) { + addCriterion("active_id <>", value, "activeId"); return (Criteria) this; } - public Criteria andCodeGreaterThan(String value) { - addCriterion("code >", value, "code"); + public Criteria andActiveIdGreaterThan(Long value) { + addCriterion("active_id >", value, "activeId"); return (Criteria) this; } - public Criteria andCodeGreaterThanOrEqualTo(String value) { - addCriterion("code >=", value, "code"); + public Criteria andActiveIdGreaterThanOrEqualTo(Long value) { + addCriterion("active_id >=", value, "activeId"); return (Criteria) this; } - public Criteria andCodeLessThan(String value) { - addCriterion("code <", value, "code"); + public Criteria andActiveIdLessThan(Long value) { + addCriterion("active_id <", value, "activeId"); return (Criteria) this; } - public Criteria andCodeLessThanOrEqualTo(String value) { - addCriterion("code <=", value, "code"); + public Criteria andActiveIdLessThanOrEqualTo(Long value) { + addCriterion("active_id <=", value, "activeId"); return (Criteria) this; } - public Criteria andCodeLike(String value) { - addCriterion("code like", value, "code"); + public Criteria andActiveIdIn(List values) { + addCriterion("active_id in", values, "activeId"); return (Criteria) this; } - public Criteria andCodeNotLike(String value) { - addCriterion("code not like", value, "code"); + public Criteria andActiveIdNotIn(List values) { + addCriterion("active_id not in", values, "activeId"); return (Criteria) this; } - public Criteria andCodeIn(List values) { - addCriterion("code in", values, "code"); + public Criteria andActiveIdBetween(Long value1, Long value2) { + addCriterion("active_id between", value1, value2, "activeId"); return (Criteria) this; } - public Criteria andCodeNotIn(List values) { - addCriterion("code not in", values, "code"); - return (Criteria) this; - } - - public Criteria andCodeBetween(String value1, String value2) { - addCriterion("code between", value1, value2, "code"); - return (Criteria) this; - } - - public Criteria andCodeNotBetween(String value1, String value2) { - addCriterion("code not between", value1, value2, "code"); + public Criteria andActiveIdNotBetween(Long value1, Long value2) { + addCriterion("active_id not between", value1, value2, "activeId"); return (Criteria) this; } diff --git a/src/main/java/com/ccsens/braintraining/bean/vo/BrainVo.java b/src/main/java/com/ccsens/braintraining/bean/vo/BrainVo.java index b107212..589b1a6 100644 --- a/src/main/java/com/ccsens/braintraining/bean/vo/BrainVo.java +++ b/src/main/java/com/ccsens/braintraining/bean/vo/BrainVo.java @@ -1,6 +1,7 @@ package com.ccsens.braintraining.bean.vo; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.ccsens.braintraining.bean.po.TrainActiveQuestion; @@ -91,11 +92,29 @@ public class BrainVo { @JsonIgnore @ApiModelProperty("生成题目") private Byte generate; - @JsonIgnore @ApiModelProperty("生成题目的参数") private String generateParam; @ApiModelProperty("共多少道题") private Integer total; + @ApiModelProperty("分类,仅抽象分类使用") + private List classifies; + + public List getClassifies() { + if (classifies != null) { + return classifies; + } + if (generate == null || StrUtil.isEmpty(generateParam)) { + return null; + } + if (generate == BrainTrainingConstant.Train.RULE_GENERATE_CHILD_RANDOM) { + classifies = JSONArray.parseArray(generateParam, RuleGenerateVo.ChildRandom.class); + } + return classifies; + } + + public String getGenerateParam() { + return generate == BrainTrainingConstant.Train.RULE_GENERATE_CONTINUE_SUB ? generateParam : null; + } public Integer getTotal() { if (total != null || generate == null) { @@ -133,7 +152,7 @@ public class BrainVo { @Data @ApiModel("训练题目-返回") public static class Question { - @ApiModelProperty("题目ID") + @ApiModelProperty("活动题目ID") private Long questionId; @ApiModelProperty("题干") private List contents; @@ -144,16 +163,58 @@ public class BrainVo { @Data @ApiModel("题干-返回") public static class QuestionContent { + @ApiModelProperty("题干ID") private Long contentId; + @ApiModelProperty("题干内容") private String content; + @ApiModelProperty("题干类型 0:文字 1:图片 2:语音") private Byte showType; } @Data @ApiModel("选项-返回") private static class QuestionOption { + @ApiModelProperty("选项ID") private Long optionId; + @ApiModelProperty("选项内容") private String content; + @ApiModelProperty("选项类型 0:文字 1:图片 2:语音") private Byte showType; } + + @Data + @ApiModel("脑力测评活动排名-返回") + public static class Rank { + @ApiModelProperty("活动用户ID") + private Long activeUserId; + @ApiModelProperty("头像,无,则给默认头像") + private String avatarUrl; + @ApiModelProperty("用户名") + private String userName; + @ApiModelProperty("总分数") + private Integer totalScore; + @ApiModelProperty("操作时间") + private Long operationTime; + } + @Data + @ApiModel("脑力测评活动排名-返回") + public static class QuestionAnswer { + @ApiModelProperty("活动题目ID") + private Long questionId; + @ApiModelProperty("答案") + private String content; + } + @Data + @ApiModel("脑力测评活动-返回") + public static class ClassifyAnswer { + @ApiModelProperty("分类ID") + private Long classifyId; + @ApiModelProperty("活动题目ID") + private Long questionId; + @ApiModelProperty("答案状态 0:错误 1:正确") + private Byte answer; + + public static final byte ANSWER_RIGHT = 1; + } + } diff --git a/src/main/java/com/ccsens/braintraining/bean/vo/RuleGenerateVo.java b/src/main/java/com/ccsens/braintraining/bean/vo/RuleGenerateVo.java index 0ff8f08..a1ea024 100644 --- a/src/main/java/com/ccsens/braintraining/bean/vo/RuleGenerateVo.java +++ b/src/main/java/com/ccsens/braintraining/bean/vo/RuleGenerateVo.java @@ -25,6 +25,10 @@ public class RuleGenerateVo { private Long classifyId; @ApiModelProperty("生成几题") private int num; + @ApiModelProperty("类型code") + private String classifyCode; + @ApiModelProperty("类型名字") + private String classifyName; } @Data @ApiModel("组题规则-等级随机") diff --git a/src/main/java/com/ccsens/braintraining/bean/vo/RuleScoreVo.java b/src/main/java/com/ccsens/braintraining/bean/vo/RuleScoreVo.java new file mode 100644 index 0000000..70d83cd --- /dev/null +++ b/src/main/java/com/ccsens/braintraining/bean/vo/RuleScoreVo.java @@ -0,0 +1,72 @@ +package com.ccsens.braintraining.bean.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + * @description: + * @author: whj + * @time: 2022/3/28 15:11 + */ +public class RuleScoreVo { + + @Data + @ApiModel("分数规则-对加错减") + public static class WrongSub{ + @ApiModelProperty("正确的分数") + private BigDecimal rightScore; + @ApiModelProperty("错误的分数") + private BigDecimal wrongScore; + @ApiModelProperty("时间增加分数") + private List timeScores; + } + + @Data + @ApiModel("分数规则-正确个数") + public static class RightNum{ + @ApiModelProperty("时间增加分数") + private List numScores; + @ApiModelProperty("时间增加分数") + private List timeScores; + } + @Data + @ApiModel("分数规则-对加错0") + public static class WrongZero{ + @ApiModelProperty("正确的分数") + private BigDecimal rightScore; + @ApiModelProperty("时间增加分数") + private List timeScores; + } + @Data + @ApiModel("分数规则-分类") + public static class Classify{ + @ApiModelProperty("正确的分数") + private Long classifyId; + @ApiModelProperty("时间增加分数") + private BigDecimal score; + } + + + + @Data + @ApiModel("个数和分数") + public static class NumAndScore { + @ApiModelProperty("正确的分数") + private int num; + @ApiModelProperty("对应的分数") + private BigDecimal score; + } + + @Data + @ApiModel("时间和分数") + public static class TimeAndScore { + @ApiModelProperty("操作时间,单位:秒") + private Byte operationTime; + @ApiModelProperty("增加的分数") + private BigDecimal addScore; + } +} diff --git a/src/main/java/com/ccsens/braintraining/persist/dao/BrainDao.java b/src/main/java/com/ccsens/braintraining/persist/dao/BrainDao.java index 0a284e5..a4e30ce 100644 --- a/src/main/java/com/ccsens/braintraining/persist/dao/BrainDao.java +++ b/src/main/java/com/ccsens/braintraining/persist/dao/BrainDao.java @@ -1,6 +1,9 @@ package com.ccsens.braintraining.persist.dao; +import com.ccsens.braintraining.bean.dto.BrainDto; +import com.ccsens.braintraining.bean.po.TrainActiveLog; import com.ccsens.braintraining.bean.po.TrainActiveQuestion; +import com.ccsens.braintraining.bean.po.TrainActiveScore; import com.ccsens.braintraining.bean.vo.BrainVo; import com.ccsens.braintraining.bean.vo.RuleGenerateVo; import org.apache.ibatis.annotations.Param; @@ -14,11 +17,11 @@ import java.util.List; public interface BrainDao { /** * 查询该类型下的随机若干道题目 - * @param activeId 类型ID + * @param classifyId 类型ID * @param num 题目数量 * @return 题目ID */ - List queryRandom(@Param("activeId") Long activeId, @Param("num") int num); + List queryRandom(@Param("classifyId") Long classifyId, @Param("num") int num); /** * 查询指定类型下的随机若干道题目 @@ -29,11 +32,11 @@ public interface BrainDao { /** * 查询指定类型下指定等级的的随机若干道题 - * @param activeId 类型 + * @param classifyId 类型 * @param gradeRandom 等级和题目数量 * @return 题目ID */ - List queryGradeRandom(@Param("activeId") Long activeId, @Param("list") List gradeRandom); + List queryGradeRandom(@Param("classifyId") Long classifyId, @Param("list") List gradeRandom); /** * 根据活动ID查询活动信息 @@ -63,4 +66,49 @@ public interface BrainDao { * @return 题目 */ BrainVo.QuestionClassify getQuestion(@Param("activeUserId") Long activeUserId, @Param("classifyId") Long classifyId); + + /** + * 统计正确的答案个数 + * + * @param activeUserId 用户活动ID + * @param answerParams 题目和选项 + * @return 个数 + */ + Integer countRight(@Param("activeUserId") Long activeUserId, @Param("list") List answerParams); + + /** + * 查询类型下的答案是否正确 + * @param activeUserId 用户活动ID + * @param answerParams 答案 + * @return 类型+答案状态 + */ + List queryClassifyScores(@Param("activeUserId") Long activeUserId, @Param("list")List answerParams); + + /** + * 查询答案,并按顺序排列 + * @param activeQuestionId 活动题目ID + * @return 答案 + */ + List queryAnswerSort(@Param("activeQuestionId") Long activeQuestionId); + + /** + * 批量添加分数 + * @param scores 分数 + */ + void batchInsertScore(List scores); + + /** + * 批量添加日志 + * @param logs 日志 + */ + void batchInsertLog(List logs); + + /** + * + * 查询活动题目对应的答案 + * @param activeUserId 活动用户ID + * @param questionIds 题目 + * @return 答案 + */ + List queryQuestionAnswers(@Param("activeUserId") Long activeUserId, @Param("list")List questionIds); } diff --git a/src/main/java/com/ccsens/braintraining/service/BrainService.java b/src/main/java/com/ccsens/braintraining/service/BrainService.java index e46e66d..a9c8abc 100644 --- a/src/main/java/com/ccsens/braintraining/service/BrainService.java +++ b/src/main/java/com/ccsens/braintraining/service/BrainService.java @@ -2,19 +2,19 @@ package com.ccsens.braintraining.service; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.ccsens.braintraining.bean.dto.BrainDto; import com.ccsens.braintraining.bean.po.*; import com.ccsens.braintraining.bean.vo.BrainVo; import com.ccsens.braintraining.bean.vo.RuleGenerateVo; +import com.ccsens.braintraining.bean.vo.RuleScoreVo; import com.ccsens.braintraining.persist.dao.BrainDao; -import com.ccsens.braintraining.persist.mapper.TrainActiveLogMapper; -import com.ccsens.braintraining.persist.mapper.TrainActiveMapper; -import com.ccsens.braintraining.persist.mapper.TrainActiveScoreMapper; -import com.ccsens.braintraining.persist.mapper.TrainActiveUserMapper; +import com.ccsens.braintraining.persist.mapper.*; import com.ccsens.braintraining.util.BrainTrainingCodeError; import com.ccsens.braintraining.util.BrainTrainingConstant; +import com.ccsens.util.RedisUtil; import com.ccsens.util.exception.BaseException; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -22,9 +22,8 @@ import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; +import java.math.BigDecimal; +import java.util.*; /** * @description: @@ -38,15 +37,21 @@ public class BrainService implements IBrainService { @Resource private Snowflake snowflake; @Resource + private RedisUtil redisUtil; + @Resource private BrainDao brainDao; @Resource private TrainActiveMapper trainActiveMapper; @Resource private TrainActiveUserMapper trainActiveUserMapper; @Resource - private TrainActiveScoreMapper trainActiveScoreMapper; + private TrainActiveQuestionMapper trainActiveQuestionMapper; @Resource private TrainActiveLogMapper trainActiveLogMapper; + @Resource + private TrainRuleScoreMapper trainRuleScoreMapper; + @Resource + private TrainClassifyMapper trainClassifyMapper; @Override public BrainVo.Active generateTest(BrainDto.Equipment param, Long userId) { @@ -75,18 +80,17 @@ public class BrainService implements IBrainService { trainActiveUserMapper.insertSelective(activeUser); // 遍历规则,查询试题 List questions = new ArrayList<>(); - rules.forEach(rule -> generateQuestion(userId, active, questions, rule)); + rules.forEach(rule -> generateQuestion(activeUser.getId(), questions, rule)); // 批量添加题库内容 if (CollectionUtil.isNotEmpty(questions)) { log.info("批量生成活动题目"); brainDao.batchInsertActiveQuestion(questions); } - return new BrainVo.Active(active.getId(), rules); + return new BrainVo.Active(activeUser.getId(), rules); } @Override public BrainVo.QuestionClassify queryByClassify(BrainDto.Question param, Long userId) { - long now = System.currentTimeMillis(); // 判断是否已经做过 Integer score = brainDao.getScore(param.getActiveUserId(), param.getClassifyId()); log.info("参数:{},{},分数:{}", param.getActiveUserId(), param.getClassifyId(), score); @@ -107,33 +111,433 @@ public class BrainService implements IBrainService { return question; } + @Override + public void saveAnswer(BrainDto.Answer param, Long userId) { + Long now = System.currentTimeMillis(); + if (CollectionUtil.isEmpty(param.getQuestions())) { + log.info("保存答案时没有保存题目的信息"); + throw new BaseException(BrainTrainingCodeError.PARAM_ERROR); + } + // 判断有无正在进行的分数保存 + String key = StrUtil.format(BrainTrainingConstant.Train.REDIS_SAVE_ANSWER, param.getActiveUserId(), param.getClassifyId(), param.getQuestions().get(0).getQuestionId()); + Object o = redisUtil.get(key); + if (o != null) { + throw new BaseException(BrainTrainingCodeError.BRAIN_ACTIVE_QUESTION_ANSWER_SAVING); + } + // 存储当前正在进行的题目 + redisUtil.set(key, param.getActiveUserId(), BrainTrainingConstant.Train.REDIS_TIME_DEFAULT); + try { + // 判断是否已经做过 + Integer score = brainDao.getScore(param.getActiveUserId(), param.getClassifyId()); + log.info("参数:{},{},分数:{}", param.getActiveUserId(), param.getClassifyId(), score); + if (score != null) { + throw new BaseException(BrainTrainingCodeError.BRAIN_ACTIVE_QUESTION_ANSWER_YES); + } + // 查询分类 + TrainClassify classify = trainClassifyMapper.selectByPrimaryKey(param.getClassifyId()); + if (classify == null) { + throw new BaseException(BrainTrainingCodeError.PARAM_ERROR); + } + // 后续使用的参数处理 + List answerParams = new ArrayList<>(); + List logs = new ArrayList<>(); + List activeQuestions = new ArrayList<>(); + initNeedData(classify, param, userId, answerParams, logs, activeQuestions); + + // 查询用户活动信息 + TrainActiveUser activeUser = trainActiveUserMapper.selectByPrimaryKey(param.getActiveUserId()); + if (activeUser == null) { + log.info("没有找到用户活动信息:{}", param.getActiveUserId()); + throw new BaseException(BrainTrainingCodeError.PARAM_ERROR); + } + // 查询类型计分规则 + TrainRuleScore ruleScore = getTrainRuleScore(activeUser.getActiveId(), param.getClassifyId()); + // 分数计算 + List scores = getTrainActiveScores(param, now, answerParams, ruleScore); + + //存储分数 + if (CollectionUtil.isNotEmpty(scores)) { + brainDao.batchInsertScore(scores); + } + // 存储日志 + TrainActiveLog log = initFinishLog(param, userId); + logs.add(log); + brainDao.batchInsertLog(logs); + }finally { + redisUtil.del(key); + } + + } + + private TrainActiveLog initFinishLog(BrainDto.Answer param, Long userId) { + TrainActiveLog log = new TrainActiveLog(); + log.setId(snowflake.nextId()); + log.setActiveUserId(param.getActiveUserId()); + log.setClassifyId(param.getClassifyId()); + log.setQuestionId(0L); + log.setOptionContent(""); + log.setTime(System.currentTimeMillis()); + log.setOperationType(param.getFinishReason()); + log.setOperator(userId); + return log; + } + + private List getTrainActiveScores(BrainDto.Answer param, Long now, List answerParams, TrainRuleScore ruleScore) { + List scores = new ArrayList<>(); + switch (ruleScore.getCalculateType()) { + case BrainTrainingConstant.Train.RULE_SCORE_NO:break; + case BrainTrainingConstant.Train.RULE_SCORE_WRONG_SUB: + BigDecimal wrongSubScore = getWrongSubScore(param.getActiveUserId(), param.getClassifyId(), now, answerParams, ruleScore.getCalculateParam()); + TrainActiveScore wrongSubActiveScore = initScore(param.getActiveUserId(), param.getClassifyId(), 0L, wrongSubScore); + scores.add(wrongSubActiveScore); + break; + case BrainTrainingConstant.Train.RULE_SCORE_RIGHT_NUMBER: + BigDecimal rightNumScore = getRightNumScore(param.getActiveUserId(), param.getClassifyId(), now, answerParams, ruleScore.getCalculateParam()); + TrainActiveScore rightNumActiveScore = initScore(param.getActiveUserId(), param.getClassifyId(), 0L, rightNumScore); + scores.add(rightNumActiveScore); + break; + case BrainTrainingConstant.Train.RULE_SCORE_WRONG_ZERO: + BigDecimal wrongZeroScore = getWrongZeroScore(param.getActiveUserId(), param.getClassifyId(), now, answerParams, ruleScore.getCalculateParam()); + TrainActiveScore wrongZeroActiveScore = initScore(param.getActiveUserId(), param.getClassifyId(), 0L, wrongZeroScore ); + scores.add(wrongZeroActiveScore); + break; + case BrainTrainingConstant.Train.RULE_SCORE_CLASSIFY: + initClassifyScore(param, answerParams, ruleScore, scores); + break; + case BrainTrainingConstant.Train.RULE_SCORE_CONTINUE_SUB: + BigDecimal continueSubScore = getContinueSubScore(param.getActiveUserId(), param.getClassifyId(), now, param.getQuestions(), ruleScore.getCalculateParam()); + scores.add(initScore(param.getActiveUserId(), param.getClassifyId(), 0L, continueSubScore)); + break; + case BrainTrainingConstant.Train.RULE_SCORE_SORT: + BigDecimal sortScore = getSortScore(param.getActiveUserId(), param.getClassifyId(), now, param.getQuestions().get(0), ruleScore.getCalculateParam()); + scores.add(initScore(param.getActiveUserId(), param.getClassifyId(), param.getQuestions().get(0).getQuestionId(), sortScore)); + break; + case BrainTrainingConstant.Train.RULE_SCORE_SPACE: + BigDecimal spaceScore = getSpaceScore(param.getActiveUserId(), param.getClassifyId(), now, param.getQuestions(), ruleScore.getCalculateParam()); + scores.add(initScore(param.getActiveUserId(), param.getClassifyId(), 0L, spaceScore)); + break; + default: + + } + return scores; + } + + /** + * 按照个数计算分数 + * @param activeUserId 活动ID + * @param classifyId 类型ID + * @param now 时间 + * @param answerParams 答案 + * @param calculateParam 规则 + * @return 分数 + */ + private BigDecimal getSpaceScore(Long activeUserId, Long classifyId, Long now, List answerParams, String calculateParam) { + // 正确的个数 + List questionIds = new ArrayList<>(); + answerParams.forEach(answerParam->{ + questionIds.add(answerParam.getQuestionId()); + }); + List answers = brainDao.queryQuestionAnswers(activeUserId, questionIds); + Map> answerMap = new HashMap<>(); + answers.forEach(questionAnswer->{ + List answerList = answerMap.getOrDefault(questionAnswer.getQuestionId(), new ArrayList<>()); + answerList.add(questionAnswer.getContent()); + answerMap.put(questionAnswer.getQuestionId(), answerList); + }); + int rightNum = 0; + for (BrainDto.UserAnswer userAnswer:answerParams) { + List options = answerMap.get(userAnswer.getQuestionId()); + if (CollectionUtil.isEmpty(options) || CollectionUtil.isEmpty(userAnswer.getTimeAndOptions()) + || options.size() != userAnswer.getTimeAndOptions().size()) { + continue; + } + boolean current = true; + for (BrainDto.OptionTime optionTime: userAnswer.getTimeAndOptions()) { + if (!options.contains(optionTime.getContent())) { + current = false; + break; + } + } + rightNum += current ? 1 : 0; + } + return getByNum(activeUserId, classifyId, now, calculateParam, rightNum); + } + + /** + * 计算对加错减类型的分数 + * @param activeUserId 活动用户ID + * @param classifyId 类型ID + * @param now 保存答案时间 + * @param question 题目 + * @param calculateParam 计分规则字符串 + * @return 分数 + */ + private BigDecimal getSortScore(Long activeUserId, Long classifyId, Long now, BrainDto.UserAnswer question, String calculateParam) { + // 查询正确的答案 + List answerSorts = brainDao.queryAnswerSort(question.getQuestionId()); + // 比较答案并计算分数 + int rightNum = 0; + int wrongNum = 0; + int j = 0; + List options = question.getTimeAndOptions(); + for (int i = 0; i < answerSorts.size() && j < options.size(); i++) { + for (; j < options.size() ; j++) { + if (answerSorts.get(i).equals(options.get(j).getContent())) { + rightNum++; + j++; + break; + } else { + wrongNum++; + } + } + } + return calculateWrongSubScore(activeUserId, classifyId, now, calculateParam, rightNum, wrongNum); + } + + private BigDecimal getContinueSubScore(Long activeUserId, Long classifyId, Long now, List answerParams, String calculateParam) { + // 判断正误 + + TrainActiveQuestion question = trainActiveQuestionMapper.selectByPrimaryKey(answerParams.get(0).getQuestionId()); + if (question == null) { + log.info("连续减法题目错误:{}", answerParams.get(0).getQuestionId()); + throw new BaseException(BrainTrainingCodeError.PARAM_ERROR); + } + int totalNums = question.getQuestionAnswer().equals(answerParams.get(0).getTimeAndOptions().get(0).getContent()) ? 1 : 0; + for (int i = 1; i ruleScores = trainRuleScoreMapper.selectByExample(scoreExample); + if (CollectionUtil.isEmpty(ruleScores) || ruleScores.get(0).getCalculateType() == null) { + log.info("没有找到计分规则,活动:{}, 类型:{}", activeId, classifyId); + throw new BaseException(BrainTrainingCodeError.SETTING_ERROR); + } + // 根据计分规则 + return ruleScores.get(0); + } + + /** + * 对加错0 + * @param activeUserId 活动ID + * @param classifyId 类型ID + * @param now 时间 + * @param answerParams 答案 + * @param calculateParam 规则 + * @return 分数 + */ + private BigDecimal getWrongZeroScore(Long activeUserId, Long classifyId, Long now, List answerParams, String calculateParam) { + // 和答案比较,判断正确的个数和错误的个数 + int rightNum = brainDao.countRight(activeUserId, answerParams); + RuleScoreVo.WrongZero wrongZeroRule = JSONObject.parseObject(calculateParam, RuleScoreVo.WrongZero.class); + // 根据规则加减 + BigDecimal wrongZeroScore = wrongZeroRule.getRightScore().multiply(new BigDecimal(rightNum)); + // 判断规则中有无时间加减分 + return addTimeScore(activeUserId, classifyId, now, wrongZeroScore, wrongZeroRule.getTimeScores()); + } + + /** + * 按照个数计算分数 + * @param activeUserId 活动ID + * @param classifyId 类型ID + * @param now 时间 + * @param answerParams 答案 + * @param calculateParam 规则 + * @return 分数 + */ + private BigDecimal getRightNumScore(Long activeUserId, Long classifyId, Long now, List answerParams, String calculateParam) { + // 正确的个数 + int rightNum = brainDao.countRight(activeUserId, answerParams); + return getByNum(activeUserId, classifyId, now, calculateParam, rightNum); + } + + /** + * 计算对加错减类型的分数 + * @param activeUserId 活动用户ID + * @param classifyId 类型ID + * @param now 保存答案时间 + * @param answerParams 答案 + * @param calculateParam 计分规则字符串 + * @return 分数 + */ + private BigDecimal getWrongSubScore(Long activeUserId, Long classifyId, Long now, List answerParams, String calculateParam) { + // 和答案比较,判断正确的个数和错误的个数 + int rightNum = brainDao.countRight(activeUserId, answerParams); + int wrongNum = answerParams.size() - rightNum; + return calculateWrongSubScore(activeUserId, classifyId, now, calculateParam, rightNum, wrongNum); + } + + private BigDecimal getByNum(Long activeUserId, Long classifyId, Long now, String calculateParam, int rightNum) { + RuleScoreVo.RightNum ruleScore = JSONObject.parseObject(calculateParam, RuleScoreVo.RightNum.class); + BigDecimal totalScore = new BigDecimal(0); + for (int i = ruleScore.getNumScores().size() - 1; i >= 0 ; i--) { + RuleScoreVo.NumAndScore rule = ruleScore.getNumScores().get(i); + if (rightNum >= rule.getNum()) { + totalScore = rule.getScore(); + break; + } + } + return addTimeScore(activeUserId, classifyId, now, totalScore, ruleScore.getTimeScores()); + } + + /** + * 初始化分数对象 + * @param activeUserId 活动用户ID + * @param classifyId 分类ID + * @param totalScore 分数 + * @return 分数 + */ + private TrainActiveScore initScore(Long activeUserId, Long classifyId, Long questionId, BigDecimal totalScore) { + TrainActiveScore score = new TrainActiveScore(); + score.setId(snowflake.nextId()); + score.setActiveUserId(activeUserId); + score.setClassifyId(classifyId); + score.setQuestionId(questionId); + score.setScore(totalScore); + return score; + } + + private void initClassifyScore(BrainDto.Answer param, List answerParams, TrainRuleScore ruleScore, List scores) { + // {classifyId:score} + List classifyAnswers = brainDao.queryClassifyScores(param.getActiveUserId(), answerParams); + JSONObject scoreRule = JSONObject.parseObject(ruleScore.getCalculateParam()); + classifyAnswers.forEach(answer -> { + BigDecimal questionScore = answer.getAnswer() == BrainVo.ClassifyAnswer.ANSWER_RIGHT ? scoreRule.getBigDecimal(answer.getClassifyId() + "") : new BigDecimal(0); + TrainActiveScore activeScore = initScore(param.getActiveUserId(), param.getClassifyId(), answer.getQuestionId(), questionScore); + scores.add(activeScore); + }); + } + + private void initNeedData(TrainClassify classify, BrainDto.Answer param, Long userId, List answerParams, List logs, List activeQuestions) { + + param.getQuestions().forEach(question -> { + question.getTimeAndOptions().forEach(optionTime -> { + BrainDto.QuestionAnswer answer = new BrainDto.QuestionAnswer(); + answer.setQuestionId(question.getQuestionId()); + answer.setAnswer(optionTime.getContent()); + answerParams.add(answer); + TrainActiveLog log = new TrainActiveLog(); + log.setId(snowflake.nextId()); + log.setActiveUserId(param.getActiveUserId()); + log.setClassifyId(param.getClassifyId()); + log.setQuestionId(question.getQuestionId()); + log.setOptionContent(optionTime.getContent()); + log.setTime(optionTime.getOperateTime()); + log.setOperationType(BrainTrainingConstant.Train.LOG_OPERATE_OPERATE); + log.setOperator(userId); + logs.add(log); + }); + // 动态生成题目 + String content = question.getQuestionContent(); + if (StrUtil.isEmpty(content) || !(question.getQuestionId() != null && question.getQuestionId() != 0)) { + return; + } + + switch (classify.getCode()) { + case BrainTrainingConstant.Train.CLASSIFY_CONTINUE_SUB: + TrainActiveQuestion activeQuestion = new TrainActiveQuestion(); + activeQuestion.setId(snowflake.nextId()); + activeQuestion.setActiveUserId(param.getActiveUserId()); + activeQuestion.setClassifyId(param.getClassifyId()); + activeQuestion.setQuestionContent(content); + int answer = getAnswer(content); + activeQuestion.setQuestionAnswer(answer + ""); + activeQuestions.add(activeQuestion); + break; + default: + break; + } + + }); + } + + private int getAnswer(String content) { + return Integer.parseInt(content.split(BrainTrainingConstant.Train.SYMBOL_SUB)[0]) - Integer.parseInt(content.split(BrainTrainingConstant.Train.SYMBOL_SUB)[1]); + } + + private BigDecimal calculateWrongSubScore(Long activeUserId, Long classifyId, Long now, String calculateParam, int rightNum, int wrongNum) { + RuleScoreVo.WrongSub wrongSubRule = JSONObject.parseObject(calculateParam, RuleScoreVo.WrongSub.class); + // 根据规则加减 + BigDecimal wrongSubScore = wrongSubRule.getRightScore().multiply(new BigDecimal(rightNum)) + .add(wrongSubRule.getWrongScore().multiply(new BigDecimal(wrongNum))); + // 判断规则中有无时间加减分 + return addTimeScore(activeUserId, classifyId, now, wrongSubScore, wrongSubRule.getTimeScores()); + } + + /** + * 快速提交加分 + * @param activeUserId 活动用户ID + * @param classifyId 类型ID + * @param now 提交时间 + * @param totalScore 分数 + * @param timeScores 时间分数规则 + */ + private BigDecimal addTimeScore(Long activeUserId, Long classifyId, Long now, BigDecimal totalScore, List timeScores) { + if (CollectionUtil.isEmpty(timeScores)) { + return totalScore; + } + // 计算当前时间 - 查询试题的时间 + // 查询试题的日志 + TrainActiveLogExample logExample = new TrainActiveLogExample(); + logExample.createCriteria().andActiveUserIdEqualTo(activeUserId) + .andClassifyIdEqualTo(classifyId) + .andOperationTypeEqualTo(BrainTrainingConstant.Train.LOG_OPERATE_QUERY); + logExample.setOrderByClause("id desc limit 1"); + List queryLogs = trainActiveLogMapper.selectByExample(logExample); + if (CollectionUtil.isNotEmpty(queryLogs)) { + TrainActiveLog log = queryLogs.get(0); + long time = now - log.getTime(); + for (RuleScoreVo.TimeAndScore timeAndScore: timeScores) { + if (time <= timeAndScore.getOperationTime() * 1000) { + return totalScore.add(timeAndScore.getAddScore()); + } + } + } + return totalScore; + } + /** * 按照规则生成题目,并添加到questions中 - * @param userId 操作者ID - * @param active 活动信息 + * @param activeUserId 用户活动ID * @param questions 题目 * @param rule 规则 */ - private void generateQuestion(Long userId, TrainActive active, List questions, BrainVo.GenerateRule rule) { + private void generateQuestion(Long activeUserId, List questions, BrainVo.GenerateRule rule) { switch (rule.getGenerate()) { case BrainTrainingConstant.Train.RULE_GENERATE_RANDOM: RuleGenerateVo.Random random = JSONObject.parseObject(rule.getGenerateParam(), RuleGenerateVo.Random.class); - List randomIds = brainDao.queryRandom(rule.getActiveId(), random.getNum()); - addQuestion(questions, randomIds, active.getId(), userId); + List randomIds = brainDao.queryRandom(rule.getClassifyId(), random.getNum()); + addQuestion(questions, randomIds, activeUserId, rule.getClassifyId()); break; case BrainTrainingConstant.Train.RULE_GENERATE_CHILD_RANDOM: List childRandom = JSONArray.parseArray(rule.getGenerateParam(), RuleGenerateVo.ChildRandom.class); List childRandomIds = brainDao.queryChildRandom(childRandom); - addQuestion(questions, childRandomIds, active.getId(), userId); + addQuestion(questions, childRandomIds, activeUserId, rule.getClassifyId()); break; case BrainTrainingConstant.Train.RULE_GENERATE_GRADE_RANDOM: List gradeRandom = JSONArray.parseArray(rule.getGenerateParam(), RuleGenerateVo.GradeRandom.class); - List ids = brainDao.queryGradeRandom(rule.getActiveId(), gradeRandom); - addQuestion(questions, ids, active.getId(), userId); + List ids = brainDao.queryGradeRandom(rule.getClassifyId(), gradeRandom); + addQuestion(questions, ids, activeUserId, rule.getClassifyId()); break; case BrainTrainingConstant.Train.RULE_GENERATE_CONTINUE_SUB: RuleGenerateVo.ContinuousSub continueSub = JSONObject.parseObject(rule.getGenerateParam(), RuleGenerateVo.ContinuousSub.class); - TrainActiveQuestion question = initContinueSubQuestion(active.getId(), rule.getClassifyId(), continueSub, userId); + TrainActiveQuestion question = initContinueSubQuestion(activeUserId, rule.getClassifyId(), continueSub); questions.add(question); break; default: @@ -141,12 +545,26 @@ public class BrainService implements IBrainService { } } - private TrainActiveQuestion initContinueSubQuestion(Long activeUserId, Long classifyId, RuleGenerateVo.ContinuousSub continueSub, Long userId) { + /** + * 初始化连续减法 + * @param activeUserId 用户活动ID + * @param classifyId 分类ID + * @param continueSub 连续减法规则 + * @return 题目 + */ + private TrainActiveQuestion initContinueSubQuestion(Long activeUserId, Long classifyId, RuleGenerateVo.ContinuousSub continueSub) { Random randomNum = new Random(); // 在指定范围内随机生成被减数 int minuend = randomNum.nextInt(continueSub.getMinuendMax() - continueSub.getMinuendMin() + 1) + continueSub.getMinuendMin(); // 在指定范围内随机生成被减数 int subtrahend = randomNum.nextInt(continueSub.getSubtrahendMax() - continueSub.getSubtrahendMin() + 1) + continueSub.getSubtrahendMin(); + String partition = BrainTrainingConstant.Train.SYMBOL_DOT; + String nonNums = continueSub.getNonNums(); + while (StrUtil.isNotEmpty(nonNums) && (nonNums.equals(subtrahend) || nonNums.endsWith(partition + subtrahend) + || nonNums.startsWith(subtrahend + partition) || nonNums.contains(partition + subtrahend + partition))) { + subtrahend = randomNum.nextInt(continueSub.getSubtrahendMax() - continueSub.getSubtrahendMin() + 1) + continueSub.getSubtrahendMin(); + } + log.info("{}的连续减法首道题:{}-{}", activeUserId, minuend, subtrahend); TrainActiveQuestion question = new TrainActiveQuestion(); question.setId(snowflake.nextId()); question.setActiveUserId(activeUserId); @@ -154,11 +572,18 @@ public class BrainService implements IBrainService { question.setQuestionId(0L); question.setQuestionContent(minuend + BrainTrainingConstant.Train.SYMBOL_SUB + subtrahend); question.setQuestionAnswer(minuend - subtrahend + ""); - question.setOperator(userId); + question.setOperator(0L); return question; } - private void addQuestion(List questions, List questionIds, Long activeUserId, Long userId) { + /** + * 添加题目信息 + * @param questions 题目列表 + * @param questionIds 题目ID + * @param activeUserId 用户活动ID + * @param classifyId 分类ID + */ + private void addQuestion(List questions, List questionIds, Long activeUserId, Long classifyId) { if (CollectionUtil.isEmpty(questionIds)) { log.info("没有查找到题目,不添加该题型的题目"); return; @@ -167,8 +592,9 @@ public class BrainService implements IBrainService { TrainActiveQuestion question = new TrainActiveQuestion(); question.setId(snowflake.nextId()); question.setActiveUserId(activeUserId); + question.setClassifyId(classifyId); question.setQuestionId(id); - question.setOperator(userId); + question.setOperator(0L); question.setQuestionContent(""); question.setQuestionAnswer(""); questions.add(question); diff --git a/src/main/java/com/ccsens/braintraining/service/IBrainService.java b/src/main/java/com/ccsens/braintraining/service/IBrainService.java index d52d5e5..4c78645 100644 --- a/src/main/java/com/ccsens/braintraining/service/IBrainService.java +++ b/src/main/java/com/ccsens/braintraining/service/IBrainService.java @@ -25,4 +25,11 @@ public interface IBrainService { * @return 题目信息 */ BrainVo.QuestionClassify queryByClassify(BrainDto.Question param, Long userId); + + /** + * 保存答案 + * @param param 答案 + * @param userId 答题人 + */ + void saveAnswer(BrainDto.Answer param, Long userId); } diff --git a/src/main/java/com/ccsens/braintraining/util/BrainTrainingCodeError.java b/src/main/java/com/ccsens/braintraining/util/BrainTrainingCodeError.java index be66b5a..c705bde 100644 --- a/src/main/java/com/ccsens/braintraining/util/BrainTrainingCodeError.java +++ b/src/main/java/com/ccsens/braintraining/util/BrainTrainingCodeError.java @@ -17,6 +17,7 @@ public class BrainTrainingCodeError extends CodeError { public static final Code BRAIN_ACTIVE_NOT_OPEN = new Code(506,"当前没有正在进行的脑力活动,请咨询管理人员开放时间。",true); public static final Code BRAIN_ACTIVE_RULE_NO = new Code(507,"活动还没有配置规则,请联系管理人员配置。",true); public static final Code BRAIN_ACTIVE_QUESTION_ANSWER_YES = new Code(508,"该类型您已经完成,不能重复进行。",true); + public static final Code BRAIN_ACTIVE_QUESTION_ANSWER_SAVING = new Code(509,"答案在保存中,无需重复提交。",true); } diff --git a/src/main/java/com/ccsens/braintraining/util/BrainTrainingConstant.java b/src/main/java/com/ccsens/braintraining/util/BrainTrainingConstant.java index 5f89237..3477a94 100644 --- a/src/main/java/com/ccsens/braintraining/util/BrainTrainingConstant.java +++ b/src/main/java/com/ccsens/braintraining/util/BrainTrainingConstant.java @@ -21,8 +21,29 @@ public class BrainTrainingConstant extends WebConstant { public final static byte RULE_GENERATE_GRADE_RANDOM = 2; /**脑力测评组题规则:连续减法*/ public final static byte RULE_GENERATE_CONTINUE_SUB = 3; + /**脑力测评计分规则:不计分*/ + public final static byte RULE_SCORE_NO = 0; + /**脑力测评组题规则:对加错减*/ + public final static byte RULE_SCORE_WRONG_SUB = 1; + /**脑力测评组题规则:按个数计分*/ + public final static byte RULE_SCORE_RIGHT_NUMBER = 2; + /**脑力测评组题规则:正确计分,错误不计分*/ + public final static byte RULE_SCORE_WRONG_ZERO = 3; + /**脑力测评组题规则:根据题目的分类不同给分*/ + public final static byte RULE_SCORE_CLASSIFY = 4; + /**脑力测评组题规则:连续减法*/ + public final static byte RULE_SCORE_CONTINUE_SUB = 5; + /**脑力测评组题规则:按顺序判断对错,且对加错减*/ + public final static byte RULE_SCORE_SORT = 6; + public final static byte RULE_SCORE_SPACE = 7; + + /**类型:连续减法*/ + public final static String CLASSIFY_CONTINUE_SUB = "LXJF"; + /**符号:减法*/ public final static String SYMBOL_SUB = "-"; + /**符号:逗号*/ + public final static String SYMBOL_DOT = ","; /**日志操作类型:查看题目*/ public final static byte LOG_OPERATE_QUERY = 0; /**日志操作类型:操作过程*/ @@ -31,8 +52,10 @@ public class BrainTrainingConstant extends WebConstant { public final static byte LOG_OPERATE_SAVE = 2; /**日志操作类型:到时切换*/ public final static byte LOG_OPERATE_TIME = 3; - - + /**redis key:保存答案_用户活动ID_类型ID_题目ID*/ + public final static String REDIS_SAVE_ANSWER = "save_answer_{}_{}_{}"; + /**默认有效时长:10分钟*/ + public final static long REDIS_TIME_DEFAULT = 10 * 60; } public static class User{ diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 37260fb..a622e9e 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -45,7 +45,7 @@ swagger: # timeout: 1000 file: - path: /home/cloud/braintraining/uploads/ + path: /home/cloud/braintraining/server/uploads/ domain: http://127.0.0.1:7280/v1.0/ imgDomain: http://127.0.0.1:7280/v1.0/uploads/ url: diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 10e94aa..28f5966 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -11,7 +11,7 @@ swagger: enable: true file: - path: /home/cloud/braintraining/uploads/ + path: /home/cloud/braintraining/server/uploads/ domain: https://www.tall.wiki/braintraining/v1.0/ imgDomain: https://www.tall.wiki/braintraining/v1.0/uploads/ url: diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index c1d8e17..e5735f6 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -11,7 +11,7 @@ swagger: enable: true file: - path: /home/cloud/braintraining/uploads/ + path: /home/cloud/braintraining/server/uploads/ domain: http://test.tall.wiki/braintraining/v1.0/ imgDomain: http://test.tall.wiki/braintraining/v1.0/uploads/ url: diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 0ee65bb..95706ce 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,4 +1,4 @@ spring: profiles: - active: test + active: dev include: common diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml index c6324a2..e441704 100644 --- a/src/main/resources/logback-spring.xml +++ b/src/main/resources/logback-spring.xml @@ -9,7 +9,7 @@ logback - + diff --git a/src/main/resources/mapper_dao/BrainDao.xml b/src/main/resources/mapper_dao/BrainDao.xml index 1f1a0a7..ce300a7 100644 --- a/src/main/resources/mapper_dao/BrainDao.xml +++ b/src/main/resources/mapper_dao/BrainDao.xml @@ -26,7 +26,21 @@ INSERT INTO t_train_active_question ( id, active_user_id, classify_id, question_id, question_content, question_answer, operator ) VALUES - (#{id}, #{activeUserId}, #{classifyId}, #{questionId}, #{questionContent}, #{questionAnswer}, #{operator}) + (#{item.id}, #{item.activeUserId}, #{item.classifyId}, #{item.questionId}, #{item.questionContent}, #{item.questionAnswer}, #{item.operator}) + + + + INSERT INTO t_train_active_score ( id, active_user_id, classify_id, question_id, score ) + VALUES + + ( #{item.id}, #{item.activeUserId}, #{item.classifyId}, #{item.questionId}, #{item.score} ) + + + + INSERT INTO t_train_active_log ( id, active_user_id, classify_id, question_id, option_content, time, operation_type, operator ) + VALUES + + ( #{item.id}, #{item.activeUserId}, #{item.classifyId}, #{item.questionId}, #{item.optionContent}, #{item.time}, #{item.operationType}, #{item.operator} ) + + + + \ No newline at end of file diff --git a/src/main/resources/mapper_raw/TrainActiveScoreMapper.xml b/src/main/resources/mapper_raw/TrainActiveScoreMapper.xml index b8043f7..cdfa64c 100644 --- a/src/main/resources/mapper_raw/TrainActiveScoreMapper.xml +++ b/src/main/resources/mapper_raw/TrainActiveScoreMapper.xml @@ -6,7 +6,7 @@ - + @@ -110,7 +110,7 @@ created_at, updated_at, rec_status ) values (#{id,jdbcType=BIGINT}, #{activeUserId,jdbcType=BIGINT}, #{classifyId,jdbcType=BIGINT}, - #{questionId,jdbcType=BIGINT}, #{score,jdbcType=INTEGER}, #{operator,jdbcType=BIGINT}, + #{questionId,jdbcType=BIGINT}, #{score,jdbcType=DECIMAL}, #{operator,jdbcType=BIGINT}, #{createdAt,jdbcType=TIMESTAMP}, #{updatedAt,jdbcType=TIMESTAMP}, #{recStatus,jdbcType=TINYINT} ) @@ -159,7 +159,7 @@ #{questionId,jdbcType=BIGINT}, - #{score,jdbcType=INTEGER}, + #{score,jdbcType=DECIMAL}, #{operator,jdbcType=BIGINT}, @@ -197,7 +197,7 @@ question_id = #{record.questionId,jdbcType=BIGINT}, - score = #{record.score,jdbcType=INTEGER}, + score = #{record.score,jdbcType=DECIMAL}, operator = #{record.operator,jdbcType=BIGINT}, @@ -222,7 +222,7 @@ active_user_id = #{record.activeUserId,jdbcType=BIGINT}, classify_id = #{record.classifyId,jdbcType=BIGINT}, question_id = #{record.questionId,jdbcType=BIGINT}, - score = #{record.score,jdbcType=INTEGER}, + score = #{record.score,jdbcType=DECIMAL}, operator = #{record.operator,jdbcType=BIGINT}, created_at = #{record.createdAt,jdbcType=TIMESTAMP}, updated_at = #{record.updatedAt,jdbcType=TIMESTAMP}, @@ -244,7 +244,7 @@ question_id = #{questionId,jdbcType=BIGINT}, - score = #{score,jdbcType=INTEGER}, + score = #{score,jdbcType=DECIMAL}, operator = #{operator,jdbcType=BIGINT}, @@ -266,7 +266,7 @@ set active_user_id = #{activeUserId,jdbcType=BIGINT}, classify_id = #{classifyId,jdbcType=BIGINT}, question_id = #{questionId,jdbcType=BIGINT}, - score = #{score,jdbcType=INTEGER}, + score = #{score,jdbcType=DECIMAL}, operator = #{operator,jdbcType=BIGINT}, created_at = #{createdAt,jdbcType=TIMESTAMP}, updated_at = #{updatedAt,jdbcType=TIMESTAMP}, diff --git a/src/main/resources/mapper_raw/TrainQuestionOptionMapper.xml b/src/main/resources/mapper_raw/TrainQuestionOptionMapper.xml index 377d2fb..51acd3d 100644 --- a/src/main/resources/mapper_raw/TrainQuestionOptionMapper.xml +++ b/src/main/resources/mapper_raw/TrainQuestionOptionMapper.xml @@ -6,7 +6,6 @@ - @@ -72,8 +71,7 @@ - id, question_id, content, show_type, page_type, sort, operator, created_at, updated_at, - rec_status + id, question_id, content, show_type, sort, operator, created_at, updated_at, rec_status select @@ -105,11 +105,11 @@ - insert into t_train_rule_score (id, code, classify_id, + insert into t_train_rule_score (id, active_id, classify_id, calculate_type, calculate_param, operator, created_at, updated_at, rec_status ) - values (#{id,jdbcType=BIGINT}, #{code,jdbcType=VARCHAR}, #{classifyId,jdbcType=BIGINT}, + values (#{id,jdbcType=BIGINT}, #{activeId,jdbcType=BIGINT}, #{classifyId,jdbcType=BIGINT}, #{calculateType,jdbcType=TINYINT}, #{calculateParam,jdbcType=VARCHAR}, #{operator,jdbcType=BIGINT}, #{createdAt,jdbcType=TIMESTAMP}, #{updatedAt,jdbcType=TIMESTAMP}, #{recStatus,jdbcType=TINYINT} ) @@ -120,8 +120,8 @@ id, - - code, + + active_id, classify_id, @@ -149,8 +149,8 @@ #{id,jdbcType=BIGINT}, - - #{code,jdbcType=VARCHAR}, + + #{activeId,jdbcType=BIGINT}, #{classifyId,jdbcType=BIGINT}, @@ -187,8 +187,8 @@ id = #{record.id,jdbcType=BIGINT}, - - code = #{record.code,jdbcType=VARCHAR}, + + active_id = #{record.activeId,jdbcType=BIGINT}, classify_id = #{record.classifyId,jdbcType=BIGINT}, @@ -219,7 +219,7 @@ update t_train_rule_score set id = #{record.id,jdbcType=BIGINT}, - code = #{record.code,jdbcType=VARCHAR}, + active_id = #{record.activeId,jdbcType=BIGINT}, classify_id = #{record.classifyId,jdbcType=BIGINT}, calculate_type = #{record.calculateType,jdbcType=TINYINT}, calculate_param = #{record.calculateParam,jdbcType=VARCHAR}, @@ -234,8 +234,8 @@ update t_train_rule_score - - code = #{code,jdbcType=VARCHAR}, + + active_id = #{activeId,jdbcType=BIGINT}, classify_id = #{classifyId,jdbcType=BIGINT}, @@ -263,7 +263,7 @@ update t_train_rule_score - set code = #{code,jdbcType=VARCHAR}, + set active_id = #{activeId,jdbcType=BIGINT}, classify_id = #{classifyId,jdbcType=BIGINT}, calculate_type = #{calculateType,jdbcType=TINYINT}, calculate_param = #{calculateParam,jdbcType=VARCHAR},