ke
2024-07-19 08a962d2925baa255207fdf979e6fee794f1773b
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/sjztmd/service/impl/StBdDataServiceImpl.java
@@ -4,14 +4,27 @@
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 com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.support.Condition;
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;
import java.util.ArrayList;
@@ -19,20 +32,17 @@
import java.util.List;
import java.util.UUID;
@Slf4j
@Service
@DS("zt")
public class StBdDataServiceImpl extends ServiceImpl<StBdDataMapper, StBdData> implements IStBdDataService {
   private static final ObjectMapper objectMapper = new ObjectMapper();
   private final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
   @Override
   public Boolean insertData(String stBdDataStr) {
      StBdDataVO stBdDataVO;
      try {
         stBdDataVO = objectMapper.readValue(stBdDataStr, StBdDataVO.class);
      } catch (JsonProcessingException e) {
         throw new ServiceException("转换北斗平台监测数据失败,详情:" + e.getMessage());
      }
   public Boolean insertData(StBdDataVO stBdDataVO) throws Exception {
      List<StBdDataVO.CommInfo> commInfos = stBdDataVO.getCommInfos();
      if (null == commInfos || commInfos.isEmpty()) {
         throw new ServiceException("获取北斗平台数据失败,无效的commInfos");
@@ -41,18 +51,92 @@
      for (StBdDataVO.CommInfo commInfo : commInfos) {
         StBdData stBdData = new StBdData();
         stBdData.setId(UUID.randomUUID().toString().replaceAll("-", ""));
         stBdData.setTm(commInfo.getTime());
         stBdData.setTm(formatter.parse(commInfo.getTime()));
         stBdData.setCreateTime(new Date());
         stBdData.setFromAddr(commInfo.getFromAddr());
         stBdData.setToAddr(commInfo.getToAddr());
         String content = commInfo.getContent();
          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.setLongitude(longitude);
      bdParsedContentVO.setLatitude(latitude);
      bdParsedContentVO.setAltitude(altitude);
      bdParsedContentVO.setSuccess(true);
      return bdParsedContentVO;
   }
   @Override
   public IPage<StBdData> selectAlarmRecordPage(Query query, StBdVO stBdVO) {
      LambdaQueryWrapper<StBdData> queryWrapper = Wrappers.<StBdData>query().lambda()
         .eq(StrUtil.isNotEmpty(stBdVO.getCodeType()), StBdData::getCodeType, stBdVO.getCodeType())
         .eq(StrUtil.isNotEmpty(stBdVO.getFromAddr()), StBdData::getFromAddr, stBdVO.getFromAddr())
         .eq(StrUtil.isNotEmpty(stBdVO.getToAddr()), StBdData::getToAddr, stBdVO.getToAddr())
         .ge(stBdVO.getStartTime() != null, StBdData::getTm, stBdVO.getStartTime())
         .le(stBdVO.getEndTime() != null, StBdData::getTm, stBdVO.getEndTime());
      return page(Condition.getPage(query), queryWrapper);
   }
   private boolean contentIsContainChinese(String content) {
@@ -64,4 +148,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"));
   }
}