|
|
@@ -90,7 +90,7 @@ public class MedicalRecordQc123Service {
|
|
|
*/
|
|
|
|
|
|
public int processAllUncontrolledRecords() {
|
|
|
- return processAllUncontrolledRecords(false); // 启用并行,使用4个线程
|
|
|
+ return processAllUncontrolledRecords(true); // 启用并行,使用4个线程
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -207,8 +207,8 @@ public class MedicalRecordQc123Service {
|
|
|
Map.entry("lab_reports", "检查检验规则清单"), // 检验报告单
|
|
|
Map.entry("exam_reports", "检查检验规则清单"), // 检查报告单
|
|
|
Map.entry("orders", "医嘱规则清单"), // 医嘱记录
|
|
|
- Map.entry("discharge_summary", "出院(死亡)记录规则清单") // 出院小结
|
|
|
- // Map.entry("consent_forms", "知情同意书") // 知情同意书 - 暂时注释掉
|
|
|
+ Map.entry("discharge_summary", "出院(死亡)记录规则清单"), // 出院小结
|
|
|
+ Map.entry("consent_forms", "知情同意书") // 知情同意书 - 暂时注释掉
|
|
|
);
|
|
|
|
|
|
|
|
|
@@ -277,10 +277,10 @@ public class MedicalRecordQc123Service {
|
|
|
}
|
|
|
|
|
|
// 5. 处理 common 规则(分开质控)
|
|
|
- processCommonRules(recordId, commonRules, stepMap);
|
|
|
+ processCommonRules(recordId, commonRules, stepMap, record);
|
|
|
|
|
|
// 6. 处理 specific 规则(同时质控)
|
|
|
- processSpecificRules(recordId, specificRules, stepMap);
|
|
|
+ processSpecificRules(recordId, specificRules, stepMap, record);
|
|
|
|
|
|
// 7. 全部完成,更新状态为已质控
|
|
|
patientRecordMapper.updateStatusById(recordId, 2);
|
|
|
@@ -314,15 +314,15 @@ public class MedicalRecordQc123Service {
|
|
|
new QcStep(11, SECTION_LABEL_MAP.get("lab_reports"), record.getLabReports()),
|
|
|
new QcStep(12, SECTION_LABEL_MAP.get("exam_reports"), record.getExamReports()),
|
|
|
new QcStep(13, SECTION_LABEL_MAP.get("orders"), record.getOrders()),
|
|
|
- new QcStep(14, SECTION_LABEL_MAP.get("discharge_summary"), record.getDischargeSummary())
|
|
|
- // new QcStep(15, SECTION_LABEL_MAP.get("consent_forms"), record.getConsentForms()) // 暂时注释掉知情同意书质控
|
|
|
+ new QcStep(14, SECTION_LABEL_MAP.get("discharge_summary"), record.getDischargeSummary()),
|
|
|
+ new QcStep(15, SECTION_LABEL_MAP.get("consent_forms"), record.getConsentForms()) // 暂时注释掉知情同意书质控
|
|
|
);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 处理 common 规则(分开质控)
|
|
|
*/
|
|
|
- private void processCommonRules(String recordId, List<QualityControlRuleVo> commonRules, Map<Integer, QcStep> stepMap) {
|
|
|
+ private void processCommonRules(String recordId, List<QualityControlRuleVo> commonRules, Map<Integer, QcStep> stepMap, PatientRecord record) {
|
|
|
log.info("🔄 开始处理 common 规则,共 {} 条", commonRules.size());
|
|
|
|
|
|
// 按 type 分类 common 规则
|
|
|
@@ -346,16 +346,18 @@ public class MedicalRecordQc123Service {
|
|
|
|
|
|
log.info("📝 病历 {} type={} 开始质控,共 {} 条规则", recordId, type, rules.size());
|
|
|
|
|
|
- // 判断是否需要分批处理(type=2病程记录 或 type=13医嘱记录 或 type=4查房记录)
|
|
|
- boolean needBatch = (type == 2 || type == 4 || type == 13) && isJsonArray(step.content);
|
|
|
+ // 判断是否需要分批处理(type=2病程记录 或 type=13医嘱记录 或 type=4查房记录 或 type=15知情同意书)
|
|
|
+ boolean needBatch = (type == 2 || type == 4 || type == 13 || type == 15) && isJsonArray(step.content);
|
|
|
|
|
|
if (needBatch) {
|
|
|
// 大数据量类型,使用分批处理,根据 type 设置不同的批次大小
|
|
|
int batchSize;
|
|
|
if (type == 13) {
|
|
|
- batchSize = 40; // 医嘱记录:30条一组
|
|
|
+ batchSize = 40; // 医嘱记录:40条一组
|
|
|
+ } else if (type == 15) {
|
|
|
+ batchSize = 5; // 知情同意书:4条一组
|
|
|
} else {
|
|
|
- batchSize = 7; // 病程记录(type=2)和查房记录(type=4):5条一组
|
|
|
+ batchSize = 7; // 病程记录(type=2)和查房记录(type=4):7条一组
|
|
|
}
|
|
|
|
|
|
// 收集所有规则的不通过项
|
|
|
@@ -365,7 +367,7 @@ public class MedicalRecordQc123Service {
|
|
|
for (QualityControlRuleVo rule : rules) {
|
|
|
try {
|
|
|
String ragResult = fetchMatchingRules(rule.getRuleContent());
|
|
|
- List<Object> ruleFailures = batchQcForRule(recordId, type, rule, step.content, batchSize, ragResult);
|
|
|
+ List<Object> ruleFailures = batchQcForRule(recordId, type, rule, step.content, batchSize, ragResult, record);
|
|
|
allFailures.addAll(ruleFailures);
|
|
|
log.info("✅ 规则 [{}] type={} 分批质控完成(批次大小={}),不通过 {} 条",
|
|
|
rule.getRuleCode(), type, batchSize, ruleFailures.size());
|
|
|
@@ -401,7 +403,7 @@ public class MedicalRecordQc123Service {
|
|
|
String ragResult = fetchMatchingRules(rule.getRuleContent());
|
|
|
|
|
|
// 构造提示词(传入病历部分名称)
|
|
|
- String prompt = buildPromptWithRule(rule, step.content, ragResult, getTypeName(type));
|
|
|
+ String prompt = buildPromptWithRule(rule, step.content, ragResult, getTypeName(type), record);
|
|
|
|
|
|
// 调用大模型
|
|
|
String modelOutput = callLLM(prompt);
|
|
|
@@ -458,7 +460,7 @@ public class MedicalRecordQc123Service {
|
|
|
/**
|
|
|
* 处理 specific 规则(同时质控)
|
|
|
*/
|
|
|
- private void processSpecificRules(String recordId, List<QualityControlRuleVo> specificRules, Map<Integer, QcStep> stepMap) {
|
|
|
+ private void processSpecificRules(String recordId, List<QualityControlRuleVo> specificRules, Map<Integer, QcStep> stepMap, PatientRecord record) {
|
|
|
log.info("🔄 开始处理 specific 规则,共 {} 条", specificRules.size());
|
|
|
|
|
|
for (QualityControlRuleVo rule : specificRules) {
|
|
|
@@ -469,10 +471,10 @@ public class MedicalRecordQc123Service {
|
|
|
|
|
|
if (hasCourseRecords && hasOrders) {
|
|
|
// 按日期融合质控
|
|
|
- processSpecificRuleWithDateMerge(recordId, rule, stepMap);
|
|
|
+ processSpecificRuleWithDateMerge(recordId, rule, stepMap, record);
|
|
|
} else {
|
|
|
// 普通的 specific 规则处理
|
|
|
- processSpecificRuleNormally(recordId, rule, stepMap);
|
|
|
+ processSpecificRuleNormally(recordId, rule, stepMap, record);
|
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
@@ -484,7 +486,7 @@ public class MedicalRecordQc123Service {
|
|
|
/**
|
|
|
* 普通的 specific 规则处理(不需要按日期融合)
|
|
|
*/
|
|
|
- private void processSpecificRuleNormally(String recordId, QualityControlRuleVo rule, Map<Integer, QcStep> stepMap) {
|
|
|
+ private void processSpecificRuleNormally(String recordId, QualityControlRuleVo rule, Map<Integer, QcStep> stepMap, PatientRecord record) {
|
|
|
LocalDateTime start = LocalDateTime.now();
|
|
|
|
|
|
// 合并 qcTypeList 中所有 type 的病历内容
|
|
|
@@ -517,7 +519,7 @@ public class MedicalRecordQc123Service {
|
|
|
String combinedSectionName = validTypes.stream()
|
|
|
.map(this::getTypeName)
|
|
|
.collect(Collectors.joining(" + "));
|
|
|
- String prompt = buildPromptWithRule(rule, mergedContent.toString(), ragResult, combinedSectionName);
|
|
|
+ String prompt = buildPromptWithRule(rule, mergedContent.toString(), ragResult, combinedSectionName, record);
|
|
|
|
|
|
// 调用大模型
|
|
|
String modelOutput = callLLM(prompt);
|
|
|
@@ -612,7 +614,7 @@ public class MedicalRecordQc123Service {
|
|
|
/**
|
|
|
* 按日期融合 type=2 和 type=13 进行质控
|
|
|
*/
|
|
|
- private void processSpecificRuleWithDateMerge(String recordId, QualityControlRuleVo rule, Map<Integer, QcStep> stepMap) {
|
|
|
+ private void processSpecificRuleWithDateMerge(String recordId, QualityControlRuleVo rule, Map<Integer, QcStep> stepMap, PatientRecord record) {
|
|
|
log.info("📝 规则 [{}] 开始按日期融合质控 types={}", rule.getRuleCode(), rule.getQcTypeList());
|
|
|
|
|
|
// 1. 解析病程记录(以病程记录的日期为主时间轴)
|
|
|
@@ -678,7 +680,7 @@ public class MedicalRecordQc123Service {
|
|
|
// 调用大模型质控(使用融合质控专用提示词)
|
|
|
String ragResult = fetchMatchingRules(rule.getRuleContent());
|
|
|
String dateRange = batchDates.get(0) + " ~ " + batchDates.get(batchDates.size() - 1);
|
|
|
- String prompt = buildPromptForMergedRecords(rule, dateRange, batchContent.toString(), ragResult);
|
|
|
+ String prompt = buildPromptForMergedRecords(rule, dateRange, batchContent.toString(), ragResult, record);
|
|
|
String modelOutput = callLLM(prompt);
|
|
|
String processedOutput = processModelOutput(modelOutput);
|
|
|
|
|
|
@@ -896,7 +898,7 @@ public class MedicalRecordQc123Service {
|
|
|
private String getTypeName(int type) {
|
|
|
String[] names = {"入院志", "首次病程记录", "病程记录", "阶段小结", "查房记录",
|
|
|
"会诊记录", "疑难病例讨论", "超长住院讨论", "死亡病例讨论", "抢救记录",
|
|
|
- "手术记录", "检验报告", "检查报告", "医嘱记录", "出院小结"};
|
|
|
+ "手术记录", "检验报告", "检查报告", "医嘱记录", "出院小结", "知情同意书"};
|
|
|
return type >= 0 && type < names.length ? names[type] : "未知类型";
|
|
|
}
|
|
|
|
|
|
@@ -915,7 +917,7 @@ public class MedicalRecordQc123Service {
|
|
|
* 针对单条规则的分批质控(返回不通过项列表)
|
|
|
*/
|
|
|
private List<Object> batchQcForRule(String recordId, int qcType, QualityControlRuleVo rule,
|
|
|
- String jsonArrayContent, int batchSize, String ragResult) {
|
|
|
+ String jsonArrayContent, int batchSize, String ragResult, PatientRecord record) {
|
|
|
LocalDateTime start = LocalDateTime.now();
|
|
|
|
|
|
try {
|
|
|
@@ -950,7 +952,7 @@ public class MedicalRecordQc123Service {
|
|
|
rule.getRuleCode(), batchNo, totalBatches, startIdx, endIdx - 1, batchItems.size());
|
|
|
|
|
|
String batchContent = String.join("\n\n", batchItems);
|
|
|
- String prompt = buildPromptWithRule(rule, batchContent, ragResult, getTypeName(qcType));
|
|
|
+ String prompt = buildPromptWithRule(rule, batchContent, ragResult, getTypeName(qcType), record);
|
|
|
String batchOutput = callLLM(prompt);
|
|
|
String processedOutput = processModelOutput(batchOutput);
|
|
|
|
|
|
@@ -994,10 +996,10 @@ public class MedicalRecordQc123Service {
|
|
|
/**
|
|
|
* 构造提示词(用于按日期融合的病程记录和医嘱)
|
|
|
*/
|
|
|
- private String buildPromptForMergedRecords(QualityControlRuleVo rule, String date, String content, String ragResult) {
|
|
|
+ private String buildPromptForMergedRecords(QualityControlRuleVo rule, String date, String content, String ragResult, PatientRecord record) {
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
|
- sb.append("你是一名医疗病历质控员,需要依据【质控规则】对病历进行审查。\n\n");
|
|
|
+ sb.append("你是一名医疗病历质控员,需要依据【质控规则】对病历进行审查。如果提供了【参考内容】,请参考这些内容进行判断。\n\n");
|
|
|
|
|
|
sb.append("***【质控规则】***\n");
|
|
|
sb.append("规则编码: ").append(rule.getRuleCode()).append("\n");
|
|
|
@@ -1008,7 +1010,8 @@ public class MedicalRecordQc123Service {
|
|
|
sb.append("\n");
|
|
|
|
|
|
if (ragResult != null && !ragResult.isEmpty()) {
|
|
|
- sb.append("***【参考内容】***:\n")
|
|
|
+ sb.append("***【参考内容】***\n")
|
|
|
+ .append("以下是与当前规则相关的参考示例,正例表示符合要求,反例表示不符合要求:\n")
|
|
|
.append(ragResult).append("\n\n");
|
|
|
}
|
|
|
|
|
|
@@ -1020,6 +1023,18 @@ public class MedicalRecordQc123Service {
|
|
|
sb.append("根据给出的参考内容进行判断,正例是符合改规则质控要求,反例为不符合质控要求。\n");
|
|
|
sb.append("请针对这两部分的融合内容进行质控审查。\n\n");
|
|
|
|
|
|
+ // 添加病人基本信息
|
|
|
+ sb.append("【病人基本信息】\n");
|
|
|
+ if (record.getName() != null) sb.append("姓名: ").append(record.getName()).append("\n");
|
|
|
+ if (record.getGender() != null) sb.append("性别: ").append(record.getGender()).append("\n");
|
|
|
+ if (record.getAge() != null) sb.append("年龄: ").append(record.getAge()).append("岁\n");
|
|
|
+ if (record.getAdmissionNo() != null) sb.append("入院编号: ").append(record.getAdmissionNo()).append("\n");
|
|
|
+ if (record.getAdmissionDept() != null) sb.append("入院科室: ").append(record.getAdmissionDept()).append("\n");
|
|
|
+ if (record.getAdmissionDate() != null) sb.append("入院日期: ").append(record.getAdmissionDate()).append("\n");
|
|
|
+ if (record.getDischargeDate() != null) sb.append("出院日期: ").append(record.getDischargeDate()).append("\n");
|
|
|
+ if (record.getAttendingDoctor() != null) sb.append("主治医生: ").append(record.getAttendingDoctor()).append("\n");
|
|
|
+ sb.append("\n");
|
|
|
+
|
|
|
sb.append("【病历原文】:\n")
|
|
|
.append(content).append("\n\n");
|
|
|
|
|
|
@@ -1039,6 +1054,7 @@ public class MedicalRecordQc123Service {
|
|
|
sb.append("- 禁止输出 Markdown 代码块符号(如 ```json)\n");
|
|
|
sb.append("- 只针对当前规则进行质控,不要关联其他规则\n");
|
|
|
sb.append("- 所有结论必须严格基于病历原文记载\n");
|
|
|
+ sb.append("- 输出中不要出现参考内容\n");
|
|
|
sb.append("- 质控时要综合考虑病程记录和医嘱记录的关联性和一致性\n");
|
|
|
|
|
|
return sb.toString();
|
|
|
@@ -1047,13 +1063,15 @@ public class MedicalRecordQc123Service {
|
|
|
/**
|
|
|
* 构造提示词(带规则信息)
|
|
|
*/
|
|
|
- private String buildPromptWithRule(QualityControlRuleVo rule, String content, String ragResult, String sectionName) {
|
|
|
+ private String buildPromptWithRule(QualityControlRuleVo rule, String content, String ragResult, String sectionName, PatientRecord record) {
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
-
|
|
|
- sb.append("你是一名医疗病历质控员,需要依据【质控规则】对病历进行审查。\n\n");
|
|
|
-
|
|
|
+
|
|
|
+ sb.append("你是一名专业的医疗病历质控员,需要依据【质控规则】对病历内容进行审核。\n");
|
|
|
+ sb.append("若提供了【参考内容】,仅用于理解规则,不得直接引用或照抄。\n");
|
|
|
+ sb.append("请严格基于【病历原文】判断是否违反该规则。\n\n");
|
|
|
+
|
|
|
+ // === 质控规则 ===
|
|
|
sb.append("***【质控规则】***\n");
|
|
|
- sb.append("以下是本次质控的规则:\n");
|
|
|
sb.append("规则编码: ").append(rule.getRuleCode()).append("\n");
|
|
|
sb.append("规则内容: ").append(rule.getRuleContent()).append("\n");
|
|
|
if (rule.getRuleDesc() != null && !rule.getRuleDesc().isEmpty()) {
|
|
|
@@ -1061,38 +1079,87 @@ public class MedicalRecordQc123Service {
|
|
|
}
|
|
|
sb.append("\n");
|
|
|
|
|
|
+ // === 参考内容 ===
|
|
|
if (ragResult != null && !ragResult.isEmpty()) {
|
|
|
sb.append("***【参考内容】***\n");
|
|
|
- sb.append("根据给出的参考内容进行判断,正例是符合改规则质控要求,反例为不符合质控要求\n");
|
|
|
- sb.append("以下是相关的正反例参考:\n")
|
|
|
- .append(ragResult).append("\n\n");
|
|
|
+ sb.append("以下为与当前规则相关的参考示例,仅供理解标准使用:\n");
|
|
|
+ sb.append("正例代表符合要求,反例代表不符合要求。\n");
|
|
|
+ sb.append(ragResult).append("\n\n");
|
|
|
}
|
|
|
- sb.append("\n");
|
|
|
-
|
|
|
- sb.append("【病历原文】\n");
|
|
|
- sb.append("以下是").append(sectionName != null ? sectionName : "病历").append("部分:\n")
|
|
|
- .append(content).append("\n\n");
|
|
|
|
|
|
- sb.append("1.输出格式:\n");
|
|
|
- sb.append("请严格按照以下要求输出:\n");
|
|
|
- sb.append("如果病历完全符合所有规则:[{\"result\": \"pass\", \"message\": \"病例校验通过\"}]\n\n");
|
|
|
-
|
|
|
- sb.append("如果存在不符合规则:逐条输出 JSON 对象,数组形式,每个对象包含以下字段:\n");
|
|
|
- sb.append("- result: 固定为 \"fail\"\n");
|
|
|
- sb.append("- detail: 违规位置及内容(如\\\"入院记录-主诉\\\")\n");
|
|
|
- sb.append("- content:从病历原文中提取违规内容所在的一小段(约10字左右),保持完整病历内容,便于定位。\n");
|
|
|
- sb.append("- ruleCode: 对应规则编号(如 \"").append(rule.getRuleCode()).append("\")\n");
|
|
|
- sb.append("- ruleContent: 对应规则详情,必须与质控规则完全一致\n");
|
|
|
- sb.append("- qcResult: 结论,给出违反本条规则的原因,简要描述。\n\n");
|
|
|
-
|
|
|
- sb.append("2.注意事项:\n");
|
|
|
- sb.append("- 禁止输出 Markdown 代码块符号(如 ```json)\n");
|
|
|
- sb.append("- 只针对当前规则进行质控,不要关联其他规则\n");
|
|
|
- sb.append("- 所有结论必须严格基于病历原文记载\n");
|
|
|
-
|
|
|
+ // === 病人基本信息(可选) ===
|
|
|
+ if (shouldShowPatientInfo(sectionName) && record != null) {
|
|
|
+ sb.append("===【病人基本信息】===\n");
|
|
|
+ if (record.getName() != null) sb.append("姓名: ").append(record.getName()).append("\n");
|
|
|
+ if (record.getGender() != null) sb.append("性别: ").append(record.getGender()).append("\n");
|
|
|
+ if (record.getAge() != null) sb.append("年龄: ").append(record.getAge()).append("岁\n");
|
|
|
+ if (record.getAdmissionNo() != null) sb.append("入院编号: ").append(record.getAdmissionNo()).append("\n");
|
|
|
+ if (record.getAdmissionDept() != null) sb.append("入院科室: ").append(record.getAdmissionDept()).append("\n");
|
|
|
+ if (record.getAdmissionDate() != null) sb.append("入院日期: ").append(record.getAdmissionDate()).append("\n");
|
|
|
+ if (record.getDischargeDate() != null) sb.append("出院日期: ").append(record.getDischargeDate()).append("\n");
|
|
|
+ if (record.getAttendingDoctor() != null) sb.append("主治医生: ").append(record.getAttendingDoctor()).append("\n");
|
|
|
+ sb.append("\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ // === 病历原文 ===
|
|
|
+ sb.append("===【病历原文】===\n");
|
|
|
+ sb.append("以下为").append(sectionName != null ? sectionName : "病历").append("部分:\n");
|
|
|
+ sb.append(content).append("\n\n");
|
|
|
+
|
|
|
+ // === 输出格式 ===
|
|
|
+ sb.append("===【输出要求】===\n");
|
|
|
+ sb.append("请严格输出 JSON 数组格式,不得输出解释性文字或额外内容。\n\n");
|
|
|
+
|
|
|
+ sb.append("如果病历完全符合所有规则,请输出:\n");
|
|
|
+ sb.append("[{\"result\": \"pass\", \"message\": \"病例校验通过\"}]\n\n");
|
|
|
+
|
|
|
+ sb.append("如果存在不符合规则,请输出以下格式的数组,每条违规单独一项:\n");
|
|
|
+ sb.append("[{\n");
|
|
|
+ sb.append(" \"result\": \"fail\", // 质控结果,固定为 'fail'\n");
|
|
|
+ sb.append(" \"detail\": \"违规位置及所属内容(如 '入院记录-主诉')\",\n");
|
|
|
+ sb.append(" \"content\": \"病历中约10字左右的违规文本片段\",\n");
|
|
|
+ sb.append(" \"ruleCode\": \"").append(rule.getRuleCode()).append("\", // 对应规则编号\n");
|
|
|
+ sb.append(" \"ruleContent\": \"").append(rule.getRuleContent()).append("\", // 对应规则内容\n");
|
|
|
+ sb.append(" \"qcResult\": \"违反该规则的原因描述\"\n");
|
|
|
+ sb.append("}]\n\n");
|
|
|
+
|
|
|
+ // === 字段解释 ===
|
|
|
+ sb.append("每个字段说明如下:\n");
|
|
|
+ sb.append("- result: 质控结果,固定为 \"fail\" 表示不通过\n");
|
|
|
+ sb.append("- detail: 违规位置及所属内容(如 \"入院记录-主诉\")\n");
|
|
|
+ sb.append("- content: 从病历原文中截取违规片段(约10字左右),保留上下文,便于定位\n");
|
|
|
+ sb.append("- ruleCode: 对应规则编号(如 \"").append(rule.getRuleCode()).append("\"),用于标识当前规则\n");
|
|
|
+ sb.append("- ruleContent: 对应规则内容(如 \"").append(rule.getRuleContent()).append("\"),必须与质控规则完全一致\n");
|
|
|
+ sb.append("- qcResult: 质控结论,只描述违反本条规则的原因,不要包含其他解释\n\n");
|
|
|
+
|
|
|
+ // === 注意事项 ===
|
|
|
+ sb.append("===【注意事项】===\n");
|
|
|
+ sb.append("- 严禁输出 Markdown 代码块(如 ```json)\n");
|
|
|
+ sb.append("- 严禁输出解释性文字、分析过程或无关说明\n");
|
|
|
+ sb.append("- 不得引用或复述【参考内容】中的文字\n");
|
|
|
+ sb.append("- 若规则不适用于当前病历内容,应视为通过\n");
|
|
|
+ sb.append("- 所有结论必须严格基于【病历原文】内容\n");
|
|
|
+
|
|
|
return sb.toString();
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断是否需要显示病人基本信息
|
|
|
+ * 只在入院志、首次病程记录、病程记录、阶段小结、查房记录这几个类型中显示
|
|
|
+ */
|
|
|
+ private boolean shouldShowPatientInfo(String sectionName) {
|
|
|
+ if (sectionName == null) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ // 判断是否包含需要显示病人信息的病历类型
|
|
|
+ return sectionName.contains("入院志")
|
|
|
+ || sectionName.contains("首次病程记录")
|
|
|
+ || sectionName.contains("病程记录")
|
|
|
+ || sectionName.contains("阶段小结")
|
|
|
+ || sectionName.contains("查房记录");
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 调用 RAG 获取匹配规则
|
|
|
*/
|
|
|
@@ -1118,11 +1185,14 @@ public class MedicalRecordQc123Service {
|
|
|
}
|
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
+ int validCount = 0; // 有效内容计数器
|
|
|
for (int i = 0; i < nearest.size(); i++) {
|
|
|
JSONObject item = nearest.getJSONObject(i);
|
|
|
String text = item.getString("text");
|
|
|
if (text != null && !text.trim().isEmpty()) {
|
|
|
- if (sb.length() > 0) sb.append("\n");
|
|
|
+ validCount++;
|
|
|
+ if (sb.length() > 0) sb.append("\n\n"); // 两个换行,增加间距
|
|
|
+ sb.append(validCount).append(". ");
|
|
|
sb.append(text.trim());
|
|
|
}
|
|
|
}
|