fix(ai): Copilot 审计修复 — C-1/H-1/H-2/H-3/H-4/H-5/L-2

- L-2: value_to_f64 对 Null 返回 NaN(防止误触发规则)
- C-1: load_patient_data 空数据时跳过写入快照
- H-1: 每日刷新定时器添加初始延迟
- H-2: copilot_consumer 传内层 content
- H-3: 前端 hooks/Alert 修复分页响应解析
- H-4: risk_handler 动态选择 AI provider
- H-5: 新增 DELETE /copilot/rules/{id} 软删除路由
This commit is contained in:
iven
2026-05-13 00:21:27 +08:00
parent 6d97328ff6
commit d6676abecf
9 changed files with 73 additions and 9 deletions

View File

@@ -16,12 +16,21 @@ where
{
require_permission(&ctx, "copilot.risk.view")?;
// 动态选择第一个可用的 AI 提供商(优先 ollama其次其他
let provider_name = state
.provider_registry
.provider_names()
.into_iter()
.find(|n| n == "ollama")
.or_else(|| state.provider_registry.provider_names().into_iter().next())
.unwrap_or_default();
let risk = crate::service::risk_service::RiskService::compute_risk_with_llm(
&state.db,
ctx.tenant_id,
patient_id,
&state.provider_registry,
"ollama",
&provider_name,
)
.await?;

View File

@@ -127,3 +127,31 @@ where
let result = active.update(&state.db).await?;
Ok(Json(ApiResponse::ok(result)))
}
pub async fn delete_rule<S>(
State(state): State<AiState>,
Extension(ctx): Extension<TenantContext>,
Path(rule_id): Path<uuid::Uuid>,
) -> Result<Json<ApiResponse<serde_json::Value>>, erp_core::error::AppError>
where
AiState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "copilot.rules.manage")?;
let model = copilot_rules::Entity::find()
.filter(copilot_rules::Column::Id.eq(rule_id))
.filter(copilot_rules::Column::TenantId.eq(ctx.tenant_id))
.filter(copilot_rules::Column::DeletedAt.is_null())
.one(&state.db)
.await?
.ok_or_else(|| erp_core::error::AppError::NotFound("Copilot 规则".into()))?;
let mut active: copilot_rules::ActiveModel = model.into();
active.deleted_at = Set(Some(chrono::Utc::now()));
active.updated_at = Set(chrono::Utc::now());
active.updated_by = Set(Some(ctx.user_id));
active.update(&state.db).await?;
Ok(Json(ApiResponse::ok(serde_json::json!({"deleted": true}))))
}