Преглед изворни кода

Merge remote-tracking branch 'origin/shaoyf/dev' into shaoyf/dev

rengb пре 5 година
родитељ
комит
1bfe09d0b5

+ 3 - 3
dbanaly/src/main/resources/application-dev.yml

@@ -44,10 +44,10 @@ spring:
 xml-is-encryped: true
 
 CRF:
-  url: http://192.168.3.150:3456/api/mr_info_ex/entity_predict
+  url: http://192.168.2.234:3456/api/mr_info_ex/entity_predict
 
 Similarity:
-  url: http://192.168.3.150:3456/api/mr_info_ex/similarity
+  url: http://192.168.2.234:3456/api/mr_info_ex/similarity
 
 ChiefPresentSimilarity:
-  url: http://192.168.3.150:3456/api/mr_info_ex/chief_present_similarity
+  url: http://192.168.2.234:3456/api/mr_info_ex/chief_present_similarity

+ 202 - 54
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR02985.java

@@ -1,94 +1,187 @@
 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.kernel.util.SimilarityUtil;
 import com.lantone.qc.pub.model.InputInfo;
 import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.BeHospitalizedDoc;
 import com.lantone.qc.pub.model.doc.DoctorAdviceDoc;
 import com.lantone.qc.pub.model.doc.FirstCourseRecordDoc;
 import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationDiscussionDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationRecordDoc;
+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.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * @ClassName : THR02985
  * @Description : 医嘱有抗生素使用病程无记录
- * 药品类型(0.普药 1.抗生素 2.素)
+ * 药品类型(0.普药 1.抗生素 2.抗生素)
  * @Author : 胡敬
  * @Date: 2020-06-23 10:04
  */
 @Component
 public class THR02985 extends QCCatalogue {
-    private static final String[] KSS = {
-            "阿昔洛韦片",
-            "[国产]伐昔洛韦分散片",
-            "阿昔洛韦针",
-            "[进口]伐昔洛韦片"
-            , "[浓缩型]双黄连口服液",
-            "异烟肼片",
-            "[黄连素]小檗碱片",
-            "乙胺丁醇片",
-            "利福平胶囊",
-            "异烟肼针"
-    };
+    @Autowired
+    SimilarityUtil similarityUtil;
 
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
         List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
         List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
+        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
+        BeHospitalizedDoc beHospitalizedDoc = inputInfo.getBeHospitalizedDoc();
+        List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
         if (doctorAdviceDocs.size() == 0 || threeLevelWardDocs.size() == 0) {
             status.set("0");
             return;
         }
+        List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDocs.get(0).getAllDoctorWradDocs();
+        if (allDoctorWradDocs.size() == 0) {
+            status.set("0");
+            return;
+        }
         Map<Date, String> doctorAdviceDrugMap = new HashMap<>();
+        String regex = "[()*+-]";
         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.equals("抗生素")) {
+            if (StringUtil.isNotBlank(drugCategory) && drugCategory.contains("抗生素")) {
                 if (StringUtil.isNotBlank(name)) {
-                    if (Arrays.asList(KSS).contains(name)) {
-                        continue;
+                    if (name.contains(" ")) {
+                        name = name.split(" ")[0];
                     }
                     doctorAdviceDrugMap.put(StringUtil.parseDateTime(startDateStr), name);
                 }
             }
         }
-        List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDocs.get(0).getAllDoctorWradDocs();
-        if (allDoctorWradDocs.size() == 0) {
-            status.set("0");
-            return;
+
+        //入院记录中找药
+        String behospContent = null, firstCourseContent = null, operContent = null, afterOperContent = null;
+        Date behospDate = null, firstCourseDate = null, operDate = null, afterOperDate = null;
+        if (beHospitalizedDoc != null) {
+            behospContent = CatalogueUtil.structureMapJoin(beHospitalizedDoc.getStructureMap(), Lists.newArrayList("治疗计划"));
+            String recordDateStr = firstCourseRecordDoc.getStructureMap().get("入院日期");
+            if (StringUtil.isNotBlank(recordDateStr)) {
+                behospDate = StringUtil.parseDateTime(recordDateStr);
+            }
+        }
+        //从首程治疗计划中找药
+        if (firstCourseRecordDoc != null) {
+            firstCourseContent = firstCourseRecordDoc.getStructureMap().get("治疗计划");
+            String recordDateStr = firstCourseRecordDoc.getStructureMap().get("记录时间");
+            if (StringUtil.isNotBlank(recordDateStr)) {
+                firstCourseDate = StringUtil.parseDateTime(recordDateStr);
+            }
         }
+
+        Map<String, Date> operInfo = Maps.newHashMap();
+        if (operationDocs.size() > 0) {
+            for (OperationDoc oDoc : operationDocs) {
+                OperationRecordDoc operationRecordDoc = oDoc.getOperationRecordDoc();
+                if (operationRecordDoc != null) {
+                    operContent = operationRecordDoc.getStructureMap().get("手术经过");
+                    String operDateStr = operationRecordDoc.getStructureMap().get("手术日期");
+                    if (StringUtil.isNotBlank(operDateStr)) {
+                        operDate = StringUtil.parseDateTime(operDateStr);
+                    }
+                    if (StringUtil.isNotBlank(operContent) && operDate != null) {
+                        operInfo.put(operContent, operDate);
+                    }
+                }
+                OperationDiscussionDoc operationDiscussionDoc = oDoc.getOperationDiscussionDoc();
+                if (operationDiscussionDoc != null) {
+                    afterOperContent = operationDiscussionDoc.getStructureMap().get("手术经过");
+                    String operDateStr = operationDiscussionDoc.getStructureMap().get("手术日期");
+                    if (StringUtil.isNotBlank(operDateStr)) {
+                        afterOperDate = StringUtil.parseDateTime(operDateStr);
+                    }
+                    if (StringUtil.isNotBlank(afterOperContent) && afterOperDate != null) {
+                        operInfo.put(afterOperContent, afterOperDate);
+                    }
+                }
+            }
+        }
+
         String infoStr = "";
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         for (Map.Entry<Date, String> doctorAdviceDrug : doctorAdviceDrugMap.entrySet()) {
             Date doctorAdviceDate = doctorAdviceDrug.getKey();
-            Set<String> splitDrugs = CatalogueUtil.getRegexWords(doctorAdviceDrug.getValue(), "[((\\[][^\\[\\]()()]+[\\]))]");
-
-            boolean isFind = false;
-            for (String drug : splitDrugs) {
-                int matchSum = 0;
-                if (drug.equals("合资") || drug.equals("进口") || drug.equals("国产")) {
+            String drugs = doctorAdviceDrug.getValue();
+            String[] drugArr = drugs.split(regex);
+            String missDrug = "";
+            //入院记录中找药
+            if (StringUtil.isNotBlank(behospContent) && behospDate != null) {
+                missDrug = getMissDrug(behospContent, behospDate, doctorAdviceDate, drugArr, 2, missDrug);
+                if (StringUtil.isBlank(missDrug)) {//文本中已找到该抗生素
+                    continue;
+                }
+            }
+            //从首程治疗计划中找药
+            if (StringUtil.isNotBlank(firstCourseContent) && firstCourseDate != null) {
+                missDrug = getMissDrug(firstCourseContent, firstCourseDate, doctorAdviceDate, drugArr, 2, missDrug);
+                if (StringUtil.isBlank(missDrug)) {
                     continue;
                 }
-                matchSum = getMatchSum(inputInfo.getFirstCourseRecordDoc(), allDoctorWradDocs, doctorAdviceDate, drug.replace("针", ""), matchSum, 2);
-                if (matchSum > 0) {
-                    isFind = true;
+            }
+            for (Map.Entry<String, Date> info : operInfo.entrySet()) {
+                missDrug = getMissDrug(info.getKey(), info.getValue(), doctorAdviceDate, drugArr, 2, missDrug);
+                //当前抗生素药(drugs)在手术记录或术后首次病程录中已找到,直接跳出当前循环
+                if (StringUtil.isBlank(missDrug)) {
+                    break;
                 }
             }
-            if (!isFind) {
-                String.format(infoStr = CatalogueUtil.concatInfo(infoStr, doctorAdviceDrug.getValue() + "<医嘱时间>:" + sdf.format(doctorAdviceDate)));
+            if (StringUtil.isBlank(missDrug)) {
+                continue;
+            }
+            boolean modelFind = false;
+            for (ThreeLevelWardDoc threeLevelWardDoc : allDoctorWradDocs) {
+                /*****************纯文本匹配******************/
+                Map<String, String> wardDocStructureMap = threeLevelWardDoc.getStructureMap();
+                String wardDateStr = wardDocStructureMap.get("查房日期");
+                String content = wardDocStructureMap.get("病情记录") + wardDocStructureMap.get("治疗计划和措施");
+                Date wardDate = StringUtil.parseDateTime(wardDateStr);
+                missDrug = getMissDrug(content, wardDate, doctorAdviceDate, drugArr, 2, missDrug);
+                //当前抗生素药(drugs)在查房记录中已找到,直接跳出当前查房记录的循环
+                /*****************药品相似度模型******************/
+                List<ThreeLevelWardLabel> label = threeLevelWardDoc.getThreeLevelWardLabel();
+                if (label.size() > 0) {
+                    List<Drug> drugList = label.get(0).getDrugs();
+                    for (Drug drug : drugList) {
+                        for (String adDrug : drugArr) {
+                            if (compareStandard(drug.getName(), adDrug)) {
+                                modelFind = true;
+                                break;
+                            }
+                        }
+                        if (modelFind) {
+                            break;
+                        }
+                    }
+                }
+                if (StringUtil.isBlank(missDrug) || modelFind) {
+                    break;
+                }
             }
-        }
 
+            if (StringUtil.isNotBlank(missDrug) && !"时间不匹配".equals(missDrug) && !modelFind) {
+                infoStr = CatalogueUtil.concatInfo(infoStr, missDrug);
+            }
+        }
         if (StringUtil.isNotBlank(infoStr)) {
             status.set("-1");
             info.set(infoStr);
@@ -97,28 +190,83 @@ public class THR02985 extends QCCatalogue {
         }
     }
 
-    private int getMatchSum(FirstCourseRecordDoc firstCourseRecordDoc, List<ThreeLevelWardDoc> allDoctorWradDocs, Date doctorAdviceDate, String drug, int matchSum, int days) {
-        if (firstCourseRecordDoc != null) {
-            String wardDateStr = firstCourseRecordDoc.getStructureMap().get("病历日期");
-            String content = firstCourseRecordDoc.getStructureMap().get("治疗计划") + firstCourseRecordDoc.getStructureMap().get("诊疗计划");
-            Date wardDate = StringUtil.parseDateTime(wardDateStr);
-            if (doctorAdviceDate.before(wardDate) && !CatalogueUtil.compareTime(doctorAdviceDate, wardDate, days * 24 * 60L)) {
-                if (content.contains(drug)) {
-                    matchSum++;
+    /**
+     * 从文本中找药
+     *
+     * @param content          文本
+     * @param wardDate
+     * @param doctorAdviceDate
+     * @param drugs
+     * @param days
+     * @return 如果文本中找到该药,则返回空字符串
+     */
+    private String getMissDrug(String content, Date wardDate, Date doctorAdviceDate, String[] drugs, int days, String missDrug) {
+        if ("时间不匹配".equals(missDrug)) {
+            missDrug = "";//初始化缺失药物
+        }
+        if (doctorAdviceDate.before(wardDate) && !CatalogueUtil.compareTime(doctorAdviceDate, wardDate, days * 24 * 60L)) {
+            boolean findDrug = false;
+            for (String drug : drugs) {
+                if (StringUtil.isBlank(drug)) {
+                    continue;
+                }
+                if (content.contains(drug.replaceAll("[^\\u4e00-\\u9fa5]", ""))
+                        || regexFind(content, "继续", "治疗") || regexFind(content, "维持", "治疗")) {
+                    findDrug = true;
+                    break;
+                } else {
+                    missDrug = concatInfo(missDrug, drug);
                 }
             }
+            if (findDrug) {
+                missDrug = "";//如果找到一种抗生素药,就把报错信息置为空
+            }
+        } else {
+            if (StringUtil.isBlank(missDrug)) {
+                missDrug = "时间不匹配";
+            }
         }
-        for (ThreeLevelWardDoc threeLevelWardDoc : allDoctorWradDocs) {
-            Map<String, String> wardDocStructureMap = threeLevelWardDoc.getStructureMap();
-            String wardDateStr = wardDocStructureMap.get("查房日期");
-            String content = wardDocStructureMap.get("病情记录") + wardDocStructureMap.get("治疗计划和措施");
-            Date wardDate = StringUtil.parseDateTime(wardDateStr);
-            if (doctorAdviceDate.before(wardDate) && !CatalogueUtil.compareTime(doctorAdviceDate, wardDate, days * 24 * 60L)) {
-                if (content.contains(drug)) {
-                    matchSum++;
-                }
+        return missDrug;
+    }
+
+    private String concatInfo(String infoStr, String content) {
+        if (StringUtil.isBlank(infoStr)) {
+            infoStr += content;
+        } else {
+            if (!infoStr.contains(content)) {
+                infoStr += "或" + content;
             }
         }
-        return matchSum;
+        return infoStr;
+    }
+
+    private boolean regexFind(String content, String... str) {
+        String s = "";
+        for (String word : str) {
+            s += word + ".*";
+        }
+        s = s.substring(0, s.lastIndexOf(".*"));
+        Pattern p = Pattern.compile(s);
+        Matcher m = p.matcher(content);
+        return m.find();
+    }
+
+    /**
+     * 比较两个抗生素标准词是否一致
+     *
+     * @param firstWord
+     * @param secordWord
+     * @return
+     */
+    private boolean compareStandard(String firstWord, String secordWord) {
+        if (StringUtil.isBlank(firstWord) || StringUtil.isBlank(secordWord)) {
+            return false;
+        }
+        String drugStandardWord1 = similarityUtil.getDrugStandardWord(firstWord);
+        String drugStandardWord2 = similarityUtil.getDrugStandardWord(secordWord);
+        if (drugStandardWord1 == null || drugStandardWord2 == null) {
+            return false;
+        }
+        return drugStandardWord1.equals(drugStandardWord2);
     }
 }

+ 158 - 127
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR02986.java

@@ -1,87 +1,162 @@
 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.BeHospitalizedDoc;
 import com.lantone.qc.pub.model.doc.DoctorAdviceDoc;
 import com.lantone.qc.pub.model.doc.FirstCourseRecordDoc;
 import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationDiscussionDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationRecordDoc;
 import com.lantone.qc.pub.util.StringUtil;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Component;
 
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * @ClassName : THR02986
  * @Description : 医嘱有激素使用病程无记录
- * 药品类型(0.普药 1.抗生素 2.激素)
+ * 药品类型(0.普药 1.素 2.激素)
  * @Author : 胡敬
- * @Date: 2020-06-23 10:04
+ * @Date: 2020-06-23 10:43
  */
 @Component
 public class THR02986 extends QCCatalogue {
-
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
         List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
         List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
+        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
+        BeHospitalizedDoc beHospitalizedDoc = inputInfo.getBeHospitalizedDoc();
+        List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
         if (doctorAdviceDocs.size() == 0 || threeLevelWardDocs.size() == 0) {
             status.set("0");
             return;
         }
+        List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDocs.get(0).getAllDoctorWradDocs();
+        if (allDoctorWradDocs.size() == 0) {
+            status.set("0");
+            return;
+        }
         Map<Date, String> doctorAdviceDrugMap = new HashMap<>();
+        String regex = "[()*+-]";
         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.equals("激素")) {
-
+            if (StringUtil.isNotBlank(drugCategory) && drugCategory.contains("激素")) {
                 if (StringUtil.isNotBlank(name)) {
-                    if (Arrays.asList(JS).contains(name)) {
-                        continue;
+                    if (name.contains(" ")) {
+                        name = name.split(" ")[0];
                     }
                     doctorAdviceDrugMap.put(StringUtil.parseDateTime(startDateStr), name);
                 }
             }
         }
-        List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDocs.get(0).getAllDoctorWradDocs();
-        if (allDoctorWradDocs.size() == 0) {
-            status.set("0");
-            return;
+
+        //入院记录中找药
+        String behospContent = null, firstCourseContent = null, operContent = null, afterOperContent = null;
+        Date behospDate = null, firstCourseDate = null, operDate = null, afterOperDate = null;
+        if (beHospitalizedDoc != null) {
+            behospContent = CatalogueUtil.structureMapJoin(beHospitalizedDoc.getStructureMap(), Lists.newArrayList("治疗计划"));
+            String recordDateStr = firstCourseRecordDoc.getStructureMap().get("入院日期");
+            if (StringUtil.isNotBlank(recordDateStr)) {
+                behospDate = StringUtil.parseDateTime(recordDateStr);
+            }
+        }
+        //从首程治疗计划中找药
+        if (firstCourseRecordDoc != null) {
+            firstCourseContent = firstCourseRecordDoc.getStructureMap().get("治疗计划");
+            String recordDateStr = firstCourseRecordDoc.getStructureMap().get("记录时间");
+            if (StringUtil.isNotBlank(recordDateStr)) {
+                firstCourseDate = StringUtil.parseDateTime(recordDateStr);
+            }
+        }
+
+        Map<String, Date> operInfo = Maps.newHashMap();
+        if (operationDocs.size() > 0) {
+            for (OperationDoc oDoc : operationDocs) {
+                OperationRecordDoc operationRecordDoc = oDoc.getOperationRecordDoc();
+                if (operationRecordDoc != null) {
+                    operContent = operationRecordDoc.getStructureMap().get("手术经过");
+                    String operDateStr = operationRecordDoc.getStructureMap().get("手术日期");
+                    if (StringUtil.isNotBlank(operDateStr)) {
+                        operDate = StringUtil.parseDateTime(operDateStr);
+                    }
+                    if (StringUtil.isNotBlank(operContent) && operDate != null) {
+                        operInfo.put(operContent, operDate);
+                    }
+                }
+                OperationDiscussionDoc operationDiscussionDoc = oDoc.getOperationDiscussionDoc();
+                if (operationDiscussionDoc != null) {
+                    afterOperContent = operationDiscussionDoc.getStructureMap().get("手术经过");
+                    String operDateStr = operationDiscussionDoc.getStructureMap().get("手术日期");
+                    if (StringUtil.isNotBlank(operDateStr)) {
+                        afterOperDate = StringUtil.parseDateTime(operDateStr);
+                    }
+                    if (StringUtil.isNotBlank(afterOperContent) && afterOperDate != null) {
+                        operInfo.put(afterOperContent, afterOperDate);
+                    }
+                }
+            }
         }
+
         String infoStr = "";
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
         for (Map.Entry<Date, String> doctorAdviceDrug : doctorAdviceDrugMap.entrySet()) {
             Date doctorAdviceDate = doctorAdviceDrug.getKey();
-            String format = sdf1.format(doctorAdviceDate);
-            doctorAdviceDate = StringUtil.parseDateTime(format);
-            Set<String> splitDrugs = CatalogueUtil.getRegexWords(doctorAdviceDrug.getValue(), "[((\\[][^\\[\\]()()]+[\\]))]");
-
-            boolean isFind = false;
-            for (String drug : splitDrugs) {
-                int matchSum = 0;
-                if (drug.equals("合资") || drug.equals("进口") || drug.equals("国产")) {
+            String drugs = doctorAdviceDrug.getValue();
+            String[] drugArr = drugs.split(regex);
+            String missDrug = "";
+            //入院记录中找药
+            if (StringUtil.isNotBlank(behospContent) && behospDate != null) {
+                missDrug = getMissDrug(behospContent, behospDate, doctorAdviceDate, drugArr, 2, missDrug);
+                if (StringUtil.isBlank(missDrug)) {//文本中已找到该激素
                     continue;
                 }
-                matchSum = getMatchSum(inputInfo.getFirstCourseRecordDoc(), allDoctorWradDocs, doctorAdviceDate, drug, matchSum, 2);
-                if (matchSum > 0) {
-                    isFind = true;
+            }
+            //从首程治疗计划中找药
+            if (StringUtil.isNotBlank(firstCourseContent) && firstCourseDate != null) {
+                missDrug = getMissDrug(firstCourseContent, firstCourseDate, doctorAdviceDate, drugArr, 2, missDrug);
+                if (StringUtil.isBlank(missDrug)) {
+                    continue;
                 }
             }
-            if (!isFind) {
-                String.format(infoStr = CatalogueUtil.concatInfo(infoStr, doctorAdviceDrug.getValue() + "<医嘱时间>:" + sdf.format(doctorAdviceDate)));
+            for (Map.Entry<String, Date> info : operInfo.entrySet()) {
+                missDrug = getMissDrug(info.getKey(), info.getValue(), doctorAdviceDate, drugArr, 2, missDrug);
+                //当前激素药(drugs)在手术记录或术后首次病程录中已找到,直接跳出当前循环
+                if (StringUtil.isBlank(missDrug)) {
+                    break;
+                }
+            }
+            if (StringUtil.isBlank(missDrug)) {
+                continue;
+            }
+            for (ThreeLevelWardDoc threeLevelWardDoc : allDoctorWradDocs) {
+                Map<String, String> wardDocStructureMap = threeLevelWardDoc.getStructureMap();
+                String wardDateStr = wardDocStructureMap.get("查房日期");
+                String content = wardDocStructureMap.get("病情记录") + wardDocStructureMap.get("治疗计划和措施");
+                Date wardDate = StringUtil.parseDateTime(wardDateStr);
+                missDrug = getMissDrug(content, wardDate, doctorAdviceDate, drugArr, 2, missDrug);
+                //当前激素药(drugs)在查房记录中已找到,直接跳出当前查房记录的循环
+                if (StringUtil.isBlank(missDrug)) {
+                    break;
+                }
             }
-        }
 
+            if (StringUtil.isNotBlank(missDrug) && !"时间不匹配".equals(missDrug)) {
+                infoStr = CatalogueUtil.concatInfo(infoStr, missDrug);
+            }
+        }
         if (StringUtil.isNotBlank(infoStr)) {
             status.set("-1");
             info.set(infoStr);
@@ -90,108 +165,64 @@ public class THR02986 extends QCCatalogue {
         }
     }
 
-    private int getMatchSum(FirstCourseRecordDoc firstCourseRecordDoc, List<ThreeLevelWardDoc> allDoctorWradDocs, Date doctorAdviceDate, String drug, int matchSum, int days) {
-        if (firstCourseRecordDoc != null) {
-            String wardDateStr = firstCourseRecordDoc.getStructureMap().get("病历日期");
-            String content = firstCourseRecordDoc.getStructureMap().get("治疗计划") + firstCourseRecordDoc.getStructureMap().get("诊疗计划");
-            Date wardDate = StringUtil.parseDateTime(wardDateStr);
-            if (doctorAdviceDate.before(wardDate) && !CatalogueUtil.compareTime(doctorAdviceDate, wardDate, days * 24 * 60L)) {
-                if (content.contains(drug)) {
-                    matchSum++;
+    /**
+     * 从文本中找药
+     *
+     * @param content          文本
+     * @param wardDate
+     * @param doctorAdviceDate
+     * @param drugs
+     * @param days
+     * @return 如果文本中找到该药,则返回空字符串
+     */
+    private String getMissDrug(String content, Date wardDate, Date doctorAdviceDate, String[] drugs, int days, String missDrug) {
+        if ("时间不匹配".equals(missDrug)) {
+            missDrug = "";//初始化缺失药物
+        }
+        if (doctorAdviceDate.before(wardDate) && !CatalogueUtil.compareTime(doctorAdviceDate, wardDate, days * 24 * 60L)) {
+            boolean findDrug = false;
+            for (String drug : drugs) {
+                if (StringUtil.isBlank(drug)) {
+                    continue;
+                }
+                if (content.contains(drug.replaceAll("[^\\u4e00-\\u9fa5]", ""))
+                        || regexFind(content, "继续", "治疗") || regexFind(content, "维持", "治疗")) {
+                    findDrug = true;
+                    break;
+                } else {
+                    missDrug = concatInfo(missDrug, drug);
                 }
             }
-        }
-        for (ThreeLevelWardDoc threeLevelWardDoc : allDoctorWradDocs) {
-            Map<String, String> wardDocStructureMap = threeLevelWardDoc.getStructureMap();
-            String wardDateStr = wardDocStructureMap.get("查房日期");
-            if (StringUtils.isNotBlank(wardDateStr)) {
-                wardDateStr = wardDateStr.split(" ")[0];
+            if (findDrug) {
+                missDrug = "";//如果找到一种激素药,就把报错信息置为空
             }
-            String content = wardDocStructureMap.get("病情记录") + wardDocStructureMap.get("治疗计划和措施");
-            Date wardDate = StringUtil.parseDateTime(wardDateStr);
-            if ((doctorAdviceDate.before(wardDate) || doctorAdviceDate.equals(wardDate)) && !CatalogueUtil.compareTime(doctorAdviceDate, wardDate, days * 24 * 60L)) {
-                if (content.contains(drug)) {
-                    matchSum++;
-                }
+        } else {
+            if (StringUtil.isBlank(missDrug)) {
+                missDrug = "时间不匹配";
             }
         }
-        return matchSum;
+        return missDrug;
     }
 
-    private static final String[] JS = { "瑞格列奈片", "西格列汀片", "维格列汀片", "伏格列波糖片", "[合资]二甲双胍片"
-            , "[进口]硫辛酸针", "[合资]阿卡波糖片", "格列齐特缓释片", "达格列净片", "[合资]格列美脲片", "[绿叶]阿卡波糖胶囊"
-            , "[海汇]格列美脲片", "格列吡嗪缓释胶囊", "[国产]阿卡波糖片", "格列吡嗪控释片", "[国产]二甲双胍片", "沙格列汀片"
-            , "吡格列酮二甲双胍片", "[艾可拓]吡格列酮片", "阿仑膦酸钠维D3片", "[卡司平]吡格列酮片", "[国产]硫辛酸针"
-            , "格列喹酮片", "[国产]阿仑膦酸钠肠溶片", "那格列奈片", "[自备]格列齐特-II片",
-            "[特]门冬胰岛素针",
-            "[预填充]甘精胰岛素针",
-            "[优泌乐50]精蛋白锌赖脯胰岛素针",
-            "[特30]门冬胰岛素30针",
-            "左旋甲状腺素片",
-            "胰岛素针",
-            "[进口]奥曲肽针",
-            "[优泌乐25]精蛋白锌赖脯胰岛素针",
-            "[国产]生长抑素针",
-            "[国产]特利加压素针",
-            "[国产]奥曲肽针",
-            "[诺和灵30R]精蛋白生物合成人胰岛素针",
-            "谷赖胰岛素针",
-            "地特胰岛素针",
-            "[进口]生长抑素针",
-            "甲巯咪唑片",
-            "降钙素针",
-            "[优泌乐]赖脯胰岛素针",
-            "利拉鲁肽针",
-            "重组甘精胰岛素针",
-            "[70/30]精蛋白锌重组人胰岛素针",
-            "[预灌封优泌乐50]精蛋白锌赖脯胰岛素针",
-            "黄体酮针",
-            "地屈孕酮片",
-            "50/50混合重组人胰岛素针",
-            "炔诺酮片",
-            "[进口]特利加压素针",
-            "戊酸雌二醇片",
-            "4.5iu生长激素针",
-            "生物合成人胰岛素针",
-            "米非司酮片",
-            "[进口]黄体酮软胶囊",
-            "十一酸睾酮胶囊",
-            "[芯中效]精蛋白锌重组人胰岛素针",
-            "[国产]丙硫氧嘧啶片",
-            "[国产]黄体酮胶囊",
-            "[芯常规]重组人胰岛素针",
-            "[自备]重组甘精胰岛素针",
-            "[密盖息]降钙素鼻喷剂",
-            "甲羟孕酮片",
-            "替勃龙片",
-            "[金尔力]降钙素鼻喷剂",
-            "雷洛昔芬片",
-            "瑞格列奈片",
-            "西格列汀片",
-            "维格列汀片",
-            "伏格列波糖片",
-            "[合资]二甲双胍片",
-            "[进口]硫辛酸针",
-            "[合资]阿卡波糖片",
-            "格列齐特缓释片",
-            "达格列净片",
-            "[合资]格列美脲片",
-            "[绿叶]阿卡波糖胶囊",
-            "[海汇]格列美脲片",
-            "格列吡嗪缓释胶囊",
-            "[国产]阿卡波糖片",
-            "格列吡嗪控释片",
-            "[国产]二甲双胍片",
-            "吡格列酮二甲双胍片",
-            "沙格列汀片",
-            "[艾可拓]吡格列酮片",
-            "阿仑膦酸钠维D3片",
-            "[卡司平]吡格列酮片",
-            "[国产]硫辛酸针",
-            "格列喹酮片",
-            "[国产]阿仑膦酸钠肠溶片",
-            "那格列奈片",
-            "[自备]格列齐特-II片"
-    };
+    private String concatInfo(String infoStr, String content) {
+        if (StringUtil.isBlank(infoStr)) {
+            infoStr += content;
+        } else {
+            if (!infoStr.contains(content)) {
+                infoStr += "或" + content;
+            }
+        }
+        return infoStr;
+    }
 
+    private boolean regexFind(String content, String... str) {
+        String s = "";
+        for (String word : str) {
+            s += word + ".*";
+        }
+        s = s.substring(0, s.lastIndexOf(".*"));
+        Pattern p = Pattern.compile(s);
+        Matcher m = p.matcher(content);
+        return m.find();
+    }
 }

+ 17 - 2
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03069.java

@@ -4,6 +4,7 @@ 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.kernel.util.SimilarityUtil;
 import com.lantone.qc.pub.model.InputInfo;
 import com.lantone.qc.pub.model.OutputInfo;
 import com.lantone.qc.pub.model.doc.DoctorAdviceDoc;
@@ -11,6 +12,7 @@ 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.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.Date;
@@ -28,6 +30,9 @@ import java.util.stream.Collectors;
  **/
 @Component
 public class THR03069 extends QCCatalogue {
+    @Autowired
+    SimilarityUtil similarityUtil;
+
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
         status.set("0");
         List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
@@ -60,6 +65,10 @@ public class THR03069 extends QCCatalogue {
             value = structMap.get("医嘱单次剂量");
             startDateStr = structMap.get("医嘱开始时间");
             drugName = removeBracket(drugName);
+            String drugStandardWord = similarityUtil.getDrugStandardWord(drugName);
+            if (StringUtil.isNotBlank(drugStandardWord)) {
+                drugName = drugStandardWord;
+            }
             collectAntibioticInfo(antibioticDate, antibioticStatus, antibioticValue, drugName, value, startDateStr);
         }
 
@@ -88,12 +97,18 @@ public class THR03069 extends QCCatalogue {
             ThreeLevelWardLabel label = doc.getThreeLevelWardLabel().get(0);
             List<Drug> drugs = label.getDrugs();
             for (Drug drug : drugs) {
+                String wardDrug = drug.getName();
+                wardDrug = removeBracket(wardDrug);
+                String drugStandardWord = similarityUtil.getDrugStandardWord(wardDrug);
+                if (StringUtil.isNotBlank(drugStandardWord)) {
+                    wardDrug = drugStandardWord;
+                }
                 //药品用量和使用原因都有时
                 if (drug.getConsumption() != null) {
                     //查房记录抗生素加用过的集合中没包含该抗生素,则认为该抗生素是第一次出现,此时不需要加用原因
-                    if (!antibioticStatusWard.containsKey(drug.getName()) || drug.getUsageWardRound() != null) {
+                    if (!antibioticStatusWard.containsKey(wardDrug) || drug.getUsageWardRound() != null) {
                         String consumption = drug.getConsumption().getName();
-                        collectAntibioticInfo(antibioticDateWard, antibioticStatusWard, antibioticValueWard, removeBracket(drug.getName()), consumption, doc.getStructureMap().get("查房日期"));
+                        collectAntibioticInfo(antibioticDateWard, antibioticStatusWard, antibioticValueWard, wardDrug, consumption, doc.getStructureMap().get("查房日期"));
                     }
                 }
             }

+ 17 - 2
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03072.java

@@ -4,6 +4,7 @@ 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.kernel.util.SimilarityUtil;
 import com.lantone.qc.pub.model.InputInfo;
 import com.lantone.qc.pub.model.OutputInfo;
 import com.lantone.qc.pub.model.doc.DoctorAdviceDoc;
@@ -11,6 +12,7 @@ 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.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.Date;
@@ -28,6 +30,9 @@ import java.util.stream.Collectors;
  **/
 @Component
 public class THR03072 extends QCCatalogue {
+    @Autowired
+    SimilarityUtil similarityUtil;
+
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
         status.set("0");
         List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
@@ -60,6 +65,10 @@ public class THR03072 extends QCCatalogue {
             value = structMap.get("医嘱单次剂量");
             startDateStr = structMap.get("医嘱开始时间");
             drugName = removeBracket(drugName);
+            String drugStandardWord = similarityUtil.getDrugStandardWord(drugName);
+            if (StringUtil.isNotBlank(drugStandardWord)) {
+                drugName = drugStandardWord;
+            }
             collectAntibioticInfo(antibioticDate, antibioticStatus, antibioticValue, drugName, value, startDateStr);
         }
 
@@ -88,12 +97,18 @@ public class THR03072 extends QCCatalogue {
             ThreeLevelWardLabel label = doc.getThreeLevelWardLabel().get(0);
             List<Drug> drugs = label.getDrugs();
             for (Drug drug : drugs) {
+                String wardDrug = drug.getName();
+                wardDrug = removeBracket(wardDrug);
+                String drugStandardWord = similarityUtil.getDrugStandardWord(wardDrug);
+                if (StringUtil.isNotBlank(drugStandardWord)) {
+                    wardDrug = drugStandardWord;
+                }
                 //药品用量和使用原因都有时
                 if (drug.getConsumption() != null) {
                     //查房记录抗生素减用过的集合中没包含该抗生素,则认为该抗生素是第一次出现,此时不需要减用原因
-                    if (!antibioticStatusWard.containsKey(drug.getName()) || drug.getUsageWardRound() != null) {
+                    if (!antibioticStatusWard.containsKey(wardDrug) || drug.getUsageWardRound() != null) {
                         String consumption = drug.getConsumption().getName();
-                        collectAntibioticInfo(antibioticDateWard, antibioticStatusWard, antibioticValueWard, removeBracket(drug.getName()), consumption, doc.getStructureMap().get("查房日期"));
+                        collectAntibioticInfo(antibioticDateWard, antibioticStatusWard, antibioticValueWard, wardDrug, consumption, doc.getStructureMap().get("查房日期"));
                     }
                 }
             }

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

@@ -4,6 +4,7 @@ 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.kernel.util.SimilarityUtil;
 import com.lantone.qc.pub.model.InputInfo;
 import com.lantone.qc.pub.model.OutputInfo;
 import com.lantone.qc.pub.model.doc.DoctorAdviceDoc;
@@ -11,6 +12,7 @@ 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.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.Date;
@@ -28,6 +30,9 @@ import java.util.stream.Collectors;
  **/
 @Component
 public class THR03074 extends QCCatalogue {
+    @Autowired
+    SimilarityUtil similarityUtil;
+
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
         status.set("0");
         List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
@@ -60,6 +65,10 @@ public class THR03074 extends QCCatalogue {
             value = structMap.get("医嘱单次剂量");
             startDateStr = structMap.get("医嘱开始时间");
             drugName = removeBracket(drugName);
+            String drugStandardWord = similarityUtil.getDrugStandardWord(drugName);
+            if (StringUtil.isNotBlank(drugStandardWord)) {
+                drugName = drugStandardWord;
+            }
             collectAntibioticInfo(antibioticDate, antibioticStatus, antibioticValue, drugName, value, startDateStr);
         }
 
@@ -88,9 +97,15 @@ public class THR03074 extends QCCatalogue {
             ThreeLevelWardLabel label = doc.getThreeLevelWardLabel().get(0);
             List<Drug> drugs = label.getDrugs();
             for (Drug drug : drugs) {
+                String wardDrug = drug.getName();
+                wardDrug = removeBracket(wardDrug);
+                String drugStandardWord = similarityUtil.getDrugStandardWord(wardDrug);
+                if (StringUtil.isNotBlank(drugStandardWord)) {
+                    wardDrug = drugStandardWord;
+                }
                 if (drug.getConsumption() != null) {
                     String consumption = drug.getConsumption().getName();
-                    collectAntibioticInfo(antibioticDateWard, antibioticStatusWard, antibioticValueWard, removeBracket(drug.getName()), consumption, doc.getStructureMap().get("查房日期"));
+                    collectAntibioticInfo(antibioticDateWard, antibioticStatusWard, antibioticValueWard, wardDrug, consumption, doc.getStructureMap().get("查房日期"));
                 }
             }
         }

+ 16 - 1
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03075.java

@@ -4,6 +4,7 @@ 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.kernel.util.SimilarityUtil;
 import com.lantone.qc.pub.model.InputInfo;
 import com.lantone.qc.pub.model.OutputInfo;
 import com.lantone.qc.pub.model.doc.DoctorAdviceDoc;
@@ -11,6 +12,7 @@ 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.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.Date;
@@ -28,6 +30,9 @@ import java.util.stream.Collectors;
  **/
 @Component
 public class THR03075 extends QCCatalogue {
+    @Autowired
+    SimilarityUtil similarityUtil;
+
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
         status.set("0");
         List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
@@ -60,6 +65,10 @@ public class THR03075 extends QCCatalogue {
             value = structMap.get("医嘱单次剂量");
             startDateStr = structMap.get("医嘱开始时间");
             drugName = removeBracket(drugName);
+            String drugStandardWord = similarityUtil.getDrugStandardWord(drugName);
+            if (StringUtil.isNotBlank(drugStandardWord)) {
+                drugName = drugStandardWord;
+            }
             collectAntibioticInfo(antibioticDate, antibioticStatus, antibioticValue, drugName, value, startDateStr);
         }
 
@@ -88,9 +97,15 @@ public class THR03075 extends QCCatalogue {
             ThreeLevelWardLabel label = doc.getThreeLevelWardLabel().get(0);
             List<Drug> drugs = label.getDrugs();
             for (Drug drug : drugs) {
+                String wardDrug = drug.getName();
+                wardDrug = removeBracket(wardDrug);
+                String drugStandardWord = similarityUtil.getDrugStandardWord(wardDrug);
+                if (StringUtil.isNotBlank(drugStandardWord)) {
+                    wardDrug = drugStandardWord;
+                }
                 if (drug.getConsumption() != null) {
                     String consumption = drug.getConsumption().getName();
-                    collectAntibioticInfo(antibioticDateWard, antibioticStatusWard, antibioticValueWard, removeBracket(drug.getName()), consumption, doc.getStructureMap().get("查房日期"));
+                    collectAntibioticInfo(antibioticDateWard, antibioticStatusWard, antibioticValueWard, wardDrug, consumption, doc.getStructureMap().get("查房日期"));
                 }
             }
         }