From d8a0ac7519ca1cb928285249e0d0bcfc70e330c3 Mon Sep 17 00:00:00 2001 From: iven Date: Wed, 15 Apr 2026 01:27:33 +0800 Subject: [PATCH] feat: implement on_tenant_created/deleted hooks and update ErpModule trait - ErpModule trait hooks now accept db and event_bus parameters - AuthModule.on_tenant_created: seeds default roles, permissions, and admin user for new tenants using existing seed_tenant_auth() - AuthModule.on_tenant_deleted: soft-deletes all users for the tenant - Updated all other modules (config, workflow, message) to match the new trait signature --- crates/erp-auth/src/module.rs | 48 ++++++++++++++++++++++++++++--- crates/erp-config/src/module.rs | 13 +++++++-- crates/erp-core/src/module.rs | 21 +++++++++++--- crates/erp-message/src/module.rs | 13 +++++++-- crates/erp-workflow/src/module.rs | 13 +++++++-- 5 files changed, 94 insertions(+), 14 deletions(-) diff --git a/crates/erp-auth/src/module.rs b/crates/erp-auth/src/module.rs index 99052b7..6621020 100644 --- a/crates/erp-auth/src/module.rs +++ b/crates/erp-auth/src/module.rs @@ -136,13 +136,53 @@ impl ErpModule for AuthModule { // Auth 模块暂无跨模块事件订阅需求 } - async fn on_tenant_created(&self, _tenant_id: Uuid) -> AppResult<()> { - // TODO: 创建默认角色和管理员用户 + async fn on_tenant_created( + &self, + tenant_id: Uuid, + db: &sea_orm::DatabaseConnection, + _event_bus: &EventBus, + ) -> AppResult<()> { + let password = std::env::var("ERP__SUPER_ADMIN_PASSWORD") + .unwrap_or_else(|_| "Admin@2026".to_string()); + crate::service::seed::seed_tenant_auth(db, tenant_id, &password) + .await + .map_err(|e| erp_core::error::AppError::Internal(e.to_string()))?; + tracing::info!(tenant_id = %tenant_id, "Tenant auth initialized"); Ok(()) } - async fn on_tenant_deleted(&self, _tenant_id: Uuid) -> AppResult<()> { - // TODO: 软删除该租户下所有用户 + async fn on_tenant_deleted( + &self, + tenant_id: Uuid, + db: &sea_orm::DatabaseConnection, + ) -> AppResult<()> { + use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set}; + use chrono::Utc; + + let now = Utc::now(); + + // 软删除该租户下所有用户 + let users = crate::entity::user::Entity::find() + .filter(crate::entity::user::Column::TenantId.eq(tenant_id)) + .filter(crate::entity::user::Column::DeletedAt.is_null()) + .all(db) + .await + .map_err(|e| erp_core::error::AppError::Internal(e.to_string()))?; + + for user_model in users { + let current_version = user_model.version; + let active: crate::entity::user::ActiveModel = user_model.into(); + let mut to_update: crate::entity::user::ActiveModel = active; + to_update.deleted_at = Set(Some(now)); + to_update.updated_at = Set(now); + to_update.version = Set(current_version + 1); + let _ = to_update + .update(db) + .await + .map_err(|e| erp_core::error::AppError::Internal(e.to_string()))?; + } + + tracing::info!(tenant_id = %tenant_id, "Tenant users soft-deleted"); Ok(()) } diff --git a/crates/erp-config/src/module.rs b/crates/erp-config/src/module.rs index eec58a6..d58d953 100644 --- a/crates/erp-config/src/module.rs +++ b/crates/erp-config/src/module.rs @@ -121,11 +121,20 @@ impl ErpModule for ConfigModule { fn register_event_handlers(&self, _bus: &EventBus) {} - async fn on_tenant_created(&self, _tenant_id: Uuid) -> AppResult<()> { + async fn on_tenant_created( + &self, + _tenant_id: Uuid, + _db: &sea_orm::DatabaseConnection, + _event_bus: &EventBus, + ) -> AppResult<()> { Ok(()) } - async fn on_tenant_deleted(&self, _tenant_id: Uuid) -> AppResult<()> { + async fn on_tenant_deleted( + &self, + _tenant_id: Uuid, + _db: &sea_orm::DatabaseConnection, + ) -> AppResult<()> { Ok(()) } diff --git a/crates/erp-core/src/module.rs b/crates/erp-core/src/module.rs index e4b268c..c21862c 100644 --- a/crates/erp-core/src/module.rs +++ b/crates/erp-core/src/module.rs @@ -26,13 +26,26 @@ pub trait ErpModule: Send + Sync { /// 注册事件处理器 fn register_event_handlers(&self, _bus: &EventBus) {} - /// 租户创建时的初始化钩子 - async fn on_tenant_created(&self, _tenant_id: Uuid) -> AppResult<()> { + /// 租户创建时的初始化钩子。 + /// + /// 用于为新建租户创建默认角色、管理员用户等初始数据。 + async fn on_tenant_created( + &self, + _tenant_id: Uuid, + _db: &sea_orm::DatabaseConnection, + _event_bus: &EventBus, + ) -> AppResult<()> { Ok(()) } - /// 租户删除时的清理钩子 - async fn on_tenant_deleted(&self, _tenant_id: Uuid) -> AppResult<()> { + /// 租户删除时的清理钩子。 + /// + /// 用于软删除该租户下的所有关联数据。 + async fn on_tenant_deleted( + &self, + _tenant_id: Uuid, + _db: &sea_orm::DatabaseConnection, + ) -> AppResult<()> { Ok(()) } diff --git a/crates/erp-message/src/module.rs b/crates/erp-message/src/module.rs index 20616ea..eea2de8 100644 --- a/crates/erp-message/src/module.rs +++ b/crates/erp-message/src/module.rs @@ -109,11 +109,20 @@ impl ErpModule for MessageModule { fn register_event_handlers(&self, _bus: &EventBus) {} - async fn on_tenant_created(&self, _tenant_id: Uuid) -> AppResult<()> { + async fn on_tenant_created( + &self, + _tenant_id: Uuid, + _db: &sea_orm::DatabaseConnection, + _event_bus: &EventBus, + ) -> AppResult<()> { Ok(()) } - async fn on_tenant_deleted(&self, _tenant_id: Uuid) -> AppResult<()> { + async fn on_tenant_deleted( + &self, + _tenant_id: Uuid, + _db: &sea_orm::DatabaseConnection, + ) -> AppResult<()> { Ok(()) } diff --git a/crates/erp-workflow/src/module.rs b/crates/erp-workflow/src/module.rs index 029b34c..d84a301 100644 --- a/crates/erp-workflow/src/module.rs +++ b/crates/erp-workflow/src/module.rs @@ -136,11 +136,20 @@ impl ErpModule for WorkflowModule { fn register_event_handlers(&self, _bus: &EventBus) {} - async fn on_tenant_created(&self, _tenant_id: Uuid) -> AppResult<()> { + async fn on_tenant_created( + &self, + _tenant_id: Uuid, + _db: &sea_orm::DatabaseConnection, + _event_bus: &EventBus, + ) -> AppResult<()> { Ok(()) } - async fn on_tenant_deleted(&self, _tenant_id: Uuid) -> AppResult<()> { + async fn on_tenant_deleted( + &self, + _tenant_id: Uuid, + _db: &sea_orm::DatabaseConnection, + ) -> AppResult<()> { Ok(()) }