功能修复: 1. 患者创建空名称验证:后端添加 name.trim().is_empty() 检查 2. 仪表盘统计容错:单个查询失败返回零值而非 500 3. FHIR 路由修复:从 /fhir 移到 /api/v1/fhir 保持一致 4. 冻结模块后端中间件:新增 frozen_module_middleware 拦截冻结路径 5. 积分端点权限码:health.health-data.list → health.points.list 6. 角色权限迁移:护士补充 devices.list,运营补充 points.list/manage 7. 测试结果文档:R01-R05 角色测试 + T00/T10 结果归档 Clippy 全 workspace 清零(14→0 errors): - erp-core: 修复 empty doc line、collapsible if、redundant closure 等 9 处 - erp-health: 修复 too_many_arguments、unused var、unnecessary parens 等 58 处 - erp-ai: 修复 dead_code、unused import 等 11 处 - erp-plugin: 修复 too_many_arguments、wildcard pattern 等 11 处 - erp-server-migration: 修复 enum_variant_names 5 处 - erp-auth/config/workflow/message: 各 1-3 处 工程改进: - lint-staged 配置迁移到 .lintstagedrc.js(函数式避免文件列表传给 clippy) - cargo fmt 统一格式化
86 lines
5.5 KiB
Rust
86 lines
5.5 KiB
Rust
use sea_orm_migration::prelude::*;
|
||
|
||
#[derive(DeriveMigrationName)]
|
||
pub struct Migration;
|
||
|
||
#[async_trait::async_trait]
|
||
impl MigrationTrait for Migration {
|
||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||
let db = manager.get_connection();
|
||
|
||
let result = db
|
||
.query_one(sea_orm::Statement::from_string(
|
||
sea_orm::DatabaseBackend::Postgres,
|
||
"SELECT id::text FROM tenant LIMIT 1".to_string(),
|
||
))
|
||
.await?;
|
||
|
||
let tid = match result {
|
||
Some(row) => row.try_get_by_index::<String>(0).unwrap_or_default(),
|
||
None => return Ok(()),
|
||
};
|
||
|
||
let sys = "00000000-0000-0000-0000-000000000000";
|
||
let mc = r#"{"model":"claude-sonnet-4-6","temperature":0.3,"max_tokens":2048}"#;
|
||
|
||
insert_prompt(db, &tid, sys, "lab_report_interpretation", "化验单解读", "analysis", mc,
|
||
"你是一名专业的医学检验解读助手。请根据提供的化验指标数据,为患者提供清晰、准确的解读。\n\n要求:\n1. 逐项分析每个指标的含义和是否在正常范围\n2. 对异常指标提供可能的原因说明(不作为诊断)\n3. 给出建议的后续行动\n4. 使用通俗易懂的语言\n5. 最后给出总体健康提示",
|
||
"以下是患者的化验报告数据:\n\n报告日期:{{report_date}}\n科室:{{department}}\n患者年龄段:{{age_group}},性别:{{sex}}\n\n检查项目:\n{{#each items}}\n- {{name}}:{{value}} {{unit}}(参考范围:{{reference_range}},{{#if is_abnormal}}异常{{else}}正常{{/if}})\n{{/each}}\n\n请对以上化验结果进行详细解读。",
|
||
).await?;
|
||
|
||
insert_prompt(db, &tid, sys, "health_trend_analysis", "健康趋势分析", "analysis", mc,
|
||
"你是一名健康数据分析专家。请根据提供的生命体征趋势数据,分析患者的健康变化趋势。\n\n要求:\n1. 识别数据中的关键趋势\n2. 对异常趋势提出预警\n3. 结合各指标间的关联性进行综合分析\n4. 给出健康管理建议",
|
||
"以下是患者的生命体征趋势数据:\n\n患者年龄段:{{age_group}},性别:{{sex}}\n\n监测指标:\n{{#each metrics}}\n### {{name}}({{unit}})\n数据点:{{#each values}}{{this.[0]}}: {{this.[1]}}{{#unless @last}}, {{/unless}}{{/each}}\n{{/each}}\n\n请分析以上健康趋势数据。",
|
||
).await?;
|
||
|
||
insert_prompt(db, &tid, sys, "personalized_checkup_plan", "个性化体检方案", "planning", mc,
|
||
"你是一名健康管理顾问。请根据患者的健康状况信息,为其制定个性化的体检方案。\n\n要求:\n1. 基于患者年龄、性别、既往病史推荐检查项目\n2. 按优先级排序\n3. 给出建议的检查频率\n4. 说明每项检查的目的和意义",
|
||
"请为以下患者制定个性化体检方案:\n\n年龄段:{{age_group}}\n性别:{{sex}}\n慢性疾病:{{#each chronic_conditions}}{{this}}{{#unless @last}}、{{/unless}}{{/each}}\n当前用药:{{#each medications}}{{this}}{{#unless @last}}、{{/unless}}{{/each}}\n家族病史:{{#each family_history}}{{this}}{{#unless @last}}、{{/unless}}{{/each}}\n\n请给出详细的体检方案推荐。",
|
||
).await?;
|
||
|
||
insert_prompt(db, &tid, sys, "report_summary_generation", "报告摘要生成", "summary", mc,
|
||
"你是一名医疗报告摘要撰写专家。请根据提供的健康报告内容,生成结构清晰的摘要。\n\n要求:\n1. 提取报告中的关键发现\n2. 标注异常项目及其严重程度\n3. 给出简明的结论\n4. 提供行动建议\n5. 控制在 500 字以内",
|
||
"请为以下健康报告生成摘要:\n\n报告日期:{{report_date}}\n科室:{{department}}\n患者年龄段:{{age_group}},性别:{{sex}}\n\n报告内容:\n{{#each sections}}\n## {{title}}\n发现:{{#each findings}}{{this}}{{#unless @last}};{{/unless}}{{/each}}\n{{#if abnormal_items.length}}\n异常项:{{#each abnormal_items}}{{this}}{{#unless @last}}、{{/unless}}{{/each}}\n{{/if}}\n{{/each}}\n\n请生成结构化的报告摘要。",
|
||
).await?;
|
||
|
||
Ok(())
|
||
}
|
||
|
||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||
let db = manager.get_connection();
|
||
db.execute(sea_orm::Statement::from_string(
|
||
sea_orm::DatabaseBackend::Postgres,
|
||
"DELETE FROM ai_prompt WHERE name IN ('lab_report_interpretation','health_trend_analysis','personalized_checkup_plan','report_summary_generation')".to_string(),
|
||
))
|
||
.await?;
|
||
Ok(())
|
||
}
|
||
}
|
||
|
||
fn esc(s: &str) -> String {
|
||
s.replace('\'', "''")
|
||
}
|
||
|
||
async fn insert_prompt(
|
||
db: &sea_orm_migration::SchemaManagerConnection<'_>,
|
||
tenant_id: &str,
|
||
sys: &str,
|
||
name: &str,
|
||
description: &str,
|
||
category: &str,
|
||
model_config: &str,
|
||
system_prompt: &str,
|
||
user_template: &str,
|
||
) -> Result<(), DbErr> {
|
||
db.execute(sea_orm::Statement::from_string(
|
||
sea_orm::DatabaseBackend::Postgres,
|
||
format!(
|
||
"INSERT INTO ai_prompt (id, tenant_id, name, description, system_prompt, user_prompt_template, model_config, version, is_active, category, tags, created_at, updated_at, created_by, updated_by, version_lock) \
|
||
VALUES (gen_random_uuid(), '{}', '{}', '{}', '{}', '{}', '{}', 1, true, '{}', NULL, NOW(), NOW(), '{}', '{}', 1) ON CONFLICT DO NOTHING",
|
||
tenant_id, esc(name), esc(description), esc(system_prompt), esc(user_template), esc(model_config), category, sys, sys
|
||
),
|
||
))
|
||
.await?;
|
||
Ok(())
|
||
}
|