use axum::Router; use axum::routing::{get, post, put}; use uuid::Uuid; use erp_core::error::AppResult; use erp_core::events::EventBus; use erp_core::module::{ErpModule, PermissionDescriptor}; use crate::handler::{ dictionary_handler, language_handler, menu_handler, numbering_handler, setting_handler, theme_handler, }; /// Config module implementing the `ErpModule` trait. /// /// Manages system configuration: dictionaries, menus, settings, /// numbering rules, languages, and themes. pub struct ConfigModule; impl ConfigModule { pub fn new() -> Self { Self } /// Build protected (authenticated) routes for the config module. pub fn protected_routes() -> Router where crate::config_state::ConfigState: axum::extract::FromRef, S: Clone + Send + Sync + 'static, { Router::new() // Dictionary routes .route( "/config/dictionaries", get(dictionary_handler::list_dictionaries) .post(dictionary_handler::create_dictionary), ) .route( "/config/dictionaries/{id}", put(dictionary_handler::update_dictionary) .delete(dictionary_handler::delete_dictionary), ) .route( "/config/dictionaries/items", get(dictionary_handler::list_items_by_code), ) .route( "/config/dictionaries/{dict_id}/items", post(dictionary_handler::create_item), ) .route( "/config/dictionaries/{dict_id}/items/{item_id}", put(dictionary_handler::update_item).delete(dictionary_handler::delete_item), ) // Menu routes .route( "/config/menus", get(menu_handler::get_menus) .post(menu_handler::create_menu) .put(menu_handler::batch_save_menus), ) .route( "/config/menus/{id}", put(menu_handler::update_menu).delete(menu_handler::delete_menu), ) // User menu tree (no special permission required) .route("/menus/user", get(menu_handler::get_user_menus)) // Setting routes .route( "/config/settings/{key}", get(setting_handler::get_setting) .put(setting_handler::update_setting) .delete(setting_handler::delete_setting), ) // Numbering rule routes .route( "/config/numbering-rules", get(numbering_handler::list_numbering_rules) .post(numbering_handler::create_numbering_rule), ) .route( "/config/numbering-rules/{id}", put(numbering_handler::update_numbering_rule) .delete(numbering_handler::delete_numbering_rule), ) .route( "/config/numbering-rules/{id}/generate", post(numbering_handler::generate_number), ) // Theme routes .route( "/config/themes", get(theme_handler::get_theme).put(theme_handler::update_theme), ) // Language routes .route("/config/languages", get(language_handler::list_languages)) .route( "/config/languages/{code}", put(language_handler::update_language), ) } /// Build public (unauthenticated) routes for the config module. pub fn public_routes() -> Router where S: Clone + Send + Sync + 'static, { Router::new().route("/public/brand", get(theme_handler::get_public_brand)) } } impl Default for ConfigModule { fn default() -> Self { Self::new() } } #[async_trait::async_trait] impl ErpModule for ConfigModule { fn name(&self) -> &str { "config" } fn version(&self) -> &str { env!("CARGO_PKG_VERSION") } fn dependencies(&self) -> Vec<&str> { vec!["auth"] } fn register_event_handlers(&self, _bus: &EventBus) {} 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, _db: &sea_orm::DatabaseConnection, ) -> AppResult<()> { Ok(()) } fn permissions(&self) -> Vec { vec![ PermissionDescriptor { code: "dictionary.list".into(), name: "查看字典".into(), description: "查看数据字典".into(), module: "config".into(), }, PermissionDescriptor { code: "dictionary.create".into(), name: "创建字典".into(), description: "创建数据字典".into(), module: "config".into(), }, PermissionDescriptor { code: "dictionary.update".into(), name: "编辑字典".into(), description: "编辑数据字典".into(), module: "config".into(), }, PermissionDescriptor { code: "dictionary.delete".into(), name: "删除字典".into(), description: "删除数据字典".into(), module: "config".into(), }, PermissionDescriptor { code: "menu.list".into(), name: "查看菜单".into(), description: "查看菜单配置".into(), module: "config".into(), }, PermissionDescriptor { code: "menu.update".into(), name: "编辑菜单".into(), description: "编辑菜单配置".into(), module: "config".into(), }, PermissionDescriptor { code: "setting.read".into(), name: "查看配置".into(), description: "查看系统参数".into(), module: "config".into(), }, PermissionDescriptor { code: "setting.update".into(), name: "编辑配置".into(), description: "编辑系统参数".into(), module: "config".into(), }, PermissionDescriptor { code: "setting.delete".into(), name: "删除配置".into(), description: "删除系统参数".into(), module: "config".into(), }, PermissionDescriptor { code: "numbering.list".into(), name: "查看编号规则".into(), description: "查看编号规则".into(), module: "config".into(), }, PermissionDescriptor { code: "numbering.create".into(), name: "创建编号规则".into(), description: "创建编号规则".into(), module: "config".into(), }, PermissionDescriptor { code: "numbering.update".into(), name: "编辑编号规则".into(), description: "编辑编号规则".into(), module: "config".into(), }, PermissionDescriptor { code: "numbering.delete".into(), name: "删除编号规则".into(), description: "删除编号规则".into(), module: "config".into(), }, PermissionDescriptor { code: "numbering.generate".into(), name: "生成编号".into(), description: "生成文档编号".into(), module: "config".into(), }, PermissionDescriptor { code: "theme.read".into(), name: "查看主题".into(), description: "查看主题设置".into(), module: "config".into(), }, PermissionDescriptor { code: "theme.update".into(), name: "编辑主题".into(), description: "编辑主题设置".into(), module: "config".into(), }, PermissionDescriptor { code: "language.list".into(), name: "查看语言".into(), description: "查看语言配置".into(), module: "config".into(), }, PermissionDescriptor { code: "language.update".into(), name: "编辑语言".into(), description: "编辑语言设置".into(), module: "config".into(), }, ] } fn as_any(&self) -> &dyn std::any::Any { self } }