/**
* byte 1 : 05, 表示剩余协议头的长度
* byte 2 : 00, 这个值在GSM 03.40规范9.2.3.24.1中规定,表示随后的这批超长短信的标识位长度为1(格式中的XX值)。
* byte 3 : 03, 这个值表示剩下短信标识的长度
* byte 4 : XX,这批短信的唯一标志,事实上,SME(手机或者SP)把消息合并完之后,就重新记录,所以这个标志是否唯一并不是很重要。
* byte 5 : MM, 这批短信的数量。如果一个超长短信总共5条,这里的值就是5。
* byte 6 : NN, 这批短信的数量。如果当前短信是这批短信中的第一条的值是1,第二条的值是2。
*/
byte[] tpUdhiHead = smgpDeliverMessage.getTpUdhiHead();
// 批号
int batch = tpUdhiHead[3];
// 总数
int total = tpUdhiHead[4];
// 当前数
int current = tpUdhiHead[5];
String msgContent = smgpDeliverMessage.getMsgContent();
String phone = smgpDeliverMessage.getSrcTermId();
ReceiveMsgTemp receiveMsgTemp = new ReceiveMsgTemp();
receiveMsgTemp.setBatch(batch);
receiveMsgTemp.setTotalNum(total);
receiveMsgTemp.setCurrentNum(current);
receiveMsgTemp.setMsgContent(msgContent);
receiveMsgTemp.setMark(UUID.randomUUID().toString());
receiveMsgTemp.setPhoneNum(phone);
receiveMsgTemp.setCreateTime(ZonedDateTime.now());
/**
* 长信息
* 1.查看该手机号对应的该批次数据是否接收完毕
* 1.1.已经接收完毕(当前为最后一条),排序获取所有信息,组装信息,删除临时表数据;
* 1.2.未接收完毕(当前非最后一条),查看该批次对应的总数和条数是否库里已经存在:
* 1.1.1.已存在,则判断是否为第一个,
* 1.1.1.1.若为第一个则新建一个mark标识;
* 1.1.1.2.若不是第一个则查找同批次的另一mark标识
* 1.1.2.不存在,则新建一个mark标识,存入临时表
*/
ReceiveMsgTempExample receiveMsgTempExample = new ReceiveMsgTempExample();
receiveMsgTempExample.createCriteria().andBatchEqualTo(batch).andTotalNumEqualTo(total);
receiveMsgTempExample.setOrderByClause("create_time asc");
List<ReceiveMsgTemp> receiveMsgTemps = receiveMsgTempRepository.selectByExample(receiveMsgTempExample);
if (CollectionUtils.isNotEmpty(receiveMsgTemps)) {// 数据库中有记录
Map<String, List<ReceiveMsgTemp>> msgMap = getMsgTempMap(receiveMsgTemps);
boolean lastFlag = false;// 标记是否为数据库中某条长信息最后一个缺失片段, true:是,false:否
for (String key : msgMap.keySet()) {// 优先找到只缺失一个片段的长信息,并判断缺失的是否为当前片段
List<ReceiveMsgTemp> msgTempList = msgMap.get(key);
List<Integer> currentNumList = msgTempList.stream().map(ReceiveMsgTemp::getCurrentNum).distinct().collect(Collectors.toList());
if (!currentNumList.contains(current) && currentNumList.size() == total - 1) {// 该长信息中只缺失一个片段
lastFlag = true;
String mark = msgMap.get(key).get(0).getMark();
receiveMsgTemp.setMark(mark);
msgTempList.add(receiveMsgTemp);
String content = msgTempList.stream().sorted(Comparator.comparing(ReceiveMsgTemp::getCurrentNum))
.map(ReceiveMsgTemp::getMsgContent).collect(Collectors.joining(""));// 排序并合并内容
smgpDeliverMessage.setMsgContent(content);
try {
setMsgLog(smgpDeliverMessage);
} catch (Exception e) {
log.error("短信息调用setMsgLog方法出错,收到的原始数据为:{},原因:{}", smgpDeliverMessage.getBodys(), e);
}
// 删除该信息对应的片段
ReceiveMsgTempExample deleteExample = new ReceiveMsgTempExample();
deleteExample.createCriteria().andMarkEqualTo(mark);
receiveMsgTempRepository.deleteByExample(deleteExample);
break;
}
}
if (!lastFlag) {// 当前片段不是长信息的最后一个缺失片段
boolean existflag = true;// 标记在数据库中,是否每个长信息都已包含该片段,true都包含
for (String key : msgMap.keySet()) {
List<ReceiveMsgTemp> msgTempList = msgMap.get(key);
List<Integer> currentNumList = msgTempList.stream().map(ReceiveMsgTemp::getCurrentNum).distinct().collect(Collectors.toList());
if (!currentNumList.contains(current)) {// 当前记录中不包含该片段
existflag = false;
receiveMsgTemp.setMark(msgMap.get(key).get(0).getMark());
receiveMsgTempRepository.insert(receiveMsgTemp);
break;
}
}
if (existflag) {// 当前数据库中每个长信息都已包含该片段,新建
receiveMsgTempRepository.insert(receiveMsgTemp);
}
}
} else {// 无记录则直接落库
receiveMsgTempRepository.insert(receiveMsgTemp);
}
}