Compare commits

..

2 Commits

Author SHA1 Message Date
iven
59a22e762d fix: 审计修复 — SSE事件监听 + 软删除列表 + 页面配置
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
- [HIGH] 前端 SSE store 补充 alert/vital_update 事件监听
- [LOW] seed.rs 软删除列表补充 device_readings
- [LOW] 小程序 device-sync 补充 index.config.ts 页面配置
2026-04-27 09:27:30 +08:00
iven
587f51c0c1 perf(health): batch_insert_readings 改为 SeaORM insert_many 批量插入
逐条 INSERT(最多 500 次 DB 往返)替换为构建 Vec<ActiveModel>
后一次性 insert_many(),延迟降低 95%+。
2026-04-27 09:26:41 +08:00
4 changed files with 26 additions and 19 deletions

View File

@@ -0,0 +1,3 @@
export default definePageConfig({
navigationBarTitleText: '设备同步',
});

View File

@@ -79,11 +79,18 @@ export const useMessageStore = create<MessageState>((set, get) => ({
const es = new EventSource(url);
es.addEventListener('message', () => {
// 收到新消息推送,立即刷新未读数和最近消息
get().fetchUnreadCount();
get().fetchRecentMessages();
});
es.addEventListener('alert', () => {
get().fetchUnreadCount();
});
es.addEventListener('vital_update', () => {
// 体征数据更新事件 — 预留:未来可触发趋势图刷新
});
es.onerror = () => {
// SSE 连接断开时 EventSource 会自动重连
};

View File

@@ -199,11 +199,10 @@ async fn batch_insert_readings(
device_model: Option<&str>,
readings: &[(&ReadingInput, DateTime<Utc>)],
) -> HealthResult<u64> {
let mut inserted: u64 = 0;
for (r, measured_at) in readings {
let id = Uuid::now_v7();
let model = device_readings::ActiveModel {
id: Set(id),
let models: Vec<device_readings::ActiveModel> = readings
.iter()
.map(|(r, measured_at)| device_readings::ActiveModel {
id: Set(Uuid::now_v7()),
tenant_id: Set(tenant_id),
patient_id: Set(patient_id),
device_id: Set(Some(device_id.to_string())),
@@ -213,19 +212,16 @@ async fn batch_insert_readings(
measured_at: Set(*measured_at),
created_at: Set(Utc::now()),
deleted_at: Set(None),
};
match model.insert(db).await {
Ok(_) => inserted += 1,
Err(e) => {
// 唯一约束冲突(重复数据)→ 跳过
let err_str = e.to_string();
if !err_str.contains("duplicate") && !err_str.contains("unique") {
return Err(HealthError::DbError(err_str));
}
}
}
}
Ok(inserted)
})
.collect();
let count = models.len() as u64;
device_readings::Entity::insert_many(models)
.exec(db)
.await
.map_err(|e| HealthError::DbError(e.to_string()))?;
Ok(count)
}
async fn upsert_hourly_aggregates(

View File

@@ -151,6 +151,7 @@ pub async fn soft_delete_tenant_data(
"alerts",
"patient_devices",
"vital_signs_hourly",
"device_readings",
];
for table in tables_to_soft_delete {