fix: 电话通知报警,逻辑完善,改为报警电话列表获取电话号码,通知成功后24小时不再打电话等等。
This commit is contained in:
@@ -48,4 +48,13 @@ public interface WarnCallNoticeService {
|
||||
* @return 清理的记录数量
|
||||
*/
|
||||
int cleanupExpiredNotifications();
|
||||
|
||||
/**
|
||||
* 扫描到期待发的通知记录,调用 VMS 发送语音通知
|
||||
* 对应注释:“如失败则后续通知记录会在定时任务中按时间发送”
|
||||
* 触发条件:callStatus=0 且 callTime <= 当前时间
|
||||
*
|
||||
* @return 发送成功的数量
|
||||
*/
|
||||
int processPendingNotifications();
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.intc.iot.domain.AquWarnCallNotice;
|
||||
import com.intc.iot.domain.VmsCallback;
|
||||
import com.intc.iot.domain.VmsNoticeResponse;
|
||||
import com.intc.iot.mapper.AquWarnCallNoticeMapper;
|
||||
import com.intc.iot.mapper.VmsCallbackMapper;
|
||||
import com.intc.iot.service.VmsNoticeService;
|
||||
import com.intc.iot.service.WarnCallNoticeService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -15,7 +17,9 @@ import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 告警电话通知服务实现
|
||||
@@ -30,6 +34,7 @@ public class WarnCallNoticeServiceImpl implements WarnCallNoticeService {
|
||||
|
||||
private final AquWarnCallNoticeMapper warnCallNoticeMapper;
|
||||
private final VmsCallbackMapper vmsCallbackMapper;
|
||||
private final VmsNoticeService vmsNoticeService;
|
||||
|
||||
/**
|
||||
* 呼叫状态枚举(对应 C# EnumCallNoticeStatus)
|
||||
@@ -48,9 +53,9 @@ public class WarnCallNoticeServiceImpl implements WarnCallNoticeService {
|
||||
|
||||
/**
|
||||
* 回执超时时间(分钟)
|
||||
* 对应 C# CallNoticeMinuteInterval = 3
|
||||
* VMS 回执延迟较长,改为 5 分钟,避免回执未到就被标记为超时
|
||||
*/
|
||||
private static final int CALLBACK_TIMEOUT_MINUTES = 3;
|
||||
private static final int CALLBACK_TIMEOUT_MINUTES = 5;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@@ -65,6 +70,7 @@ public class WarnCallNoticeServiceImpl implements WarnCallNoticeService {
|
||||
|
||||
// 优先从 outId(格式:ALARM_{callNoticeId}_{timestamp})中解析主键直接查询
|
||||
// 若解析失败则回退到 callId 匹配
|
||||
// 注意:不限制 callStatus,避免超时清理后回执仍可被处理
|
||||
AquWarnCallNotice callNotice = null;
|
||||
String outId = callback.getOutId();
|
||||
if (outId != null && outId.startsWith("ALARM_")) {
|
||||
@@ -76,10 +82,9 @@ public class WarnCallNoticeServiceImpl implements WarnCallNoticeService {
|
||||
callNotice = warnCallNoticeMapper.selectOne(
|
||||
new LambdaQueryWrapper<AquWarnCallNotice>()
|
||||
.eq(AquWarnCallNotice::getId, noticeId)
|
||||
.eq(AquWarnCallNotice::getCallStatus, CALL_STATUS_CALL_SUCCESS)
|
||||
);
|
||||
if (callNotice != null) {
|
||||
log.debug("[告警通知] 通过 outId 找到通知记录 - 记录ID: {}", noticeId);
|
||||
log.debug("[告警通知] 通过 outId 找到通知记录 - 记录ID: {}, 当前状态: {}", noticeId, callNotice.getCallStatus());
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
@@ -87,12 +92,11 @@ public class WarnCallNoticeServiceImpl implements WarnCallNoticeService {
|
||||
}
|
||||
}
|
||||
|
||||
// 回退:通过 callId 匹配
|
||||
// 回退:通过 callId 匹配(同样不限制 callStatus)
|
||||
if (callNotice == null) {
|
||||
callNotice = warnCallNoticeMapper.selectOne(
|
||||
new LambdaQueryWrapper<AquWarnCallNotice>()
|
||||
.eq(AquWarnCallNotice::getCallId, callback.getCallId())
|
||||
.eq(AquWarnCallNotice::getCallStatus, CALL_STATUS_CALL_SUCCESS)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -175,6 +179,11 @@ public class WarnCallNoticeServiceImpl implements WarnCallNoticeService {
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理超时的通知记录
|
||||
* 对应 C# CleanupExpiredNotifications
|
||||
* 清理规则:已呼叫成功(callStatus=1)但超过超时时间未收到回执的记录
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int cleanupExpiredNotifications() {
|
||||
@@ -224,6 +233,85 @@ public class WarnCallNoticeServiceImpl implements WarnCallNoticeService {
|
||||
return cleanedCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描到期待发的通知记录,调用 VMS 发送语音通知
|
||||
* 触发条件:callStatus=0 且 callTime <= 当前时间
|
||||
*/
|
||||
@Override
|
||||
public int processPendingNotifications() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
List<AquWarnCallNotice> pendingList = warnCallNoticeMapper.selectDuePendingNotices(now);
|
||||
|
||||
if (pendingList.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
log.info("[待发通知] 发现 {} 条到期待发通知记录,开始处理", pendingList.size());
|
||||
|
||||
int sentCount = 0;
|
||||
for (AquWarnCallNotice notice : pendingList) {
|
||||
try {
|
||||
// 查询关联的告警消息内容,用于构建 TTS 参数
|
||||
String rawMessage = warnCallNoticeMapper.selectWarnMessageByCallNoticeId(notice.getId());
|
||||
String warnMessageShort = parseWarnMessageShort(rawMessage);
|
||||
|
||||
// 构建 TTS 参数
|
||||
Map<String, String> ttsParams = new HashMap<>();
|
||||
ttsParams.put("pondName", notice.getPondName() != null ? notice.getPondName() : "未知塘口");
|
||||
ttsParams.put("deviceName", "设备");
|
||||
ttsParams.put("warnMessage", warnMessageShort);
|
||||
|
||||
String outId = "ALARM_" + notice.getId() + "_" + System.currentTimeMillis();
|
||||
|
||||
VmsNoticeResponse response = vmsNoticeService.sendTtsCall(
|
||||
notice.getMobilePhone(),
|
||||
ttsParams,
|
||||
outId
|
||||
);
|
||||
|
||||
if (response != null && response.isSuccess()) {
|
||||
notice.setCallStatus(CALL_STATUS_CALL_SUCCESS);
|
||||
notice.setCallId(response.getCallId());
|
||||
notice.setOutId(outId);
|
||||
warnCallNoticeMapper.updateById(notice);
|
||||
sentCount++;
|
||||
log.info("[待发通知] 呼叫成功: {} - 记录ID: {}", notice.getMobilePhone(), notice.getId());
|
||||
} else {
|
||||
notice.setCallStatus(CALL_STATUS_CALL_FAIL);
|
||||
notice.setStatusMsg(response != null ? response.getMessage() : "呼叫失败");
|
||||
warnCallNoticeMapper.updateById(notice);
|
||||
log.warn("[待发通知] 呼叫失败: {} - 原因: {}", notice.getMobilePhone(), notice.getStatusMsg());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("[待发通知] 处理待发通知异常 - 记录ID: {}, 电话: {}, 异常: {}",
|
||||
notice.getId(), notice.getMobilePhone(), e.getMessage(), e);
|
||||
try {
|
||||
notice.setCallStatus(CALL_STATUS_CALL_FAIL);
|
||||
notice.setStatusMsg("异常:" + e.getMessage());
|
||||
warnCallNoticeMapper.updateById(notice);
|
||||
} catch (Exception ex) {
|
||||
log.error("[待发通知] 更新失败状态异常: {}", ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.info("[待发通知] 处理完成 - 成功: {}, 总数: {}", sentCount, pendingList.size());
|
||||
return sentCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析告警消息为简短形式(取 ':' 前的部分)
|
||||
* 与 DeviceDataHandler.sendVoiceNotification 保持一致
|
||||
*/
|
||||
private String parseWarnMessageShort(String rawMessage) {
|
||||
if (rawMessage == null) {
|
||||
return "异常";
|
||||
}
|
||||
return rawMessage.contains(":")
|
||||
? rawMessage.substring(0, rawMessage.indexOf(":")).trim()
|
||||
: rawMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新电话通知的回执信息
|
||||
* 对应 C# UpdateCallNoticeFromCallback
|
||||
@@ -232,7 +320,12 @@ public class WarnCallNoticeServiceImpl implements WarnCallNoticeService {
|
||||
* @param callback VMS 回执
|
||||
*/
|
||||
private void updateCallNoticeFromCallback(AquWarnCallNotice callNotice, VmsCallback callback) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
// 如果记录已是回执成功状态,跳过不再更新,防止重复回执覆盖
|
||||
if (callNotice.getCallStatus() != null && callNotice.getCallStatus() == CALL_STATUS_CALLBACK_SUCCESS) {
|
||||
log.info("[告警通知] 记录已是成功状态,跳过重复回执 - 记录ID: {}, 电话: {}",
|
||||
callNotice.getId(), callNotice.getMobilePhone());
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新回执详细信息(直接映射字段)
|
||||
callNotice.setStatusCode(callback.getStatusCode());
|
||||
|
||||
Reference in New Issue
Block a user