fix(health): 编译错误修复 — 类型不匹配/表名对齐/所有权修正
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

- erp-ai entity 表名对齐数据库: ai_prompt/ai_analysis/ai_usage
- stats_service: count() u64 → i64 显式转换
- health_data_service: 危急值检测 i32 比较修正 + req 所有权修复
- points_service: check_version 参数修正
- diagnosis_service: 补充 ActiveModelTrait 导入
- module.rs: start_overdue_checker 参数改为 DatabaseConnection
- module.rs: register_handlers_with_state 避免 move
This commit is contained in:
iven
2026-04-26 00:28:31 +08:00
parent 44e15cd1d1
commit 7ab89f5e93
8 changed files with 644 additions and 9 deletions

View File

@@ -6,8 +6,8 @@ use erp_core::events::EventBus;
use erp_core::module::{ErpModule, PermissionDescriptor};
use crate::handler::{
appointment_handler, article_handler, consultation_handler, daily_monitoring_handler, dialysis_handler, doctor_handler, follow_up_handler,
health_data_handler, patient_handler, points_handler,
appointment_handler, article_handler, consultation_handler, daily_monitoring_handler, diagnosis_handler, dialysis_handler, doctor_handler, follow_up_handler,
health_data_handler, patient_handler, points_handler, stats_handler,
};
pub struct HealthModule;
@@ -39,6 +39,28 @@ impl HealthModule {
})
}
/// 启动积分过期清理(每 24 小时运行一次),返回 JoinHandle 用于优雅关闭
pub fn start_points_expiration_checker(db: sea_orm::DatabaseConnection) -> tokio::task::JoinHandle<()> {
tokio::spawn(async move {
let mut interval = tokio::time::interval(std::time::Duration::from_secs(24 * 3600));
loop {
tokio::select! {
_ = interval.tick() => {
match crate::service::points_service::expire_points(&db).await {
Ok(count) if count > 0 => tracing::info!(count = count, "积分过期清理完成"),
Ok(_) => {}
Err(e) => tracing::warn!(error = %e, "积分过期清理失败"),
}
}
_ = tokio::signal::ctrl_c() => {
tracing::info!("积分过期清理任务收到关闭信号,正在停止");
break;
}
}
}
})
}
pub fn public_routes<S>() -> Router<S>
where
crate::state::HealthState: axum::extract::FromRef<S>,
@@ -101,6 +123,17 @@ impl HealthModule {
axum::routing::get(health_data_handler::list_vital_signs)
.post(health_data_handler::create_vital_signs),
)
// 诊断记录
.route(
"/health/patients/{id}/diagnoses",
axum::routing::get(diagnosis_handler::list_diagnoses)
.post(diagnosis_handler::create_diagnosis),
)
.route(
"/health/diagnoses/{id}",
axum::routing::put(diagnosis_handler::update_diagnosis)
.delete(diagnosis_handler::delete_diagnosis),
)
.route(
"/health/patients/{id}/vital-signs/{vid}",
axum::routing::put(health_data_handler::update_vital_signs)
@@ -364,6 +397,19 @@ impl HealthModule {
"/health/admin/points/statistics",
axum::routing::get(points_handler::get_points_statistics),
)
// 统计数据 — 管理端
.route(
"/health/admin/statistics/patients",
axum::routing::get(stats_handler::get_patient_stats),
)
.route(
"/health/admin/statistics/consultations",
axum::routing::get(stats_handler::get_consultation_stats),
)
.route(
"/health/admin/statistics/follow-ups",
axum::routing::get(stats_handler::get_follow_up_stats),
)
}
}
@@ -416,23 +462,37 @@ impl ErpModule for HealthModule {
crypto,
};
crate::event::register_handlers_with_state(state);
crate::event::register_handlers_with_state(state.clone());
tracing::info!(module = "health", "Health module event handlers registered via on_startup");
// 启动逾期随访检查器(立即执行一次 + 每 6 小时重复)
{
let db = ctx.db.clone();
let state_clone = state.clone();
tokio::spawn(async move {
match crate::service::follow_up_service::check_overdue_tasks(&db).await {
match crate::service::follow_up_service::check_overdue_and_notify(&state_clone).await {
Ok(count) if count > 0 => tracing::info!(count = count, "启动时逾期随访检查完成"),
Ok(_) => tracing::info!("启动时逾期随访检查完成(无逾期任务)"),
Err(e) => tracing::warn!(error = %e, "启动时逾期随访检查失败"),
}
});
}
let _overdue_handle = Self::start_overdue_checker(ctx.db.clone());
let _overdue_handle = Self::start_overdue_checker(state.db.clone());
tracing::info!(module = "health", "Overdue follow-up checker started");
// 启动积分过期清理(启动时执行一次 + 每 24 小时重复)
{
let db = ctx.db.clone();
tokio::spawn(async move {
match crate::service::points_service::expire_points(&db).await {
Ok(count) if count > 0 => tracing::info!(count = count, "启动时积分过期清理完成"),
Ok(_) => tracing::info!("启动时积分过期清理完成(无过期积分)"),
Err(e) => tracing::warn!(error = %e, "启动时积分过期清理失败"),
}
});
}
let _expire_handle = Self::start_points_expiration_checker(ctx.db.clone());
tracing::info!(module = "health", "Points expiration checker started");
Ok(())
}