Browse Source

1.规则基类添加属性:extData,用于记录规则执行完需要保留的信息,以供给下一条规则使用这些信息
2.病程记录中CRF提取的抗生素,若抗生素前10个字包含“暂停”,则不保存该抗生素
3.2985,3076,3077规则一天内同一抗生素开过多次的抗生素直接过滤
4.3076,3077规则中要处理的抗生素,基于2985未记录的抗生素过滤

huj 4 years ago
parent
commit
3fbe00b8f0

+ 2 - 2
kernel/src/main/java/com/lantone/qc/kernel/analysis/QCAnalysis.java

@@ -68,8 +68,8 @@ public class QCAnalysis {
         log.error(queryVo.getBehospitalInfo().getBehospitalCode() + "-----" + "所有规则  耗时:" + (t4 - t3));
 
         outputInfo.setPageData(inputInfo.getPageData());
-        Map<String, Map<String, String>> result = outputInfo.getResult();
-        Map<String, Map<String, String>> resultNew = Maps.newHashMap();
+        Map<String, Map<String, Object>> result = outputInfo.getResult();
+        Map<String, Map<String, Object>> resultNew = Maps.newHashMap();
         result.keySet().forEach(key -> {
             if (result.get(key).get("status").equals("-1")) {
                 resultNew.put(key, result.get(key));

+ 5 - 2
kernel/src/main/java/com/lantone/qc/kernel/catalogue/QCCatalogue.java

@@ -21,6 +21,7 @@ public class QCCatalogue {
 
     protected ThreadLocal<String> status = new ThreadLocal<String>();
     protected ThreadLocal<String> info = new ThreadLocal<String>();
+    protected ThreadLocal<Map<Object, Object>> extData = new ThreadLocal<Map<Object, Object>>();
 
     public void execute(InputInfo inputInfo, OutputInfo outputInfo) {
 //        long t1 = System.currentTimeMillis();
@@ -29,7 +30,7 @@ public class QCCatalogue {
         }
         if (!precondExecute(inputInfo, outputInfo)) {
             variablePreset("-2", "");
-            return;
+            //return;
         }
         try {
             variablePreset("-1", "");
@@ -44,12 +45,14 @@ public class QCCatalogue {
     }
 
     private void insertOpt(OutputInfo outputInfo) {
-        Map<String, String> resultDetail = Maps.newHashMap();
+        Map<String, Object> resultDetail = Maps.newHashMap();
         resultDetail.put("info", info.get());
         resultDetail.put("status", status.get());
+        resultDetail.put("extData", extData.get());
         outputInfo.getResult().put(className, resultDetail);
         status.remove();
         info.remove();
+        extData.remove();
     }
 
     private void variablePreset(String arg0, String arg1) {

+ 77 - 22
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR02985.java

@@ -64,27 +64,34 @@ public class THR02985 extends QCCatalogue {
         if (allDoctorWradDocs.size() == 0) {
             return;
         }
+        List<Map<String, String>> docAdvStruct = doctorAdviceDocs
+                .stream()
+                .filter(Objects::nonNull)
+                .map(DoctorAdviceDoc::getStructureMap)
+                .filter(x -> StringUtil.isNotBlank(x.get("药品类型")) && x.get("药品类型").contains("抗生素"))
+                .filter(x -> StringUtil.isNotBlank(x.get("医嘱状态判别")) && !x.get("医嘱状态判别").contains("已停止"))
+                .filter(x -> StringUtil.isNotBlank(x.get("给药方式")) && x.get("给药方式").contains("静脉滴注"))
+                .filter(x -> StringUtil.isNotBlank(x.get("医嘱频率")) && !x.get("医嘱频率").equals("ONCE"))
+                .collect(Collectors.toList());
+
+        //记录同一天内是否开过多次同一抗生素
+        Map<String, Map<Date, Integer>> antibioticDateTimes = Maps.newHashMap();
+        //记录同一抗生素同一天内是否开过多次,用于医嘱中需要处理的抗生素过滤(一天内同一抗生素开过多次的抗生素直接过滤)
+        getAntibioticTimes(docAdvStruct, antibioticDateTimes);
         Map<Date, String> doctorAdviceDrugMap = Maps.newLinkedHashMap();
-        for (DoctorAdviceDoc adviceDoc : doctorAdviceDocs) {
-            Map<String, String> adviceDocStructureMap = adviceDoc.getStructureMap();
-            String name = adviceDocStructureMap.get("医嘱项目名称");
-            String drugCategory = adviceDocStructureMap.get("药品类型");
-            String startDateStr = adviceDocStructureMap.get("医嘱开始时间");
-            if (StringUtil.isNotBlank(drugCategory) && drugCategory.contains("抗生素")) {
-                if (StringUtil.isNotBlank(name)) {
-                    if (Arrays.asList(KSS).contains(name)) {
-                        continue;
-                    }
-                    name = name.replaceAll("[针]", "");
-                    if (name.contains(" ")) {
-                        name = name.split(" ")[0];
-                    }
-                    Date startDate = StringUtil.parseDateTime(startDateStr);
-                    if (startDate != null) {
-                        startDate = DateUtil.dateZeroClear(startDate);
-                        doctorAdviceDrugMap.put(startDate, name);
-                    }
+        Date startDate = null;
+        for (Map<String, String> adviceDoc : docAdvStruct) {
+            String drugName = adviceDoc.get("医嘱项目名称");
+            String startDateStr = adviceDoc.get("医嘱开始时间");
+            if (StringUtil.isNotBlank(drugName)) {
+                if (Arrays.asList(KSS).contains(drugName)) {
+                    continue;
+                }
+                startDate = DateUtil.dateZeroClear(StringUtil.parseDateTime(startDateStr));
+                if (antibioticDateTimes.get(drugName).get(startDate) > 0) {
+                    continue;   //一天内同一抗生素开过多次的抗生素直接过滤
                 }
+                doctorAdviceDrugMap.put(startDate, drugName);
             }
         }
 
@@ -163,10 +170,15 @@ public class THR02985 extends QCCatalogue {
             }
         }
 
+        StringBuffer sb = new StringBuffer();
+        Map<Object, Object> data = Maps.newHashMap();
         String infoStr = "";
         for (Map.Entry<Date, String> doctorAdviceDrug : doctorAdviceDrugMap.entrySet()) {
             Date doctorAdviceDate = doctorAdviceDrug.getKey();
             String drugs = doctorAdviceDrug.getValue();
+            if (drugs.contains(" ")) {
+                drugs = drugs.split(" ")[0];
+            }
             drugs = removeBracket(drugs).replaceAll("[^\u4e00-\u9fa5]", "");
             Set<String> splitDrugs = CatalogueUtil.getRegexWords(drugs, "[((\\[][^\\[\\]()()]+[\\]))]")
                     .stream().filter(x -> !x.equals("合资") && !x.equals("进口") && !x.equals("国产")).collect(Collectors.toSet());
@@ -206,12 +218,44 @@ public class THR02985 extends QCCatalogue {
             }
 
             if (StringUtil.isNotBlank(missDrug) && !modelFind && CatalogueUtil.compareTime(doctorAdviceDate, new Date(), 48 * 60L)) {
-                infoStr = CatalogueUtil.concatInfo(infoStr, splitDrugs.toString().replaceAll("[\\[\\]]", "") + "(" + DateUtil.formatDate(doctorAdviceDate) + ")");
+                infoAppend(sb, splitDrugs.toString().replaceAll("[\\[\\]]", ""), DateUtil.formatDate(doctorAdviceDate));
+                data.put(doctorAdviceDate, splitDrugs.toString().replaceAll("[\\[\\]]", ""));
             }
         }
-        if (StringUtil.isNotBlank(infoStr)) {
+        if (StringUtil.isNotBlank(sb.toString())) {
             this.status.set("-1");
-            this.info.set(infoStr);
+            this.info.set("医嘱:" + sb.toString().substring(0, sb.toString().length() - 1));
+            extData.set(data);
+        }
+    }
+
+    /**
+     * 记录同一抗生素同一天内是否开过多次,用于医嘱中需要处理的抗生素过滤(一天内同一抗生素开过多次的抗生素直接过滤)
+     *
+     * @param docAdvStruct
+     * @param antibioticDateTimes
+     */
+    private void getAntibioticTimes(List<Map<String, String>> docAdvStruct, Map<String, Map<Date, Integer>> antibioticDateTimes) {
+        String drugName;
+        String startDateStr;
+        Date startDate;
+        Map<Date, Integer> antibioticDateTime;
+        for (Map<String, String> structMap : docAdvStruct) {
+            drugName = structMap.get("医嘱项目名称");
+            startDateStr = structMap.get("医嘱开始时间");
+            startDate = DateUtil.dateZeroClear(StringUtil.parseDateTime(startDateStr));
+            if (antibioticDateTimes.containsKey(drugName)) {
+                Map<Date, Integer> map = antibioticDateTimes.get(drugName);
+                if (map.containsKey(startDate)) {
+                    map.put(startDate, map.get(startDate) + 1);
+                } else {
+                    map.put(startDate, 0);
+                }
+            } else {
+                antibioticDateTime = Maps.newHashMap();
+                antibioticDateTime.put(startDate, 0);
+                antibioticDateTimes.put(drugName, antibioticDateTime);
+            }
         }
     }
 
@@ -335,4 +379,15 @@ public class THR02985 extends QCCatalogue {
         }
         return str;
     }
+
+    /**
+     * 拼接提示信息
+     *
+     * @param sb
+     * @param drugKey
+     * @param date
+     */
+    private void infoAppend(StringBuffer sb, String drugKey, String date) {
+        sb.append(drugKey).append("(").append(date).append(")").append(",");
+    }
 }

+ 11 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03070.java

@@ -6,6 +6,7 @@ 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.CrisisInfoDoc;
 import com.lantone.qc.pub.model.doc.LisDoc;
 import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
 import com.lantone.qc.pub.util.StringUtil;
@@ -27,16 +28,26 @@ public class THR03070 extends QCCatalogue {
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
         status.set("0");
         List<LisDoc> lisDocs = inputInfo.getLisDocs();
+        List<CrisisInfoDoc> crisisInfoDocs = inputInfo.getCrisisInfoDocs();
         List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
         if (lisDocs.size() == 0 || threeLevelWardDocs.size() == 0) {
             return;
         }
+        List<String> crisisNames = crisisInfoDocs
+                .stream()
+                .map(CrisisInfoDoc::getStructureMap)
+                .filter(x -> StringUtil.isNotBlank(x.get("危急值名称")))
+                .map(x -> x.get("危急值名称"))
+                .collect(Collectors.toList());
         //异常数据列表
         List<String> abnormal = Lists.newArrayList();
         for (LisDoc lisDoc : lisDocs) {
             double resultValue = -1, max = -1, min = -1;
             Map<String, String> structureMap = lisDoc.getStructureMap();
             String itemName = structureMap.get("报告名称");
+            if (crisisNames.contains(itemName)) {
+                continue;
+            }
             String result = structureMap.get("检验结果");
             String reference = structureMap.get("参考值");
             if (StringUtil.isBlank(itemName) || StringUtil.isBlank(result) || StringUtil.isBlank(reference)) {

+ 59 - 9
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03076.java

@@ -25,6 +25,7 @@ import com.lantone.qc.pub.util.StringUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -53,22 +54,37 @@ public class THR03076 extends QCCatalogue {
         if (doctorAdviceDocs.size() == 0 || threeLevelWardDocs.size() == 0) {
             return;
         }
+
+        Map<Date, String> extData = (Map<Date, String>) outputInfo.getResult().get("THR02985").get("extData");
+
         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("医嘱单次剂量")))
                 .filter(x -> StringUtil.isNotBlank(x.get("医嘱状态判别")) && !x.get("医嘱状态判别").contains("已停止"))
+                .filter(x -> StringUtil.isNotBlank(x.get("给药方式")) && x.get("给药方式").contains("静脉滴注"))
+                .filter(x -> StringUtil.isNotBlank(x.get("医嘱频率")) && !x.get("医嘱频率").equals("ONCE"))
                 .collect(Collectors.toList());
 
         //抗生素及开医嘱时间 <抗生素名,<抗生素用量,[抗生素使用时间...]>>
         Map<String, Map<String, List<Double>>> antibioticInfo = Maps.newLinkedHashMap();
+        Map<String, Map<Date, Integer>> antibioticDateTimes = Maps.newHashMap();
+        //记录同一抗生素同一天内是否开过多次,用于医嘱中需要处理的抗生素过滤(一天内同一抗生素开过多次的抗生素直接过滤)
+        getAntibioticTimes(docAdvStruct, antibioticDateTimes);
         String drugName = null, value = null, startDateStr = null;
+        Date startDate = null;
         for (Map<String, String> structMap : docAdvStruct) {
             drugName = structMap.get("医嘱项目名称");
             value = structMap.get("医嘱单次剂量");
             startDateStr = structMap.get("医嘱开始时间");
-            drugName = removeBracket(drugName);
+            startDate = DateUtil.dateZeroClear(StringUtil.parseDateTime(startDateStr));
+            if (extData != null && extData.containsKey(startDate) && extData.get(startDate).equals(drugName)) {
+                continue;   //THR02985  医嘱有抗生素使用病程无记录,规则中没报未记录的抗生素继续走这条规则,报未记录的抗生素过滤
+            }
+            if (antibioticDateTimes.get(drugName).get(startDate) > 0) {
+                continue;   //一天内同一抗生素开过多次的抗生素直接过滤
+            }
             collectAntibioticInfo(antibioticInfo, drugName, value, startDateStr);
         }
 
@@ -144,7 +160,8 @@ public class THR03076 extends QCCatalogue {
         StringBuffer sb = new StringBuffer();
         String drugKey = null;
         for (Map.Entry<String, Map<String, List<Double>>> ai : antibioticInfo.entrySet()) {
-            drugKey = ai.getKey().replaceAll("[^\u4e00-\u9fa5]", "");
+            drugKey = ai.getKey();
+            drugKey = removeBracket(drugKey).replaceAll("[^\u4e00-\u9fa5]", "");
             String drugStandardWord = similarityUtil.getDrugStandardWord(drugKey);
             if (StringUtil.isNotBlank(drugStandardWord)) {
                 drugKey = drugStandardWord;
@@ -153,16 +170,19 @@ public class THR03076 extends QCCatalogue {
                 Map<String, List<Double>> adDateValue = ai.getValue();
                 Map<String, List<Double>> wardDateValue = antibioticWardInfo.get(drugKey);
                 for (Map.Entry<String, List<Double>> adMap : adDateValue.entrySet()) {
-                    String adDate = adMap.getKey();
+                    String adDateStr = adMap.getKey();
+                    Date adDate = StringUtil.parseDateTime(adDateStr);
                     List<Double> adUsage = adMap.getValue();
                     for (Map.Entry<String, List<Double>> wdvMap : wardDateValue.entrySet()) {
-                        String wardDate = wdvMap.getKey();
+                        String wardDateStr = wdvMap.getKey();
+                        Date wardDate = StringUtil.parseDateTime(wardDateStr);
                         List<Double> wardUsage = wdvMap.getValue();
-                        if (!CatalogueUtil.compareTime(StringUtil.parseDateTime(adDate), StringUtil.parseDateTime(wardDate), 48 * 60L)) {
+                        if ((adDate.before(wardDate) && !CatalogueUtil.compareTime(adDate, wardDate, 48 * 60L))
+                                || (wardDate.before(adDate) && !CatalogueUtil.compareTime(wardDate, adDate, 24 * 60L))) {
                             wardUsage.removeAll(adUsage);//比如adUsage有1.0、2.0,wardUsage中有2.0、3.0,removeAll之后wardUsage只剩3.0
-                            adDate = DateUtil.formatDate(StringUtil.parseDateTime(adDate));
-                            if (wardUsage.size() > 0 && !sb.toString().contains(drugKey + "(" + adDate + ")")) {
-                                infoAppend(sb, drugKey, adDate);
+                            adDateStr = DateUtil.formatDate(adDate);
+                            if (wardUsage.size() > 0 && !sb.toString().contains(drugKey + "(" + adDateStr + ")")) {
+                                infoAppend(sb, ai.getKey(), adDateStr);
                                 break;
                             }
                         }
@@ -173,7 +193,37 @@ public class THR03076 extends QCCatalogue {
 
         if (sb.toString().length() > 0) {
             status.set("-1");
-            info.set(sb.toString().substring(0, sb.toString().length() - 1));
+            info.set("医嘱:" + sb.toString().substring(0, sb.toString().length() - 1));
+        }
+    }
+
+    /**
+     * 记录同一抗生素同一天内是否开过多次,用于医嘱中需要处理的抗生素过滤(一天内同一抗生素开过多次的抗生素直接过滤)
+     *
+     * @param docAdvStruct
+     * @param antibioticDateTimes
+     */
+    private void getAntibioticTimes(List<Map<String, String>> docAdvStruct, Map<String, Map<Date, Integer>> antibioticDateTimes) {
+        String drugName;
+        String startDateStr;
+        Date startDate;
+        Map<Date, Integer> antibioticDateTime;
+        for (Map<String, String> structMap : docAdvStruct) {
+            drugName = structMap.get("医嘱项目名称");
+            startDateStr = structMap.get("医嘱开始时间");
+            startDate = DateUtil.dateZeroClear(StringUtil.parseDateTime(startDateStr));
+            if (antibioticDateTimes.containsKey(drugName)) {
+                Map<Date, Integer> map = antibioticDateTimes.get(drugName);
+                if (map.containsKey(startDate)) {
+                    map.put(startDate, map.get(startDate) + 1);
+                } else {
+                    map.put(startDate, 0);
+                }
+            } else {
+                antibioticDateTime = Maps.newHashMap();
+                antibioticDateTime.put(startDate, 0);
+                antibioticDateTimes.put(drugName, antibioticDateTime);
+            }
         }
     }
 

+ 104 - 25
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03077.java

@@ -33,7 +33,7 @@ import java.util.stream.Collectors;
 /**
  * @author HUJING
  * @create 2020-08-28 14:10
- * @desc 病程中未记录抗生素用量
+ * @desc 病程中抗生素记录不规范
  **/
 @Component
 public class THR03077 extends QCCatalogue {
@@ -51,12 +51,8 @@ public class THR03077 extends QCCatalogue {
         if (doctorAdviceDocs.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, List<Double>> antibioticValue = Maps.newHashMap();
+
+        Map<Date, String> extData = (Map<Date, String>) outputInfo.getResult().get("THR02985").get("extData");
 
         List<Map<String, String>> docAdvStruct = doctorAdviceDocs
                 .stream()
@@ -64,24 +60,49 @@ public class THR03077 extends QCCatalogue {
                 .map(DoctorAdviceDoc::getStructureMap)
                 .filter(x -> StringUtil.isNotBlank(x.get("药品类型")) && x.get("药品类型").contains("抗生素") && StringUtil.isNotBlank(x.get("医嘱单次剂量")))
                 .filter(x -> StringUtil.isNotBlank(x.get("医嘱状态判别")) && !x.get("医嘱状态判别").contains("已停止"))
+                .filter(x -> StringUtil.isNotBlank(x.get("给药方式")) && x.get("给药方式").contains("静脉滴注"))
+                .filter(x -> StringUtil.isNotBlank(x.get("医嘱频率")) && !x.get("医嘱频率").equals("ONCE"))
                 .collect(Collectors.toList());
 
+        //抗生素及开医嘱时间(包括加用过抗生素的时间)     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, List<Double>> antibioticValue = Maps.newHashMap();
+        //记录同一天内是否开过多次同一抗生素
+        Map<String, Map<Date, Integer>> antibioticDateTimes = Maps.newHashMap();
         String drugName = null, value = null, startDateStr = null;
+        Date startDate = null;
+        getAntibioticTimes(docAdvStruct, antibioticDateTimes);
         for (Map<String, String> structMap : docAdvStruct) {
             drugName = structMap.get("医嘱项目名称");
             value = structMap.get("医嘱单次剂量");
             startDateStr = structMap.get("医嘱开始时间");
-            drugName = removeBracket(drugName);
+            startDate = DateUtil.dateZeroClear(StringUtil.parseDateTime(startDateStr));
+            if (extData != null && extData.containsKey(startDate) && extData.get(startDate).equals(drugName)) {
+                continue;   //THR02985  医嘱有抗生素使用病程无记录,规则中没报未记录的抗生素继续走这条规则,报未记录的抗生素过滤
+            }
+            if (antibioticDateTimes.get(drugName).get(startDate) > 0) {
+                continue;   //一天内同一抗生素开过多次的抗生素直接过滤
+            }
             collectAntibioticInfo(antibioticDate, antibioticStatus, antibioticValue, drugName, value, startDateStr);
         }
 
-        //把抗生素没加用过的抗生素删除
-        for (Map.Entry<String, Integer> as : antibioticStatus.entrySet()) {
-            if (as.getValue() == 0) {
-                antibioticDate.remove(as.getKey());
-                antibioticValue.remove(as.getKey());
+        //把抗生素使用剂量没变化过的抗生素删除
+        antibioticStatus.forEach((x, y) -> {
+            if (y == 0) {
+                antibioticDate.remove(x);
+                antibioticValue.remove(x);
             }
-        }
+        });
+        //把同一天内同一个抗生素开过多次的抗生素删除
+//        antibioticDateTimes.forEach((x, y) -> {
+//            if (y > 0) {
+//                antibioticDate.remove(x);
+//                antibioticValue.remove(x);
+//            }
+//        });
         //抗生素加用过的集合如果为空,则一个抗生素都没有加用过,直接返回0
         if (antibioticDate.size() == 0) {
             return;
@@ -161,7 +182,8 @@ public class THR03077 extends QCCatalogue {
         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().replaceAll("[^\u4e00-\u9fa5]", "");
+            drugKey = ad.getKey();
+            drugKey = removeBracket(drugKey).replaceAll("[^\u4e00-\u9fa5]", "");
             String drugStandardWord = similarityUtil.getDrugStandardWord(drugKey);
             if (StringUtil.isNotBlank(drugStandardWord)) {
                 drugKey = drugStandardWord;
@@ -174,10 +196,11 @@ public class THR03077 extends QCCatalogue {
                     Date adStart = DateUtil.dateZeroClear(StringUtil.parseDateTime(start));
                     for (int j = 0; j < wardDateStr.size(); j++) {
                         wardStartStr = wardDateStr.get(j);         //查房记录开抗生素时间
+                        wardStartStr = wardStartStr.split("=")[0];
                         Date wardStart = StringUtil.parseDateTime(wardStartStr);
                         if ((adStart.before(wardStart) && !CatalogueUtil.compareTime(adStart, wardStart, 48 * 60L))
                                 || (wardStart.before(adStart) && !CatalogueUtil.compareTime(wardStart, adStart, 24 * 60L))) {
-                            infoAppend(sb, drugKey, start);
+                            infoAppend(sb, ad.getKey(), start, wardDateStr.get(j).split("=")[1]);
                             break;
                         }
                     }
@@ -187,19 +210,51 @@ public class THR03077 extends QCCatalogue {
 
         if (sb.toString().length() > 0) {
             status.set("-1");
-            info.set(sb.toString().substring(0, sb.toString().length() - 1));
+            info.set("医嘱:" + sb.toString().substring(0, sb.toString().length() - 1));
+        }
+    }
+
+    /**
+     * 记录同一抗生素同一天内是否开过多次,用于医嘱中需要处理的抗生素过滤(一天内同一抗生素开过多次的抗生素直接过滤)
+     *
+     * @param docAdvStruct
+     * @param antibioticDateTimes
+     */
+    private void getAntibioticTimes(List<Map<String, String>> docAdvStruct, Map<String, Map<Date, Integer>> antibioticDateTimes) {
+        String drugName;
+        String startDateStr;
+        Date startDate;
+        Map<Date, Integer> antibioticDateTime;
+        for (Map<String, String> structMap : docAdvStruct) {
+            drugName = structMap.get("医嘱项目名称");
+            startDateStr = structMap.get("医嘱开始时间");
+            startDate = DateUtil.dateZeroClear(StringUtil.parseDateTime(startDateStr));
+            if (antibioticDateTimes.containsKey(drugName)) {
+                Map<Date, Integer> map = antibioticDateTimes.get(drugName);
+                if (map.containsKey(startDate)) {
+                    map.put(startDate, map.get(startDate) + 1);
+                } else {
+                    map.put(startDate, 0);
+                }
+            } else {
+                antibioticDateTime = Maps.newHashMap();
+                antibioticDateTime.put(startDate, 0);
+                antibioticDateTimes.put(drugName, antibioticDateTime);
+            }
         }
     }
 
     /**
      * 收集各模块药品信息
      *
-     * @param antibioticDateWard 病程中没有用量的抗生素使用所有时间
+     * @param antibioticDateWard 病程中没有用量+用法+频率的抗生素使用所有时间
      * @param dateStr            记录日期
      * @param drugs              模型提取出的药品列表
      */
     private void getCourseDrugInfo(Map<String, List<String>> antibioticDateWard, String dateStr, List<Drug> drugs) {
+        StringBuffer sb = null;
         for (Drug drug : drugs) {
+            sb = new StringBuffer();
             String wardDrug = drug.getName();
             wardDrug = removeBracket(wardDrug);
             String drugStandardWord = similarityUtil.getDrugStandardWord(wardDrug);
@@ -207,15 +262,38 @@ public class THR03077 extends QCCatalogue {
                 wardDrug = drugStandardWord;
             }
             if (drug.getConsumption() == null) {
+                concatInfo(dateStr, sb, "用量");
+            }
+            if (drug.getUsageWardRound() == null) {
+                concatInfo(dateStr, sb, "用法");
+            }
+            if (drug.getFrequency() == null) {
+                concatInfo(dateStr, sb, "频率");
+            }
+            if (sb.toString().length() > 0) {
                 if (antibioticDateWard.containsKey(wardDrug)) {
-                    antibioticDateWard.get(wardDrug).add(dateStr);
+                    antibioticDateWard.get(wardDrug).add(sb.toString());
                 } else {
-                    antibioticDateWard.put(wardDrug, Lists.newArrayList(dateStr));
+                    antibioticDateWard.put(wardDrug, Lists.newArrayList(sb.toString()));
                 }
             }
         }
     }
 
+    /**
+     * 拼接抗生素缺失信息
+     *
+     * @param dateStr
+     * @param sb
+     */
+    private void concatInfo(String dateStr, StringBuffer sb, String missType) {
+        if (sb.toString().contains("=")) {
+            sb.append(",").append(missType);
+        } else {
+            sb.append(dateStr).append("=").append(missType);
+        }
+    }
+
     /**
      * 收集抗生素各种信息
      *
@@ -232,7 +310,7 @@ public class THR03077 extends QCCatalogue {
         try {
             v = Double.parseDouble(getNumber(value));
         } catch (Exception e) {
-            System.out.println("THR03074:       " + drugName + ":" + value + "解析异常");
+            System.out.println("THR03077:       " + drugName + ":" + value + "解析异常");
         }
         if (v < 0) {
             return;
@@ -255,8 +333,8 @@ public class THR03077 extends QCCatalogue {
                 return;
             }
             //2.如果抗生素剂量两次开启的时间间隔相差3天,也记录该抗生素开始时间
-            if (antibioticDate.get(drugName).size() > 0) {
-                List<String> currentAntibioticDate = antibioticDate.get(drugName);
+            List<String> currentAntibioticDate = antibioticDate.get(drugName);
+            if (currentAntibioticDate.size() > 0) {
                 String lastDate = currentAntibioticDate.get(currentAntibioticDate.size() - 1);
                 if (CatalogueUtil.compareTime(StringUtil.parseDateTime(lastDate), StringUtil.parseDateTime(startDateStr), 72 * 60L)) {
                     beforeValue.add(v);
@@ -299,8 +377,9 @@ public class THR03077 extends QCCatalogue {
      * @param drugKey
      * @param date
      */
-    private void infoAppend(StringBuffer sb, String drugKey, String date) {
-        sb.append(drugKey).append("(").append(DateUtil.formatDate(StringUtil.parseDateTime(date))).append(")").append(",");
+    private void infoAppend(StringBuffer sb, String drugKey, String date, String missType) {
+        sb.append(drugKey).append("(").append(DateUtil.formatDate(StringUtil.parseDateTime(date)))
+                .append(",").append(missType).append(")").append(",");
     }
 
 }

+ 5 - 0
kernel/src/main/java/com/lantone/qc/kernel/structure/ai/process/EntityProcessDrug.java

@@ -16,11 +16,16 @@ public class EntityProcessDrug extends EntityProcess {
     private Logger logger = LoggerFactory.getLogger(EntityProcessDrug.class);
 
     public List<Drug> extractEntity(JSONObject aiOut) {
+        String content = aiOut.getString("content");
         //药物
         List<Drug> drugs = new ArrayList<>();
         try {
             List<Lemma> DrugLemmas = createEntityTree(aiOut, EntityEnum.DRUG.toString());
             for (Lemma lemma : DrugLemmas) {
+                int lemmaPosition = Integer.parseInt(lemma.getPosition());
+                if (content.substring(Math.max(0, lemmaPosition - 10), lemmaPosition).contains("暂停")){
+                    continue;
+                }
                 Drug drug = new Drug();
                 drug.setName(lemma.getText());
                 drug.setConsumption(findTAfter(lemma, new Consumption(), EntityEnum.CONSUMPTION.toString().split("-")[0]));

+ 4 - 0
kernel/src/main/java/com/lantone/qc/kernel/structure/ai/process/EntityProcessThreeLevelWard.java

@@ -206,6 +206,10 @@ public class EntityProcessThreeLevelWard extends EntityProcess {
             List<Drug> drugs = new ArrayList<>();
             List<Lemma> DrugLemmas = createEntityTree(aiOut, EntityEnum.DRUG.toString());
             for (Lemma lemma : DrugLemmas) {
+                int lemmaPosition = Integer.parseInt(lemma.getPosition());
+                if (content.substring(Math.max(0, lemmaPosition - 10), lemmaPosition).contains("暂停")){
+                    continue;
+                }
                 Drug drug = new Drug();
                 drug.setName(lemma.getText());
                 drug.setConsumption(findTAfter(lemma, new Consumption(), EntityEnum.CONSUMPTION.toString().split("-")[0]));

+ 1 - 1
public/src/main/java/com/lantone/qc/pub/model/OutputInfo.java

@@ -21,7 +21,7 @@ public class OutputInfo {
      * "BEH001":{"status":"-1", "info": "发热"}
      * }
      */
-    private Map<String, Map<String, String>> result = new HashMap<>();
+    private Map<String, Map<String, Object>> result = new HashMap<>();
     //后结构化数据
     private Map<String, Object> pageData = new HashMap<>();