|
|
|
@ -12,14 +12,11 @@ import com.ccsens.util.DateUtil; |
|
|
|
import com.ccsens.util.RedisUtil; |
|
|
|
import com.ccsens.util.bean.message.common.*; |
|
|
|
import com.ccsens.yanyuan.bean.dto.message.TalkingPenDto; |
|
|
|
import com.ccsens.yanyuan.bean.po.EquipmentLog; |
|
|
|
import com.ccsens.yanyuan.bean.po.ToolEquipment; |
|
|
|
import com.ccsens.yanyuan.bean.po.ToolEquipmentExample; |
|
|
|
import com.ccsens.yanyuan.bean.po.*; |
|
|
|
import com.ccsens.yanyuan.bean.vo.TrainContentVo; |
|
|
|
import com.ccsens.yanyuan.persist.dao.TrainContentDao; |
|
|
|
import com.ccsens.yanyuan.persist.dao.TrainEquipmentDao; |
|
|
|
import com.ccsens.yanyuan.persist.dao.UserRelationDao; |
|
|
|
import com.ccsens.yanyuan.persist.dao.*; |
|
|
|
import com.ccsens.yanyuan.persist.mapper.EquipmentLogMapper; |
|
|
|
import com.ccsens.yanyuan.persist.mapper.ToolCardMapper; |
|
|
|
import com.ccsens.yanyuan.persist.mapper.ToolEquipmentMapper; |
|
|
|
import com.ccsens.yanyuan.service.IConstantService; |
|
|
|
import com.ccsens.yanyuan.util.YanYuanConstant; |
|
|
|
@ -29,8 +26,8 @@ import org.springframework.amqp.rabbit.annotation.RabbitListener; |
|
|
|
import org.springframework.stereotype.Component; |
|
|
|
|
|
|
|
import javax.annotation.Resource; |
|
|
|
import java.math.BigDecimal; |
|
|
|
import java.util.*; |
|
|
|
import java.util.concurrent.atomic.AtomicReference; |
|
|
|
|
|
|
|
/** |
|
|
|
* @description: |
|
|
|
@ -60,6 +57,14 @@ public class TalkingPenReceive { |
|
|
|
private TrainContentDao trainContentDao; |
|
|
|
@Resource |
|
|
|
private EquipmentLogMapper equipmentLogMapper; |
|
|
|
@Resource |
|
|
|
private TrainResultDao trainResultDao; |
|
|
|
@Resource |
|
|
|
private ToolCardMapper toolCardMapper; |
|
|
|
@Resource |
|
|
|
private TrainCardDao trainCardDao; |
|
|
|
@Resource |
|
|
|
private TrainRecordDao trainRecordDao; |
|
|
|
|
|
|
|
@RabbitHandler |
|
|
|
public void process(String messageJson) throws Exception { |
|
|
|
@ -90,6 +95,9 @@ public class TalkingPenReceive { |
|
|
|
case TalkingPenDto.Type.QUESTION: |
|
|
|
dealQuestion(messageMap.get(type).get(0)); |
|
|
|
break; |
|
|
|
case TalkingPenDto.Type.INDEX: |
|
|
|
dealIndex(messageMap.get(type).get(0)); |
|
|
|
break; |
|
|
|
default: |
|
|
|
// 处理过程
|
|
|
|
dealProcess(messageMap.get(TalkingPenDto.Type.PACKAGE).get(0), messageMap.get(TalkingPenDto.Type.FRAME).get(0), messageMap.get(TalkingPenDto.Type.PROCESS)); |
|
|
|
@ -102,6 +110,148 @@ public class TalkingPenReceive { |
|
|
|
log.info("保存日志"); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 处理序号 |
|
|
|
* @param talkingPen 序号或结果 |
|
|
|
*/ |
|
|
|
private void dealIndex(TalkingPenDto talkingPen) throws Exception { |
|
|
|
YanYuanConstant.Card card = YanYuanConstant.Card.getByCardIndex(talkingPen.getValue()); |
|
|
|
byte type = card == null ? YanYuanConstant.CardType.INDEX : card.getType(); |
|
|
|
Long value = card == null ? talkingPen.getValue() : card.getRealIndex(); |
|
|
|
// 查找点读笔
|
|
|
|
ToolEquipment toolEquipment = getToolEquipment(talkingPen.getAuthId()); |
|
|
|
if (toolEquipment == null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
Long equipmentId = toolEquipment.getId(); |
|
|
|
// 查找使用者
|
|
|
|
Long keyUserId = getUser(equipmentId, talkingPen.getAuthId()); |
|
|
|
if (keyUserId < 0) { |
|
|
|
// 未找到题目
|
|
|
|
saveResult(type, 0L, toolEquipment.getId(), value); |
|
|
|
return; |
|
|
|
} |
|
|
|
// 如果是序号,查找卡片对应题目code
|
|
|
|
ToolCard toolCard = null; |
|
|
|
if (type == YanYuanConstant.CardType.INDEX) { |
|
|
|
ToolCardExample cardExample = new ToolCardExample(); |
|
|
|
cardExample.createCriteria().andRealNumEqualTo(Math.toIntExact(value)); |
|
|
|
cardExample.setOrderByClause(" id desc limit 1"); |
|
|
|
List<ToolCard> toolCards = toolCardMapper.selectByExample(cardExample); |
|
|
|
log.info("卡片对应类型:{}", toolCards); |
|
|
|
if (CollectionUtil.isEmpty(toolCards)) { |
|
|
|
saveResult(type, 0L, toolEquipment.getId(), value); |
|
|
|
return; |
|
|
|
} |
|
|
|
toolCard = toolCards.get(0); |
|
|
|
} |
|
|
|
// 查询点读笔正在读的题目
|
|
|
|
String key = StrUtil.format(YanYuanConstant.Equipment.TALKING_PEN_QUESTION, toolEquipment.getId(), keyUserId); |
|
|
|
Object o = redisUtil.get(key); |
|
|
|
log.info("点读笔{}正在读的题目:{}", key, o); |
|
|
|
// 有正在读的题目,结果直接保存,序号判断类型一致保存
|
|
|
|
if (o!=null) { |
|
|
|
TrainContentVo.Audio audioRedis = (TrainContentVo.Audio) o; |
|
|
|
//
|
|
|
|
boolean save = type == YanYuanConstant.CardType.RESULT || |
|
|
|
(type == YanYuanConstant.CardType.INDEX && toolCard.getType().equals(audioRedis.getCode())); |
|
|
|
if (save) { |
|
|
|
// 结果 或 序号,判断类型是否一致
|
|
|
|
saveResult(type, audioRedis.getRecordId(), toolEquipment.getId(), value); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
long today = DateUtil.beginOfDay(new Date()).getTime(); |
|
|
|
// 点读笔没有正在进行的题目
|
|
|
|
if (type == YanYuanConstant.CardType.RESULT) { |
|
|
|
// 查询今天的训练计划和结果
|
|
|
|
saveTrainResult(value, toolEquipment.getId(), keyUserId, today); |
|
|
|
} else { |
|
|
|
// 查询前后一周的、同类型的训练计划
|
|
|
|
saveCard(toolCard, toolEquipment.getId(), keyUserId, today); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 保存卡片序号 |
|
|
|
* @param toolCard 卡片 |
|
|
|
* @param toolEquipmentId 设备ID |
|
|
|
* @param keyUserId 使用者 |
|
|
|
* @param today 今天 |
|
|
|
*/ |
|
|
|
private void saveCard(ToolCard toolCard, Long toolEquipmentId, Long keyUserId, long today) { |
|
|
|
long startTime = today - YanYuanConstant.MentalTest.PERIOD / 2 * YanYuanConstant.DAY_TIME; |
|
|
|
long endTime = today + YanYuanConstant.MentalTest.PERIOD / 2 * YanYuanConstant.DAY_TIME; |
|
|
|
List<TrainContentVo.RecordTime> times = trainRecordDao.queryTime(keyUserId, startTime, endTime, toolCard.getType()); |
|
|
|
if (CollectionUtil.isEmpty(times)) { |
|
|
|
saveCard(toolCard, 0L, keyUserId, today); |
|
|
|
return; |
|
|
|
} |
|
|
|
Long recordId = null; |
|
|
|
Long subTime = null; |
|
|
|
for (TrainContentVo.RecordTime time: times) { |
|
|
|
if (subTime == null || subTime > Math.abs(today - time.getStartTime())) { |
|
|
|
recordId = time.getRecordId(); |
|
|
|
subTime = Math.abs(today - time.getStartTime()); |
|
|
|
} |
|
|
|
} |
|
|
|
saveResult(YanYuanConstant.CardType.INDEX, recordId, toolEquipmentId, toolCard.getRealNum()); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 保存答案 |
|
|
|
* @param value 答案 |
|
|
|
* @param toolEquipmentId 设备ID |
|
|
|
* @param keyUserId 用户ID |
|
|
|
* @param today 时间 |
|
|
|
*/ |
|
|
|
private void saveTrainResult(Long value, Long toolEquipmentId, Long keyUserId, long today) { |
|
|
|
List<TrainContentVo.RecordResultCount> records = trainRecordDao.queryCount(keyUserId, today); |
|
|
|
log.info("{}今天{}的训练计划:{}", keyUserId, today, records); |
|
|
|
if (CollectionUtil.isEmpty(records)) { |
|
|
|
saveResult(YanYuanConstant.CardType.RESULT, 0L, toolEquipmentId, value); |
|
|
|
} else if (records.size() == 1) { |
|
|
|
saveResult(YanYuanConstant.CardType.RESULT, records.get(0).getRecordId(), toolEquipmentId, value); |
|
|
|
} else { |
|
|
|
// 找到第一个没有答案的进行记录
|
|
|
|
for (TrainContentVo.RecordResultCount record: records) { |
|
|
|
if (record.getCount() == 0) { |
|
|
|
saveResult(YanYuanConstant.CardType.RESULT, record.getRecordId(), toolEquipmentId, value); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
// 都有答案,记录在最后一道题下
|
|
|
|
saveResult(YanYuanConstant.CardType.RESULT, records.get(records.size()).getRecordId(), toolEquipmentId, value); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void saveResult(Byte type, Long recordId, Long equipmentId, long value) { |
|
|
|
log.info("保存类型为:{}的结果,recordId:{}, equipmentId:{}, value:{}", type, recordId, equipmentId, value); |
|
|
|
if (type == null || type == YanYuanConstant.CardType.INDEX) { |
|
|
|
// 序号
|
|
|
|
// 根据序号查询卡片
|
|
|
|
ToolCardExample example = new ToolCardExample(); |
|
|
|
example.createCriteria().andRealNumEqualTo((int)value); |
|
|
|
example.setOrderByClause("id desc limit 1"); |
|
|
|
List<ToolCard> cards = toolCardMapper.selectByExample(example); |
|
|
|
// 存储训练结果
|
|
|
|
TrainCard trainCard = new TrainCard(); |
|
|
|
trainCard.setId(snowflake.nextId()); |
|
|
|
trainCard.setRecordId(recordId); |
|
|
|
trainCard.setAssistId(CollectionUtil.isEmpty(cards) ? 0 : cards.get(0).getId()); |
|
|
|
trainCard.setEquipmentId(equipmentId); |
|
|
|
trainCardDao.insertSelective(trainCard); |
|
|
|
} else if (type == YanYuanConstant.CardType.RESULT) { |
|
|
|
// 结果
|
|
|
|
TrainResult result = new TrainResult(); |
|
|
|
result.setId(snowflake.nextId()); |
|
|
|
result.setRecordId(recordId); |
|
|
|
result.setEquipmentId(equipmentId); |
|
|
|
result.setFinishResult(new BigDecimal(value)); |
|
|
|
trainResultDao.insertSelective(result); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 存储日志 |
|
|
|
* @param messageMap 数据信息 |
|
|
|
@ -134,8 +284,11 @@ public class TalkingPenReceive { |
|
|
|
* @param processList 坐标数据 |
|
|
|
*/ |
|
|
|
private void dealProcess(TalkingPenDto packageDto, TalkingPenDto frameDto, List<TalkingPenDto> processList) { |
|
|
|
String indexTime = constantService.getValue(YanYuanConstant.Equipment.VALID_INDEX_TIME_KEY); |
|
|
|
// 查询点读笔对应的序号
|
|
|
|
TrainCard trainCard = trainCardDao.getRecent(packageDto.getAuthId(), System.currentTimeMillis() - Long.parseLong(indexTime) * 3600 * 1000); |
|
|
|
//校验是否已经存在
|
|
|
|
|
|
|
|
System.out.println(packageDto + "" + frameDto + processList); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
@ -148,20 +301,19 @@ public class TalkingPenReceive { |
|
|
|
if (toolEquipment == null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
Long equipmentId = toolEquipment.getId(); |
|
|
|
// 查找使用者
|
|
|
|
Long keyUserId = getUser(equipmentId, talkingPen.getAuthId()); |
|
|
|
Long keyUserId = getUser(toolEquipment.getId(), talkingPen.getAuthId()); |
|
|
|
if (keyUserId < 0) { |
|
|
|
return; |
|
|
|
} |
|
|
|
// 查找题目
|
|
|
|
TrainContentVo.Audio nextPlan = getNextPlan(talkingPen, equipmentId, keyUserId, talkingPen.getAuthId()); |
|
|
|
log.info("{}的下一个训练计划:{}", equipmentId, nextPlan); |
|
|
|
TrainContentVo.Audio nextPlan = getNextPlan(talkingPen, toolEquipment.getId(), keyUserId, talkingPen.getAuthId()); |
|
|
|
log.info("{}的下一个训练计划:{}", toolEquipment.getId(), nextPlan); |
|
|
|
if (nextPlan == null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
String key = StrUtil.format(YanYuanConstant.Equipment.TALKING_PEN_QUESTION, equipmentId, keyUserId); |
|
|
|
redisUtil.set(key, nextPlan, YanYuanConstant.DAY_TIME / 1000); |
|
|
|
String key = StrUtil.format(YanYuanConstant.Equipment.TALKING_PEN_QUESTION, toolEquipment.getId(), keyUserId); |
|
|
|
redisUtil.set(key, nextPlan, YanYuanConstant.Train.TALKING_PEN_WRITE_TIME); |
|
|
|
//通知点读笔
|
|
|
|
sendAudio(nextPlan.getAudioPosition() == null ? YanYuanConstant.Equipment.AUDIO_DEFAULT : nextPlan.getAudioPosition(), talkingPen.getAuthId()); |
|
|
|
} |
|
|
|
@ -181,22 +333,23 @@ public class TalkingPenReceive { |
|
|
|
// 提醒登录小程序进行脑力测评
|
|
|
|
sendAudio(YanYuanConstant.Equipment.AUDIO_MENTAL, serial); |
|
|
|
return null; |
|
|
|
} else { |
|
|
|
return audio; |
|
|
|
} |
|
|
|
} else { |
|
|
|
TrainContentVo.Audio audioRedis = (TrainContentVo.Audio) o; |
|
|
|
audio = trainContentDao.getNext(audioRedis.getContentId(), talkingPen.getValue()); |
|
|
|
if (audio == null) { |
|
|
|
if (talkingPen.getValue() != YanYuanConstant.Equipment.NEXT) { |
|
|
|
// 上一道为空 提醒没有更多题目
|
|
|
|
sendAudio(YanYuanConstant.Equipment.AUDIO_TRAIN_PLAN_NO, serial); |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
TrainContentVo.Audio audioRedis = (TrainContentVo.Audio) o; |
|
|
|
audio = trainContentDao.getNext(audioRedis.getRecordId(), talkingPen.getValue()); |
|
|
|
if (audio == null) { |
|
|
|
if (talkingPen.getValue() != YanYuanConstant.Equipment.NEXT) { |
|
|
|
// 上一道为空 提醒没有更多题目
|
|
|
|
sendAudio(YanYuanConstant.Equipment.AUDIO_TRAIN_PLAN_NO, serial); |
|
|
|
} else { |
|
|
|
// 下一道为空
|
|
|
|
//当前题目日期小于今天 提醒登录小程序进行脑力测评, 否则 提醒没有更多题目
|
|
|
|
int audioIndex = audioRedis.getStartTime() < todayBegin ? YanYuanConstant.Equipment.AUDIO_MENTAL : YanYuanConstant.Equipment.AUDIO_TRAIN_PLAN_NO; |
|
|
|
sendAudio(audioIndex, serial); |
|
|
|
return null; |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
return audio; |
|
|
|
} |
|
|
|
@ -210,8 +363,10 @@ public class TalkingPenReceive { |
|
|
|
// 查询时间
|
|
|
|
String key = YanYuanConstant.Equipment.VALID_TIME_KEY; |
|
|
|
String value = constantService.getValue(key); |
|
|
|
Long time = System.currentTimeMillis() - Long.parseLong(value) * YanYuanConstant.DAY_TIME; |
|
|
|
Long keyUserId = trainEquipmentDao.queryRecentUserId(equipmentId, time); |
|
|
|
long time = System.currentTimeMillis() - Long.parseLong(value) * YanYuanConstant.DAY_TIME; |
|
|
|
Date date = new Date(); |
|
|
|
date.setTime(time); |
|
|
|
Long keyUserId = trainEquipmentDao.queryRecentUserId(equipmentId, date); |
|
|
|
log.info("{}有效期内选择的用户:{}", equipmentId, keyUserId); |
|
|
|
if (keyUserId != null) { |
|
|
|
return keyUserId; |
|
|
|
@ -219,6 +374,7 @@ public class TalkingPenReceive { |
|
|
|
// 查询购买者关联的用户
|
|
|
|
List<Long> userIds = userRelationDao.countUserByEquipment(equipmentId); |
|
|
|
log.info("{}关联的使用者:{}", equipmentId, userIds); |
|
|
|
// TODO 记录一下点读笔发送的语音,时长1分钟,若1分钟内发送过相同的内容,则不再发送(仅限用户未绑定,时长待定)
|
|
|
|
if (CollectionUtil.isEmpty(userIds)) { |
|
|
|
sendAudio(YanYuanConstant.Equipment.AUDIO_NO_TRAINEE, authId); |
|
|
|
return YanYuanConstant.Equipment.BIND_USER_NUM_ZERO; |
|
|
|
|