From 50dd09f15a2bff24a1e135133ee2497a2fdcb525 Mon Sep 17 00:00:00 2001 From: zhizhi wu <2377881365@qq.com> Date: Wed, 16 Jun 2021 15:15:01 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A2=98=E7=9B=AE=E5=85=B6=E4=BB=96=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ccsens/ht/api/QuestionController.java | 10 +- .../ht/bean/dto/message/MessageDto.java | 38 +++ .../com/ccsens/ht/bean/vo/QuestionShowVo.java | 21 +- .../com/ccsens/ht/bean/vo/QuestionVo.java | 62 ++-- .../ccsens/ht/service/QuestionService.java | 271 ++++++++++-------- .../java/com/ccsens/ht/uitl/Constant.java | 5 + .../java/com/ccsens/util/JsonResponse.java | 4 +- .../util/bean/message/common/InMessage.java | 24 +- .../util/bean/message/common/MessageRule.java | 12 + 9 files changed, 277 insertions(+), 170 deletions(-) create mode 100644 ht/src/main/java/com/ccsens/ht/bean/dto/message/MessageDto.java diff --git a/ht/src/main/java/com/ccsens/ht/api/QuestionController.java b/ht/src/main/java/com/ccsens/ht/api/QuestionController.java index 2b798dae..49493700 100644 --- a/ht/src/main/java/com/ccsens/ht/api/QuestionController.java +++ b/ht/src/main/java/com/ccsens/ht/api/QuestionController.java @@ -9,7 +9,6 @@ import com.ccsens.ht.bean.vo.QuestionVo; import com.ccsens.ht.service.IQuestionService; import com.ccsens.util.CodeEnum; import com.ccsens.util.JsonResponse; -import com.ccsens.util.NotSupportedFileTypeException; import io.swagger.annotations.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -19,7 +18,6 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; -import java.io.IOException; import java.util.List; /** @@ -71,7 +69,7 @@ public class QuestionController { @ApiImplicitParam(name = "json", value = "试题得分情况", required = true) }) @RequestMapping(value="/saveScore", method = RequestMethod.POST) - public JsonResponse saveScore(@RequestBody @ApiParam @Valid QueryDto queryDto) throws IOException, NotSupportedFileTypeException { + public JsonResponse saveScore(@RequestBody @ApiParam @Valid QueryDto queryDto) { log.info("保存试题得分:{}", queryDto); CodeEnum codeEnum = questionService.saveScore(queryDto.getParam(), queryDto.getUserId()); log.info("保存试题得分结果:{}", codeEnum); @@ -84,7 +82,7 @@ public class QuestionController { @ApiImplicitParams({ }) @RequestMapping(value="/saveCanvas", method = RequestMethod.POST) - public JsonResponse> saveCanvas(@RequestBody @ApiParam @Valid QueryDto queryDto) throws IOException, NotSupportedFileTypeException { + public JsonResponse> saveCanvas(@RequestBody @ApiParam @Valid QueryDto queryDto) { log.info("保存用户画图信息"); List patientCanvas = questionService.saveCanvas(queryDto.getParam(), queryDto.getUserId()); log.info("保存用户画图信息成功后返回"); @@ -110,7 +108,7 @@ public class QuestionController { @ApiImplicitParams({ }) @RequestMapping(value="/queryCanvas", method = RequestMethod.POST) - public JsonResponse> queryCanvas(@RequestBody @ApiParam @Valid QueryDto queryDto) throws IOException, NotSupportedFileTypeException { + public JsonResponse> queryCanvas(@RequestBody @ApiParam @Valid QueryDto queryDto) { log.info("查看用户画图信息"); List patientCanvas = questionService.getCanvas(queryDto.getParam(), queryDto.getUserId()); log.info("查看用户画图信息成功"); @@ -123,7 +121,7 @@ public class QuestionController { @ApiImplicitParams({ }) @RequestMapping(value="/delCanvas", method = RequestMethod.POST) - public JsonResponse delCanvas(@RequestBody @ApiParam @Valid QueryDto queryDto) throws IOException, NotSupportedFileTypeException { + public JsonResponse delCanvas(@RequestBody @ApiParam @Valid QueryDto queryDto) { log.info("删除画图轨迹"); questionService.delCanvas(queryDto.getParam(), queryDto.getUserId()); log.info("删除画图轨迹成功"); diff --git a/ht/src/main/java/com/ccsens/ht/bean/dto/message/MessageDto.java b/ht/src/main/java/com/ccsens/ht/bean/dto/message/MessageDto.java new file mode 100644 index 00000000..58a96628 --- /dev/null +++ b/ht/src/main/java/com/ccsens/ht/bean/dto/message/MessageDto.java @@ -0,0 +1,38 @@ +package com.ccsens.ht.bean.dto.message; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.lang.reflect.ParameterizedType; + + +/** + * @description: + * @author: whj + * @time: 2021/6/15 9:17 + */ +@Data +public class MessageDto { + private String type; + private String event; + private T data; + + public void setData(T data) { + this.data = data; + if (data != null) { + this.type = data.getClass().getSimpleName(); + } + } + + @ApiModel("通知跳转到指定题目") + @Data + public static final class QuestionInform{ + @ApiModelProperty("提醒文案") + private String content; + @ApiModelProperty("量表") + private String code; + @ApiModelProperty("序号") + private byte sort; + } +} diff --git a/ht/src/main/java/com/ccsens/ht/bean/vo/QuestionShowVo.java b/ht/src/main/java/com/ccsens/ht/bean/vo/QuestionShowVo.java index 4dbc7236..0cf23701 100644 --- a/ht/src/main/java/com/ccsens/ht/bean/vo/QuestionShowVo.java +++ b/ht/src/main/java/com/ccsens/ht/bean/vo/QuestionShowVo.java @@ -3,6 +3,7 @@ package com.ccsens.ht.bean.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import lombok.EqualsAndHashCode; import java.util.ArrayList; import java.util.List; @@ -17,9 +18,12 @@ public class QuestionShowVo { @Data @ApiModel("显示信息") public static class Show{ - @ApiModelProperty("类型 0:倒计时 1:限制选项数量 2:选中某些指定选项执行操作") + @ApiModelProperty("类型 0:倒计时 1:限制选项数量 2:选中某些指定选项执行操作 3:显示内容") private byte showType; } + + + @EqualsAndHashCode(callSuper = true) @Data @ApiModel("选项限制") public static class OptionLimit extends Show{ @@ -33,6 +37,7 @@ public class QuestionShowVo { private byte min; } + @EqualsAndHashCode(callSuper = true) @Data @ApiModel("特殊指定-返回") public static class OptionSpecial extends Show{ @@ -48,10 +53,22 @@ public class QuestionShowVo { private String content; } + @EqualsAndHashCode(callSuper = true) + @Data + @ApiModel("题目内容补充") + public static class QuestionSupplement extends Show{ + @ApiModelProperty("类型 0:图片") + private byte type; + @ApiModelProperty("内容") + private String content; + } + @ApiModel("倒计时配置") @Data public static class MesTimer { - @ApiModelProperty("限制类型 0:选中选项数量达到最大后,内容非指定选项,则显示对应信息") + @ApiModelProperty("提醒文案") + private String content; + @ApiModelProperty("限制类型 0:跳转指定题目") private byte type; @ApiModelProperty("量表") private String code; diff --git a/ht/src/main/java/com/ccsens/ht/bean/vo/QuestionVo.java b/ht/src/main/java/com/ccsens/ht/bean/vo/QuestionVo.java index 919285da..f6eec212 100644 --- a/ht/src/main/java/com/ccsens/ht/bean/vo/QuestionVo.java +++ b/ht/src/main/java/com/ccsens/ht/bean/vo/QuestionVo.java @@ -69,13 +69,11 @@ public class QuestionVo { }); } this.records = records; - this.isLast = question.getSort().intValue() == maxSort; - this.isFirst = question.getSort().intValue() == 1; + this.isLast = question.getSort() == maxSort; + this.isFirst = question.getSort() == 1; if (CollectionUtil.isEmpty(shows)) { return; } - List questionShows = new ArrayList<>(); - List optionShows = new ArrayList<>(); shows.forEach(show->{ if (StrUtil.isBlank(show.getParam())) { return; @@ -109,6 +107,12 @@ public class QuestionVo { // 追加到题目信息里 question.getQuestionShows().add(special); break; + case Constant.Ht.QuestionShow.SHOW_TYPE_SHOW: + QuestionShowVo.QuestionSupplement questionSupplement = JSONObject.parseObject(show.getParam(), QuestionShowVo.QuestionSupplement.class); + questionSupplement.setShowType(Constant.Ht.QuestionShow.SHOW_TYPE_SHOW); + // 追加到题目信息里 + question.getQuestionShows().add(questionSupplement); + break; default: break; } @@ -142,7 +146,7 @@ public class QuestionVo { vo.setQuestion(Question.toQuestionVo(question)); if (CollectionUtil.isNotEmpty(options)) { //方便后续把相同属性的选项放到一个对象的List中 - Map map = new HashMap<>(); + Map map = new HashMap<>(16); options.forEach(option -> { if (map.get(option.getName()) == null) { OptionJson json = new OptionJson(); @@ -204,8 +208,8 @@ public class QuestionVo { List questionShows = new ArrayList<>(); /** * 将HtQuestion转化成Question - * @param question - * @return + * @param question 试题信息 + * @return 试题vo */ public static Question toQuestionVo(HtQuestion question) { Question vo = new Question(); @@ -213,23 +217,6 @@ public class QuestionVo { return vo; } - /** - * 将HtQuestion集合转化成Question集合 - * @param questions - * @return - */ - public static List toQuestionVos(List questions) { - List vos = new ArrayList<>(); - if (CollectionUtils.isEmpty(questions)) { - return vos; - } - questions.forEach(question -> { - Question vo = new Question(); - BeanUtils.copyProperties(question, vo); - vos.add(vo); - }); - return vos; - } } @Data @@ -255,15 +242,18 @@ public class QuestionVo { private List options; public List getOptions() { - if (CollectionUtil.isNotEmpty(answers) && CollectionUtil.isNotEmpty(options)) { - for (RecordOption option: options) { - for (String answer: answers) { - if (option.getDataKey().equals(answer)) { - option.choose = 1; - } + if (CollectionUtil.isEmpty(answers) || CollectionUtil.isEmpty(options)) { + return options; + } + for (RecordOption option: options) { + for (String answer: answers) { + if (option.getDataKey().equals(answer)) { + option.choose = 1; + break; } } } + return options; } } @@ -352,17 +342,17 @@ public class QuestionVo { /** * 将HtQuestionIntroduce转化成介绍vo - * @param introduces - * @return + * @param introduces 引导语 + * @return 引导语vo */ public static List toIntroduces(List introduces) { List vos = new ArrayList<>(); if (CollectionUtils.isEmpty(introduces)) { return vos; } - introduces.forEach(introducer -> { + introduces.forEach(introduce -> { Introduce vo = new Introduce(); - BeanUtils.copyProperties(introducer, vo); + BeanUtils.copyProperties(introduce, vo); vos.add(vo); }); return vos; @@ -383,8 +373,8 @@ public class QuestionVo { /** * HtPatientQuestionRecord转化成介绍vo - * @param records - * @return + * @param records 其他记录 + * @return 其他记录VO */ public static List toRecords(List records) { List vos = new ArrayList<>(); diff --git a/ht/src/main/java/com/ccsens/ht/service/QuestionService.java b/ht/src/main/java/com/ccsens/ht/service/QuestionService.java index d38610bb..ea498a0b 100644 --- a/ht/src/main/java/com/ccsens/ht/service/QuestionService.java +++ b/ht/src/main/java/com/ccsens/ht/service/QuestionService.java @@ -8,18 +8,25 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.ccsens.ht.bean.dto.QuestionDto; +import com.ccsens.ht.bean.dto.message.MessageDto; import com.ccsens.ht.bean.po.*; import com.ccsens.ht.bean.vo.QuestionShowVo; import com.ccsens.ht.bean.vo.QuestionVo; import com.ccsens.ht.persist.dao.*; -import com.ccsens.ht.persist.mapper.*; +import com.ccsens.ht.persist.mapper.HtPatientCanvasLineMapper; +import com.ccsens.ht.persist.mapper.HtPatientQuestionRecordMapper; +import com.ccsens.ht.persist.mapper.HtPatientReportMapper; import com.ccsens.ht.uitl.Constant; -import com.ccsens.util.*; +import com.ccsens.util.CodeEnum; +import com.ccsens.util.bean.message.common.InMessage; +import com.ccsens.util.bean.message.common.MessageRule; +import com.ccsens.util.config.RabbitMQConfig; import com.ccsens.util.exception.BaseException; import io.swagger.annotations.ApiModel; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.springframework.amqp.core.AmqpTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @@ -29,12 +36,11 @@ import javax.annotation.Resource; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; -import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; -import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -49,7 +55,7 @@ import java.util.concurrent.atomic.AtomicInteger; public class QuestionService implements IQuestionService { - @Autowired + @Resource private Snowflake snowflake; @Resource private HtQuestionDao htQuestionDao; @@ -75,11 +81,8 @@ public class QuestionService implements IQuestionService { private HtPatientReportRecordDescDao htPatientReportRecordDescDao; @Resource private HtQuestionShowDao htQuestionShowDao; - - - - - + @Resource + private AmqpTemplate rabbitTemplate; @Override public QuestionVo.Query queryQuestion(QuestionDto.Query query, Long userId) { @@ -199,7 +202,7 @@ public class QuestionService implements IQuestionService { } @Override - public CodeEnum saveScore(QuestionDto.Score score, Long userId) { + public CodeEnum saveScore(QuestionDto.Score score, final Long userId) { log.info("保存分数{}", score); if (score.getPatientReportId() == null) { @@ -242,17 +245,17 @@ public class QuestionService implements IQuestionService { for(QuestionDto.Option option : score.getOptions()) { HtQuestionOption questionOption = htQuestionOptionDao.selectByPrimaryKey(option.getId()); + //未找到对应选项 或选项不是该试题的选项 + if (questionOption == null || questionOption.getQuestionId().longValue() != question.getId()) { + log.info("选项不存在或不是对应试题的选项"); + return CodeEnum.PARAM_ERROR; + } //去除整数后多余的小数点 if(ObjectUtil.isNotNull(questionOption.getScore())){ if(BigDecimal.valueOf(questionOption.getScore().intValue()).compareTo(questionOption.getScore()) == 0){ questionOption.setScore(questionOption.getScore().setScale(0,BigDecimal.ROUND_HALF_UP)); } } - //未找到对应选项 或选项不是该试题的选项 - if (questionOption == null || questionOption.getQuestionId().longValue() != question.getId()) { - log.info("选项不存在或不是对应试题的选项"); - return CodeEnum.PARAM_ERROR; - } nameOption.put(questionOption.getName(), questionOption); idOption.put(questionOption.getId(), questionOption); } @@ -262,7 +265,7 @@ public class QuestionService implements IQuestionService { if (!CollectionUtils.isEmpty(ruleList)) { HtQuestionScoringRule rule = ruleList.get(0); - if (rule.getType() == null || rule.getType().byteValue() == Constant.Ht.Rule.SMALL) { + if (rule.getType() == null || rule.getType() == Constant.Ht.Rule.SMALL) { // 计算分数 countScore(score, parentCode, report, scores, rule); } else { @@ -296,22 +299,37 @@ public class QuestionService implements IQuestionService { return CodeEnum.SUCCESS; } log.info("执行提交后的任务"); - ScheduledExecutorService executor = Executors.newScheduledThreadPool(shows.size()); + ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(shows.size(), + new BasicThreadFactory.Builder().namingPattern("question-schedule-pool-%d").daemon(true).build()); + shows.forEach(show -> { - switch (show.getShowType()) { - case Constant.Ht.QuestionShow.SHOW_TYPE_COUNT_DOWN: - QuestionShowVo.MesTimer mesTimer = JSONObject.parseObject(show.getParam(), QuestionShowVo.MesTimer.class); - executor.schedule(new Thread(new Runnable() { - @Override - public void run() { - // TODO 消息推送 - } - }), mesTimer.getTime(), TimeUnit.SECONDS); - break; - default: - break; + // 倒计时 + if (show.getShowType() == Constant.Ht.QuestionShow.SHOW_TYPE_COUNT_DOWN) { + QuestionShowVo.MesTimer mesTimer = JSONObject.parseObject(show.getParam(), QuestionShowVo.MesTimer.class); + + executor.schedule(() -> { + // 设置 + try { + MessageDto.QuestionInform inform = new MessageDto.QuestionInform(); + inform.setContent(mesTimer.getContent()); + inform.setCode(mesTimer.getCode()); + inform.setSort(mesTimer.getSort()); + MessageDto data = new MessageDto<>(); + data.setData(inform); + InMessage inMessage = new InMessage(MessageRule.noAck(), JSONObject.toJSONString(data), String.valueOf(userId)); + rabbitTemplate.convertAndSend(RabbitMQConfig.TALL_MESSAGE_1, JSONObject.toJSONString(inMessage)); + log.info("发送成功:{}", inMessage); + } catch (Exception e) { + log.error("保存试题答案后,推送消息异常", e); + } + }, mesTimer.getTime(), TimeUnit.SECONDS); } }); + /* + + */ + executor.shutdown(); + log.info("线程池结束"); return CodeEnum.SUCCESS; } @@ -332,15 +350,15 @@ public class QuestionService implements IQuestionService { /** * 修改报告单显示状态 - * @param report - * @param question + * @param report 报告单 + * @param question 题目 */ private void changeShowStatus(HtPatientReport report, HtQuestion question) { - if (report.getShowStatus() != null && report.getShowStatus().byteValue() == Constant.Ht.Report.SHOW_HISTORY) { + if (report.getShowStatus() != null && report.getShowStatus() == Constant.Ht.Report.SHOW_HISTORY) { return; } Integer maxSort = htQuestionDao.selectMaxSort(question.getEvaluationCode()); - if (question.getSort() != null && maxSort != null && question.getSort().intValue() >= maxSort) { + if (question.getSort() != null && maxSort != null && question.getSort() >= maxSort) { report.setShowStatus(Constant.Ht.Report.SHOW_HISTORY); htPatientReportMapper.updateByPrimaryKeySelective(report); } @@ -351,16 +369,17 @@ public class QuestionService implements IQuestionService { HtPatientQuestionRecordExample example = new HtPatientQuestionRecordExample(); String type; switch (question.getOperateType()) { - - case Constant.Ht.Operation.VOICE://语音 - - case Constant.Ht.Operation.KNOCK://敲击 + //语音 + case Constant.Ht.Operation.VOICE: + //敲击 + case Constant.Ht.Operation.KNOCK: type = Constant.Ht.Record.ANSWER_AUDIO; break; - case Constant.Ht.Operation.PAINT: //画图 - case Constant.Ht.Operation.PAINT_HALF: //画图 - case Constant.Ht.Operation.PAINT_HALF_IMG: //画图 - case Constant.Ht.Operation.PAINT_NO_IMG: //画图 + //画图 + case Constant.Ht.Operation.PAINT: + case Constant.Ht.Operation.PAINT_HALF: + case Constant.Ht.Operation.PAINT_HALF_IMG: + case Constant.Ht.Operation.PAINT_NO_IMG: type = Constant.Ht.Record.ANSWER_IMG; break; default: @@ -404,9 +423,9 @@ public class QuestionService implements IQuestionService { } /** - * 查询试题正确个数 - * @param scores - * @return + * 计算试题正确个数 + * @param scores 分数 + * @return 正确格式 */ private int getCurrentNum(List scores) { if (CollectionUtil.isEmpty(scores)) { @@ -430,15 +449,13 @@ public class QuestionService implements IQuestionService { /** * 分数数据处理 - * @param score - * @param question - * @param report - * @param ruleList - * @param nameOption - * @param idOption - * @return - * @throws IOException - * @throws NotSupportedFileTypeException + * @param score 分数 + * @param question 题目 + * @param report 报告单 + * @param ruleList 计分规则 + * @param nameOption 选项 + * @param idOption 题目ID + * @return 父子关联的分数集合 */ private List getHtPatientScores(QuestionDto.Score score, HtQuestion question, HtPatientReport report, List ruleList, Map nameOption, Map idOption) { List scores = new ArrayList<>(); @@ -462,13 +479,13 @@ public class QuestionService implements IQuestionService { /** * 组装分数对象 - * @param score + * @param score 分数 * @param option 当前选项(前端传入) - * @param question - * @param report - * @param ruleList - * @param nameOption - * @param scores + * @param question 题目 + * @param report 报告单 + * @param ruleList 计分规则 + * @param nameOption 选项 + * @param scores 分数集合 * @param questionOption 当前选项(数据库查询) */ private void assembleScore(QuestionDto.Score score, QuestionDto.Option option, HtQuestion question, HtPatientReport report, List ruleList, Map nameOption, List scores, HtQuestionOption questionOption) { @@ -494,26 +511,26 @@ public class QuestionService implements IQuestionService { } private void countScoreByFormula(Map nameOption, HtQuestionOption questionOption, HtPatientScore patientScore, JSONObject remark) { - switch (remark.getIntValue("isAutoformula")) { - case 1: - String formulaSymbol = remark.getString("formulaSymbol"); - String[] params = remark.getString("formulaName").split(","); - StringBuilder formula = new StringBuilder(); - for (String param: params) { - formula.append(formulaSymbol).append(nameOption.get(param) == null ? 0 : nameOption.get(param) .getScore()); - } - String substring = formula.substring(formulaSymbol.length()); - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine js = manager.getEngineByName("js"); - try { - BigDecimal result = BigDecimal.valueOf((Integer)js.eval(substring)); - patientScore.setScore(result); - } catch (ScriptException e) { - log.error("计算出现异常",e); - throw new BaseException(CodeEnum.PARAM_ERROR) ; - } - break; - default: patientScore.setScore(questionOption.getScore());break; + String key = "isAutoformula"; + if (remark.getIntValue(key) == 1) { + String formulaSymbol = remark.getString("formulaSymbol"); + String[] params = remark.getString("formulaName").split(","); + StringBuilder formula = new StringBuilder(); + for (String param : params) { + formula.append(formulaSymbol).append(nameOption.get(param) == null ? 0 : nameOption.get(param).getScore()); + } + String substring = formula.substring(formulaSymbol.length()); + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine js = manager.getEngineByName("js"); + try { + BigDecimal result = BigDecimal.valueOf((Integer) js.eval(substring)); + patientScore.setScore(result); + } catch (ScriptException e) { + log.error("计算出现异常", e); + throw new BaseException(CodeEnum.PARAM_ERROR); + } + } else { + patientScore.setScore(questionOption.getScore()); } } @@ -613,7 +630,8 @@ public class QuestionService implements IQuestionService { private List getCanvasPoints(HtPatientCanvas htPatientCanvas) { List canvasPoints = patientCanvasDao.getCanvasPoints(htPatientCanvas.getId()); - if(canvasPoints.size() > 16){ + int num = 16; + if(canvasPoints.size() > num){ int c = 240 / (((canvasPoints.size() + 1) / 4) - 1); int a = 0; int b = 0; @@ -678,7 +696,7 @@ public class QuestionService implements IQuestionService { /** * 统计画图的参数 * - * @param question + * @param question 题目 * @param htPatientCanvas 画板信息 * @param param 请求参数 参考长度 参考思考时间 * @return 返回此次画图的参数 @@ -735,7 +753,7 @@ public class QuestionService implements IQuestionService { PointPosition maxY = null; //总长度 double totalLength = 0; - /**已经给最大最小点赋值*/ + // 已经给最大最小点赋值 boolean hadValue = false; for (int i = 0; i < canvasPoints.size(); i++) { QuestionVo.Point canvas = canvasPoints.get(i); @@ -825,15 +843,7 @@ public class QuestionService implements IQuestionService { // lineParameter.setIntervalDuration(intervalDuration); // reflectOnTime += intervalDuration; // } - if (i == 0) { - lineParameter.setIntervalDuration(parameter.getStartDuration()); - reflectOnTime += parameter.getStartDuration(); - } else { - String[] prevPoints = canvasPoints.get(i - 1).getValue().split(";"); - String prevEnd = prevPoints[prevPoints.length - 1].split(",")[2]; - lineParameter.setIntervalDuration(Long.parseLong(s[s.length - 1]) - Long.parseLong(prevEnd)); - reflectOnTime += lineParameter.getIntervalDuration(); - } + reflectOnTime = getReflectOnTime(parameter, canvasPoints, reflectOnTime, i, lineParameter, s); lineParameterList.add(lineParameter); } @@ -859,38 +869,26 @@ public class QuestionService implements IQuestionService { log.info("画板中心:{},{}", centerX, centerY); //计算图形中心 - int x = (maxX.value + minX.value) / 2; - int y = (maxY.value + minY.value) / 2; + int x = maxX == null || minX == null ? 0 : (maxX.value + minX.value) / 2; + int y = maxY == null || minY == null ? 0 : (maxY.value + minY.value) / 2; String centreCoordinate = x + "," + y; parameter.setCentreCoordinate(centreCoordinate); // TODO 重心 parameter.setBarycenterCoordinate(centreCoordinate); //最小长方形面积 - double acreage = (maxX.value - minX.value) * (maxY.value - minY.value); + boolean extremeNoValue = maxX == null || minX == null || maxY == null || minY == null; + double acreage = extremeNoValue ? 0 : (maxX.value - minX.value) * (maxY.value - minY.value); parameter.setMinRectangleAcreage(acreage); // 最小圆面积 距离中心最远点-->最小长方形长宽一半的平均数 - double radius = ((double)(maxX.value - minX.value + maxY.value - minY.value)) /2 /2; + double radius = extremeNoValue ? 0 : ((double)(maxX.value - minX.value + maxY.value - minY.value)) /2 /2; parameter.setMinCircleAcreage(new BigDecimal(Math.PI * radius * radius).setScale(2, BigDecimal.ROUND_HALF_UP)); // 四个边界点 四舍五入 sqrt setFourPoint(canvasPoints, minX, maxX, minY, maxY); log.info("half:{}",half); - if (half) { - parameter.setShowCentreCoordinate(new QuestionVo.Coordinate(y-centerY, x-centerX )); - // x:y, y:x - parameter.setTop(new QuestionVo.Coordinate(maxY.y - centerY, maxY.x - centerX )); - parameter.setBottom(new QuestionVo.Coordinate(minY.y - centerY, minY.x - centerX)); - parameter.setLeft(new QuestionVo.Coordinate(minX.y - centerY, minX.x - centerX)); - parameter.setRight(new QuestionVo.Coordinate(maxX.y - centerY, maxX.x - centerX)); - } else { - parameter.setShowCentreCoordinate(new QuestionVo.Coordinate(centerX - x, y - centerY)); - parameter.setTop(new QuestionVo.Coordinate(centerX - maxY.x , maxY.y - centerY)); - parameter.setBottom(new QuestionVo.Coordinate(centerX - minY.x, minY.y - centerY)); - parameter.setLeft(new QuestionVo.Coordinate(centerX - minX.x , minX.y - centerY)); - parameter.setRight(new QuestionVo.Coordinate(centerX - maxX.x , maxX.y - centerY)); - } + setPosition(parameter, minX, maxX, minY, maxY, half, centerX, centerY, x, y, extremeNoValue); //平均长度 BigDecimal aveLength = BigDecimal.valueOf(totalLength / canvasPoints.size()).setScale(2, RoundingMode.HALF_UP); @@ -916,6 +914,36 @@ public class QuestionService implements IQuestionService { return parameter; } + private void setPosition(QuestionVo.Parameter parameter, PointPosition minX, PointPosition maxX, PointPosition minY, PointPosition maxY, boolean half, int centerX, int centerY, int x, int y, boolean extremeNoValue) { + if (half && !extremeNoValue) { + parameter.setShowCentreCoordinate(new QuestionVo.Coordinate(y-centerY, x-centerX )); + // x:y, y:x + parameter.setTop(new QuestionVo.Coordinate(maxY.y - centerY, maxY.x - centerX )); + parameter.setBottom(new QuestionVo.Coordinate(minY.y - centerY, minY.x - centerX)); + parameter.setLeft(new QuestionVo.Coordinate(minX.y - centerY, minX.x - centerX)); + parameter.setRight(new QuestionVo.Coordinate(maxX.y - centerY, maxX.x - centerX)); + } else if (!extremeNoValue) { + parameter.setShowCentreCoordinate(new QuestionVo.Coordinate(centerX - x, y - centerY)); + parameter.setTop(new QuestionVo.Coordinate(centerX - maxY.x , maxY.y - centerY)); + parameter.setBottom(new QuestionVo.Coordinate(centerX - minY.x, minY.y - centerY)); + parameter.setLeft(new QuestionVo.Coordinate(centerX - minX.x , minX.y - centerY)); + parameter.setRight(new QuestionVo.Coordinate(centerX - maxX.x , maxX.y - centerY)); + } + } + + private long getReflectOnTime(QuestionVo.Parameter parameter, List canvasPoints, long reflectOnTime, int i, QuestionVo.LineParameter lineParameter, String[] s) { + if (i == 0) { + lineParameter.setIntervalDuration(parameter.getStartDuration()); + reflectOnTime += parameter.getStartDuration(); + } else { + String[] prevPoints = canvasPoints.get(i - 1).getValue().split(";"); + String prevEnd = prevPoints[prevPoints.length - 1].split(",")[2]; + lineParameter.setIntervalDuration(Long.parseLong(s[s.length - 1]) - Long.parseLong(prevEnd)); + reflectOnTime += lineParameter.getIntervalDuration(); + } + return reflectOnTime; + } + /** * 设置 四个特殊点,计算中心点、四个特殊点相对原点(画板中心)的距离 计算点到中心点距离的平方的最大值 * @param canvasPoints 记录 @@ -925,14 +953,19 @@ public class QuestionService implements IQuestionService { * @param maxY 最下点 */ private void setFourPoint(List canvasPoints, PointPosition minX, PointPosition maxX, PointPosition minY, PointPosition maxY) { -// int max = 0; + boolean extremeNoValue = maxX == null || minX == null || maxY == null || minY == null; + if (extremeNoValue) { + log.info("有极限值未找到:{},{},{},{}", maxX, minX, maxY, minY); + return; + } + for (int i = 0; i < canvasPoints.size(); i++) { QuestionVo.Point point = canvasPoints.get(i); if (StrUtil.isEmpty(point.getValue())) { continue; } String[] pointArr = point.getValue().split(";"); - if (pointArr == null || pointArr.length <= 0) { + if (pointArr.length <= 0) { continue; } //1左 2右 3 上 4 下 @@ -952,17 +985,9 @@ public class QuestionService implements IQuestionService { } else { pointArr[j] += ",0"; } - String[] strArr = s.split(","); - if (strArr == null || strArr.length < 2) { - continue; - } -// int pointX = Integer.parseInt(strArr[0]); -// int pointY = Integer.parseInt(strArr[1]); -// max = (int) Math.max(max, Math.pow(pointX-x, 2) + Math.pow(pointY - y, 2)); } point.setValue(StringUtils.join(pointArr, ";")); } -// return max; } @@ -1004,7 +1029,7 @@ public class QuestionService implements IQuestionService { QuestionVo.LineParameter lineParameter = lineParameterList.get(i); // 长短笔画 - if(aveLength.compareTo(new BigDecimal(lineParameter.getLength())) >= 0){ + if(aveLength.compareTo(BigDecimal.valueOf(lineParameter.getLength())) >= 0){ lineParameter.setLengthStatus(Constant.LineColour.LENGTH_STATUS_SHORT); shortNums++; } else { @@ -1040,7 +1065,7 @@ public class QuestionService implements IQuestionService { lineIndex++; // 第5条线时,计算长线段的比例 if (lineIndex == lineCount) { - parameter.setLongLineRate(new BigDecimal(longLineIndex * 100).divide(new BigDecimal(lineCount))); + parameter.setLongLineRate(new BigDecimal(longLineIndex * 100).divide(new BigDecimal(lineCount), 2, BigDecimal.ROUND_HALF_UP)); } } diff --git a/ht/src/main/java/com/ccsens/ht/uitl/Constant.java b/ht/src/main/java/com/ccsens/ht/uitl/Constant.java index dc730e8b..6d3078d0 100644 --- a/ht/src/main/java/com/ccsens/ht/uitl/Constant.java +++ b/ht/src/main/java/com/ccsens/ht/uitl/Constant.java @@ -159,18 +159,23 @@ public class Constant { public static final byte SHOW_NODE_CHOOSING = 1; /**结点:选择结束*/ public static final byte SHOW_NODE_CHOSE = 2; + /**结点:显示题目时*/ + public static final byte SHOW_NODE_QUERY = 3; /**类型:倒计时*/ public static final byte SHOW_TYPE_COUNT_DOWN = 0; /**类型:限制选项数量*/ public static final byte SHOW_TYPE_LIMIT = 1; /**类型:选中某些指定选项执行操作*/ public static final byte SHOW_TYPE_SPECIAL = 2; + /**类型:查询题目时的展示内容*/ + public static final byte SHOW_TYPE_SHOW = 3; public static final List SHOW_NODE_RUNNING = new ArrayList<>(); public static final List SHOW_NODE_RUN = new ArrayList<>(); static { SHOW_NODE_RUNNING.add(SHOW_NODE_CHOOSING); SHOW_NODE_RUNNING.add(SHOW_NODE_CHOSE); + SHOW_NODE_RUNNING.add(SHOW_NODE_QUERY); SHOW_NODE_RUN.add(SHOW_NODE_SUBMIT); } } diff --git a/util/src/main/java/com/ccsens/util/JsonResponse.java b/util/src/main/java/com/ccsens/util/JsonResponse.java index 537127d5..7302ebd5 100644 --- a/util/src/main/java/com/ccsens/util/JsonResponse.java +++ b/util/src/main/java/com/ccsens/util/JsonResponse.java @@ -61,7 +61,7 @@ public class JsonResponse { return this; } - public JsonResponse ok(T data){ + public JsonResponse ok(T data){ ok(); this.data = data; return this; @@ -74,7 +74,7 @@ public class JsonResponse { return this; } - public JsonResponse ok(CodeEnum codeEnum, T data){ + public JsonResponse ok(CodeEnum codeEnum, T data){ this.code = codeEnum.getCode(); this.msg = codeEnum.getMsg(); this.success = codeEnum.isSuccess(); diff --git a/util/src/main/java/com/ccsens/util/bean/message/common/InMessage.java b/util/src/main/java/com/ccsens/util/bean/message/common/InMessage.java index c4d3cdc6..836c1b2f 100644 --- a/util/src/main/java/com/ccsens/util/bean/message/common/InMessage.java +++ b/util/src/main/java/com/ccsens/util/bean/message/common/InMessage.java @@ -5,7 +5,9 @@ import com.ccsens.util.JacksonUtil; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import lombok.Data; +import org.apache.poi.ss.formula.functions.T; +import java.util.HashSet; import java.util.Set; /** @@ -60,6 +62,17 @@ public class InMessage { public InMessage(){ this.time = DateUtil.currentSeconds(); } + + public InMessage(MessageRule rule, String data, String... toArr){ + this(); + this.rule = rule; + this.data = data; + this.tos = new HashSet<>(); + for (String to: toArr) { + tos.add(to); + } + } + public static InMessage newToServerMessage(MessageConstant.DomainType fromDomain,ServerMessage serverMessage) throws JsonProcessingException { InMessage inMessage = new InMessage(); inMessage.setFromDomain(fromDomain); @@ -88,7 +101,16 @@ public class InMessage { inMessage.setData(data); return inMessage; } - + public static InMessage newNo(String from, Set tos, String unikey, MessageRule rule, String data) throws JsonProcessingException { + InMessage inMessage = new InMessage(); + inMessage.setToDomain(MessageConstant.DomainType.User); + inMessage.setFrom(from); + inMessage.setTos(tos); + inMessage.setUnikey(unikey); + inMessage.setRule(rule); + inMessage.setData(data); + return inMessage; + } //TODO //添加方便链式调用的构造方法,类似builder diff --git a/util/src/main/java/com/ccsens/util/bean/message/common/MessageRule.java b/util/src/main/java/com/ccsens/util/bean/message/common/MessageRule.java index 98b97eb0..7624fb2f 100644 --- a/util/src/main/java/com/ccsens/util/bean/message/common/MessageRule.java +++ b/util/src/main/java/com/ccsens/util/bean/message/common/MessageRule.java @@ -77,4 +77,16 @@ public class MessageRule { } return messageRule; } + + /** + * 不需要回复ACK,离线状态直接丢弃 + * @return + */ + public static MessageRule noAck(){ + MessageRule rule = new MessageRule(); + rule.setAckRule(MessageRule.AckRule.NONE); + rule.setOfflineDiscard((byte) 1); + rule.setNoAckRetryTimes(3); + return rule; + } }