瀏覽代碼

义乌妇保:乳腺良性肿瘤年龄和性别规则

yuchengwei 4 月之前
父節點
當前提交
062f3a26e6

+ 144 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/yiwu/firstpagerecord/FIRP03260.java

@@ -0,0 +1,144 @@
+package com.lantone.qc.kernel.catalogue.hospital.yiwu.firstpagerecord;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.util.CatalogueUtil;
+import com.lantone.qc.pub.Content;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @ClassName : FIRP03260
+ * @Description : 首页-专病-主诊断-年龄-不符 乳腺良性肿瘤年龄年龄应大于28天小于14周岁错误
+ */
+@Component
+public class FIRP03260 extends QCCatalogue {
+
+    // 增强版正则表达式,支持组合单位和更多书写形式
+    private static final Pattern AGE_PATTERN = Pattern.compile(
+            "(\\d+\\.?\\d*)\\s*([岁年yY]|个?月|m|M|天|日|d|D)(?=\\s*(?:\\d|$))"
+    );
+
+    // 单位转换基准(医疗常用标准)
+    private static final double MONTHS_PER_YEAR = 12.0;
+
+    private static final double DAYS_PER_MONTH = 30.0;
+    private static final double DAYS_PER_YEAR = 365.2425; // 格里高利年平均值
+
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        if (inputInfo.getFirstPageRecordDoc() != null && inputInfo.getFirstPageRecordDoc().getStructureExtMap() != null) {
+            Map<String, Object> firstpageStructureMap = inputInfo.getFirstPageRecordDoc().getStructureExtMap();
+            List<Map<String, String>> outpatientEmergencyDiagList = (List) firstpageStructureMap.get(Content.dischargeDiag);
+            if (ListUtil.isEmpty(outpatientEmergencyDiagList)) {
+                return;
+            }
+            List<String> firstpageDischargeDiag = getFirstpageDischargeDiag(outpatientEmergencyDiagList);
+            if (!firstpageDischargeDiag.contains("包茎")) {
+                return;
+            }
+            String admissionAge = (String)firstpageStructureMap.get(Content.age);
+            if (!isUnder14Years(admissionAge) || isUnder28Days(admissionAge)) {
+                status.set("-1");
+                info.set("患者年龄:" + admissionAge);
+                String xmlId = CatalogueUtil.getXmlId(firstpageStructureMap, Content.age);
+                id.set(xmlId);
+            }
+        }
+    }
+
+    private List<String> getFirstpageDischargeDiag(List<Map<String, String>> outpatientEmergencyDiagList) {
+        List<String> firstpageDischargeDiag = new ArrayList<>();
+        for (Map<String, String> outpatientEmergencyDiag : outpatientEmergencyDiagList) {
+            String diag = outpatientEmergencyDiag.get(Content.diagnoseName);
+            if (StringUtil.isNotBlank(diag)) {
+                firstpageDischargeDiag.add(diag);
+            }
+        }
+        return firstpageDischargeDiag;
+    }
+
+    public static boolean isUnder14Years(String ageString) {
+        if (ageString == null || ageString.trim().isEmpty()) {
+            return false;
+        }
+
+        double totalYears = 0.0;
+        Matcher matcher = AGE_PATTERN.matcher(ageString);
+
+        while (matcher.find()) {
+            try {
+                double value = Double.parseDouble(matcher.group(1));
+                String unit = normalizeUnit(matcher.group(2));
+
+                switch (unit) {
+                    case "year":
+                        totalYears += value;
+                        break;
+                    case "month":
+                        totalYears += value / MONTHS_PER_YEAR;
+                        break;
+                    case "day":
+                        totalYears += value / DAYS_PER_YEAR;
+                        break;
+                }
+            } catch (NumberFormatException e) {
+                // 记录无效数值日志
+            }
+        }
+
+        // 四舍五入保留4位小数处理精度问题
+        return Math.round(totalYears * 10000.0) / 10000.0 < 14.0;
+    }
+
+    public static boolean isUnder28Days(String ageString) {
+        if (ageString == null || ageString.trim().isEmpty()) {
+            return false; // 无效输入处理
+        }
+
+        double totalDays = 0.0;
+        Matcher matcher = AGE_PATTERN.matcher(ageString);
+
+        while (matcher.find()) {
+            try {
+                double value = Double.parseDouble(matcher.group(1));
+                String unit = matcher.group(2).toLowerCase();
+
+                switch (unit) {
+                    case "年": case "岁": case "y":
+                        totalDays += value * DAYS_PER_YEAR;
+                        break;
+                    case "个月": case "月": case "m":
+                        totalDays += value * DAYS_PER_MONTH;
+                        break;
+                    case "天": case "日": case "d":
+                        totalDays += value;
+                        break;
+                    // 可扩展周等单位
+                }
+            } catch (NumberFormatException e) {
+                // 记录日志或处理异常数值
+            }
+        }
+
+        // 精确浮点数比较(保留两位小数)
+        return Math.round(totalDays * 100) / 100.0 <= 28.0;
+    }
+
+    // 单位标准化方法
+    private static String normalizeUnit(String rawUnit) {
+        String unit = rawUnit.toLowerCase();
+        if (unit.matches("[岁年y]")) return "year";
+        if (unit.matches("个?月|m")) return "month";
+        if (unit.matches("[天日d]")) return "day";
+        return "unknown";
+    }
+}

+ 56 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/yiwu/firstpagerecord/FIRP03261.java

@@ -0,0 +1,56 @@
+package com.lantone.qc.kernel.catalogue.hospital.yiwu.firstpagerecord;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.util.CatalogueUtil;
+import com.lantone.qc.pub.Content;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : FIRP03261
+ * @Description : 首页-专病-主诊断-性别-不符 乳腺良性肿瘤性别不应为男性错误
+ */
+@Component
+public class FIRP03261 extends QCCatalogue {
+
+    private List<String> genderList = Lists.newArrayList("男", "男性", "1", "1男", "1男性", "1.男");
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        if (inputInfo.getFirstPageRecordDoc() != null && inputInfo.getFirstPageRecordDoc().getStructureExtMap() != null) {
+            Map<String, Object> firstpageStructureMap = inputInfo.getFirstPageRecordDoc().getStructureExtMap();
+            List<Map<String, String>> outpatientEmergencyDiagList = (List) firstpageStructureMap.get(Content.dischargeDiag);
+            if (ListUtil.isEmpty(outpatientEmergencyDiagList)) {
+                return;
+            }
+            List<String> firstpageDischargeDiag = getFirstpageDischargeDiag(outpatientEmergencyDiagList);
+            if (!firstpageDischargeDiag.contains("乳腺良性肿瘤")) {
+                return;
+            }
+            String gender = (String)firstpageStructureMap.get(Content.gender);
+            if (genderList.contains(gender)) {
+                status.set("-1");
+                info.set("患者性别:" + gender);
+                String xmlId = CatalogueUtil.getXmlId(firstpageStructureMap, Content.gender);
+                id.set(xmlId);
+            }
+        }
+    }
+    private List<String> getFirstpageDischargeDiag(List<Map<String, String>> outpatientEmergencyDiagList) {
+        List<String> firstpageDischargeDiag = new ArrayList<>();
+        for (Map<String, String> outpatientEmergencyDiag : outpatientEmergencyDiagList) {
+            String diag = outpatientEmergencyDiag.get(Content.diagnoseName);
+            if (StringUtil.isNotBlank(diag)) {
+                firstpageDischargeDiag.add(diag);
+            }
+        }
+        return firstpageDischargeDiag;
+    }
+}