feat: 初始化ERP平台底座项目结构
- 添加基础crate结构(erp-core, erp-common) - 实现核心模块trait和事件总线 - 配置Docker开发环境(PostgreSQL+Redis) - 添加Tauri桌面端基础框架 - 设置CI/CD工作流 - 编写项目协作规范文档(CLAUDE.md)
This commit is contained in:
61
crates/erp-core/src/events.rs
Normal file
61
crates/erp-core/src/events.rs
Normal file
@@ -0,0 +1,61 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::broadcast;
|
||||
use tracing::{error, info};
|
||||
use uuid::Uuid;
|
||||
|
||||
/// 领域事件
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DomainEvent {
|
||||
pub id: Uuid,
|
||||
pub event_type: String,
|
||||
pub tenant_id: Uuid,
|
||||
pub payload: serde_json::Value,
|
||||
pub timestamp: DateTime<Utc>,
|
||||
pub correlation_id: Uuid,
|
||||
}
|
||||
|
||||
impl DomainEvent {
|
||||
pub fn new(event_type: impl Into<String>, tenant_id: Uuid, payload: serde_json::Value) -> Self {
|
||||
Self {
|
||||
id: Uuid::now_v7(),
|
||||
event_type: event_type.into(),
|
||||
tenant_id,
|
||||
payload,
|
||||
timestamp: Utc::now(),
|
||||
correlation_id: Uuid::now_v7(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 事件处理器 trait
|
||||
pub trait EventHandler: Send + Sync {
|
||||
fn event_types(&self) -> Vec<String>;
|
||||
fn handle(&self, event: &DomainEvent) -> impl std::future::Future<Output = anyhow::Result<()>> + Send;
|
||||
}
|
||||
|
||||
/// 进程内事件总线
|
||||
#[derive(Clone)]
|
||||
pub struct EventBus {
|
||||
sender: broadcast::Sender<DomainEvent>,
|
||||
}
|
||||
|
||||
impl EventBus {
|
||||
pub fn new(capacity: usize) -> Self {
|
||||
let (sender, _) = broadcast::channel(capacity);
|
||||
Self { sender }
|
||||
}
|
||||
|
||||
/// 发布事件
|
||||
pub fn publish(&self, event: DomainEvent) {
|
||||
info!(event_type = %event.event_type, event_id = %event.id, "Event published");
|
||||
if let Err(e) = self.sender.send(event) {
|
||||
error!("Failed to publish event: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// 订阅所有事件,返回接收端
|
||||
pub fn subscribe(&self) -> broadcast::Receiver<DomainEvent> {
|
||||
self.sender.subscribe()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user