feat(health): 告警微信模板消息通知 + alert.triggered 事件消费者
This commit is contained in:
@@ -5,6 +5,8 @@ export const TEMPLATE_IDS = {
|
|||||||
APPOINTMENT_REMINDER: '',
|
APPOINTMENT_REMINDER: '',
|
||||||
FOLLOWUP_REMINDER: '',
|
FOLLOWUP_REMINDER: '',
|
||||||
REPORT_NOTIFICATION: '',
|
REPORT_NOTIFICATION: '',
|
||||||
|
CRITICAL_HEALTH_ALERT: '',
|
||||||
|
HEALTH_DATA_ABNORMAL: '',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
/** 检查模板 ID 是否已配置,未配置时返回 false 并打印警告 */
|
/** 检查模板 ID 是否已配置,未配置时返回 false 并打印警告 */
|
||||||
|
|||||||
@@ -159,6 +159,46 @@ pub fn register_handlers_with_state(state: crate::state::HealthState) {
|
|||||||
|
|
||||||
// ── P1 事件消费者补全 ──
|
// ── 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 → 欢迎消息通知
|
// patient.created → 欢迎消息通知
|
||||||
let (mut patient_rx, _patient_handle) = state.event_bus.subscribe_filtered("patient.".to_string());
|
let (mut patient_rx, _patient_handle) = state.event_bus.subscribe_filtered("patient.".to_string());
|
||||||
let patient_db = state.db.clone();
|
let patient_db = state.db.clone();
|
||||||
|
|||||||
Reference in New Issue
Block a user