use axum::Extension; use axum::extract::{FromRef, Path, Query, State}; use axum::response::IntoResponse; use serde::Deserialize; use utoipa::IntoParams; use uuid::Uuid; use erp_core::error::AppError; use erp_core::rbac::require_permission; use erp_core::types::{ApiResponse, PaginatedResponse, TenantContext}; use crate::service::critical_alert_service; use crate::state::HealthState; #[derive(Debug, Deserialize, IntoParams)] pub struct CriticalAlertListQuery { pub page: Option, pub page_size: Option, } pub async fn list_critical_alerts( State(state): State, Extension(ctx): Extension, Query(query): Query, ) -> Result where HealthState: FromRef, S: Clone + Send + Sync + 'static, { require_permission(&ctx, "health.critical-alerts.list")?; let page = query.page.unwrap_or(1); let page_size = query.page_size.unwrap_or(20).min(100); let (items, total) = critical_alert_service::list_pending_alerts(&state, ctx.tenant_id, page, page_size) .await .map_err(|e| { tracing::error!(error = %e, tenant_id = %ctx.tenant_id, "查询危急值告警列表失败"); e })?; let total_pages = if page_size > 0 { total.div_ceil(page_size) } else { 0 }; Ok(axum::Json(ApiResponse::ok(PaginatedResponse { data: items, total, page, page_size, total_pages, }))) } pub async fn get_critical_alert( State(state): State, Extension(ctx): Extension, Path(id): Path, ) -> Result where HealthState: FromRef, S: Clone + Send + Sync + 'static, { require_permission(&ctx, "health.critical-alerts.list")?; let alert = critical_alert_service::get_alert(&state, ctx.tenant_id, id).await?; Ok(axum::Json(ApiResponse::ok(alert))) } #[derive(Debug, serde::Deserialize, utoipa::ToSchema)] pub struct AcknowledgeCriticalAlertRequest { pub notes: Option, } pub async fn acknowledge_critical_alert( State(state): State, Extension(ctx): Extension, Path(id): Path, axum::Json(body): axum::Json, ) -> Result where HealthState: FromRef, S: Clone + Send + Sync + 'static, { require_permission(&ctx, "health.critical-alerts.manage")?; critical_alert_service::acknowledge_alert(&state, ctx.tenant_id, id, ctx.user_id, body.notes) .await?; Ok(axum::Json(ApiResponse::ok( serde_json::json!({"message": "告警已确认"}), ))) }