fix: 电话通知判断逻辑问题修复。

This commit is contained in:
tianyongbao
2026-03-10 00:02:37 +08:00
parent 1676ef7599
commit 60879f6e8b
2 changed files with 56 additions and 18 deletions

View File

@@ -506,8 +506,12 @@ public class DeviceDataHandler {
}
String pondName = warnList.isEmpty() ? deviceName : warnList.get(0).getPondName();
// 抑制时间:根据配置的小时数展开,查找 callStatus=3回执成功的记录
LocalDateTime intervalTime = LocalDateTime.now().minusHours(aliyunIotProperties.getCallSuccessSuppressHours());
// 抑制时间:查找 callStatus=3回执成功的记录
LocalDateTime suppressTime = LocalDateTime.now().minusHours(aliyunIotProperties.getCallSuccessSuppressHours());
// 活跍批次查找窗口:一个完整通知批次的最大时长 = 重试次数 * 手机号数,每次间隔 CALL_NOTICE_MINUTE_INTERVAL 分钟
// 这里简化用 2 倍的全周期时间保证导式内等待记录能被查到
int maxBatchMinutes = CALL_NOTICE_RETRY_COUNT * CALL_NOTICE_MINUTE_INTERVAL * 2;
LocalDateTime activeBatchStart = LocalDateTime.now().minusMinutes(maxBatchMinutes);
LocalDateTime periodStart = getCurrentPeriodStart();
// 按 title 分组,每种类型独立判断间隔并发送通知
@@ -533,18 +537,25 @@ public class DeviceDataHandler {
noDisturbEnabled = true;
}
// 按设备+title检查是否已通知
// 按设备+title检查是否已通知(双重抑制)
long recentCount;
if (noDisturbEnabled) {
// 免打扰开启:当前时段内已通知过则跳过
// 免打扰开启:当前时段内已有任意状态的通知就跳过
recentCount = warnCallNoticeMapper.countByDeviceAndTitleInPeriod(deviceId, title, periodStart);
if (recentCount > 0) {
log.debug("[告警] {} title={} 免打扰:当前时段内已通知,跳过", deviceName, title);
continue;
}
} else {
// 免打扰关闭:查找指定小时内是否已有回执成功的通知
recentCount = warnCallNoticeMapper.countByDeviceAndTitleAfter(deviceId, title, intervalTime);
// 免打扰关闭:双重抑制
// 1. 先查活跍批次(未完成的通知批次),防止当前轮重复创建
long activeCount = warnCallNoticeMapper.countActiveByDeviceAndTitleAfter(deviceId, title, activeBatchStart);
if (activeCount > 0) {
log.debug("[告警] {} title={} - 当前有活跍通知批次在进行,跳过", deviceName, title);
continue;
}
// 2. 再查N小时内是否已有回执成功的记录
recentCount = warnCallNoticeMapper.countSuccessByDeviceAndTitleAfter(deviceId, title, suppressTime);
if (recentCount > 0) {
log.debug("[告警] {} title={} - {}h内已有回执成功的通知跳过", deviceName, title, aliyunIotProperties.getCallSuccessSuppressHours());
continue;
@@ -793,11 +804,18 @@ public class DeviceDataHandler {
return;
}
// 检查告警间隔(防止频繁通知
LocalDateTime intervalTime = LocalDateTime.now().minusMinutes(aliyunIotProperties.getAlarmNotificationIntervalMinutes());
long recentCount = warnCallNoticeMapper.countByDeviceAndTitleAfter(deviceId, "设备离线", intervalTime);
// 双重抑制1) 活跃批次检查(防止当前轮重复); 2) 成功通知抑制N小时内已成功则不再打
int maxBatchMinutesOff = CALL_NOTICE_RETRY_COUNT * CALL_NOTICE_MINUTE_INTERVAL * 2;
LocalDateTime activeBatchStartOff = LocalDateTime.now().minusMinutes(maxBatchMinutesOff);
long activeCountOff = warnCallNoticeMapper.countActiveByDeviceAndTitleAfter(deviceId, "设备离线", activeBatchStartOff);
if (activeCountOff > 0) {
log.debug("[离线告警] 当前有活跃通知批次在进行,跳过: {}", deviceName);
return;
}
LocalDateTime suppressTimeOff = LocalDateTime.now().minusHours(aliyunIotProperties.getCallSuccessSuppressHours());
long recentCount = warnCallNoticeMapper.countSuccessByDeviceAndTitleAfter(deviceId, "设备离线", suppressTimeOff);
if (recentCount > 0) {
log.debug("[离线告警] {}分钟内已通知,跳过: {}", aliyunIotProperties.getAlarmNotificationIntervalMinutes(), deviceName);
log.debug("[离线告警] {}h内已有回执成功的通知,跳过: {}", aliyunIotProperties.getCallSuccessSuppressHours(), deviceName);
return;
}