feat(health): BLE 网关后端接入 — 网关管理 + API Key 认证 + 多患者批量上报
- 新增 ble_gateways + gateway_patient_bindings 表迁移 (000113) - 网关 CRUD:注册/编辑/删除/重生成 API Key,含患者绑定管理 - API Key 认证中间件(SHA-256 hash + prefix 快速查找) - 网关数据上报端点:多患者批量读数,复用 device_reading_service 管道 - 网关心跳端点:固件版本/IP 更新 + last_heartbeat_at - 10 个管理端路由(JWT)+ 2 个网关端路由(API Key) - health.ble-gateways.list/manage 权限声明 - 修复 000112 迁移 ForeignKey 借用错误
This commit is contained in:
141
crates/erp-health/src/dto/ble_gateway_dto.rs
Normal file
141
crates/erp-health/src/dto/ble_gateway_dto.rs
Normal file
@@ -0,0 +1,141 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// BLE Gateway DTOs
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BleGatewayResp {
|
||||
pub id: Uuid,
|
||||
pub tenant_id: Uuid,
|
||||
pub gateway_id: String,
|
||||
pub name: String,
|
||||
pub status: String,
|
||||
pub firmware_version: Option<String>,
|
||||
pub ip_address: Option<String>,
|
||||
pub last_heartbeat_at: Option<chrono::DateTime<chrono::Utc>>,
|
||||
pub metadata: Option<serde_json::Value>,
|
||||
pub created_at: chrono::DateTime<chrono::Utc>,
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
pub version: i32,
|
||||
/// 网关 API Key(仅在创建时返回一次)
|
||||
pub api_key: Option<String>,
|
||||
/// 绑定的患者数量
|
||||
pub patient_count: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CreateBleGatewayReq {
|
||||
pub gateway_id: String,
|
||||
pub name: String,
|
||||
pub firmware_version: Option<String>,
|
||||
pub metadata: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UpdateBleGatewayReq {
|
||||
pub name: Option<String>,
|
||||
pub status: Option<String>,
|
||||
pub firmware_version: Option<String>,
|
||||
pub metadata: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UpdateBleGatewayWithVersion {
|
||||
pub version: i32,
|
||||
pub data: UpdateBleGatewayReq,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ListBleGatewaysParams {
|
||||
pub status: Option<String>,
|
||||
pub page: Option<u64>,
|
||||
pub page_size: Option<u64>,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GatewayPatientBinding DTOs
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GatewayBindingResp {
|
||||
pub id: Uuid,
|
||||
pub tenant_id: Uuid,
|
||||
pub gateway_id_fk: Uuid,
|
||||
pub patient_id: Uuid,
|
||||
pub peripheral_mac: Option<String>,
|
||||
pub device_type: Option<String>,
|
||||
pub status: String,
|
||||
pub created_at: chrono::DateTime<chrono::Utc>,
|
||||
pub updated_at: chrono::DateTime<chrono::Utc>,
|
||||
pub version: i32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CreateBindingReq {
|
||||
pub patient_id: Uuid,
|
||||
pub peripheral_mac: Option<String>,
|
||||
pub device_type: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BatchBindReq {
|
||||
pub bindings: Vec<CreateBindingReq>,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 网关数据上报 DTOs
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// 网关多患者批量上报请求
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GatewayUploadReq {
|
||||
pub readings: Vec<PatientReadingBatch>,
|
||||
}
|
||||
|
||||
/// 单个患者的读数批次
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PatientReadingBatch {
|
||||
pub patient_id: Uuid,
|
||||
pub device_id: String,
|
||||
pub device_model: Option<String>,
|
||||
pub readings: Vec<ReadingEntry>,
|
||||
}
|
||||
|
||||
/// 单条读数
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ReadingEntry {
|
||||
pub device_type: String,
|
||||
pub values: serde_json::Value,
|
||||
pub measured_at: String,
|
||||
}
|
||||
|
||||
/// 网关上报结果
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GatewayUploadResp {
|
||||
pub total_patients: u64,
|
||||
pub total_readings: u64,
|
||||
pub total_duplicates: u64,
|
||||
pub errors: Vec<String>,
|
||||
}
|
||||
|
||||
/// 网关心跳请求
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct HeartbeatReq {
|
||||
pub firmware_version: Option<String>,
|
||||
pub ip_address: Option<String>,
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
pub mod appointment_dto;
|
||||
pub mod alert_dto;
|
||||
pub mod ble_gateway_dto;
|
||||
pub mod care_plan_dto;
|
||||
pub mod article_dto;
|
||||
pub mod consent_dto;
|
||||
|
||||
Reference in New Issue
Block a user