feat(ai): AiState + AiModule (ErpModule impl + 权限 + 路由骨架)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
20
crates/erp-ai/src/handler/mod.rs
Normal file
20
crates/erp-ai/src/handler/mod.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use axum::response::IntoResponse;
|
||||
|
||||
pub async fn stream_lab_report() -> impl IntoResponse {
|
||||
"stub"
|
||||
}
|
||||
pub async fn stream_trends() -> impl IntoResponse {
|
||||
"stub"
|
||||
}
|
||||
pub async fn stream_checkup_plan() -> impl IntoResponse {
|
||||
"stub"
|
||||
}
|
||||
pub async fn stream_report_summary() -> impl IntoResponse {
|
||||
"stub"
|
||||
}
|
||||
pub async fn list_analysis() -> impl IntoResponse {
|
||||
"stub"
|
||||
}
|
||||
pub async fn get_analysis() -> impl IntoResponse {
|
||||
"stub"
|
||||
}
|
||||
@@ -1,9 +1,14 @@
|
||||
pub mod dto;
|
||||
pub mod entity;
|
||||
pub mod error;
|
||||
pub mod handler;
|
||||
pub mod module;
|
||||
pub mod prompt;
|
||||
pub mod provider;
|
||||
pub mod sanitization;
|
||||
pub mod service;
|
||||
pub mod state;
|
||||
|
||||
pub use error::{AiError, AiResult};
|
||||
pub use module::AiModule;
|
||||
pub use state::AiState;
|
||||
|
||||
108
crates/erp-ai/src/module.rs
Normal file
108
crates/erp-ai/src/module.rs
Normal file
@@ -0,0 +1,108 @@
|
||||
use async_trait::async_trait;
|
||||
use axum::Router;
|
||||
use erp_core::module::{ErpModule, ModuleType, PermissionDescriptor};
|
||||
use std::any::Any;
|
||||
|
||||
pub struct AiModule;
|
||||
|
||||
#[async_trait]
|
||||
impl ErpModule for AiModule {
|
||||
fn name(&self) -> &str {
|
||||
"ai"
|
||||
}
|
||||
|
||||
fn module_type(&self) -> ModuleType {
|
||||
ModuleType::Builtin
|
||||
}
|
||||
|
||||
fn dependencies(&self) -> Vec<&str> {
|
||||
vec!["health"]
|
||||
}
|
||||
|
||||
fn permissions(&self) -> Vec<PermissionDescriptor> {
|
||||
vec![
|
||||
PermissionDescriptor {
|
||||
code: "ai.analysis.list".into(),
|
||||
name: "查看分析历史".into(),
|
||||
description: "查看 AI 分析结果历史记录".into(),
|
||||
module: "ai".into(),
|
||||
},
|
||||
PermissionDescriptor {
|
||||
code: "ai.analysis.manage".into(),
|
||||
name: "请求分析".into(),
|
||||
description: "发起 AI 分析请求".into(),
|
||||
module: "ai".into(),
|
||||
},
|
||||
PermissionDescriptor {
|
||||
code: "ai.prompt.list".into(),
|
||||
name: "查看 Prompt".into(),
|
||||
description: "查看 AI Prompt 模板列表".into(),
|
||||
module: "ai".into(),
|
||||
},
|
||||
PermissionDescriptor {
|
||||
code: "ai.prompt.manage".into(),
|
||||
name: "管理 Prompt".into(),
|
||||
description: "创建/编辑/激活/回滚 Prompt 模板".into(),
|
||||
module: "ai".into(),
|
||||
},
|
||||
PermissionDescriptor {
|
||||
code: "ai.usage.list".into(),
|
||||
name: "查看用量".into(),
|
||||
description: "查看 AI 用量统计".into(),
|
||||
module: "ai".into(),
|
||||
},
|
||||
PermissionDescriptor {
|
||||
code: "ai.provider.manage".into(),
|
||||
name: "管理提供商".into(),
|
||||
description: "管理 AI 提供商配置".into(),
|
||||
module: "ai".into(),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl AiModule {
|
||||
pub fn public_routes<S>() -> Router<S>
|
||||
where
|
||||
crate::state::AiState: axum::extract::FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
Router::new()
|
||||
}
|
||||
|
||||
pub fn protected_routes<S>() -> Router<S>
|
||||
where
|
||||
crate::state::AiState: axum::extract::FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
Router::new()
|
||||
.route(
|
||||
"/ai/analyze/lab-report",
|
||||
axum::routing::post(crate::handler::stream_lab_report),
|
||||
)
|
||||
.route(
|
||||
"/ai/analyze/trends",
|
||||
axum::routing::post(crate::handler::stream_trends),
|
||||
)
|
||||
.route(
|
||||
"/ai/analyze/checkup-plan",
|
||||
axum::routing::post(crate::handler::stream_checkup_plan),
|
||||
)
|
||||
.route(
|
||||
"/ai/analyze/report-summary",
|
||||
axum::routing::post(crate::handler::stream_report_summary),
|
||||
)
|
||||
.route(
|
||||
"/ai/analysis/history",
|
||||
axum::routing::get(crate::handler::list_analysis),
|
||||
)
|
||||
.route(
|
||||
"/ai/analysis/{id}",
|
||||
axum::routing::get(crate::handler::get_analysis),
|
||||
)
|
||||
}
|
||||
}
|
||||
17
crates/erp-ai/src/state.rs
Normal file
17
crates/erp-ai/src/state.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use erp_core::events::EventBus;
|
||||
use sea_orm::DatabaseConnection;
|
||||
|
||||
use crate::service::analysis::AnalysisService;
|
||||
use crate::service::prompt::PromptService;
|
||||
use crate::service::usage::UsageService;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AiState {
|
||||
pub db: DatabaseConnection,
|
||||
pub event_bus: EventBus,
|
||||
pub analysis: Arc<AnalysisService>,
|
||||
pub prompt: Arc<PromptService>,
|
||||
pub usage: Arc<UsageService>,
|
||||
}
|
||||
Reference in New Issue
Block a user