From 29c0fcda9fc14dbc0093a8fcc6b0a332b19b4320 Mon Sep 17 00:00:00 2001 From: chenqi Date: Thu, 18 Jun 2026 21:34:03 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=89=A9=E4=BD=99MEDI?= =?UTF-8?q?UM/LOW=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../appservice/impl/CdssAppServiceImpl.java | 58 ++++++++++++++++++- .../impl/RegionalShareAppServiceImpl.java | 6 +- .../impl/InfectionEnhancedAppServiceImpl.java | 2 +- .../InfectionScreeningAppServiceImpl.java | 2 +- .../TargetedSurveillanceAppServiceImpl.java | 2 +- .../impl/EmrQualityAppServiceImpl.java | 50 +++++++++++++++- .../impl/TerminalQualityAppServiceImpl.java | 27 +++++++-- 7 files changed, 135 insertions(+), 12 deletions(-) diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/cdss/appservice/impl/CdssAppServiceImpl.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/cdss/appservice/impl/CdssAppServiceImpl.java index 84bd67882..e536f0d1a 100644 --- a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/cdss/appservice/impl/CdssAppServiceImpl.java +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/cdss/appservice/impl/CdssAppServiceImpl.java @@ -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) { diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/esbmanage/appservice/impl/RegionalShareAppServiceImpl.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/esbmanage/appservice/impl/RegionalShareAppServiceImpl.java index a12b36aea..f01ae7a40 100644 --- a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/esbmanage/appservice/impl/RegionalShareAppServiceImpl.java +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/esbmanage/appservice/impl/RegionalShareAppServiceImpl.java @@ -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"); diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/InfectionEnhancedAppServiceImpl.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/InfectionEnhancedAppServiceImpl.java index 27539a868..692602b91 100644 --- a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/InfectionEnhancedAppServiceImpl.java +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/InfectionEnhancedAppServiceImpl.java @@ -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) { diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/InfectionScreeningAppServiceImpl.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/InfectionScreeningAppServiceImpl.java index 7355cb880..2ee2a56ac 100644 --- a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/InfectionScreeningAppServiceImpl.java +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/InfectionScreeningAppServiceImpl.java @@ -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; } diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/TargetedSurveillanceAppServiceImpl.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/TargetedSurveillanceAppServiceImpl.java index 13d98601c..2ffc55c2c 100644 --- a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/TargetedSurveillanceAppServiceImpl.java +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/infection/appservice/impl/TargetedSurveillanceAppServiceImpl.java @@ -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) { diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/quality/appservice/impl/EmrQualityAppServiceImpl.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/quality/appservice/impl/EmrQualityAppServiceImpl.java index 98a19b044..bd20d4021 100644 --- a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/quality/appservice/impl/EmrQualityAppServiceImpl.java +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/quality/appservice/impl/EmrQualityAppServiceImpl.java @@ -32,9 +32,22 @@ public class EmrQualityAppServiceImpl implements IEmrQualityAppService { List> checks = new ArrayList<>(); String[] items = {"入院记录24h完成", "首次病程8h完成", "日常病程及时", "出院记录完整", "签名完整"}; int pass = 0; + List defects = defectMapper.selectList(new LambdaQueryWrapper() + .eq(EmrDefect::getEncounterId, encounterId).eq(EmrDefect::getDelFlag, "0")); + Set defectTypes = new HashSet<>(); + for (EmrDefect d : defects) { + if (d.getDefectType() != null) defectTypes.add(d.getDefectType()); + } for (String item : items) { Map 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 getCompletionRate(String startDate, String endDate) { + LambdaQueryWrapper 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 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 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 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; } diff --git a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/quality/appservice/impl/TerminalQualityAppServiceImpl.java b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/quality/appservice/impl/TerminalQualityAppServiceImpl.java index b3b7b6453..8cbf72520 100644 --- a/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/quality/appservice/impl/TerminalQualityAppServiceImpl.java +++ b/healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/quality/appservice/impl/TerminalQualityAppServiceImpl.java @@ -26,24 +26,41 @@ public class TerminalQualityAppServiceImpl implements ITerminalQualityAppService result.put("encounterId", encounterId); result.put("checkTime", new Date()); - // 检查各项指标 List> checks = new ArrayList<>(); String[] items = {"入院记录24h完成", "首次病程8h完成", "日常病程及时", "出院记录完整", "签名完整"}; int passCount = 0; + List defects = defectMapper.selectList( + new LambdaQueryWrapper() + .eq(EmrDefect::getEncounterId, encounterId) + .eq(EmrDefect::getDelFlag, "0") + .orderByDesc(EmrDefect::getReportTime) + ); + + Set 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 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);