| | |
| | | import cn.gistack.sm.sjztmd.entity.StBdData; |
| | | import cn.gistack.sm.sjztmd.mapper.StBdDataMapper; |
| | | import cn.gistack.sm.sjztmd.service.IStBdDataService; |
| | | import cn.gistack.sm.sjztmd.vo.BdParsedContentVO; |
| | | import cn.gistack.sm.sjztmd.vo.StBdDataVO; |
| | | import cn.gistack.sm.sjztmd.vo.StBdVO; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.dynamic.datasource.annotation.DS; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | |
| | | import org.springblade.core.mp.support.Query; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.nio.charset.Charset; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | |
| | | stBdData.setToAddr(commInfo.getToAddr()); |
| | | String content = commInfo.getContent(); |
| | | stBdData.setContent(content); |
| | | boolean isContainsChinese = contentIsContainChinese(content); |
| | | stBdData.setCodeType(isContainsChinese? RainfallConstant.CONTAINS_CHINESE : RainfallConstant.NOT_CONTAINS_CHINESE); |
| | | BdParsedContentVO parsedContentVO = parseContent(content); |
| | | if (!parsedContentVO.getSuccess()) { |
| | | log.warn("解析content失败, parsedContentVO : {}", parsedContentVO); |
| | | } |
| | | stBdData.setParsedContent(parsedContentVO.getParsedContent()); |
| | | stBdData.setLongitude(parsedContentVO.getLongitude()); |
| | | stBdData.setLatitude(parsedContentVO.getLatitude()); |
| | | stBdData.setAltitude(parsedContentVO.getAltitude()); |
| | | boolean containsChinese = parsedContentVO.isContainChinese(); |
| | | stBdData.setCodeType(containsChinese? RainfallConstant.CONTAINS_CHINESE : RainfallConstant.NOT_CONTAINS_CHINESE); |
| | | stBdDataList.add(stBdData); |
| | | } |
| | | this.saveBatch(stBdDataList); |
| | | return true; |
| | | } |
| | | |
| | | private BdParsedContentVO parseContent(String content) { |
| | | BdParsedContentVO bdParsedContentVO = new BdParsedContentVO(); |
| | | bdParsedContentVO.setContainChinese(false); |
| | | bdParsedContentVO.setSuccess(false); |
| | | if (StrUtil.isEmpty(content)) { |
| | | bdParsedContentVO.setErrorMessage("无效的content"); |
| | | return bdParsedContentVO; |
| | | } |
| | | |
| | | // 信息类型 |
| | | StringBuilder contentSb = new StringBuilder(content); |
| | | String infoType = contentSb.substring(0, 2); |
| | | |
| | | if (!"91".equals(infoType)) { |
| | | bdParsedContentVO.setErrorMessage("报文信息类型不是91,无法解析"); |
| | | return bdParsedContentVO; |
| | | } |
| | | |
| | | // 接受者手机号 |
| | | Long phoneNumber = Long.parseLong(contentSb.substring(2, 12), 16); |
| | | |
| | | String formattedDate = formatter.format(new Date(1000L * Long.parseLong(contentSb.substring(12, 20), 16))); |
| | | |
| | | // 经度 |
| | | String longitude = new BigDecimal(Long.parseLong(contentSb.substring(20, 28), 16)) |
| | | .divide(new BigDecimal(1000000), 6, RoundingMode.HALF_UP).toString(); |
| | | |
| | | // 纬度 |
| | | String latitude = new BigDecimal(Long.parseLong(contentSb.substring(28, 36), 16)) |
| | | .divide(new BigDecimal(1000000), 6 ,RoundingMode.HALF_UP).toString(); |
| | | |
| | | // 海拔 |
| | | String altitude = String.valueOf(Integer.parseInt(contentSb.substring(36, 40), 16)); |
| | | |
| | | // 短信内容解析 |
| | | String textMessage = hexStr2Str(contentSb.substring(40, content.length())); |
| | | |
| | | // 是否包含中文 |
| | | bdParsedContentVO.setContainChinese(contentIsContainChinese(textMessage)); |
| | | |
| | | JSONObject dataObject = new JSONObject(); |
| | | dataObject.put("phone", phoneNumber); |
| | | dataObject.put("time", formattedDate); |
| | | dataObject.put("longitude", longitude); |
| | | dataObject.put("latitude", latitude); |
| | | dataObject.put("altitude", altitude); |
| | | dataObject.put("message", textMessage); |
| | | bdParsedContentVO.setParsedContent(dataObject.toString()); |
| | | bdParsedContentVO.setSuccess(true); |
| | | return bdParsedContentVO; |
| | | } |
| | | |
| | | @Override |
| | |
| | | Matcher matcher = pattern.matcher(content); |
| | | return matcher.find(); |
| | | } |
| | | |
| | | public static String hexStr2Str(String hexStr) { |
| | | String str = "0123456789ABCDEF"; // 16进制能用到的所有字符 0-15 |
| | | char[] hexs = hexStr.toCharArray(); // toCharArray() 方法将字符串转换为字符数组。 |
| | | int length = (hexStr.length() / 2); // 1个byte数值 -> 两个16进制字符 |
| | | byte[] bytes = new byte[length]; |
| | | int n; |
| | | for (int i = 0; i < bytes.length; i++) { |
| | | int position = i * 2; //两个16进制字符 -> 1个byte数值 |
| | | n = str.indexOf(hexs[position]) * 16; |
| | | n += str.indexOf(hexs[position + 1]); |
| | | // 保持二进制补码的一致性 因为byte类型字符是8bit的 而int为32bit 会自动补齐高位1 所以与上0xFF之后可以保持高位一致性 |
| | | // 当byte要转化为int的时候,高的24位必然会补1,这样,其二进制补码其实已经不一致了,&0xff可以将高的24位置为0,低8位保持原样, |
| | | // 这样做的目的就是为了保证二进制数据的一致性。 |
| | | bytes[i] = (byte) (n & 0xff); |
| | | } |
| | | return new String(bytes, Charset.forName("GB18030")); |
| | | } |
| | | } |