fix: 修复剩余MEDIUM/LOW问题
This commit is contained in:
@@ -110,7 +110,63 @@ public class CdssAppServiceImpl implements ICdssAppService {
|
||||
}
|
||||
|
||||
private boolean evaluateCondition(String conditionExpr, Long encounterId, Long patientId) {
|
||||
return conditionExpr.contains("encounterId") || conditionExpr.contains("patientId");
|
||||
String expr = conditionExpr.trim();
|
||||
if (expr.isEmpty()) return false;
|
||||
|
||||
if (expr.contains(" OR ")) {
|
||||
for (String part : expr.split("(?i)\\s+OR\\s+")) {
|
||||
if (evaluateCondition(part.trim(), encounterId, patientId)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (expr.contains(" AND ")) {
|
||||
for (String part : expr.split("(?i)\\s+AND\\s+")) {
|
||||
if (!evaluateCondition(part.trim(), encounterId, patientId)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
String[] ops = {">=", "<=", "!=", "=", ">", "<"};
|
||||
for (String op : ops) {
|
||||
int idx = expr.indexOf(op);
|
||||
if (idx > 0) {
|
||||
String left = expr.substring(0, idx).trim();
|
||||
String right = expr.substring(idx + op.length()).trim();
|
||||
Object leftVal = resolveParam(left, encounterId, patientId);
|
||||
if (leftVal == null) return false;
|
||||
int cmp = compareValues(leftVal.toString(), right);
|
||||
return switch (op) {
|
||||
case ">=" -> cmp >= 0;
|
||||
case "<=" -> cmp <= 0;
|
||||
case "!=" -> cmp != 0;
|
||||
case "=" -> cmp == 0;
|
||||
case ">" -> cmp > 0;
|
||||
case "<" -> cmp < 0;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return !"0".equals(expr) && !"false".equalsIgnoreCase(expr) && !"null".equalsIgnoreCase(expr);
|
||||
}
|
||||
|
||||
private Object resolveParam(String name, Long encounterId, Long patientId) {
|
||||
return switch (name.trim().toLowerCase()) {
|
||||
case "encounterid" -> encounterId;
|
||||
case "patientid" -> patientId;
|
||||
default -> {
|
||||
try { yield Long.parseLong(name); }
|
||||
catch (NumberFormatException e) { yield name; }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private int compareValues(String left, String right) {
|
||||
try {
|
||||
return Long.compare(Long.parseLong(left), Long.parseLong(right));
|
||||
} catch (NumberFormatException e) {
|
||||
return left.compareTo(right);
|
||||
}
|
||||
}
|
||||
|
||||
private CdssAlert buildAlert(CdssRule rule, Long encounterId, Long patientId) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.healthlink.his.web.esbmanage.appservice.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.healthlink.his.administration.domain.Encounter;
|
||||
import com.healthlink.his.administration.service.IEncounterService;
|
||||
import com.healthlink.his.esb.domain.EsbServiceRegistry;
|
||||
import com.healthlink.his.esb.domain.RegionalShareRecord;
|
||||
import com.healthlink.his.esb.service.IEsbServiceRegistryService;
|
||||
@@ -21,6 +23,7 @@ public class RegionalShareAppServiceImpl implements IRegionalShareAppService {
|
||||
|
||||
private final IRegionalShareRecordService shareRecordService;
|
||||
private final IEsbServiceRegistryService registryService;
|
||||
private final IEncounterService encounterService;
|
||||
|
||||
@Override
|
||||
public RegionalShareRecord sharePatientData(Long encounterId, String targetSystem) {
|
||||
@@ -34,7 +37,8 @@ public class RegionalShareAppServiceImpl implements IRegionalShareAppService {
|
||||
|
||||
RegionalShareRecord record = new RegionalShareRecord();
|
||||
record.setEncounterId(encounterId);
|
||||
record.setPatientId(0L);
|
||||
Encounter encounter = encounterService.getById(encounterId);
|
||||
record.setPatientId(encounter != null ? encounter.getPatientId() : 0L);
|
||||
record.setShareType("PATIENT_DATA");
|
||||
record.setTargetSystem(targetSystem);
|
||||
record.setShareStatus("PENDING");
|
||||
|
||||
@@ -169,7 +169,7 @@ public class InfectionEnhancedAppServiceImpl implements IInfectionEnhancedAppSer
|
||||
|
||||
private Date parseDate(String s) {
|
||||
try { return new java.text.SimpleDateFormat("yyyy-MM-dd").parse(s); }
|
||||
catch (Exception e) { return null; }
|
||||
catch (Exception e) { log.warn("日期解析失败: {}", s); return null; }
|
||||
}
|
||||
|
||||
private int parseInt(Object val, int defaultVal) {
|
||||
|
||||
@@ -108,7 +108,7 @@ public class InfectionScreeningAppServiceImpl implements IInfectionScreeningAppS
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException ignored) {}
|
||||
} catch (NumberFormatException e) { log.warn("minDays解析失败: {}", params.get("minDays")); }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ public class TargetedSurveillanceAppServiceImpl implements ITargetedSurveillance
|
||||
try {
|
||||
java.time.LocalDate ld = java.time.LocalDate.parse(s, java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
return java.util.Date.from(ld.atStartOfDay(java.time.ZoneId.systemDefault()).toInstant());
|
||||
} catch (Exception e) { return null; }
|
||||
} catch (Exception e) { log.warn("日期解析失败: {}", s); return null; }
|
||||
}
|
||||
|
||||
private int parseInt(Object val, int defaultVal) {
|
||||
|
||||
@@ -32,9 +32,22 @@ public class EmrQualityAppServiceImpl implements IEmrQualityAppService {
|
||||
List<Map<String, Object>> checks = new ArrayList<>();
|
||||
String[] items = {"入院记录24h完成", "首次病程8h完成", "日常病程及时", "出院记录完整", "签名完整"};
|
||||
int pass = 0;
|
||||
List<EmrDefect> defects = defectMapper.selectList(new LambdaQueryWrapper<EmrDefect>()
|
||||
.eq(EmrDefect::getEncounterId, encounterId).eq(EmrDefect::getDelFlag, "0"));
|
||||
Set<String> defectTypes = new HashSet<>();
|
||||
for (EmrDefect d : defects) {
|
||||
if (d.getDefectType() != null) defectTypes.add(d.getDefectType());
|
||||
}
|
||||
for (String item : items) {
|
||||
Map<String, Object> check = new HashMap<>();
|
||||
check.put("item", item); check.put("result", "PASS"); checks.add(check); pass++;
|
||||
boolean passed = true;
|
||||
if ("入院记录24h完成".equals(item) && defectTypes.contains("TIMELY")) passed = false;
|
||||
if ("首次病程8h完成".equals(item) && defectTypes.contains("TIMELY")) passed = false;
|
||||
if ("日常病程及时".equals(item) && defectTypes.contains("TIMELY")) passed = false;
|
||||
if ("出院记录完整".equals(item) && defectTypes.contains("COMPLETENESS")) passed = false;
|
||||
if ("签名完整".equals(item) && defectTypes.contains("SIGNATURE")) passed = false;
|
||||
check.put("item", item); check.put("result", passed ? "PASS" : "FAIL"); checks.add(check);
|
||||
if (passed) pass++;
|
||||
}
|
||||
result.put("encounterId", encounterId); result.put("checks", checks);
|
||||
result.put("totalItems", items.length); result.put("passItems", pass);
|
||||
@@ -78,8 +91,41 @@ public class EmrQualityAppServiceImpl implements IEmrQualityAppService {
|
||||
}
|
||||
@Override
|
||||
public Map<String, Object> getCompletionRate(String startDate, String endDate) {
|
||||
LambdaQueryWrapper<EmrDefect> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(EmrDefect::getDelFlag, "0");
|
||||
if (startDate != null && !startDate.isEmpty()) {
|
||||
wrapper.ge(EmrDefect::getReportTime, startDate);
|
||||
}
|
||||
if (endDate != null && !endDate.isEmpty()) {
|
||||
wrapper.le(EmrDefect::getReportTime, endDate);
|
||||
}
|
||||
long totalDefects = defectMapper.selectCount(wrapper);
|
||||
LambdaQueryWrapper<EmrDefect> overdueWrapper = new LambdaQueryWrapper<>();
|
||||
overdueWrapper.eq(EmrDefect::getDelFlag, "0").eq(EmrDefect::getDefectType, "TIMELY");
|
||||
if (startDate != null && !startDate.isEmpty()) {
|
||||
overdueWrapper.ge(EmrDefect::getReportTime, startDate);
|
||||
}
|
||||
if (endDate != null && !endDate.isEmpty()) {
|
||||
overdueWrapper.le(EmrDefect::getReportTime, endDate);
|
||||
}
|
||||
long overdueEmr = defectMapper.selectCount(overdueWrapper);
|
||||
LambdaQueryWrapper<QualityScore> scoreWrapper = new LambdaQueryWrapper<>();
|
||||
scoreWrapper.eq(QualityScore::getDelFlag, "0");
|
||||
if (startDate != null && !startDate.isEmpty()) {
|
||||
scoreWrapper.ge(QualityScore::getCreateTime, startDate);
|
||||
}
|
||||
if (endDate != null && !endDate.isEmpty()) {
|
||||
scoreWrapper.le(QualityScore::getCreateTime, endDate);
|
||||
}
|
||||
long totalEncounters = scoreMapper.selectCount(scoreWrapper);
|
||||
long completedEmr = totalEncounters - overdueEmr;
|
||||
if (completedEmr < 0) completedEmr = 0;
|
||||
double completionRate = totalEncounters > 0 ? Math.round(completedEmr * 100.0 / totalEncounters) : 100;
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("totalEncounters", 0); result.put("completedEmr", 0); result.put("overdueEmr", 0); result.put("completionRate", 100);
|
||||
result.put("totalEncounters", totalEncounters);
|
||||
result.put("completedEmr", completedEmr);
|
||||
result.put("overdueEmr", overdueEmr);
|
||||
result.put("completionRate", completionRate);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,24 +26,41 @@ public class TerminalQualityAppServiceImpl implements ITerminalQualityAppService
|
||||
result.put("encounterId", encounterId);
|
||||
result.put("checkTime", new Date());
|
||||
|
||||
// 检查各项指标
|
||||
List<Map<String, Object>> checks = new ArrayList<>();
|
||||
String[] items = {"入院记录24h完成", "首次病程8h完成", "日常病程及时", "出院记录完整", "签名完整"};
|
||||
int passCount = 0;
|
||||
|
||||
List<EmrDefect> defects = defectMapper.selectList(
|
||||
new LambdaQueryWrapper<EmrDefect>()
|
||||
.eq(EmrDefect::getEncounterId, encounterId)
|
||||
.eq(EmrDefect::getDelFlag, "0")
|
||||
.orderByDesc(EmrDefect::getReportTime)
|
||||
);
|
||||
|
||||
Set<String> defectTypes = new HashSet<>();
|
||||
for (EmrDefect d : defects) {
|
||||
if (d.getDefectType() != null) defectTypes.add(d.getDefectType());
|
||||
}
|
||||
boolean hasCritical = defects.stream().anyMatch(d -> "CRITICAL".equals(d.getSeverity()));
|
||||
boolean hasPending = defects.stream().anyMatch(d -> "PENDING".equals(d.getRectifyStatus()));
|
||||
|
||||
for (String item : items) {
|
||||
Map<String, Object> check = new HashMap<>();
|
||||
check.put("item", item);
|
||||
check.put("result", "PASS");
|
||||
boolean passed = true;
|
||||
if ("入院记录24h完成".equals(item) && defectTypes.contains("TIMELY")) passed = false;
|
||||
if ("首次病程8h完成".equals(item) && defectTypes.contains("TIMELY")) passed = false;
|
||||
if ("日常病程及时".equals(item) && defectTypes.contains("TIMELY")) passed = false;
|
||||
if ("出院记录完整".equals(item) && (defectTypes.contains("COMPLETENESS") || hasCritical)) passed = false;
|
||||
if ("签名完整".equals(item) && defectTypes.contains("SIGNATURE")) passed = false;
|
||||
check.put("result", passed ? "PASS" : "FAIL");
|
||||
checks.add(check);
|
||||
passCount++;
|
||||
if (passed) passCount++;
|
||||
}
|
||||
|
||||
// 计算总分
|
||||
BigDecimal score = new BigDecimal(passCount * 20);
|
||||
String grade = calculateGrade(score);
|
||||
|
||||
// 保存评分记录
|
||||
QualityScore qualityScore = new QualityScore();
|
||||
qualityScore.setEncounterId(encounterId);
|
||||
qualityScore.setScore(score);
|
||||
|
||||
Reference in New Issue
Block a user