Files
erp/crates/erp-server/src/state.rs
iven 091d517af6 feat(plugin): Schema 缓存 — moka LRU Cache 消除 resolve_entity_info 重复查库
- 添加 moka 0.12 依赖到 erp-plugin 和 erp-server
- 重写 state.rs: 新增 EntityInfo (含 generated_fields) 和 moka Cache
- AppState 新增 plugin_entity_cache 字段
- data_service.rs: 旧 resolve_entity_info 保留兼容,新增 resolve_entity_info_cached
2026-04-17 10:23:43 +08:00

99 lines
3.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use axum::extract::FromRef;
use sea_orm::DatabaseConnection;
use crate::config::AppConfig;
use erp_core::events::EventBus;
use erp_core::module::ModuleRegistry;
/// Axum shared application state.
/// All handlers access database connections, configuration, etc. through `State<AppState>`.
#[derive(Clone)]
pub struct AppState {
pub db: DatabaseConnection,
pub config: AppConfig,
pub event_bus: EventBus,
pub module_registry: ModuleRegistry,
pub redis: redis::Client,
/// 实际的默认租户 ID从数据库种子数据中获取。
pub default_tenant_id: uuid::Uuid,
/// 插件引擎
pub plugin_engine: erp_plugin::engine::PluginEngine,
/// 插件实体缓存
pub plugin_entity_cache: moka::sync::Cache<String, erp_plugin::state::EntityInfo>,
}
/// Allow handlers to extract `DatabaseConnection` directly from `State<AppState>`.
impl FromRef<AppState> for DatabaseConnection {
fn from_ref(state: &AppState) -> Self {
state.db.clone()
}
}
/// Allow handlers to extract `EventBus` directly from `State<AppState>`.
impl FromRef<AppState> for EventBus {
fn from_ref(state: &AppState) -> Self {
state.event_bus.clone()
}
}
/// Allow erp-auth handlers to extract their required state without depending on erp-server.
///
/// This bridges the gap: erp-auth defines `AuthState` with the fields it needs,
/// and erp-server fills them from `AppState`.
impl FromRef<AppState> for erp_auth::AuthState {
fn from_ref(state: &AppState) -> Self {
use erp_auth::auth_state::parse_ttl;
Self {
db: state.db.clone(),
event_bus: state.event_bus.clone(),
jwt_secret: state.config.jwt.secret.clone(),
access_ttl_secs: parse_ttl(&state.config.jwt.access_token_ttl),
refresh_ttl_secs: parse_ttl(&state.config.jwt.refresh_token_ttl),
default_tenant_id: state.default_tenant_id,
}
}
}
/// Allow erp-config handlers to extract their required state without depending on erp-server.
impl FromRef<AppState> for erp_config::ConfigState {
fn from_ref(state: &AppState) -> Self {
Self {
db: state.db.clone(),
event_bus: state.event_bus.clone(),
}
}
}
/// Allow erp-workflow handlers to extract their required state without depending on erp-server.
impl FromRef<AppState> for erp_workflow::WorkflowState {
fn from_ref(state: &AppState) -> Self {
Self {
db: state.db.clone(),
event_bus: state.event_bus.clone(),
}
}
}
/// Allow erp-message handlers to extract their required state without depending on erp-server.
impl FromRef<AppState> for erp_message::MessageState {
fn from_ref(state: &AppState) -> Self {
Self {
db: state.db.clone(),
event_bus: state.event_bus.clone(),
}
}
}
/// Allow erp-plugin handlers to extract their required state.
impl FromRef<AppState> for erp_plugin::state::PluginState {
fn from_ref(state: &AppState) -> Self {
Self {
db: state.db.clone(),
event_bus: state.event_bus.clone(),
engine: state.plugin_engine.clone(),
entity_cache: state.plugin_entity_cache.clone(),
}
}
}