//! 设备管理 API — 设备列表查询与解绑 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::dto::DeleteWithVersion; use crate::service::device_service; use crate::state::HealthState; /// 设备列表查询参数 #[derive(Debug, Deserialize, IntoParams)] pub struct DeviceListQuery { /// 按患者 ID 筛选 pub patient_id: Option, /// 按设备类型筛选 pub device_type: Option, pub page: Option, pub page_size: Option, } /// GET /api/v1/health/devices — 设备绑定列表 #[utoipa::path( get, path = "/health/devices", params(DeviceListQuery), responses( (status = 200, description = "设备列表"), ), tag = "设备管理", security(("bearer_auth" = [])), )] pub async fn list_devices( State(state): State, Extension(ctx): Extension, Query(query): Query, ) -> Result where HealthState: FromRef, S: Clone + Send + Sync + 'static, { require_permission(&ctx, "health.devices.list")?; let page = query.page.unwrap_or(1); let page_size = query.page_size.unwrap_or(20).min(100); let (items, total) = device_service::list_devices( &state, ctx.tenant_id, query.patient_id, query.device_type.as_deref(), page, page_size, ) .await?; Ok(axum::Json(ApiResponse::ok(PaginatedResponse { data: items, total, page, page_size, total_pages: total.div_ceil(page_size.max(1)), }))) } /// DELETE /api/v1/health/devices/{id} — 解绑设备(软删除) #[utoipa::path( delete, path = "/health/devices/{id}", responses( (status = 200, description = "解绑成功"), (status = 404, description = "设备不存在"), ), tag = "设备管理", security(("bearer_auth" = [])), )] pub async fn unbind_device( 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.devices.manage")?; let device = device_service::unbind_device(&state, ctx.tenant_id, id, ctx.user_id, body.version).await?; Ok(axum::Json(ApiResponse::ok(device))) }