From a36720cbbccdeed04cd856bbaa9e017b8aed6c40 Mon Sep 17 00:00:00 2001 From: iven Date: Mon, 27 Apr 2026 13:33:11 +0800 Subject: [PATCH] =?UTF-8?q?feat(health):=20=E8=A1=A5=E5=85=A8=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E5=8F=91=E5=B8=83=20=E2=80=94=20consent/points/articl?= =?UTF-8?q?e=206=20=E4=B8=AA=E9=A2=86=E5=9F=9F=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - consent.granted/revoked: 知情同意授权/撤销 - points.earned/exchanged: 积分获得/兑换 - article.published/rejected: 文章审核发布/拒绝 所有事件通过 EventBus 发布,支持跨模块订阅和审计追溯。 --- crates/erp-health/src/event.rs | 10 ++++++++++ .../erp-health/src/service/article_service.rs | 15 +++++++++++++++ .../erp-health/src/service/consent_service.rs | 17 +++++++++++++++++ crates/erp-health/src/service/points_service.rs | 17 +++++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/crates/erp-health/src/event.rs b/crates/erp-health/src/event.rs index 3f74718..2655001 100644 --- a/crates/erp-health/src/event.rs +++ b/crates/erp-health/src/event.rs @@ -12,6 +12,14 @@ pub const APPOINTMENT_CREATED: &str = "appointment.created"; // 告警 pub const ALERT_TRIGGERED: &str = "alert.triggered"; +// 知情同意 +pub const CONSENT_GRANTED: &str = "consent.granted"; +pub const CONSENT_REVOKED: &str = "consent.revoked"; + +// 文章 +pub const ARTICLE_PUBLISHED: &str = "article.published"; +pub const ARTICLE_REJECTED: &str = "article.rejected"; + // 咨询 pub const CONSULTATION_OPENED: &str = "consultation.opened"; pub const CONSULTATION_CLOSED: &str = "consultation.closed"; @@ -39,6 +47,8 @@ pub const PATIENT_DECEASED: &str = "patient.deceased"; // 积分 pub const POINTS_EXPIRED: &str = "points.expired"; +pub const POINTS_EARNED: &str = "points.earned"; +pub const POINTS_EXCHANGED: &str = "points.exchanged"; /// 兼容旧签名 — 不做任何实际订阅(逻辑已迁移到 on_startup) pub fn register_handlers(_bus: &EventBus) { diff --git a/crates/erp-health/src/service/article_service.rs b/crates/erp-health/src/service/article_service.rs index 5721fe6..a6e8150 100644 --- a/crates/erp-health/src/service/article_service.rs +++ b/crates/erp-health/src/service/article_service.rs @@ -8,6 +8,7 @@ use uuid::Uuid; use erp_core::audit::AuditLog; use erp_core::audit_service; use erp_core::error::check_version; +use erp_core::events::DomainEvent; use erp_core::types::PaginatedResponse; use crate::dto::article_dto::{ArticleListItem, ArticleResp, CreateArticleReq, ReviewArticleReq, UpdateArticleReq}; @@ -184,6 +185,13 @@ pub async fn approve_article( &state.db, ).await; + state.event_bus.publish( + DomainEvent::new(crate::event::ARTICLE_PUBLISHED, tenant_id, serde_json::json!({ + "article_id": m.id, "title": m.title, "category": m.category, + })), + &state.db, + ).await; + let tags = load_article_tags(state, m.id).await?; Ok(full_model_to_resp(m, tags)) } @@ -220,6 +228,13 @@ pub async fn reject_article( &state.db, ).await; + state.event_bus.publish( + DomainEvent::new(crate::event::ARTICLE_REJECTED, tenant_id, serde_json::json!({ + "article_id": m.id, "title": m.title, + })), + &state.db, + ).await; + let tags = load_article_tags(state, m.id).await?; Ok(full_model_to_resp(m, tags)) } diff --git a/crates/erp-health/src/service/consent_service.rs b/crates/erp-health/src/service/consent_service.rs index 6c913af..4735931 100644 --- a/crates/erp-health/src/service/consent_service.rs +++ b/crates/erp-health/src/service/consent_service.rs @@ -6,6 +6,7 @@ use uuid::Uuid; use erp_core::audit::AuditLog; use erp_core::audit_service; use erp_core::error::check_version; +use erp_core::events::DomainEvent; use erp_core::types::PaginatedResponse; use crate::dto::consent_dto::*; @@ -107,6 +108,14 @@ pub async fn grant_consent( &state.db, ).await; + state.event_bus.publish( + DomainEvent::new(crate::event::CONSENT_GRANTED, tenant_id, serde_json::json!({ + "consent_id": m.id, "patient_id": m.patient_id, + "consent_type": m.consent_type, "consent_scope": m.consent_scope, + })), + &state.db, + ).await; + Ok(model_to_resp(m)) } @@ -145,6 +154,14 @@ pub async fn revoke_consent( &state.db, ).await; + state.event_bus.publish( + DomainEvent::new(crate::event::CONSENT_REVOKED, tenant_id, serde_json::json!({ + "consent_id": m.id, "patient_id": m.patient_id, + "consent_type": m.consent_type, + })), + &state.db, + ).await; + Ok(model_to_resp(m)) } diff --git a/crates/erp-health/src/service/points_service.rs b/crates/erp-health/src/service/points_service.rs index 5faa3a9..b7e416a 100644 --- a/crates/erp-health/src/service/points_service.rs +++ b/crates/erp-health/src/service/points_service.rs @@ -9,6 +9,7 @@ use uuid::Uuid; use erp_core::audit::AuditLog; use erp_core::audit_service; use erp_core::error::check_version; +use erp_core::events::DomainEvent; use erp_core::types::PaginatedResponse; use crate::dto::points_dto::*; @@ -190,6 +191,14 @@ pub async fn earn_points( &state.db, ).await; + state.event_bus.publish( + DomainEvent::new(crate::event::POINTS_EARNED, tenant_id, serde_json::json!({ + "transaction_id": inserted.id, "account_id": inserted.account_id, + "amount": inserted.amount, "balance_after": inserted.balance_after, + })), + &state.db, + ).await; + Ok(PointsTransactionResp { id: inserted.id, account_id: inserted.account_id, @@ -923,6 +932,14 @@ pub async fn exchange_product( &state.db, ).await; + state.event_bus.publish( + DomainEvent::new(crate::event::POINTS_EXCHANGED, tenant_id, serde_json::json!({ + "order_id": inserted_order.id, "patient_id": inserted_order.patient_id, + "product_id": inserted_order.product_id, "points_cost": inserted_order.points_cost, + })), + &state.db, + ).await; + Ok(PointsOrderResp { id: inserted_order.id, patient_id: inserted_order.patient_id,