feat(plugin): 评估量表插件骨架 — assessment_scale + assessment_response + PHQ-9 默认数据
- 创建 erp-plugin-assessment cdylib crate - 实现 Guest trait(init/on_tenant_created/handle_event) - on_tenant_created 自动插入 PHQ-9 抑郁筛查量表 - plugin.toml 声明 2 实体 + 4 权限 + 触发事件
This commit is contained in:
@@ -17,6 +17,7 @@ members = [
|
|||||||
"crates/erp-plugin-itops",
|
"crates/erp-plugin-itops",
|
||||||
"crates/erp-health",
|
"crates/erp-health",
|
||||||
"crates/erp-ai",
|
"crates/erp-ai",
|
||||||
|
"crates/erp-plugin-assessment",
|
||||||
]
|
]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
|
|||||||
13
crates/erp-plugin-assessment/Cargo.toml
Normal file
13
crates/erp-plugin-assessment/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[package]
|
||||||
|
name = "erp-plugin-assessment"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
description = "标准化医学评估量表插件(PHQ-9、GAD-7 等)"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
wit-bindgen = "0.55"
|
||||||
|
serde = { workspace = true }
|
||||||
|
serde_json = { workspace = true }
|
||||||
149
crates/erp-plugin-assessment/plugin.toml
Normal file
149
crates/erp-plugin-assessment/plugin.toml
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
# 评估量表 — plugin.toml
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
id = "assessment"
|
||||||
|
name = "评估量表"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "标准化医学评估量表(PHQ-9、GAD-7 等)"
|
||||||
|
author = "HMS"
|
||||||
|
min_platform_version = "0.1.0"
|
||||||
|
|
||||||
|
[[permissions]]
|
||||||
|
code = "assessment_scale.list"
|
||||||
|
name = "查看评估量表"
|
||||||
|
description = "查看评估量表列表和详情"
|
||||||
|
|
||||||
|
[[permissions]]
|
||||||
|
code = "assessment_scale.manage"
|
||||||
|
name = "管理评估量表"
|
||||||
|
description = "创建、编辑、删除评估量表"
|
||||||
|
|
||||||
|
[[permissions]]
|
||||||
|
code = "assessment_response.list"
|
||||||
|
name = "查看评估结果"
|
||||||
|
description = "查看患者评估答卷"
|
||||||
|
|
||||||
|
[[permissions]]
|
||||||
|
code = "assessment_response.manage"
|
||||||
|
name = "管理评估结果"
|
||||||
|
description = "提交、编辑评估答卷"
|
||||||
|
|
||||||
|
[[schema.entities]]
|
||||||
|
name = "assessment_scale"
|
||||||
|
display_name = "评估量表"
|
||||||
|
|
||||||
|
[[schema.entities.fields]]
|
||||||
|
name = "scale_code"
|
||||||
|
field_type = "string"
|
||||||
|
required = true
|
||||||
|
display_name = "量表编码"
|
||||||
|
unique = true
|
||||||
|
ui_widget = "select"
|
||||||
|
options = ["PHQ-9", "GAD-7", "SF-36", "MMSE", "ADL", "IADL"]
|
||||||
|
|
||||||
|
[[schema.entities.fields]]
|
||||||
|
name = "title"
|
||||||
|
field_type = "string"
|
||||||
|
required = true
|
||||||
|
display_name = "量表名称"
|
||||||
|
searchable = true
|
||||||
|
|
||||||
|
[[schema.entities.fields]]
|
||||||
|
name = "description"
|
||||||
|
field_type = "string"
|
||||||
|
display_name = "描述"
|
||||||
|
ui_widget = "textarea"
|
||||||
|
|
||||||
|
[[schema.entities.fields]]
|
||||||
|
name = "questions_json"
|
||||||
|
field_type = "json"
|
||||||
|
required = true
|
||||||
|
display_name = "题目定义(JSON)"
|
||||||
|
|
||||||
|
[[schema.entities.fields]]
|
||||||
|
name = "scoring_rules_json"
|
||||||
|
field_type = "json"
|
||||||
|
required = true
|
||||||
|
display_name = "评分规则(JSON)"
|
||||||
|
|
||||||
|
[[schema.entities.fields]]
|
||||||
|
name = "status"
|
||||||
|
field_type = "string"
|
||||||
|
required = true
|
||||||
|
display_name = "状态"
|
||||||
|
default = "active"
|
||||||
|
ui_widget = "select"
|
||||||
|
options = ["active", "inactive"]
|
||||||
|
|
||||||
|
[[schema.entities]]
|
||||||
|
name = "assessment_response"
|
||||||
|
display_name = "评估答卷"
|
||||||
|
|
||||||
|
[[schema.entities.fields]]
|
||||||
|
name = "scale_id"
|
||||||
|
field_type = "uuid"
|
||||||
|
required = true
|
||||||
|
display_name = "量表"
|
||||||
|
ui_widget = "entity_select"
|
||||||
|
ref_entity = "assessment_scale"
|
||||||
|
ref_plugin = "assessment"
|
||||||
|
|
||||||
|
[[schema.entities.fields]]
|
||||||
|
name = "patient_id"
|
||||||
|
field_type = "uuid"
|
||||||
|
required = true
|
||||||
|
display_name = "患者 ID"
|
||||||
|
|
||||||
|
[[schema.entities.fields]]
|
||||||
|
name = "answers_json"
|
||||||
|
field_type = "json"
|
||||||
|
required = true
|
||||||
|
display_name = "答案(JSON)"
|
||||||
|
|
||||||
|
[[schema.entities.fields]]
|
||||||
|
name = "total_score"
|
||||||
|
field_type = "integer"
|
||||||
|
required = true
|
||||||
|
display_name = "总分"
|
||||||
|
|
||||||
|
[[schema.entities.fields]]
|
||||||
|
name = "severity_level"
|
||||||
|
field_type = "string"
|
||||||
|
required = true
|
||||||
|
display_name = "严重程度"
|
||||||
|
ui_widget = "select"
|
||||||
|
options = ["normal", "mild", "moderate", "moderate_severe", "severe"]
|
||||||
|
|
||||||
|
[[schema.entities.fields]]
|
||||||
|
name = "assessed_by"
|
||||||
|
field_type = "uuid"
|
||||||
|
display_name = "评估人"
|
||||||
|
|
||||||
|
[[schema.entities.fields]]
|
||||||
|
name = "status"
|
||||||
|
field_type = "string"
|
||||||
|
required = true
|
||||||
|
display_name = "状态"
|
||||||
|
default = "completed"
|
||||||
|
ui_widget = "select"
|
||||||
|
options = ["draft", "completed", "reviewed"]
|
||||||
|
|
||||||
|
[[schema.entities.relations]]
|
||||||
|
entity = "assessment_scale"
|
||||||
|
foreign_key = "scale_id"
|
||||||
|
on_delete = "restrict"
|
||||||
|
name = "scale"
|
||||||
|
type = "belongs_to"
|
||||||
|
display_field = "title"
|
||||||
|
|
||||||
|
[[trigger_events]]
|
||||||
|
name = "assessment_completed"
|
||||||
|
display_name = "评估完成"
|
||||||
|
description = "患者完成评估量表,触发评分计算和后续流程"
|
||||||
|
entity = "assessment_response"
|
||||||
|
on = "create"
|
||||||
|
|
||||||
|
[[ui.pages]]
|
||||||
|
type = "crud"
|
||||||
|
label = "评估量表"
|
||||||
|
icon = "FormOutlined"
|
||||||
145
crates/erp-plugin-assessment/src/lib.rs
Normal file
145
crates/erp-plugin-assessment/src/lib.rs
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
//! 评估量表插件 — 标准化医学评估(PHQ-9, GAD-7 等)
|
||||||
|
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
wit_bindgen::generate!({
|
||||||
|
path: "../erp-plugin-prototype/wit/plugin.wit",
|
||||||
|
world: "plugin-world",
|
||||||
|
});
|
||||||
|
|
||||||
|
use crate::erp::plugin::host_api;
|
||||||
|
use crate::exports::erp::plugin::plugin_api::Guest;
|
||||||
|
|
||||||
|
struct AssessmentPlugin;
|
||||||
|
|
||||||
|
impl Guest for AssessmentPlugin {
|
||||||
|
fn init() -> Result<(), String> {
|
||||||
|
host_api::log_write("info", "AssessmentPlugin initialized");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_tenant_created(tenant_id: String) -> Result<(), String> {
|
||||||
|
host_api::log_write(
|
||||||
|
"info",
|
||||||
|
&format!("AssessmentPlugin: tenant {} created, inserting default scales", tenant_id),
|
||||||
|
);
|
||||||
|
|
||||||
|
insert_phq9_scale(&tenant_id)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_event(event_type: String, payload: Vec<u8>) -> Result<(), String> {
|
||||||
|
host_api::log_write(
|
||||||
|
"debug",
|
||||||
|
&format!("AssessmentPlugin received: {}", event_type),
|
||||||
|
);
|
||||||
|
|
||||||
|
if event_type == "assessment_completed" {
|
||||||
|
let data: serde_json::Value =
|
||||||
|
serde_json::from_slice(&payload).map_err(|e| format!("解析失败: {}", e))?;
|
||||||
|
host_api::log_write(
|
||||||
|
"info",
|
||||||
|
&format!("评估完成: scale_id={}, patient_id={}",
|
||||||
|
data["scale_id"].as_str().unwrap_or("?"),
|
||||||
|
data["patient_id"].as_str().unwrap_or("?")
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 插入 PHQ-9 抑郁筛查量表默认数据
|
||||||
|
fn insert_phq9_scale(tenant_id: &str) -> Result<(), String> {
|
||||||
|
let questions = json!([
|
||||||
|
{"id": 1, "text": "做事时提不起劲或没有兴趣", "options": [
|
||||||
|
{"label": "完全不会", "score": 0},
|
||||||
|
{"label": "好几天", "score": 1},
|
||||||
|
{"label": "一半以上的天数", "score": 2},
|
||||||
|
{"label": "几乎每天", "score": 3}
|
||||||
|
]},
|
||||||
|
{"id": 2, "text": "感到心情低落、沮丧或绝望", "options": [
|
||||||
|
{"label": "完全不会", "score": 0},
|
||||||
|
{"label": "好几天", "score": 1},
|
||||||
|
{"label": "一半以上的天数", "score": 2},
|
||||||
|
{"label": "几乎每天", "score": 3}
|
||||||
|
]},
|
||||||
|
{"id": 3, "text": "入睡困难、睡不安稳或睡眠过多", "options": [
|
||||||
|
{"label": "完全不会", "score": 0},
|
||||||
|
{"label": "好几天", "score": 1},
|
||||||
|
{"label": "一半以上的天数", "score": 2},
|
||||||
|
{"label": "几乎每天", "score": 3}
|
||||||
|
]},
|
||||||
|
{"id": 4, "text": "感觉疲倦或没有活力", "options": [
|
||||||
|
{"label": "完全不会", "score": 0},
|
||||||
|
{"label": "好几天", "score": 1},
|
||||||
|
{"label": "一半以上的天数", "score": 2},
|
||||||
|
{"label": "几乎每天", "score": 3}
|
||||||
|
]},
|
||||||
|
{"id": 5, "text": "食欲不振或吃太多", "options": [
|
||||||
|
{"label": "完全不会", "score": 0},
|
||||||
|
{"label": "好几天", "score": 1},
|
||||||
|
{"label": "一半以上的天数", "score": 2},
|
||||||
|
{"label": "几乎每天", "score": 3}
|
||||||
|
]},
|
||||||
|
{"id": 6, "text": "觉得自己很糟,或觉得自己失败了,或让自己和家人失望", "options": [
|
||||||
|
{"label": "完全不会", "score": 0},
|
||||||
|
{"label": "好几天", "score": 1},
|
||||||
|
{"label": "一半以上的天数", "score": 2},
|
||||||
|
{"label": "几乎每天", "score": 3}
|
||||||
|
]},
|
||||||
|
{"id": 7, "text": "对事物专注有困难(例如阅读或看电视)", "options": [
|
||||||
|
{"label": "完全不会", "score": 0},
|
||||||
|
{"label": "好几天", "score": 1},
|
||||||
|
{"label": "一半以上的天数", "score": 2},
|
||||||
|
{"label": "几乎每天", "score": 3}
|
||||||
|
]},
|
||||||
|
{"id": 8, "text": "动作或说话速度缓慢到别人可以察觉,或正好相反——烦躁不安地动来动去", "options": [
|
||||||
|
{"label": "完全不会", "score": 0},
|
||||||
|
{"label": "好几天", "score": 1},
|
||||||
|
{"label": "一半以上的天数", "score": 2},
|
||||||
|
{"label": "几乎每天", "score": 3}
|
||||||
|
]},
|
||||||
|
{"id": 9, "text": "有不如死掉或者用某种方式伤害自己的念头", "options": [
|
||||||
|
{"label": "完全不会", "score": 0},
|
||||||
|
{"label": "好几天", "score": 1},
|
||||||
|
{"label": "一半以上的天数", "score": 2},
|
||||||
|
{"label": "几乎每天", "score": 3}
|
||||||
|
]}
|
||||||
|
]);
|
||||||
|
|
||||||
|
let scoring_rules = json!([
|
||||||
|
{"min": 0, "max": 4, "level": "normal", "label": "无抑郁症状"},
|
||||||
|
{"min": 5, "max": 9, "level": "mild", "label": "轻度抑郁"},
|
||||||
|
{"min": 10, "max": 14, "level": "moderate", "label": "中度抑郁"},
|
||||||
|
{"min": 15, "max": 19, "level": "moderate_severe", "label": "中重度抑郁"},
|
||||||
|
{"min": 20, "max": 27, "level": "severe", "label": "重度抑郁"}
|
||||||
|
]);
|
||||||
|
|
||||||
|
let data = json!({
|
||||||
|
"scale_code": "PHQ-9",
|
||||||
|
"title": "PHQ-9 患者健康问卷(抑郁筛查)",
|
||||||
|
"description": "Patient Health Questionnaire-9,用于抑郁症状筛查和严重程度评估",
|
||||||
|
"questions_json": questions,
|
||||||
|
"scoring_rules_json": scoring_rules,
|
||||||
|
"status": "active",
|
||||||
|
"tenant_id": tenant_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
let result = host_api::db_insert("assessment_scale", data.to_string().as_bytes())
|
||||||
|
.map_err(|e| format!("插入 PHQ-9 默认量表失败: {}", e))?;
|
||||||
|
|
||||||
|
let record: serde_json::Value =
|
||||||
|
serde_json::from_slice(&result).map_err(|e| format!("解析结果失败: {}", e))?;
|
||||||
|
|
||||||
|
host_api::log_write(
|
||||||
|
"info",
|
||||||
|
&format!("PHQ-9 默认量表已创建: id={}", record["id"].as_str().unwrap_or("?")),
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
export!(AssessmentPlugin);
|
||||||
Reference in New Issue
Block a user