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 行,独立可维护。 编译零错误,测试全部通过。
This commit is contained in:
124
crates/erp-health/src/event/points.rs
Normal file
124
crates/erp-health/src/event/points.rs
Normal file
@@ -0,0 +1,124 @@
|
||||
/// points.earned/exchanged/expired → 积分变动通知
|
||||
pub fn spawn(state: &crate::state::HealthState) -> Vec<erp_core::events::SubscriptionHandle> {
|
||||
let mut handles = Vec::new();
|
||||
|
||||
let (mut points_rx, points_handle) = state.event_bus.subscribe_filtered("points.".to_string());
|
||||
handles.push(points_handle);
|
||||
let points_db = state.db.clone();
|
||||
let points_bus = state.event_bus.clone();
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
match points_rx.recv().await {
|
||||
Some(event) if event.event_type == super::POINTS_EARNED => {
|
||||
if erp_core::events::is_event_processed(
|
||||
&points_db,
|
||||
event.id,
|
||||
"points_earned_notifier",
|
||||
)
|
||||
.await
|
||||
.unwrap_or(false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let patient_id = event.payload.get("patient_id").and_then(|v| v.as_str());
|
||||
let amount = event.payload.get("amount").and_then(|v| v.as_u64());
|
||||
if let (Some(pid), Some(amt)) = (patient_id, amount) {
|
||||
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": "POINTS_EARNED",
|
||||
"params": { "amount": amt }
|
||||
})),
|
||||
);
|
||||
points_bus.publish(notify, &points_db).await;
|
||||
tracing::info!(patient_id = pid, amount = amt, "积分获得通知已发送");
|
||||
}
|
||||
let _ = erp_core::events::mark_event_processed(
|
||||
&points_db,
|
||||
event.id,
|
||||
"points_earned_notifier",
|
||||
)
|
||||
.await;
|
||||
}
|
||||
Some(event) if event.event_type == super::POINTS_EXCHANGED => {
|
||||
if erp_core::events::is_event_processed(
|
||||
&points_db,
|
||||
event.id,
|
||||
"points_exchanged_notifier",
|
||||
)
|
||||
.await
|
||||
.unwrap_or(false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let patient_id = event.payload.get("patient_id").and_then(|v| v.as_str());
|
||||
let amount = event.payload.get("amount").and_then(|v| v.as_u64());
|
||||
if let (Some(pid), Some(amt)) = (patient_id, amount) {
|
||||
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": "POINTS_EXCHANGED",
|
||||
"params": { "amount": amt }
|
||||
})),
|
||||
);
|
||||
points_bus.publish(notify, &points_db).await;
|
||||
tracing::info!(patient_id = pid, amount = amt, "积分兑换通知已发送");
|
||||
}
|
||||
let _ = erp_core::events::mark_event_processed(
|
||||
&points_db,
|
||||
event.id,
|
||||
"points_exchanged_notifier",
|
||||
)
|
||||
.await;
|
||||
}
|
||||
Some(event) if event.event_type == super::POINTS_EXPIRED => {
|
||||
if erp_core::events::is_event_processed(
|
||||
&points_db,
|
||||
event.id,
|
||||
"points_expired_notifier",
|
||||
)
|
||||
.await
|
||||
.unwrap_or(false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let patient_id = event.payload.get("patient_id").and_then(|v| v.as_str());
|
||||
let amount = event.payload.get("amount").and_then(|v| v.as_u64());
|
||||
if let (Some(pid), Some(amt)) = (patient_id, amount) {
|
||||
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": "POINTS_EXPIRED",
|
||||
"params": { "amount": amt }
|
||||
})),
|
||||
);
|
||||
points_bus.publish(notify, &points_db).await;
|
||||
tracing::info!(patient_id = pid, amount = amt, "积分过期通知已发送");
|
||||
}
|
||||
let _ = erp_core::events::mark_event_processed(
|
||||
&points_db,
|
||||
event.id,
|
||||
"points_expired_notifier",
|
||||
)
|
||||
.await;
|
||||
}
|
||||
Some(_) => {}
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
handles
|
||||
}
|
||||
Reference in New Issue
Block a user