feat(config): add system configuration module (Phase 3)

Implement the complete erp-config crate with:
- Data dictionaries (CRUD + items management)
- Dynamic menus (tree structure with role filtering)
- System settings (hierarchical: platform > tenant > org > user)
- Numbering rules (concurrency-safe via PostgreSQL advisory_lock)
- Theme and language configuration (via settings store)
- 6 database migrations (dictionaries, menus, settings, numbering_rules)
- Frontend Settings page with 5 tabs (dictionary, menu, numbering, settings, theme)

Refactor: move RBAC functions (require_permission) from erp-auth to erp-core
to avoid cross-module dependencies.

Add 20 new seed permissions for config module operations.
This commit is contained in:
iven
2026-04-11 08:09:19 +08:00
parent 8a012f6c6a
commit 0baaf5f7ee
55 changed files with 5295 additions and 12 deletions

View File

@@ -0,0 +1,41 @@
use erp_core::error::AppError;
/// Config module error types.
#[derive(Debug, thiserror::Error)]
pub enum ConfigError {
#[error("验证失败: {0}")]
Validation(String),
#[error("资源未找到: {0}")]
NotFound(String),
#[error("键已存在: {0}")]
DuplicateKey(String),
#[error("编号序列耗尽: {0}")]
NumberingExhausted(String),
}
impl From<sea_orm::TransactionError<ConfigError>> for ConfigError {
fn from(err: sea_orm::TransactionError<ConfigError>) -> Self {
match err {
sea_orm::TransactionError::Connection(err) => {
ConfigError::Validation(err.to_string())
}
sea_orm::TransactionError::Transaction(inner) => inner,
}
}
}
impl From<ConfigError> for AppError {
fn from(err: ConfigError) -> Self {
match err {
ConfigError::Validation(s) => AppError::Validation(s),
ConfigError::NotFound(s) => AppError::NotFound(s),
ConfigError::DuplicateKey(s) => AppError::Conflict(s),
ConfigError::NumberingExhausted(s) => AppError::Internal(s),
}
}
}
pub type ConfigResult<T> = Result<T, ConfigError>;