Browse Source

排名和结果

master
zhizhi wu 3 years ago
parent
commit
e558acb332
  1. 18
      src/main/java/com/ccsens/braintraining/api/BrainController.java
  2. 8
      src/main/java/com/ccsens/braintraining/bean/dto/BrainDto.java
  3. 140
      src/main/java/com/ccsens/braintraining/bean/vo/BrainVo.java
  4. 8
      src/main/java/com/ccsens/braintraining/bean/vo/RuleGenerateVo.java
  5. 22
      src/main/java/com/ccsens/braintraining/persist/dao/BrainDao.java
  6. 37
      src/main/java/com/ccsens/braintraining/service/BrainService.java
  7. 17
      src/main/java/com/ccsens/braintraining/service/IBrainService.java
  8. 10
      src/main/java/com/ccsens/braintraining/util/BrainTrainingConstant.java
  9. 2
      src/main/resources/application.yml
  10. 97
      src/main/resources/mapper_dao/BrainDao.xml

18
src/main/java/com/ccsens/braintraining/api/BrainController.java

@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List;
/** /**
* @description: * @description:
@ -34,11 +35,11 @@ public class BrainController {
@ApiOperation(value = "脑力测评排名") @ApiOperation(value = "脑力测评排名")
@RequestMapping(value = "/rank", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) @RequestMapping(value = "/rank", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
public JsonResponse<BrainVo.Rank> rank(@ApiParam @Validated @RequestBody QueryDto<BrainDto.Rank> params) { public JsonResponse<List<BrainVo.Rank>> rank(@ApiParam @Validated @RequestBody QueryDto<BrainDto.Rank> params) {
log.info("脑力测评排名:{}", params); log.info("脑力测评排名:{}", params);
List<BrainVo.Rank> ranks = brainService.queryRank(params.getParam());
log.info("脑力测评排名结束:{}"); log.info("脑力测评排名结束:{}", ranks);
return JsonResponse.newInstance().ok(); return JsonResponse.newInstance().ok(ranks);
} }
@MustLogin @MustLogin
@ -69,4 +70,13 @@ public class BrainController {
log.info("保存答案结束"); log.info("保存答案结束");
return JsonResponse.newInstance().ok(); return JsonResponse.newInstance().ok();
} }
@ApiOperation(value = "查询认知筛查报告")
@RequestMapping(value = "/queryGrade", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
public JsonResponse<BrainVo.ActiveUserScore> queryGrade(@ApiParam @Validated @RequestBody QueryDto<BrainDto.ActiveUser> params) {
log.info("查询认知筛查报告:{}", params);
BrainVo.ActiveUserScore score = brainService.queryGrade(params.getParam(), params.getUserId());
log.info("查询认知筛查报告结果:{}", score);
return JsonResponse.newInstance().ok(score);
}
} }

8
src/main/java/com/ccsens/braintraining/bean/dto/BrainDto.java

@ -16,13 +16,19 @@ import java.util.List;
*/ */
public class BrainDto { public class BrainDto {
@Data @Data
@ApiModel("脑力训练活动-请求") @ApiModel("脑力训练活动设备-请求")
public static class Equipment { public static class Equipment {
@NotNull(message="请输入设备信息") @NotNull(message="请输入设备信息")
@ApiModelProperty("设备ID") @ApiModelProperty("设备ID")
private Long equipmentId; private Long equipmentId;
} }
@Data
@ApiModel("脑力训练活动ID-请求")
public static class ActiveUser {
@ApiModelProperty("活动用户ID")
private Long activeUserId;
}
@Data @Data
@ApiModel("脑力训练活动-请求") @ApiModel("脑力训练活动-请求")
public static class Question { public static class Question {

140
src/main/java/com/ccsens/braintraining/bean/vo/BrainVo.java

@ -13,8 +13,8 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.util.ArrayList; import java.math.BigDecimal;
import java.util.List; import java.util.*;
/** /**
* @description: * @description:
@ -22,6 +22,103 @@ import java.util.List;
* @time: 2022/3/25 9:01 * @time: 2022/3/25 9:01
*/ */
public class BrainVo { public class BrainVo {
@Data
@ApiModel("脑力筛查报告-返回")
public static class ActiveUserScore {
@ApiModelProperty("活动用户ID")
private Long activeUserId;
@ApiModelProperty("头像,无,则给默认头像")
private String avatarUrl;
@ApiModelProperty("测评时间")
private Date trainTime;
@ApiModelProperty("测评分数")
private BigDecimal totalScore;
@ApiModelProperty("8维得分")
private List<CapacityScore> scores;
@ApiModelProperty("专家点评")
private String comment;
@ApiModelProperty("完成状态 0:创建 1:完成 2:中断")
@JsonIgnore
private Byte finishStatus;
public BigDecimal getTotalScore() {
if (totalScore != null || CollectionUtil.isEmpty(scores)) {
return totalScore;
}
totalScore = new BigDecimal(0);
scores.forEach(score -> totalScore = totalScore.add(score.score));
return totalScore;
}
public String getComment() {
if (StrUtil.isNotEmpty(comment) || CollectionUtil.isEmpty(scores)) {
return comment;
}
List<CapacityScore> dest = new ArrayList<>(scores.size());
scores.forEach(score->dest.add(score));
Collections.sort(dest, (t1,t2) -> t1.realScore().subtract(t2.realScore()).compareTo(new BigDecimal(0)));
BigDecimal goodScore = new BigDecimal(4);
if (dest.get(0).realScore().compareTo(goodScore) >= 0) {
comment = BrainTrainingConstant.Train.COMMENT_GOOD;
} else {
StringBuilder builder = new StringBuilder(dest.get(0).getCapacityName());
BigDecimal prevScore = dest.get(0).realScore();
int index = 2;
for (int i = 1; i < dest.size() ; i++) {
CapacityScore capacityScore = dest.get(i);
BigDecimal score = capacityScore.realScore();
boolean lowScore = score.compareTo(goodScore) < 0 && (score.compareTo(prevScore) == 0 || i < index);
if (!lowScore) {
break;
}
builder.append(BrainTrainingConstant.Train.SYMBOL_DOT).append(capacityScore.getCapacityName());
prevScore = score;
}
comment = StrUtil.format(BrainTrainingConstant.Train.COMMENT_GENERAL, builder.toString());
}
return comment;
}
}
@Data
@ApiModel("脑力维度分数-返回")
public static class CapacityScore {
@ApiModelProperty("关联能力 1:执行力 2:抽象力 3:空间定向力 4:时间定向力 5:即刻记忆 6:延迟回忆 7:注意力 8:计算力")
private Byte capacity;
@ApiModelProperty("测评分数")
private BigDecimal score;
@ApiModelProperty("关联能力名字")
private String capacityName;
public BigDecimal realScore(){
return score;
}
public BigDecimal getScore() {
if(score == null) {
return null;
}
return score.compareTo(new BigDecimal(0)) > 0 ? score : new BigDecimal(0);
}
public String getCapacityName() {
if (StrUtil.isNotEmpty(capacityName)) {
return capacityName;
}
switch (capacity) {
case 1: capacityName = "执行力";break;
case 2: capacityName = "抽象力";break;
case 3: capacityName = "空间定向力";break;
case 4: capacityName = "时间定向力";break;
case 5: capacityName = "即刻记忆";break;
case 6: capacityName = "延迟回忆";break;
case 7: capacityName = "注意力";break;
case 8: capacityName = "计算力";break;
default: break;
}
return capacityName;
}
}
@Data @Data
@ApiModel("脑力测评活动-返回") @ApiModel("脑力测评活动-返回")
public static class Active { public static class Active {
@ -97,21 +194,11 @@ public class BrainVo {
@ApiModelProperty("共多少道题") @ApiModelProperty("共多少道题")
private Integer total; private Integer total;
@ApiModelProperty("分类,仅抽象分类使用") @ApiModelProperty("分类,仅抽象分类使用")
private List<RuleGenerateVo.ChildRandom> classifies; private List<RuleGenerateVo.ClassifyMsg> classifies;
public List<RuleGenerateVo.ChildRandom> getClassifies() { public String generateParamReal(){
if (classifies != null) { return generateParam;
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() { public String getGenerateParam() {
return generate == BrainTrainingConstant.Train.RULE_GENERATE_CONTINUE_SUB ? generateParam : null; return generate == BrainTrainingConstant.Train.RULE_GENERATE_CONTINUE_SUB ? generateParam : null;
} }
@ -158,8 +245,20 @@ public class BrainVo {
private List<QuestionContent> contents; private List<QuestionContent> contents;
@ApiModelProperty("选项") @ApiModelProperty("选项")
private List<QuestionOption> options; private List<QuestionOption> options;
@ApiModelProperty("答案")
private List<AnswerSort> answers;
public List<AnswerSort> getAnswers() {
if ( answers== null || answers.size() <= 1) {
return answers;
}
Collections.sort(answers, Comparator.comparingInt(answer -> answer.sort));
return answers;
}
} }
@Data @Data
@ApiModel("题干-返回") @ApiModel("题干-返回")
public static class QuestionContent { public static class QuestionContent {
@ -193,7 +292,7 @@ public class BrainVo {
private String userName; private String userName;
@ApiModelProperty("总分数") @ApiModelProperty("总分数")
private Integer totalScore; private Integer totalScore;
@ApiModelProperty("操作时间") @ApiModelProperty("操作时间,单位:毫秒")
private Long operationTime; private Long operationTime;
} }
@Data @Data
@ -217,4 +316,13 @@ public class BrainVo {
public static final byte ANSWER_RIGHT = 1; public static final byte ANSWER_RIGHT = 1;
} }
@ApiModel("答案和排序")
@Data
private static class AnswerSort {
@ApiModelProperty("答案")
private String answer;
@JsonIgnore
@ApiModelProperty("排序")
private Integer sort;
}
} }

8
src/main/java/com/ccsens/braintraining/bean/vo/RuleGenerateVo.java

@ -25,10 +25,18 @@ public class RuleGenerateVo {
private Long classifyId; private Long classifyId;
@ApiModelProperty("生成几题") @ApiModelProperty("生成几题")
private int num; private int num;
}
@Data
@ApiModel("分类信息")
public static class ClassifyMsg{
@ApiModelProperty("类型ID")
private Long classifyId;
@ApiModelProperty("类型code") @ApiModelProperty("类型code")
private String classifyCode; private String classifyCode;
@ApiModelProperty("类型名字") @ApiModelProperty("类型名字")
private String classifyName; private String classifyName;
@ApiModelProperty("图片路径")
private String classifyUrl;
} }
@Data @Data
@ApiModel("组题规则-等级随机") @ApiModel("组题规则-等级随机")

22
src/main/java/com/ccsens/braintraining/persist/dao/BrainDao.java

@ -111,4 +111,26 @@ public interface BrainDao {
* @return 答案 * @return 答案
*/ */
List<BrainVo.QuestionAnswer> queryQuestionAnswers(@Param("activeUserId") Long activeUserId, @Param("list")List<Long> questionIds); List<BrainVo.QuestionAnswer> queryQuestionAnswers(@Param("activeUserId") Long activeUserId, @Param("list")List<Long> questionIds);
/**
* 根据分类ID查询分类信息
* @param children 分类ID
* @return 分类信息
*/
List<RuleGenerateVo.ClassifyMsg> queryClassify(List<RuleGenerateVo.ChildRandom> children);
/**
* 查询测评结果
* @param activeUserId 活动用户ID
* @return 测评结果
*/
BrainVo.ActiveUserScore queryGrade(@Param("activeUserId") Long activeUserId);
/**
* 查询排名
* @param equipmentId 设备ID
* @param pageSize 查询几条
* @return 排名
*/
List<BrainVo.Rank> queryRank(@Param("equipmentId") Long equipmentId, @Param("pageSize") Integer pageSize);
} }

37
src/main/java/com/ccsens/braintraining/service/BrainService.java

@ -15,6 +15,7 @@ import com.ccsens.braintraining.persist.mapper.*;
import com.ccsens.braintraining.util.BrainTrainingCodeError; import com.ccsens.braintraining.util.BrainTrainingCodeError;
import com.ccsens.braintraining.util.BrainTrainingConstant; import com.ccsens.braintraining.util.BrainTrainingConstant;
import com.ccsens.util.RedisUtil; import com.ccsens.util.RedisUtil;
import com.ccsens.util.WebConstant;
import com.ccsens.util.exception.BaseException; import com.ccsens.util.exception.BaseException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -67,6 +68,14 @@ public class BrainService implements IBrainService {
throw new BaseException(BrainTrainingCodeError.BRAIN_ACTIVE_NOT_OPEN); throw new BaseException(BrainTrainingCodeError.BRAIN_ACTIVE_NOT_OPEN);
} }
TrainActive active = actives.get(0); TrainActive active = actives.get(0);
// 将同一活动、同一用户的未完成的活动置为中断
TrainActiveUser activeUserRecord = new TrainActiveUser();
activeUserRecord.setFinishStatus(BrainTrainingConstant.Train.TRAINING_FINISH_INTERRUPT);
TrainActiveUserExample activeUserExample = new TrainActiveUserExample();
activeUserExample.createCriteria().andActiveIdEqualTo(active.getId())
.andUserIdEqualTo(userId).andFinishStatusEqualTo(BrainTrainingConstant.Train.TRAINING_FINISH_CREATE)
.andRecStatusEqualTo(BrainTrainingConstant.REC_STATUS.Normal.value);
trainActiveUserMapper.updateByExampleSelective(activeUserRecord, activeUserExample);
// 查询规则 // 查询规则
List<BrainVo.GenerateRule> rules = brainDao.queryGenerateRules(active.getId()); List<BrainVo.GenerateRule> rules = brainDao.queryGenerateRules(active.getId());
if (CollectionUtil.isEmpty(rules)) { if (CollectionUtil.isEmpty(rules)) {
@ -99,6 +108,15 @@ public class BrainService implements IBrainService {
} }
// 查询题目 // 查询题目
BrainVo.QuestionClassify question = brainDao.getQuestion(param.getActiveUserId(), param.getClassifyId()); BrainVo.QuestionClassify question = brainDao.getQuestion(param.getActiveUserId(), param.getClassifyId());
log.info("题目信息:{}", question);
if (question == null) {
throw new BaseException(BrainTrainingCodeError.PARAM_ERROR);
}
if (question.getGenerate() == BrainTrainingConstant.Train.RULE_GENERATE_CHILD_RANDOM) {
List<RuleGenerateVo.ChildRandom> children = JSONArray.parseArray(question.generateParamReal(), RuleGenerateVo.ChildRandom.class);
List<RuleGenerateVo.ClassifyMsg> classifies = brainDao.queryClassify(children);
question.setClassifies(classifies);
}
// 记录日志 // 记录日志
TrainActiveLog log = new TrainActiveLog(); TrainActiveLog log = new TrainActiveLog();
log.setId(snowflake.nextId()); log.setId(snowflake.nextId());
@ -169,6 +187,25 @@ public class BrainService implements IBrainService {
} }
@Override
public BrainVo.ActiveUserScore queryGrade(BrainDto.ActiveUser param, Long userId) {
BrainVo.ActiveUserScore score = brainDao.queryGrade(param.getActiveUserId());
if (score == null || score.getFinishStatus() != BrainTrainingConstant.Train.TRAINING_FINISH_CREATE) {
return score;
}
TrainActiveUser record = new TrainActiveUser();
record.setId(param.getActiveUserId());
record.setFinishStatus(BrainTrainingConstant.Train.TRAINING_FINISH_CLOSE);
trainActiveUserMapper.updateByPrimaryKeySelective(record);
log.info("修改用户活动:{}的状态为完成", param.getActiveUserId());
return score;
}
@Override
public List<BrainVo.Rank> queryRank(BrainDto.Rank param) {
return brainDao.queryRank(param.getEquipmentId(), param.getLevelSeveral());
}
private TrainActiveLog initFinishLog(BrainDto.Answer param, Long userId) { private TrainActiveLog initFinishLog(BrainDto.Answer param, Long userId) {
TrainActiveLog log = new TrainActiveLog(); TrainActiveLog log = new TrainActiveLog();
log.setId(snowflake.nextId()); log.setId(snowflake.nextId());

17
src/main/java/com/ccsens/braintraining/service/IBrainService.java

@ -4,6 +4,8 @@ import com.ccsens.braintraining.bean.dto.BrainDto;
import com.ccsens.braintraining.bean.vo.BrainVo; import com.ccsens.braintraining.bean.vo.BrainVo;
import com.ccsens.util.bean.dto.QueryDto; import com.ccsens.util.bean.dto.QueryDto;
import java.util.List;
/** /**
* @author: whj * @author: whj
* @time: 2022/3/25 8:58 * @time: 2022/3/25 8:58
@ -32,4 +34,19 @@ public interface IBrainService {
* @param userId 答题人 * @param userId 答题人
*/ */
void saveAnswer(BrainDto.Answer param, Long userId); void saveAnswer(BrainDto.Answer param, Long userId);
/**
* 查询测评分数
* @param param 活动用户信息
* @param userId 用户ID
* @return 分数
*/
BrainVo.ActiveUserScore queryGrade(BrainDto.ActiveUser param, Long userId);
/**
* 查询排名
* @param param 设备信息和分页信息
* @return 排名
*/
List<BrainVo.Rank> queryRank(BrainDto.Rank param);
} }

10
src/main/java/com/ccsens/braintraining/util/BrainTrainingConstant.java

@ -56,6 +56,16 @@ public class BrainTrainingConstant extends WebConstant {
public final static String REDIS_SAVE_ANSWER = "save_answer_{}_{}_{}"; public final static String REDIS_SAVE_ANSWER = "save_answer_{}_{}_{}";
/**默认有效时长:10分钟*/ /**默认有效时长:10分钟*/
public final static long REDIS_TIME_DEFAULT = 10 * 60; public final static long REDIS_TIME_DEFAULT = 10 * 60;
/**完成状态:创建*/
public final static byte TRAINING_FINISH_CREATE = 0;
/**完成状态:结束*/
public final static byte TRAINING_FINISH_CLOSE = 1;
/**完成状态:中断*/
public final static byte TRAINING_FINISH_INTERRUPT = 2;
public final static String COMMENT_GOOD = "您的综合认知能力表现良好,各维度能力分布均衡,可以时常进行专项脑力训练,保持大脑活力。";
public final static String COMMENT_GENERAL = "您在{}方面的能力表现一般,存在认知衰退过快的风险,建议您尽早通过定制化大脑训练进行干预,提升大脑活力。";
} }
public static class User{ public static class User{

2
src/main/resources/application.yml

@ -1,4 +1,4 @@
spring: spring:
profiles: profiles:
active: dev active: test
include: common include: common

97
src/main/resources/mapper_dao/BrainDao.xml

@ -19,6 +19,21 @@
<result column="optionContent" property="content"/> <result column="optionContent" property="content"/>
<result column="optionShowType" property="showType"/> <result column="optionShowType" property="showType"/>
</collection> </collection>
<collection property="answers" ofType="com.ccsens.braintraining.bean.vo.BrainVo$AnswerSort">
<id column="answerId"/>
<result column="answerContent" property="answer"/>
<result column="answerSort" property="sort"/>
</collection>
</collection>
</resultMap>
<resultMap id="ActiveUserScoreMap" type="com.ccsens.braintraining.bean.vo.BrainVo$ActiveUserScore">
<id column="activeUserId" property="activeUserId"/>
<result column="avatarUrl" property="avatarUrl"/>
<result column="trainTime" property="trainTime"/>
<result column="finishStatus" property="finishStatus"/>
<collection property="scores" ofType="com.ccsens.braintraining.bean.vo.BrainVo$CapacityScore">
<id column="capacity" property="capacity"/>
<id column="score" property="score"/>
</collection> </collection>
</resultMap> </resultMap>
@ -132,7 +147,10 @@
IFNULL(qc.show_type,0) AS questionShowType, IFNULL(qc.show_type,0) AS questionShowType,
o.id AS optionId, o.id AS optionId,
o.content AS optionContent, o.content AS optionContent,
o.show_type AS optionShowType o.show_type AS optionShowType,
a.id as answerId,
a.content as answerContent,
a.sort as answerSort
FROM FROM
t_train_active_question q t_train_active_question q
LEFT JOIN t_train_classify c ON q.classify_id = c.id LEFT JOIN t_train_classify c ON q.classify_id = c.id
@ -143,6 +161,8 @@
AND qc.rec_status = 0 AND qc.rec_status = 0
LEFT JOIN t_train_question_option o ON q.question_id = o.question_id LEFT JOIN t_train_question_option o ON q.question_id = o.question_id
AND o.rec_status = 0 AND o.rec_status = 0
LEFT JOIN t_train_question_answer a ON q.question_id = a.question_id
AND a.rec_status = 0
WHERE WHERE
q.active_user_id = #{activeUserId} q.active_user_id = #{activeUserId}
AND q.classify_id = #{classifyId} AND q.classify_id = #{classifyId}
@ -219,4 +239,79 @@
AND a.rec_status = 0 AND a.rec_status = 0
AND q.rec_status = 0 AND q.rec_status = 0
</select> </select>
<select id="queryClassify" resultType="com.ccsens.braintraining.bean.vo.RuleGenerateVo$ClassifyMsg">
SELECT
id AS classifyId,
CODE AS classifyCode,
NAME AS classifyName,
logo AS classifyUrl
FROM
t_train_classify
WHERE
<foreach collection="list" item="item" open="id IN (" close=")" separator=",">
#{item.classifyId}
</foreach>
AND rec_status = 0
</select>
<select id="queryGrade" resultMap="ActiveUserScoreMap">
SELECT
au.id AS activeUserId,
u.avatar_url AS avatarUrl,
au.created_at AS trainTime,
au.finish_status AS finishStatus,
c.capacity,
sum( s.score ) AS score
FROM
t_train_active_user au,
t_user u,
t_train_active_score s,
t_train_classify c
WHERE
au.user_id = u.id
AND au.id = s.active_user_id
AND s.classify_id = c.id
AND au.id = #{activeUserId}
AND au.rec_status = 0
AND u.rec_status = 0
AND s.rec_status = 0
AND c.rec_status = 0
GROUP BY
au.id,
c.capacity
</select>
<select id="queryRank" resultType="com.ccsens.braintraining.bean.vo.BrainVo$Rank">
SELECT
au.id AS activeUserId,
u.avatar_url,
u.`name` AS userName,
sum( s.score ) AS totalScore,
max( l.time ) - min( l.time ) AS operationTime
FROM
t_train_active a,
t_train_active_user au,
t_user u,
t_train_active_score s,
t_train_active_log l
WHERE
a.id = au.active_id
AND au.user_id = u.id
AND au.id = s.active_user_id
AND au.id = l.active_user_id
AND a.equipment_id = #{equipmentId}
AND a.start_time &lt;= UNIX_TIMESTAMP(now()) * 1000
AND a.end_time &gt;= UNIX_TIMESTAMP(now()) * 1000
AND au.finish_status = 1
AND a.rec_status = 0
AND au.rec_status = 0
AND u.rec_status = 0
AND l.rec_status = 0
AND s.rec_status = 0
GROUP BY
au.id
ORDER BY
totalScore DESC,
operationTime ASC,
au.created_at ASC
LIMIT ${pageSize}
</select>
</mapper> </mapper>
Loading…
Cancel
Save