“djh”
2026-01-16 2e5582facc8d161780dec8e58a74fb36d094ca37
src/main/java/com/gkhy/fourierSpecialGasMonitor/service/impl/DataReceiveServiceImpl.java
@@ -5,6 +5,7 @@
import com.gkhy.fourierSpecialGasMonitor.commons.domain.Result;
import com.gkhy.fourierSpecialGasMonitor.commons.enums.ForeignResultCode;
import com.gkhy.fourierSpecialGasMonitor.commons.enums.ResultCode;
import com.gkhy.fourierSpecialGasMonitor.commons.enums.SystemCacheKeyEnum;
import com.gkhy.fourierSpecialGasMonitor.commons.exception.DataReceiveException;
import com.gkhy.fourierSpecialGasMonitor.decorator.WarningThresholdUpdateEvent;
import com.gkhy.fourierSpecialGasMonitor.entity.*;
@@ -16,6 +17,7 @@
import com.gkhy.fourierSpecialGasMonitor.repository.GasConcentrationRepository;
import com.gkhy.fourierSpecialGasMonitor.service.*;
import com.gkhy.fourierSpecialGasMonitor.utils.SendMessageUtil;
import com.gkhy.fourierSpecialGasMonitor.utils.SummaryUtils;
import com.gkhy.fourierSpecialGasMonitor.websocket.GasConcentrationExcWebsocketServer;
import com.gkhy.fourierSpecialGasMonitor.websocket.GasConcentrationWebsocketServer;
import com.gkhy.fourierSpecialGasMonitor.websocket.GasDeviceExcWebsocketServer;
@@ -38,12 +40,10 @@
import java.io.IOException;
import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
@@ -93,6 +93,9 @@
    @Autowired
    private GasFluxWebsocketServer gasFluxWebsocketServer;
    @Autowired
    private SummaryStatsService summaryStatsService;
    private static final ReentrantLock lock = new ReentrantLock();
    @Autowired
@@ -121,6 +124,7 @@
    private static final DateTimeFormatter warnLogFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
    private static final String[] DEVICE_EXC_RECEIVER = {"17625323889","18019908965","18899396560"};
    @PostConstruct
    public void init() {
@@ -172,6 +176,9 @@
        return ForeignResult.success();
    }
    /**
     * 设备预警
     * */
    @Override
    public ForeignResult deviceMonitor(DeviceMonitorReqDTO reqDTO) {
        if (reqDTO == null)
@@ -199,34 +206,46 @@
            descs.add(GasFluxStateEnum.INVERSION_FAILED_10_MINUTES_NO_DATA.getDesc());
        }
        String message = JSON.toJSONString(reqDTO);
        //todo 暂时改为实时推送给前端
        //暂时改为实时推送给前端
        try {
            GasDeviceExcWebsocketServer.sendInfo(message,null);
        } catch (IOException e) {
            logger.info("【警告】设备异常提醒推送>>>>>>>>>>>>>>>>>>失败");
        }
        if (push){
            //todo 线上环境还是异常才向前端推送
            //String message = JSON.toJSONString(reqDTO);
            //try {
            //    GasDeviceExcWebsocketServer.sendInfo(message,null);
            //} catch (IOException e) {
            //    logger.info("【警告】设备异常提醒推送>>>>>>>>>>>>>>>>>>失败");
            //}
            DeviceExceptionLog lastLog = deviceExceptionLogService.getLastLog();
            LocalDateTime now = LocalDateTime.now();
            if (lastLog == null || now.compareTo(lastLog.getTime().plusHours(1)) >= 0) {
                Map<String, String> mesMap = new HashMap<>();
                mesMap.put("message","数据异常,无法进行监测");
                mesMap.put(" level","设备离线");  // todo
                List<String> deviceExcReceiver = Arrays.asList(DEVICE_EXC_RECEIVER);
                if (!CollectionUtils.isEmpty(deviceExcReceiver)) {
                    List<String> distinctPhone = deviceExcReceiver.stream().distinct().collect(Collectors.toList());
                    logger.info("【气体浓度异常短信发送】-----发送内容:" + "克拉玛依富城数据异常,无法进行监测 气体浓度连续超标,系统判断为设备离线,请相关负责人及时检查处置。"
                            + " 发送时间: " + LocalDateTime.now()+ " 接收人手机号:" + distinctPhone);
                    if (!org.springframework.util.StringUtils.isEmpty(smsSendEnabledStatus) && "true".equals(smsSendEnabledStatus)) {
                        sendMessageUtil.sendMessageCheck(deviceExcReceiver.toArray(new String[deviceExcReceiver.size()]), mesMap);
                    }
                }
            }
            String execInfo = JSON.toJSONString(descs);
            logger.info("【警告】设备异常,异常原因: "+ execInfo);
            DeviceExceptionLog log = new DeviceExceptionLog();
            LocalDateTime now = LocalDateTime.now();
            String content  = MessageFormat.format(deviceExcLogFormat,deviceExcLogFormatter.format(now));
            log.setContent(content);
            log.setTime(now);
            log.setExecDesc(execInfo);
            log.setDelFlag(1);
            DeviceExceptionLog save =  deviceExceptionLogService.save(log);
            if (save == null)
            if (save == null) {
                logger.info("【警告】设备异常日志保存>>>>>>>>>>>>>>>>>>失败");
            }
        }
        return ForeignResult.success();
    }
    private void gasFluxDataCacheAndPush(){
        LocalDateTime time = LocalDateTime.now();
@@ -254,14 +273,52 @@
        GasConcentration save = gasConcentrationService.save(gasConcentration);
        if (save == null)
            throw new DataReceiveException(this.getClass(), ForeignResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"气体实时数据保存失败");
        //计算平局值,最大值,最小值
        computeAndSaveDailySummaryStats(save);
        dataCacheAndPush(save);
        execDataCountAndPush(reqDto);
        return ForeignResult.success();
    }
    /**
     * 计算并保存当天的气体浓度统计数据(若统计为空则初始化,否则更新)
     * @param newData 新插入的气体浓度数据
     */
    private void computeAndSaveDailySummaryStats(GasConcentration newData) {
        //  定义当天时间范围(00:00:00 至当前时间)
        LocalDateTime todayStart = LocalDate.now().atStartOfDay();
        LocalDateTime now = LocalDateTime.now();
        //  查询当天已有的统计数据
        SummaryStats dailyStats = gasConcentrationService.findStats(todayStart, now);
        // 若统计数据为空,创建新对象并初始化(用新数据作为初始值)
        if (dailyStats == null || dailyStats.isEmpty()) {
            dailyStats = new SummaryStats();
            SummaryUtils.initSummaryStats(dailyStats, newData);
        } else {
            // 若统计数据已存在,更新统计值(根据新数据重新计算 min/max/avg)
            SummaryUtils.updateSummaryStats(dailyStats, newData);
        }
        dailyStats.setTemp(newData.getTemp());
        dailyStats.setHumidity(newData.getHumidity());
        dailyStats.setWindSpeed(newData.getWindSpeed());
        dailyStats.setWindDirection(newData.getWindDirection());
        dailyStats.setPressure(newData.getPressure());
        // 补充通用字段(时间取最新数据的时间)
        dailyStats.setTime(newData.getTime());
        //  保存统计结果
        summaryStatsService.save(dailyStats);
    }
    private  void execDataCountAndPush(UploadGasConcentrationReqDTO reqDto){
        RBucket<List<GasCategory>> bucket = redissonClient.getBucket("gas_category_cache_info");
        RBucket<List<GasCategory>> bucket = redissonClient.getBucket(SystemCacheKeyEnum.KEY_GAS_CATEGORY.getKey());
        List<GasCategory> gasCategoryCache = bucket.get();
        if (CollectionUtils.isEmpty(gasCategoryCache)){
            gasCategoryCache = gasCategoryService.list();
@@ -316,6 +373,9 @@
        }
    }
    /**
     * 气体数据--预警信息推送
    * */
    private void warnLogGenerateAndExecPush(Integer warnThresholdEnumCode,GasCategory gasCategory,Double value){
        if (gasCategory == null)
            throw new DataReceiveException(this.getClass(), ForeignResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"该气体不存在于对照表");
@@ -360,8 +420,7 @@
                throw new DataReceiveException(this.getClass(), ForeignResultCode.SYSTEM_ERROR_DATABASE_FAIL.getCode(),"预警异常短信接收人保存失败");
            Map<String, String> mesMap = new HashMap<>();
            mesMap.put("message",warnTime+" "+gasCategory.getName());
            mesMap.put("level",warnThresholdName);
            //todo
            mesMap.put(" level",warnThresholdName);
            if (!CollectionUtils.isEmpty(phone)) {
                List<String> distinctPhone = phone.stream().distinct().collect(Collectors.toList());
                logger.info("【气体浓度异常短信发送】-----发送内容:" + content + " 发送时间: " + now + " 接收人手机号:" + distinctPhone);