zhangk
2024-06-28 45e1162a14af5c0aac7a0709d6e4579519538111
添加解析北斗消息功能
2 files modified
1 files added
137 ■■■■■ changed files
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/sjztmd/entity/StBdData.java 29 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/sjztmd/service/impl/StBdDataServiceImpl.java 87 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/sjztmd/vo/BdParsedContentVO.java 21 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/sjztmd/entity/StBdData.java
@@ -33,6 +33,35 @@
    private String content;
    /**
     * 解析后的消息内容
     */
    @TableField(value = "\"parsed_content\"")
    @ApiModelProperty(value = "解析后的消息内容")
    private String parsedContent;
    /**
     * 经度
     */
    @TableField(value = "\"longitude\"")
    @ApiModelProperty(value = "经度")
    private String longitude;
    /**
     * 纬度
     */
    @TableField(value = "\"latitude\"")
    @ApiModelProperty(value = "纬度")
    private String latitude;
    /**
     * 海拔
     */
    @TableField(value = "\"altitude\"")
    @ApiModelProperty(value = "海拔")
    private String altitude;
    /**
     * 发送卡号
     */
    @TableField(value = "\"from_addr\"")
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/sjztmd/service/impl/StBdDataServiceImpl.java
@@ -4,9 +4,11 @@
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;
@@ -19,6 +21,9 @@
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;
@@ -52,12 +57,72 @@
            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
@@ -80,4 +145,22 @@
        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"));
    }
}
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/sjztmd/vo/BdParsedContentVO.java
New file
@@ -0,0 +1,21 @@
package cn.gistack.sm.sjztmd.vo;
import lombok.Data;
@Data
public class BdParsedContentVO {
    private Boolean success;
    private String errorMessage;
    private String parsedContent;
    private String longitude;
    private String latitude;
    private String altitude;
    private boolean containChinese;
}