diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/handler/DeviceDataHandler.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/handler/DeviceDataHandler.java index de0467b..3fe079e 100644 --- a/intc-modules/intc-iot/src/main/java/com/intc/iot/handler/DeviceDataHandler.java +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/handler/DeviceDataHandler.java @@ -1647,6 +1647,30 @@ public class DeviceDataHandler { return; } + // 对应 C# CreateNoticeCall:同一设备已有活跃通知批次时,只追加消息关联,不重复创建新批次 + // 活跃批次窗口 = 重试次数 * 手机号数量 * 间隔分钟 * 2(留余量) + int maxBatchMinutes = CALL_NOTICE_RETRY_COUNT * CALL_NOTICE_MINUTE_INTERVAL * 2; + LocalDateTime activeBatchStart = LocalDateTime.now().minusMinutes(maxBatchMinutes); + long activeCount = warnCallNoticeMapper.countActiveByDeviceAfter(device.getId(), activeBatchStart); + if (activeCount > 0) { + log.debug("[故障码] 设备={} 已有活跃通知批次,追加消息关联后跳过重复创建", device.getSerialNum()); + // 查找当前批次中最早的一条通知记录,追加关联 + AquWarnCallNotice existNotice = warnCallNoticeMapper.selectOne( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(AquWarnCallNotice::getDeviceId, device.getId()) + .ge(AquWarnCallNotice::getCallTime, activeBatchStart) + .orderByAsc(AquWarnCallNotice::getCallTime) + .last("LIMIT 1") + ); + if (existNotice != null && warn.getId() != null) { + AquMapMessageWarnCallNotice mapRecord = new AquMapMessageWarnCallNotice(); + mapRecord.setMessageWarnId(warn.getId()); + mapRecord.setCallNoticeId(existNotice.getId()); + mapMessageWarnCallNoticeMapper.insert(mapRecord); + } + return; + } + LocalDateTime baseTime = LocalDateTime.now(); int index = 0; AquWarnCallNotice firstCallNotice = null; @@ -1995,7 +2019,8 @@ public class DeviceDataHandler { if (phaseVolt != null && phaseVolt > 0 && voltage == null) { voltage = phaseVolt; } - if (phaseCur != null && phaseCur > 0 && current == null) { + // 电流允许为 0(设备空载时上报 0.00 是合法值,不可用 > 0 过滤) + if (phaseCur != null && current == null) { current = phaseCur; } if (voltage != null && current != null) break; @@ -2008,7 +2033,7 @@ public class DeviceDataHandler { com.intc.fishery.domain.DeviceSwitch updateVoltCur = new com.intc.fishery.domain.DeviceSwitch(); updateVoltCur.setId(sw.getId()); if (voltage != null) updateVoltCur.setDetectVoltageValue(voltage); - if (current != null) updateVoltCur.setDetectElectricValue(current); + if (current != null) updateVoltCur.setDetectElectricValue(current); // current=0 也需写入 deviceSwitchMapper.updateById(updateVoltCur); log.debug("更新开关电压电流: 设备={}, 开关索引={}, 电压={}V, 电流={}A", deviceName, switchIndex, voltage, current); diff --git a/intc-modules/intc-iot/src/main/java/com/intc/iot/mapper/AquWarnCallNoticeMapper.java b/intc-modules/intc-iot/src/main/java/com/intc/iot/mapper/AquWarnCallNoticeMapper.java index e473354..d8fe517 100644 --- a/intc-modules/intc-iot/src/main/java/com/intc/iot/mapper/AquWarnCallNoticeMapper.java +++ b/intc-modules/intc-iot/src/main/java/com/intc/iot/mapper/AquWarnCallNoticeMapper.java @@ -78,6 +78,22 @@ public interface AquWarnCallNoticeMapper extends BaseMapper { @Param("title") String title, @Param("periodStart") LocalDateTime periodStart); + /** + * 查询指定设备、时间范围内「活跃通知批次」的数量(不区分 title) + * 对应 C# CreateNoticeCall 中检查 _listNoticeWaitHandle / _listInsertWarnCallNotice 的去重逻辑 + * 用于故障码告警创建时判断该设备是否已有进行中的通知批次,避免重复创建 + * + * @param deviceId 设备ID + * @param afterTime 起始时间 + * @return 满足条件的通知数量 + */ + @Select("SELECT COUNT(1) FROM aqu_call_notice " + + "WHERE device_id = #{deviceId} " + + "AND call_status IN (0, 1, 2) " + + "AND call_time >= #{afterTime}") + long countActiveByDeviceAfter(@Param("deviceId") Long deviceId, + @Param("afterTime") LocalDateTime afterTime); + /** * 查询 callStatus=0 且 callTime <= now 的到期待发记录 * 用于定时任务扫描并触发语音通知