Selaa lähdekoodia

1.修改规则:加用抗生素未记录、减用抗生素未记录
2.添加规则:抗生素加用原因不明确、抗生素减用原因不明确

huj 5 vuotta sitten
vanhempi
commit
578add4989

+ 196 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03069.java

@@ -0,0 +1,196 @@
+package com.lantone.qc.kernel.catalogue.threelevelward;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.util.CatalogueUtil;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.DoctorAdviceDoc;
+import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
+import com.lantone.qc.pub.model.entity.Drug;
+import com.lantone.qc.pub.model.label.ThreeLevelWardLabel;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * @author HUJING
+ * @create 2020-08-21 10:21
+ * @desc 抗生素加用原因不明确
+ **/
+@Component
+public class THR03069 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
+        List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
+        if (doctorAdviceDocs.size() == 0 || threeLevelWardDocs.size() == 0) {
+            return;
+        }
+        //抗生素及开医嘱时间(包括加用过抗生素的时间)     key:抗生素名    "2020-08-20,2020-08-21 ..."
+        Map<String, List<String>> antibioticDate = Maps.newHashMap();
+        //抗生素加用集合   key:抗生素名    value:  0:未加用,1及以上:加用次数
+        Map<String, Integer> antibioticStatus = Maps.newHashMap();
+        //抗生素及各初始剂量     key:抗生素名    value:抗生素第一次使用时剂量
+        Map<String, Double> antibioticValue = Maps.newHashMap();
+
+        List<Map<String, String>> docAdvStruct = doctorAdviceDocs
+                .stream()
+                .filter(Objects::nonNull)
+                .map(DoctorAdviceDoc::getStructureMap)
+                .filter(x -> StringUtil.isNotBlank(x.get("药品类型")) && x.get("药品类型").contains("抗生素") && StringUtil.isNotBlank(x.get("医嘱单次剂量")))
+                .collect(Collectors.toList());
+
+        docAdvStruct
+                .stream()
+                .map(x -> x.get("医嘱项目名称"))
+                .forEach(y -> antibioticStatus.put(y.replaceAll("[\\[国产\\]\\[进口\\]\\[合信\\]\\[合资\\]]", ""), 0));
+
+        String drugName = null, value = null, startDateStr = null;
+        for (Map<String, String> structMap : docAdvStruct) {
+            drugName = structMap.get("医嘱项目名称");
+            value = structMap.get("医嘱单次剂量");
+            startDateStr = structMap.get("医嘱开始时间");
+            drugName = drugName.replaceAll("[\\[国产\\]\\[进口\\]\\[合信\\]\\[合资\\]]", "");
+            collectAntibioticInfo(antibioticDate, antibioticStatus, antibioticValue, drugName, value, startDateStr);
+        }
+
+        //把抗生素没加用过的抗生素删除
+        for (Map.Entry<String, Integer> as : antibioticStatus.entrySet()) {
+            if (as.getValue() == 0) {
+                antibioticDate.remove(as.getKey());
+            }
+        }
+        //抗生素加用过的集合如果为空,则一个抗生素都没有加用过,直接返回0
+        if (antibioticDate.size() == 0) {
+            return;
+        }
+
+        //查房记录中抗生素及查房时间(包括加用过抗生素的时间)     key:抗生素名    "2020-08-20,2020-08-21 ..."
+        Map<String, List<String>> antibioticDateWard = Maps.newHashMap();
+        //查房记录中抗生素加用集合   key:抗生素名    value:  0:未加用,1及以上:加用次数
+        Map<String, Integer> antibioticStatusWard = Maps.newHashMap();
+        //查房记录中抗生素及各初始剂量     key:抗生素名    value:抗生素第一次使用时剂量
+        Map<String, Double> antibioticValueWard = Maps.newHashMap();
+        List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDocs.get(0).getAllDoctorWradDocs();
+        for (ThreeLevelWardDoc doc : allDoctorWradDocs) {
+            if (doc.getThreeLevelWardLabel().size() == 0) {
+                continue;
+            }
+            ThreeLevelWardLabel label = doc.getThreeLevelWardLabel().get(0);
+            List<Drug> drugs = label.getDrugs();
+            for (Drug drug : drugs) {
+                //药品用量和使用原因都有时
+                if (drug.getConsumption() != null) {
+                    //查房记录抗生素加用过的集合中没包含该抗生素,则认为该抗生素是第一次出现,此时不需要加用原因
+                    if (!antibioticStatusWard.containsKey(drug.getName()) || drug.getUsageWardRound() != null) {
+                        String consumption = drug.getConsumption().getName();
+                        collectAntibioticInfo(antibioticDateWard, antibioticStatusWard, antibioticValueWard, drug.getName(), consumption, doc.getStructureMap().get("查房日期"));
+                    }
+                }
+            }
+        }
+        //把查房记录中没加用过的抗生素删除
+        for (Map.Entry<String, Integer> as : antibioticStatusWard.entrySet()) {
+            if (as.getValue() == 0) {
+                antibioticDateWard.remove(as.getKey());
+            }
+        }
+
+        /**
+         * 1.antibioticDate:从医嘱中取   key:抗生素名    value:医嘱中该抗生素所有加用时的时间(包括初始使用时间)
+         * 2.antibioticDateWard:从查房记录中取     key:抗生素名    value:查房记录中该抗生素所有已加用并且该抗生素有加用原因的查房时间(包括初始使用时间)
+         * 3.医嘱中该抗生素初始使用时间往后两天内,查房记录中该抗生素初始使用时间也在这两天内,则满足一半。
+         * 4.医嘱中该抗生素加用时的时间往后两天内,查房记录中该抗生素加用时间也在这两天内,则满足条件,该抗生素通过该条规则
+         * 5.继续判断下一个抗生素
+         * 6.若医嘱中加用过的抗生素,查房记录中没出现过,则该抗生素会报出来(存入miss,规则最后会把所有不符合的抗生素都报出来)
+         */
+        List<String> miss = Lists.newArrayList();
+        String drugKey = null, start = null, change = null, wardStartStr = null, wardChangeStr = null;
+        List<String> dateList = null;
+        for (Map.Entry<String, List<String>> ad : antibioticDate.entrySet()) {
+            drugKey = ad.getKey();
+            if (!antibioticDateWard.containsKey(drugKey)) {
+                miss.add(drugKey);
+                continue;
+            }
+            dateList = ad.getValue();
+            int matchNum = 0;
+            for (int i = 0; i < dateList.size() - 1; i++) {
+                start = dateList.get(i);        //抗生素开医嘱时间
+                change = dateList.get(i + 1);   //抗生素用量改变时间
+                Date adStart = StringUtil.parseDateTime(start);
+                Date adChange = StringUtil.parseDateTime(change);
+                List<String> wardDateStr = antibioticDateWard.get(drugKey);
+                for (int j = 0; j < wardDateStr.size() - 1; j++) {
+                    wardStartStr = wardDateStr.get(j);         //查房记录开抗生素时间
+                    wardChangeStr = wardDateStr.get(j + 1);    //查房记录改变抗生素用量时间
+                    Date wardStart = StringUtil.parseDateTime(wardStartStr);
+                    Date wardChange = StringUtil.parseDateTime(wardChangeStr);
+                    if (!CatalogueUtil.compareTime(adStart, wardStart, 48 * 60L) && !CatalogueUtil.compareTime(adChange, wardChange, 48 * 60L)) {
+                        matchNum++;
+                    }
+                }
+            }
+            if (dateList.size() - 1 != matchNum) {
+                miss.add(drugKey);
+            }
+        }
+
+        if (miss.size() > 0) {
+            status.set("-1");
+            info.set(miss.toString().replaceAll("[\\[\\]]", ""));
+        }
+    }
+
+    /**
+     * 收集抗生素各种信息
+     *
+     * @param antibioticDate   抗生素使用所有时间
+     * @param antibioticStatus 抗生素用量改变状态
+     * @param antibioticValue  抗生素及用量
+     * @param drugName         抗生素名称
+     * @param value            抗生素用量
+     * @param startDateStr     抗生素使用时间(医嘱开始时间或查房时间)
+     */
+    private void collectAntibioticInfo(Map<String, List<String>> antibioticDate, Map<String, Integer> antibioticStatus, Map<String, Double> antibioticValue, String drugName, String value, String startDateStr) {
+        double v = -1;
+        try {
+            v = Double.parseDouble(getNumber(value));
+        } catch (Exception e) {
+            System.out.println("THR03069:       " + drugName + ":" + value + "解析异常");
+        }
+        if (!antibioticValue.containsKey(drugName) && v > 0) {
+            antibioticValue.put(drugName, v);
+            antibioticDate.put(drugName, Lists.newArrayList(startDateStr));
+            antibioticStatus.put(drugName, 0);
+        } else {
+            double beforeValue = antibioticValue.get(drugName);
+            if (beforeValue < v) {
+                antibioticValue.put(drugName, v);//更新该抗生素使用值为更大的值
+                antibioticStatus.put(drugName, antibioticStatus.get(drugName) + 1);
+                antibioticDate.get(drugName).add(startDateStr);
+            }
+        }
+    }
+
+    public static String getNumber(String content) {
+        String group = "";
+        String compile = "([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9]|\\.\\d*[1-9]|0)";
+        Pattern p = Pattern.compile(compile);
+        Matcher matcher = p.matcher(content);
+        if (matcher.find()) {
+            group = matcher.group(0);
+        }
+        return group;
+    }
+
+}

+ 196 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03072.java

@@ -0,0 +1,196 @@
+package com.lantone.qc.kernel.catalogue.threelevelward;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.util.CatalogueUtil;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.DoctorAdviceDoc;
+import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
+import com.lantone.qc.pub.model.entity.Drug;
+import com.lantone.qc.pub.model.label.ThreeLevelWardLabel;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * @author HUJING
+ * @create 2020-08-21 10:21
+ * @desc 抗生素减用原因不明确
+ **/
+@Component
+public class THR03072 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
+        List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
+        if (doctorAdviceDocs.size() == 0 || threeLevelWardDocs.size() == 0) {
+            return;
+        }
+        //抗生素及开医嘱时间(包括减用过抗生素的时间)     key:抗生素名    "2020-08-20,2020-08-21 ..."
+        Map<String, List<String>> antibioticDate = Maps.newHashMap();
+        //抗生素减用集合   key:抗生素名    value:  0:未减用,1及以上:减用次数
+        Map<String, Integer> antibioticStatus = Maps.newHashMap();
+        //抗生素及各初始剂量     key:抗生素名    value:抗生素第一次使用时剂量
+        Map<String, Double> antibioticValue = Maps.newHashMap();
+
+        List<Map<String, String>> docAdvStruct = doctorAdviceDocs
+                .stream()
+                .filter(Objects::nonNull)
+                .map(DoctorAdviceDoc::getStructureMap)
+                .filter(x -> StringUtil.isNotBlank(x.get("药品类型")) && x.get("药品类型").contains("抗生素") && StringUtil.isNotBlank(x.get("医嘱单次剂量")))
+                .collect(Collectors.toList());
+
+        docAdvStruct
+                .stream()
+                .map(x -> x.get("医嘱项目名称"))
+                .forEach(y -> antibioticStatus.put(y.replaceAll("[\\[国产\\]\\[进口\\]\\[合信\\]\\[合资\\]]", ""), 0));
+
+        String drugName = null, value = null, startDateStr = null;
+        for (Map<String, String> structMap : docAdvStruct) {
+            drugName = structMap.get("医嘱项目名称");
+            value = structMap.get("医嘱单次剂量");
+            startDateStr = structMap.get("医嘱开始时间");
+            drugName = drugName.replaceAll("[\\[国产\\]\\[进口\\]\\[合信\\]\\[合资\\]]", "");
+            collectAntibioticInfo(antibioticDate, antibioticStatus, antibioticValue, drugName, value, startDateStr);
+        }
+
+        //把抗生素没减用过的抗生素删除
+        for (Map.Entry<String, Integer> as : antibioticStatus.entrySet()) {
+            if (as.getValue() == 0) {
+                antibioticDate.remove(as.getKey());
+            }
+        }
+        //抗生素减用过的集合如果为空,则一个抗生素都没有减用过,直接返回0
+        if (antibioticDate.size() == 0) {
+            return;
+        }
+
+        //查房记录中抗生素及查房时间(包括减用过抗生素的时间)     key:抗生素名    "2020-08-20,2020-08-21 ..."
+        Map<String, List<String>> antibioticDateWard = Maps.newHashMap();
+        //查房记录中抗生素减用集合   key:抗生素名    value:  0:未减用,1及以上:减用次数
+        Map<String, Integer> antibioticStatusWard = Maps.newHashMap();
+        //查房记录中抗生素及各初始剂量     key:抗生素名    value:抗生素第一次使用时剂量
+        Map<String, Double> antibioticValueWard = Maps.newHashMap();
+        List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDocs.get(0).getAllDoctorWradDocs();
+        for (ThreeLevelWardDoc doc : allDoctorWradDocs) {
+            if (doc.getThreeLevelWardLabel().size() == 0) {
+                continue;
+            }
+            ThreeLevelWardLabel label = doc.getThreeLevelWardLabel().get(0);
+            List<Drug> drugs = label.getDrugs();
+            for (Drug drug : drugs) {
+                //药品用量和使用原因都有时
+                if (drug.getConsumption() != null) {
+                    //查房记录抗生素减用过的集合中没包含该抗生素,则认为该抗生素是第一次出现,此时不需要减用原因
+                    if (!antibioticStatusWard.containsKey(drug.getName()) || drug.getUsageWardRound() != null) {
+                        String consumption = drug.getConsumption().getName();
+                        collectAntibioticInfo(antibioticDateWard, antibioticStatusWard, antibioticValueWard, drug.getName(), consumption, doc.getStructureMap().get("查房日期"));
+                    }
+                }
+            }
+        }
+        //把查房记录中没减用过的抗生素删除
+        for (Map.Entry<String, Integer> as : antibioticStatusWard.entrySet()) {
+            if (as.getValue() == 0) {
+                antibioticDateWard.remove(as.getKey());
+            }
+        }
+
+        /**
+         * 1.antibioticDate:从医嘱中取   key:抗生素名    value:医嘱中该抗生素所有减用时的时间(包括初始使用时间)
+         * 2.antibioticDateWard:从查房记录中取     key:抗生素名    value:查房记录中该抗生素所有已减用并且该抗生素有减用原因的查房时间(包括初始使用时间)
+         * 3.医嘱中该抗生素初始使用时间往后两天内,查房记录中该抗生素初始使用时间也在这两天内,则满足一半。
+         * 4.医嘱中该抗生素减用时的时间往后两天内,查房记录中该抗生素减用时间也在这两天内,则满足条件,该抗生素通过该条规则
+         * 5.继续判断下一个抗生素
+         * 6.若医嘱中减用过的抗生素,查房记录中没出现过,则该抗生素会报出来(存入miss,规则最后会把所有不符合的抗生素都报出来)
+         */
+        List<String> miss = Lists.newArrayList();
+        String drugKey = null, start = null, change = null, wardStartStr = null, wardChangeStr = null;
+        List<String> dateList = null;
+        for (Map.Entry<String, List<String>> ad : antibioticDate.entrySet()) {
+            drugKey = ad.getKey();
+            if (!antibioticDateWard.containsKey(drugKey)) {
+                miss.add(drugKey);
+                continue;
+            }
+            dateList = ad.getValue();
+            int matchNum = 0;
+            for (int i = 0; i < dateList.size() - 1; i++) {
+                start = dateList.get(i);        //抗生素开医嘱时间
+                change = dateList.get(i + 1);   //抗生素用量改变时间
+                Date adStart = StringUtil.parseDateTime(start);
+                Date adChange = StringUtil.parseDateTime(change);
+                List<String> wardDateStr = antibioticDateWard.get(drugKey);
+                for (int j = 0; j < wardDateStr.size() - 1; j++) {
+                    wardStartStr = wardDateStr.get(j);         //查房记录开抗生素时间
+                    wardChangeStr = wardDateStr.get(j + 1);    //查房记录改变抗生素用量时间
+                    Date wardStart = StringUtil.parseDateTime(wardStartStr);
+                    Date wardChange = StringUtil.parseDateTime(wardChangeStr);
+                    if (!CatalogueUtil.compareTime(adStart, wardStart, 48 * 60L) && !CatalogueUtil.compareTime(adChange, wardChange, 48 * 60L)) {
+                        matchNum++;
+                    }
+                }
+            }
+            if (dateList.size() - 1 != matchNum) {
+                miss.add(drugKey);
+            }
+        }
+
+        if (miss.size() > 0) {
+            status.set("-1");
+            info.set(miss.toString().replaceAll("[\\[\\]]", ""));
+        }
+    }
+
+    /**
+     * 收集抗生素各种信息
+     *
+     * @param antibioticDate   抗生素使用所有时间
+     * @param antibioticStatus 抗生素用量改变状态
+     * @param antibioticValue  抗生素及用量
+     * @param drugName         抗生素名称
+     * @param value            抗生素用量
+     * @param startDateStr     抗生素使用时间(医嘱开始时间或查房时间)
+     */
+    private void collectAntibioticInfo(Map<String, List<String>> antibioticDate, Map<String, Integer> antibioticStatus, Map<String, Double> antibioticValue, String drugName, String value, String startDateStr) {
+        double v = -1;
+        try {
+            v = Double.parseDouble(getNumber(value));
+        } catch (Exception e) {
+            System.out.println("THR03072:       " + drugName + ":" + value + "解析异常");
+        }
+        if (!antibioticValue.containsKey(drugName) && v > 0) {
+            antibioticValue.put(drugName, v);
+            antibioticDate.put(drugName, Lists.newArrayList(startDateStr));
+            antibioticStatus.put(drugName, 0);
+        } else {
+            double beforeValue = antibioticValue.get(drugName);
+            if (beforeValue > v) {
+                antibioticValue.put(drugName, v);//更新该抗生素使用值为更小的值
+                antibioticStatus.put(drugName, antibioticStatus.get(drugName) + 1);
+                antibioticDate.get(drugName).add(startDateStr);
+            }
+        }
+    }
+
+    public static String getNumber(String content) {
+        String group = "";
+        String compile = "([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9]|\\.\\d*[1-9]|0)";
+        Pattern p = Pattern.compile(compile);
+        Matcher matcher = p.matcher(content);
+        if (matcher.find()) {
+            group = matcher.group(0);
+        }
+        return group;
+    }
+
+}

+ 10 - 1
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03074.java

@@ -63,7 +63,7 @@ public class THR03074 extends QCCatalogue {
             collectAntibioticInfo(antibioticDate, antibioticStatus, antibioticValue, drugName, value, startDateStr);
         }
 
-        //把抗生素没加用过的抗生素塞进抗生素加用过的集合
+        //把抗生素没加用过的抗生素删除
         for (Map.Entry<String, Integer> as : antibioticStatus.entrySet()) {
             if (as.getValue() == 0) {
                 antibioticDate.remove(as.getKey());
@@ -101,6 +101,14 @@ public class THR03074 extends QCCatalogue {
             }
         }
 
+        /**
+         * 1.antibioticDate:从医嘱中取   key:抗生素名    value:医嘱中该抗生素所有加用时的时间(包括初始使用时间)
+         * 2.antibioticDateWard:从查房记录中取     key:抗生素名    value:查房记录中该抗生素所有加用时的查房时间(包括初始使用时间)
+         * 3.医嘱中该抗生素初始使用时间往后两天内,查房记录中该抗生素初始使用时间也在这两天内,则满足一半。
+         * 4.医嘱中该抗生素加用时的时间往后两天内,查房记录中该抗生素加用时间也在这两天内,则满足条件,该抗生素通过该条规则
+         * 5.继续判断下一个抗生素
+         * 6.若医嘱中加用过的抗生素,查房记录中没出现过,则该抗生素会报出来(存入miss,规则最后会把所有不符合的抗生素都报出来)
+         */
         List<String> miss = Lists.newArrayList();
         String drugKey = null, start = null, change = null, wardStartStr = null, wardChangeStr = null;
         List<String> dateList = null;
@@ -159,6 +167,7 @@ public class THR03074 extends QCCatalogue {
         if (!antibioticValue.containsKey(drugName) && v > 0) {
             antibioticValue.put(drugName, v);
             antibioticDate.put(drugName, Lists.newArrayList(startDateStr));
+            antibioticStatus.put(drugName, 0);
         } else {
             double beforeValue = antibioticValue.get(drugName);
             if (beforeValue < v) {

+ 3 - 2
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03075.java

@@ -63,7 +63,7 @@ public class THR03075 extends QCCatalogue {
             collectAntibioticInfo(antibioticDate, antibioticStatus, antibioticValue, drugName, value, startDateStr);
         }
 
-        //把抗生素没减用过的抗生素塞进抗生素减用过的集合
+        //把抗生素没减用过的抗生素删除
         for (Map.Entry<String, Integer> as : antibioticStatus.entrySet()) {
             if (as.getValue() == 0) {
                 antibioticDate.remove(as.getKey());
@@ -154,11 +154,12 @@ public class THR03075 extends QCCatalogue {
         try {
             v = Double.parseDouble(getNumber(value));
         } catch (Exception e) {
-            System.out.println("THR03074:       " + drugName + ":" + value + "解析异常");
+            System.out.println("THR03075:       " + drugName + ":" + value + "解析异常");
         }
         if (!antibioticValue.containsKey(drugName) && v > 0) {
             antibioticValue.put(drugName, v);
             antibioticDate.put(drugName, Lists.newArrayList(startDateStr));
+            antibioticStatus.put(drugName, 0);
         } else {
             double beforeValue = antibioticValue.get(drugName);
             if (beforeValue > v) {