Files
hms/crates/erp-dialysis/src/module.rs
iven 13f553590b
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled
feat(health+dialysis): 补全 8 组权限码 + 修复 N+1 查询 + 防御性编码
权限补全:
- 新增 14 个权限声明(危急值告警/阈值/随访模板/日常监测/知情同意/用药记录/药物提醒)
- 更新 8 个 handler 使用正确的专属权限码
- erp-dialysis 新增 health.dialysis.stats 权限

性能优化:
- article_service list_articles 标签加载从 N+1 改为批量查询
- follow_up_template_service 字段计数从 N+1 改为批量 GROUP BY

防御性编码:
- alert_engine/article/critical_alert 的 unwrap() 替换为 unwrap_or/expect
2026-04-30 10:22:14 +08:00

126 lines
4.2 KiB
Rust

use async_trait::async_trait;
use axum::Router;
use erp_core::error::AppResult;
use erp_core::module::{ErpModule, ModuleContext, ModuleType, PermissionDescriptor};
use crate::handler::{dialysis_handler, dialysis_prescription_handler, dialysis_stats_handler};
use crate::state::DialysisState;
pub struct DialysisModule;
impl DialysisModule {
pub fn public_routes<S>() -> Router<S>
where
DialysisState: axum::extract::FromRef<S>,
S: Clone + Send + Sync + 'static,
{
Router::new()
}
pub fn protected_routes<S>() -> Router<S>
where
DialysisState: axum::extract::FromRef<S>,
S: Clone + Send + Sync + 'static,
{
Router::new()
// 透析记录
.route(
"/health/patients/{id}/dialysis-records",
axum::routing::get(dialysis_handler::list_dialysis_records),
)
.route(
"/health/dialysis-records",
axum::routing::post(dialysis_handler::create_dialysis_record),
)
.route(
"/health/dialysis-records/{id}",
axum::routing::get(dialysis_handler::get_dialysis_record)
.put(dialysis_handler::update_dialysis_record)
.delete(dialysis_handler::delete_dialysis_record),
)
.route(
"/health/dialysis-records/{id}/review",
axum::routing::put(dialysis_handler::review_dialysis_record),
)
// 透析方案
.route(
"/health/dialysis-prescriptions",
axum::routing::get(dialysis_prescription_handler::list_prescriptions)
.post(dialysis_prescription_handler::create_prescription),
)
.route(
"/health/dialysis-prescriptions/{id}",
axum::routing::get(dialysis_prescription_handler::get_prescription)
.put(dialysis_prescription_handler::update_prescription)
.delete(dialysis_prescription_handler::delete_prescription),
)
// 透析统计
.route(
"/health/admin/statistics/dialysis",
axum::routing::get(dialysis_stats_handler::get_dialysis_stats),
)
}
}
#[async_trait]
impl ErpModule for DialysisModule {
fn name(&self) -> &str {
"透析管理"
}
fn id(&self) -> &str {
"erp-dialysis"
}
fn version(&self) -> &str {
"0.1.0"
}
fn module_type(&self) -> ModuleType {
ModuleType::Builtin
}
fn permissions(&self) -> Vec<PermissionDescriptor> {
vec![
PermissionDescriptor {
code: "health.dialysis.list".into(),
name: "查看透析记录".into(),
description: "查看透析记录列表和详情".into(),
module: "erp-dialysis".into(),
},
PermissionDescriptor {
code: "health.dialysis.manage".into(),
name: "管理透析记录".into(),
description: "创建、编辑、审阅、删除透析记录".into(),
module: "erp-dialysis".into(),
},
PermissionDescriptor {
code: "health.dialysis-prescription.list".into(),
name: "查看透析处方".into(),
description: "查看透析处方列表和详情".into(),
module: "erp-dialysis".into(),
},
PermissionDescriptor {
code: "health.dialysis-prescription.manage".into(),
name: "管理透析处方".into(),
description: "创建、编辑、删除透析处方".into(),
module: "erp-dialysis".into(),
},
PermissionDescriptor {
code: "health.dialysis.stats".into(),
name: "查看透析统计".into(),
description: "查看透析统计数据".into(),
module: "erp-dialysis".into(),
},
]
}
async fn on_startup(&self, _ctx: &ModuleContext) -> AppResult<()> {
Ok(())
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}