feat(health): 告警微信模板消息通知 + alert.triggered 事件消费者
This commit is contained in:
@@ -5,6 +5,8 @@ export const TEMPLATE_IDS = {
|
||||
APPOINTMENT_REMINDER: '',
|
||||
FOLLOWUP_REMINDER: '',
|
||||
REPORT_NOTIFICATION: '',
|
||||
CRITICAL_HEALTH_ALERT: '',
|
||||
HEALTH_DATA_ABNORMAL: '',
|
||||
} as const;
|
||||
|
||||
/** 检查模板 ID 是否已配置,未配置时返回 false 并打印警告 */
|
||||
|
||||
@@ -159,6 +159,46 @@ pub fn register_handlers_with_state(state: crate::state::HealthState) {
|
||||
|
||||
// ── P1 事件消费者补全 ──
|
||||
|
||||
// alert.triggered → 告警消息通知
|
||||
let (mut alert_rx, _alert_handle) = state.event_bus.subscribe_filtered("alert.".to_string());
|
||||
let alert_db = state.db.clone();
|
||||
let alert_bus = state.event_bus.clone();
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
match alert_rx.recv().await {
|
||||
Some(event) if event.event_type == ALERT_TRIGGERED => {
|
||||
if erp_core::events::is_event_processed(&alert_db, event.id, "alert_notifier").await.unwrap_or(false) {
|
||||
continue;
|
||||
}
|
||||
let patient_id = event.payload.get("patient_id").and_then(|v| v.as_str());
|
||||
let severity = event.payload.get("severity").and_then(|v| v.as_str()).unwrap_or("warning");
|
||||
let rule_name = event.payload.get("rule_name").and_then(|v| v.as_str()).unwrap_or("健康告警");
|
||||
if let Some(pid) = patient_id {
|
||||
let notify_event = erp_core::events::DomainEvent::new(
|
||||
"message.send",
|
||||
event.tenant_id,
|
||||
erp_core::events::build_event_payload(serde_json::json!({
|
||||
"channel": "in_app",
|
||||
"recipient_type": "patient",
|
||||
"recipient_id": pid,
|
||||
"template_key": if severity == "critical" { "CRITICAL_HEALTH_ALERT" } else { "HEALTH_DATA_ABNORMAL" },
|
||||
"params": {
|
||||
"rule_name": rule_name,
|
||||
"severity": severity,
|
||||
}
|
||||
})),
|
||||
);
|
||||
alert_bus.publish(notify_event, &alert_db).await;
|
||||
tracing::info!(patient_id = %pid, severity = %severity, "告警通知已发送");
|
||||
}
|
||||
let _ = erp_core::events::mark_event_processed(&alert_db, event.id, "alert_notifier").await;
|
||||
}
|
||||
Some(_) => {}
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// patient.created → 欢迎消息通知
|
||||
let (mut patient_rx, _patient_handle) = state.event_bus.subscribe_filtered("patient.".to_string());
|
||||
let patient_db = state.db.clone();
|
||||
|
||||
Reference in New Issue
Block a user