Files
hms/crates/erp-health/src/event/consultation.rs
iven 8c347a5de9 refactor(health): 拆分 event.rs(2871 行)为 13 个领域文件
将单体 event.rs 按业务域拆分为 event/ 模块目录:
- mod.rs (219 行): 31 事件常量 + 调度器 + 测试
- 12 个消费者文件: workflow/device/alert/patient/appointment/
  follow_up/health_data/ai/consent/consultation/points/lab_report

每个消费者文件 50-215 行,独立可维护。
编译零错误,测试全部通过。
2026-05-11 10:09:10 +08:00

136 lines
5.9 KiB
Rust

/// consultation.opened/new_message/closed → 通知相关方
pub fn spawn(state: &crate::state::HealthState) -> Vec<erp_core::events::SubscriptionHandle> {
let mut handles = Vec::new();
let (mut consult_rx, consult_handle) = state
.event_bus
.subscribe_filtered("consultation.".to_string());
handles.push(consult_handle);
let consult_db = state.db.clone();
let consult_bus = state.event_bus.clone();
tokio::spawn(async move {
loop {
match consult_rx.recv().await {
Some(event) if event.event_type == super::CONSULTATION_OPENED => {
if erp_core::events::is_event_processed(
&consult_db,
event.id,
"consult_opened_notifier",
)
.await
.unwrap_or(false)
{
continue;
}
let doctor_id = event.payload.get("doctor_id").and_then(|v| v.as_str());
let patient_id = event.payload.get("patient_id").and_then(|v| v.as_str());
if let (Some(did), Some(pid)) = (doctor_id, patient_id) {
let notify = erp_core::events::DomainEvent::new(
"message.send",
event.tenant_id,
erp_core::events::build_event_payload(serde_json::json!({
"channel": "in_app",
"recipient_type": "doctor",
"recipient_id": did,
"template_key": "CONSULTATION_OPENED",
"params": { "patient_id": pid }
})),
);
consult_bus.publish(notify, &consult_db).await;
tracing::info!(
doctor_id = did,
patient_id = pid,
"咨询开启通知已发送给医生"
);
}
let _ = erp_core::events::mark_event_processed(
&consult_db,
event.id,
"consult_opened_notifier",
)
.await;
}
Some(event) if event.event_type == super::CONSULTATION_NEW_MESSAGE => {
if erp_core::events::is_event_processed(
&consult_db,
event.id,
"consult_msg_notifier",
)
.await
.unwrap_or(false)
{
continue;
}
let recipient_id = event.payload.get("recipient_id").and_then(|v| v.as_str());
let sender_role = event
.payload
.get("sender_role")
.and_then(|v| v.as_str())
.unwrap_or("unknown");
if let Some(rid) = recipient_id {
let notify = erp_core::events::DomainEvent::new(
"message.send",
event.tenant_id,
erp_core::events::build_event_payload(serde_json::json!({
"channel": "in_app",
"recipient_type": if sender_role == "patient" { "doctor" } else { "patient" },
"recipient_id": rid,
"template_key": "CONSULTATION_NEW_MESSAGE",
})),
);
consult_bus.publish(notify, &consult_db).await;
tracing::info!(
recipient_id = rid,
sender_role = sender_role,
"咨询新消息通知已发送"
);
}
let _ = erp_core::events::mark_event_processed(
&consult_db,
event.id,
"consult_msg_notifier",
)
.await;
}
Some(event) if event.event_type == super::CONSULTATION_CLOSED => {
if erp_core::events::is_event_processed(
&consult_db,
event.id,
"consult_closed_notifier",
)
.await
.unwrap_or(false)
{
continue;
}
let patient_id = event.payload.get("patient_id").and_then(|v| v.as_str());
if let Some(pid) = patient_id {
let notify = 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": "CONSULTATION_CLOSED",
})),
);
consult_bus.publish(notify, &consult_db).await;
tracing::info!(patient_id = pid, "咨询关闭通知已发送");
}
let _ = erp_core::events::mark_event_processed(
&consult_db,
event.id,
"consult_closed_notifier",
)
.await;
}
Some(_) => {}
None => break,
}
}
});
handles
}