Преглед на файлове

Merge branch 'dev/ez' into develop

rengb преди 4 години
родител
ревизия
f930dd02e9
променени са 100 файла, в които са добавени 9789 реда и са изтрити 88 реда
  1. 1 1
      common/src/main/java/com/lantone/common/util/DateUtil.java
  2. 2 2
      common/src/main/java/com/lantone/common/util/ListUtil.java
  3. 265 14
      common/src/main/java/com/lantone/common/util/StringUtil.java
  4. 1 1
      config-center/src/main/resources/shared/structureCenter-debug.yml
  5. 1 1
      config-center/src/main/resources/shared/structureCenter-dev.yml
  6. 1 1
      config-center/src/main/resources/shared/structureCenter-local.yml
  7. 1 1
      config-center/src/main/resources/shared/structureCenter-master.yml
  8. 1 1
      config-center/src/main/resources/shared/structureCenter-test.yml
  9. 1 0
      pom.xml
  10. 8 0
      structure-center/src/main/java/com/lantone/structure/ai/AIAnalyze.java
  11. 55 14
      structure-center/src/main/java/com/lantone/structure/ai/BeHospitalizedAI.java
  12. 86 0
      structure-center/src/main/java/com/lantone/structure/ai/CaesareanSectionAI.java
  13. 85 0
      structure-center/src/main/java/com/lantone/structure/ai/ClinicalbloodAI.java
  14. 33 8
      structure-center/src/main/java/com/lantone/structure/ai/FirstCourseRecordAI.java
  15. 2 1
      structure-center/src/main/java/com/lantone/structure/ai/ModelAI.java
  16. 109 1
      structure-center/src/main/java/com/lantone/structure/ai/OperationAI.java
  17. 86 0
      structure-center/src/main/java/com/lantone/structure/ai/RescueAI.java
  18. 86 0
      structure-center/src/main/java/com/lantone/structure/ai/StagesSummaryAI.java
  19. 39 1
      structure-center/src/main/java/com/lantone/structure/ai/ThreeLevelWardAI.java
  20. 13 1
      structure-center/src/main/java/com/lantone/structure/ai/model/EntityEnum.java
  21. 218 0
      structure-center/src/main/java/com/lantone/structure/ai/process/EntityDailyCourseRecord.java
  22. 91 0
      structure-center/src/main/java/com/lantone/structure/ai/process/EntityOperationRecord.java
  23. 8 0
      structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcess.java
  24. 86 0
      structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcessBlood.java
  25. 242 0
      structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcessCaesareanSection.java
  26. 332 0
      structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcessEZaAll.java
  27. 69 0
      structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcessOperation.java
  28. 142 0
      structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcessRescue.java
  29. 72 0
      structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcessStagesSummary.java
  30. 195 0
      structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcessThreeLevelWard.java
  31. 46 0
      structure-center/src/main/java/com/lantone/structure/controller/StructureController.java
  32. 1 1
      structure-center/src/main/java/com/lantone/structure/dto/AnalysisDTO.java
  33. 105 39
      structure-center/src/main/java/com/lantone/structure/facade/StructureFacade.java
  34. 1060 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/BeHospitalizedTran.java
  35. 315 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/CesareanSectionTran.java
  36. 112 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/ClinicBloodConsentDocTran.java
  37. 153 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/ClinicalBloodTran.java
  38. 437 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/ConsultationTran.java
  39. 101 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/CriticallyIllNoticeDocTran.java
  40. 196 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/DailyCourseRecordTran.java
  41. 390 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/DeathCaseDiscussionTran.java
  42. 321 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/DeathRecordTran.java
  43. 209 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/DifficultCaseDiscussTran.java
  44. 161 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/DutyShiftSystemTran.java
  45. 234 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/FirstCourseRecordTran.java
  46. 437 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/InformedConsentTran.java
  47. 229 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/LeaveHospitalTran.java
  48. 240 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/OperationDiscussionTran.java
  49. 106 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/OperationInformedConsentDocTran.java
  50. 296 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/OperationRecordDocTran.java
  51. 427 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/PreoperativeDiscussionTran.java
  52. 250 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/RescueTran.java
  53. 122 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/SpecialCureConsentDocTran.java
  54. 239 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/StagesSummaryTran.java
  55. 41 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/TargetTran.java
  56. 170 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/ThreeLevelWardTran.java
  57. 214 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/TransferRecordTran.java
  58. 295 0
      structure-center/src/main/java/com/lantone/structure/facade/tran/util/CommonAnalysisUtil.java
  59. 11 0
      structure-center/src/main/java/com/lantone/structure/model/Content.java
  60. 2 0
      structure-center/src/main/java/com/lantone/structure/model/InputInfo.java
  61. 16 0
      structure-center/src/main/java/com/lantone/structure/model/doc/CaesareanSectionDoc.java
  62. 2 0
      structure-center/src/main/java/com/lantone/structure/model/doc/ClinicalBloodDoc.java
  63. 2 0
      structure-center/src/main/java/com/lantone/structure/model/doc/DailyCourseRecordDoc.java
  64. 2 0
      structure-center/src/main/java/com/lantone/structure/model/doc/RescueDoc.java
  65. 2 0
      structure-center/src/main/java/com/lantone/structure/model/doc/StagesSummaryDoc.java
  66. 17 0
      structure-center/src/main/java/com/lantone/structure/model/doc/WardRecordDoc.java
  67. 3 0
      structure-center/src/main/java/com/lantone/structure/model/doc/operation/PreoperativeDiscussionDoc.java
  68. 17 0
      structure-center/src/main/java/com/lantone/structure/model/entity/AmnioticFluid.java
  69. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/AmnioticFluidCharacter.java
  70. 16 0
      structure-center/src/main/java/com/lantone/structure/model/entity/Amount.java
  71. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/AnesthesiaMethod.java
  72. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/AnestheticEffect.java
  73. 16 0
      structure-center/src/main/java/com/lantone/structure/model/entity/ApgarScore.java
  74. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/AuxiliaryQuantitative.java
  75. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/AuxiliaryResult.java
  76. 20 0
      structure-center/src/main/java/com/lantone/structure/model/entity/AuxiliaryTest.java
  77. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/BleedQuantity.java
  78. 22 0
      structure-center/src/main/java/com/lantone/structure/model/entity/Blood.java
  79. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/BloodPressure.java
  80. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/BloodQuantity.java
  81. 17 0
      structure-center/src/main/java/com/lantone/structure/model/entity/CaputSuccedaneum.java
  82. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/CaputSuccedaneumPart.java
  83. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/ChildbirthCondition.java
  84. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/ChildbirthWay.java
  85. 17 0
      structure-center/src/main/java/com/lantone/structure/model/entity/Condition.java
  86. 17 0
      structure-center/src/main/java/com/lantone/structure/model/entity/CordAroundBody.java
  87. 17 0
      structure-center/src/main/java/com/lantone/structure/model/entity/CordAroundNeck.java
  88. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/Count.java
  89. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/CylinderNumber.java
  90. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/Diagnosis.java
  91. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/DrainageMaterialsAmount.java
  92. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/DrainageMaterialsName.java
  93. 1 0
      structure-center/src/main/java/com/lantone/structure/model/entity/Drug.java
  94. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/DuringDrugs.java
  95. 16 0
      structure-center/src/main/java/com/lantone/structure/model/entity/EndTime.java
  96. 15 0
      structure-center/src/main/java/com/lantone/structure/model/entity/Extent.java
  97. 16 0
      structure-center/src/main/java/com/lantone/structure/model/entity/FluidInfusion.java
  98. 16 0
      structure-center/src/main/java/com/lantone/structure/model/entity/Hemorrhage.java
  99. 16 0
      structure-center/src/main/java/com/lantone/structure/model/entity/Indication.java
  100. 0 0
      structure-center/src/main/java/com/lantone/structure/model/entity/Intervention.java

+ 1 - 1
common/src/main/java/com/lantone/common/util/DateUtil.java

@@ -63,7 +63,7 @@ public class DateUtil {
     /**
      * 中文全称精确到分钟  如:2010年12月01日  23时15分
      */
-    public static String FORMAT_LONG_CN_MI = "yyyy年MM月dd日  HH时mm分";
+    public static String FORMAT_LONG_CN_MI = "yyyy年MM月dd日HH时mm分";
 
     /**
      * 精确到毫秒的完整中文时间

+ 2 - 2
common/src/main/java/com/lantone/common/util/ListUtil.java

@@ -27,7 +27,7 @@ public class ListUtil {
      * @return
      */
     public static <E> ArrayList<E> newArrayList() {
-        return new ArrayList<>();
+        return new ArrayList<E>();
     }
 
     /**
@@ -74,7 +74,7 @@ public class ListUtil {
     }
 
     public static <E> ArrayList<E> arrayToList(E[] strArray) {
-        ArrayList<E> arrayList = new ArrayList<>(strArray.length);
+        ArrayList<E> arrayList = new ArrayList<E>(strArray.length);
         Collections.addAll(arrayList, strArray);
         return arrayList;
     }

+ 265 - 14
common/src/main/java/com/lantone/common/util/StringUtil.java

@@ -4,7 +4,12 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.time.DateUtils;
 
 import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * @Description: 字符串有关帮助类 封装了第三方帮助类
@@ -52,6 +57,124 @@ public class StringUtil {
         return StringUtils.isNotEmpty(str);
     }
 
+    /**
+     * 删除字符串中的换行和控制字符
+     *
+     * @param str
+     */
+    public static String remove_ctl(String str) {
+        String trim = "";
+        if (StringUtils.isNotEmpty(str)) {
+            trim = str.replaceAll("\r|\n|\r\n|/r/n", "").trim();
+        }
+        return trim;
+    }
+
+    /**
+     * 清除字符串中的空白
+     *
+     * @param str
+     * @return
+     */
+    public static String removeBlank(String str) {
+        if (isBlank(str)) {
+            return str;
+        }
+        return str.replaceAll("[\\s\\p{Zs}]", "").replaceAll(" ", "");
+    }
+
+    /**
+     * 比较两个列表的内容
+     */
+    public static List<String> compareList(List<String> A, List<String> B) {
+        List<String> res = new ArrayList<>();
+
+        for (String i : A) {
+            if (!B.contains(i)) {
+                res.add(i);
+            }
+        }
+
+        for (String j : B) {
+            if (!A.contains(j)) {
+                res.add(j);
+            }
+        }
+
+        return res;
+    }
+
+    /**
+     * 列表A是否包含列表B
+     */
+    public static boolean containList(List<String> A, List<String> B) {
+        boolean res = true;
+
+        try {
+            for (String item : B) {
+                if (!A.contains(item)) {
+                    res = false;
+                    break;
+                }
+            }
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        } finally {
+            return res;
+        }
+    }
+
+    /**
+     * 比较两个字符串集合是否一模一样:个数一样、顺序一样
+     *
+     * @param source
+     * @param target
+     * @return
+     */
+    public static boolean isEqually(List<String> source, List<String> target) {
+        boolean ret = false;
+        if (ListUtil.isNotEmpty(source) && ListUtil.isNotEmpty(target)) {
+            String[] sourceArray = source.toArray(new String[] {});
+            String[] targetArray = target.toArray(new String[] {});
+            ret = Arrays.equals(sourceArray, targetArray);
+        }
+        return ret;
+    }
+
+    /**
+     * 判断字符串是否包含数字
+     *
+     * @param company
+     * @return
+     */
+    public static boolean isContainNumber(String company) {
+        Pattern p = Pattern.compile("[0-9]");
+        Matcher m = p.matcher(company);
+        if (m.find()) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 标点符号空格等转逗号分割
+     *
+     * @param content
+     * @return
+     */
+    public static String specialCharComma(String content) {
+        if (StringUtil.isNotBlank(content)) {
+            content = content.replaceAll("(\\d+)|[、,。.;;??]", " ").replaceAll("(\\s+)", ",");
+            if (content.indexOf(",") == 0) {
+                content = content.substring(1);
+            }
+            if (content.lastIndexOf(",") == content.length() - 1) {
+                content = content.substring(0, content.length() - 1);
+            }
+        }
+        return content;
+    }
+
     /**
      * 判断两个字符串是否相同
      *
@@ -64,16 +187,42 @@ public class StringUtil {
     }
 
     /**
-     * 清除字符串中的空白
+     * 比较两个字符串集合是否内容一样,即A包含B,B包含A,交集为空
+     * 个数、顺序不考虑
      *
-     * @param str
+     * @param source
+     * @param target
      * @return
      */
-    public static String removeBlank(String str) {
-        if (isBlank(str)) {
-            return str;
+    //    public static boolean isSameContent(List<String> source, List<String> target) {
+    //        Set<String> sourceSet = Sets.newHashSet(source);
+    //        Set<String> targetSet = Sets.newHashSet(target);
+    //        return Sets.difference(sourceSet, targetSet).isEmpty() && Sets.difference(targetSet, sourceSet).isEmpty();
+    //    }
+
+
+    /**
+     * 根据给定的时间格式解析时间
+     *
+     * @param datetime
+     * @return
+     */
+    public static Date parseDateTime(String datetime, String[] dateFormats) {
+        Date date = null;
+        try {
+            datetime = remove_ctl(datetime);
+
+            if (datetime.contains("至")) {
+                datetime = datetime.split("至")[1].replaceAll("[\\u4e00-\\u9fa5]", "");
+            }
+            if (datetime.length() > 0) {
+                date = DateUtils.parseDate(datetime, dateFormats);
+            }
+        } catch (ParseException ex) {
+            ex.printStackTrace();
+        } finally {
+            return date;
         }
-        return str.replaceAll("[\\s\\p{Zs}]", "");
     }
 
     /**
@@ -92,7 +241,7 @@ public class StringUtil {
             }
 
             if (datetime.length() > 0) {
-                date = DateUtils.parseDate(datetime, DateUtil.dateFormats);
+                date = DateUtils.parseDate(datetime, dateFormats);
             }
         } catch (ParseException ex) {
             ex.printStackTrace();
@@ -100,17 +249,119 @@ public class StringUtil {
         return date;
     }
 
+    public static String matRegx(String source, String regex1, String regex2, String val) {
+        if (isNotBlank(source) && isNotBlank(regex1) && isNotBlank(regex2)) {
+            Pattern pattern = Pattern.compile(regex1);
+            Matcher matcher = pattern.matcher(source);
+            if (matcher.find()) {
+                String sce1 = matcher.group();
+                if (isBlank(val) || !sce1.contains(val)) {
+                    String sce2 = sce1.replaceAll(regex2, val);
+                    source = source.replaceAll(sce1, sce2);
+                }
+            }
+        }
+        return source;
+    }
+
     /**
-     * 删除字符串中的换行和控制字符
+     * 去除字符串两边空白 包含一些特殊空格
      *
-     * @param str
+     * @param msg
+     * @return
      */
-    public static String remove_ctl(String str) {
-        String trim = "";
-        if(StringUtils.isNotEmpty(str)){
-            trim = str.replaceAll("\r|\n|\r\n|/r/n", "").trim();
+    public static String trim(String msg) {
+        if (isNotBlank(msg)) {
+            return org.springframework.util.StringUtils.trimWhitespace(msg).trim();
         }
-        return trim;
+        return msg;
     }
 
+    /**
+     * 去掉尾部几位符合字符
+     *
+     * @param value
+     * @param regex
+     * @param len
+     * @return
+     */
+    public static String removeWN(String value, String regex, int len) {
+        String ret = value;
+        if (StringUtil.isNotBlank(value) && value.length() >= len) {
+            String endStr = null;
+            for (int i = len; i > 0; i--) {
+                endStr = value.substring(value.length() - len);
+                if (endStr.replaceAll(regex, "").length() == 0) {
+                    ret = value.substring(0, value.length() - len);
+                    break;
+                }
+            }
+        }
+        return ret;
+    }
+
+    public static String[] dateFormats = {
+            "yyyy年MM月dd日HH时mm分",
+            "yyyy年MM月dd日HH:mm",
+            "yyyy年MM月dd日H时mm分",
+            "yyyy年MM月dd日HH时m分",
+            "yyyy年MM月dd日H时m分",
+            "yyyy年M月dd日HH时mm分",
+            "yyyy年M月dd日H时mm分",
+            "yyyy年M月dd日HH时m分",
+            "yyyy年M月dd日H时m分",
+            "yyyy年MM月d日HH时mm分",
+            "yyyy年MM月d日H时mm分",
+            "yyyy年MM月d日HH时m分",
+            "yyyy年MM月d日H时m分",
+            "yyyy年M月d日HH时mm分",
+            "yyyy年M月d日H时mm分",
+            "yyyy年M月d日HH时m分",
+            "yyyy年M月d日H时m分",
+            "yyyy-MM-ddHH:mm:ss",
+            "yyyy-MM-ddHH:mm",
+            "yyyy-MM-ddHH:mm",
+            "yyyy-MM-ddHH:m",
+            "yyyy-MM-ddH:mm",
+            "yyyy-MM-ddH:m",
+            "yyyy-M-ddHH:mm",
+            "yyyy-M-ddHH:m",
+            "yyyy-M-ddH:mm",
+            "yyyy-M-ddH:m",
+            "yyyy-MM-dHH:mm",
+            "yyyy-MM-dHH:m",
+            "yyyy-MM-dH:mm",
+            "yyyy-MM-dH:m",
+            "yyyy-M-dHH:mm",
+            "yyyy-M-dHH:m",
+            "yyyy-M-dH:mm",
+            "yyyy-M-dH:m",
+            "yyyy-MM-dd",
+            "yyyy年MM月dd日H时",
+            "yyyy/MM/ddHH:mm:ss",
+            "yyyy/MM/ddHH:mm",
+            "yyyy/MM/ddHH:m",
+            "yyyy/MM/ddH:mm",
+            "yyyy/MM/ddH:m",
+            "yyyy/MM/ddHH:mm:",
+            "yyyy/M/ddHH:mm",
+            "yyyy/M/ddHH:m",
+            "yyyy/M/ddH:mm",
+            "yyyy/M/ddH:m",
+            "yyyy/MM/dHH:mm",
+            "yyyy/MM/dHH:m",
+            "yyyy/MM/dH:mm",
+            "yyyy/MM/dH:m",
+            "yyyy/M/dHH:mm",
+            "yyyy/M/dHH:m",
+            "yyyy/M/dH:mm",
+            "yyyy/M/dH:m",
+            "yyyy/MM/dd",
+            "yyyy.MM.dd",
+            "yyyy-MM-ddHH:mm:ss.000",
+            "yyyyMMddHH:mm",
+            "yyyy-MM-dd'T'HH:mm:ss",
+            "yyyy-MM-ddTHH:mm:ss",
+    };
+
 }

+ 1 - 1
config-center/src/main/resources/shared/structureCenter-debug.yml

@@ -3,7 +3,7 @@ swagger.des: 数据后结构化服务
 swagger.version: 0.0.1-SNAPSHOT
 
 CRF:
-  url: http://192.168.2.234:3456/api/mr_info_ex/entity_predict
+  url: http://192.168.2.234:3457/api/mr_info_ex/entity_predict
 
 Similarity:
   url: http://192.168.2.234:3456/api/mr_info_ex/similarity

+ 1 - 1
config-center/src/main/resources/shared/structureCenter-dev.yml

@@ -3,7 +3,7 @@ swagger.des: 数据后结构化服务
 swagger.version: 0.0.1-SNAPSHOT
 
 CRF:
-  url: http://192.168.2.234:3456/api/mr_info_ex/entity_predict
+  url: http://192.168.2.234:3457/api/mr_info_ex/entity_predict
 
 Similarity:
   url: http://192.168.2.234:3456/api/mr_info_ex/similarity

+ 1 - 1
config-center/src/main/resources/shared/structureCenter-local.yml

@@ -3,7 +3,7 @@ swagger.des: 数据后结构化服务
 swagger.version: 0.0.1-SNAPSHOT
 
 CRF:
-  url: http://192.168.2.234:3456/api/mr_info_ex/entity_predict
+  url: http://192.168.2.234:3457/api/mr_info_ex/entity_predict
 
 Similarity:
   url: http://192.168.2.234:3456/api/mr_info_ex/similarity

+ 1 - 1
config-center/src/main/resources/shared/structureCenter-master.yml

@@ -3,7 +3,7 @@ swagger.des: 数据后结构化服务
 swagger.version: 0.0.1-SNAPSHOT
 
 CRF:
-  url: http://192.168.2.234:3456/api/mr_info_ex/entity_predict
+  url: http://192.168.2.234:3457/api/mr_info_ex/entity_predict
 
 Similarity:
   url: http://192.168.2.234:3456/api/mr_info_ex/similarity

+ 1 - 1
config-center/src/main/resources/shared/structureCenter-test.yml

@@ -3,7 +3,7 @@ swagger.des: 数据后结构化服务
 swagger.version: 0.0.1-SNAPSHOT
 
 CRF:
-  url: http://192.168.2.234:3456/api/mr_info_ex/entity_predict
+  url: http://192.168.2.234:3457/api/mr_info_ex/entity_predict
 
 Similarity:
   url: http://192.168.2.234:3456/api/mr_info_ex/similarity

+ 1 - 0
pom.xml

@@ -22,6 +22,7 @@
         <module>config-center</module>
         <module>common</module>
         <module>structure-center</module>
+        <module>gateway-service</module>
     </modules>
 
     <properties>

+ 8 - 0
structure-center/src/main/java/com/lantone/structure/ai/AIAnalyze.java

@@ -16,6 +16,10 @@ public class AIAnalyze {
     ThreeLevelWardAI threeLevelWardAI = new ThreeLevelWardAI();
     OperationAI operationAI = new OperationAI();
     ConsultationAI consultationAI = new ConsultationAI();
+    ClinicalbloodAI clinicalbloodAI = new ClinicalbloodAI();
+    StagesSummaryAI stagesSummaryAI = new StagesSummaryAI();
+    RescueAI rescueAI = new RescueAI();
+    CaesareanSectionAI caesareanSectionAI = new CaesareanSectionAI();
 
     public AIAnalyze(CRFServiceClient crfService, SimilarityServiceClient similarityServiceClient) {
         this.crfServiceClient = crfService;
@@ -29,6 +33,10 @@ public class AIAnalyze {
         threeLevelWardAI.medrec(inputInfo, crfServiceClient);
         operationAI.medrec(inputInfo, crfServiceClient);
         consultationAI.medrec(inputInfo, crfServiceClient);
+        clinicalbloodAI.medrec(inputInfo, crfServiceClient);
+        stagesSummaryAI.medrec(inputInfo, crfServiceClient);
+        rescueAI.medrec(inputInfo, crfServiceClient);
+        caesareanSectionAI.medrec(inputInfo, crfServiceClient);
     }
 
 }

+ 55 - 14
structure-center/src/main/java/com/lantone/structure/ai/BeHospitalizedAI.java

@@ -2,6 +2,8 @@ package com.lantone.structure.ai;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.lantone.common.util.ListUtil;
+import com.lantone.structure.ai.process.*;
 import com.lantone.structure.client.CRFServiceClient;
 import com.lantone.structure.ai.process.EntityProcessClinic;
 import com.lantone.structure.ai.process.EntityProcessDiag;
@@ -16,25 +18,17 @@ import com.lantone.structure.ai.process.EntityProcessVital;
 import com.lantone.structure.model.Content;
 import com.lantone.structure.model.InputInfo;
 import com.lantone.structure.model.doc.BeHospitalizedDoc;
-import com.lantone.structure.model.entity.Diag;
-import com.lantone.structure.model.entity.Lis;
-import com.lantone.structure.model.entity.Pacs;
-import com.lantone.structure.model.entity.Vital;
-import com.lantone.structure.model.label.ChiefLabel;
-import com.lantone.structure.model.label.DiagLabel;
-import com.lantone.structure.model.label.FamilyLabel;
-import com.lantone.structure.model.label.MaritalLabel;
-import com.lantone.structure.model.label.MenstrualLabel;
-import com.lantone.structure.model.label.PacsLabel;
-import com.lantone.structure.model.label.PastLabel;
-import com.lantone.structure.model.label.PersonalLabel;
-import com.lantone.structure.model.label.PresentLabel;
+import com.lantone.structure.model.entity.*;
+import com.lantone.structure.model.label.*;
 import com.lantone.common.util.FastJsonUtils;
 import com.lantone.common.util.StringUtil;
 import org.springframework.stereotype.Component;
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
+
+import static com.lantone.structure.model.Content.familyLabel;
 
 /**
  * @ClassName : InHospitalDoc
@@ -56,7 +50,7 @@ public class BeHospitalizedAI extends ModelAI {
      * DiagnoseInAssistant[辅助检查]
      */
     public static List<String> medicalTextType = Arrays.asList("FirstCourseRecord_cx", "PastFamily_cx", "PersonalHistory_cx", "HPIForCX_cx",
-            "GeneralVital_cx", "chief_present", "Diagnoses_cx", "Present_cx", "DiagnoseInAssistant");
+            "GeneralVital_cx", "chief_present", "Diagnoses_cx", "Present_cx", "DiagnoseInAssistant","Taizhou_past_family");
     public static String entityRelationObject = "entity_relation_object";
     public static String outputs = "outputs";
 
@@ -64,6 +58,16 @@ public class BeHospitalizedAI extends ModelAI {
         JSONArray crfContent = new JSONArray();
         BeHospitalizedDoc beHospitalizedDoc = inputInfo.getBeHospitalizedDoc();
         if (beHospitalizedDoc != null) {
+            Map<String, String> structureMap = beHospitalizedDoc.getStructureMap();
+           // String text = beHospitalizedDoc.getText();
+            if (StringUtil.isNotEmpty(structureMap.get("既往史"))) {
+                String opName = "既往史:" + structureMap.get("既往史");
+                putContent(crfContent, medicalTextType.get(9), opName, Content.pastLabel);
+            }
+            if (StringUtil.isNotEmpty(structureMap.get("家族史"))) {
+                String opName = "家族史:" + structureMap.get("家族史");
+                putContent(crfContent, medicalTextType.get(9), opName, familyLabel);
+            }
             /* 主诉 */
             if (beHospitalizedDoc.getChiefLabel() != null && beHospitalizedDoc.getChiefLabel().isCrfLabel()) {
                 String chiefText = beHospitalizedDoc.getChiefLabel().getText();
@@ -147,6 +151,30 @@ public class BeHospitalizedAI extends ModelAI {
             }
 
             JSONObject midData = loadAI(crfContent, crfServiceClient);
+            if (midData.get(Content.pastLabel) != null || midData.get(familyLabel) != null){
+                BeHospitalizedDoc beHospitalizedDocs = new BeHospitalizedDoc();
+                /* 恩泽过敏史、输血史、手术史、预防接种史、疾病史(含外伤)*/
+                if (midData.get(Content.pastLabel) != null)
+                    EZAllCrfData(midData.getJSONObject(Content.pastLabel), inputInfo);
+                     beHospitalizedDocs = inputInfo.getBeHospitalizedDoc();
+                List<DiagInfectious> flagDia = beHospitalizedDocs.getPastLabel().getDiagInfectiouses();
+                /* 恩泽传染病史 */
+                if (midData.get(familyLabel) != null) {
+                    EZAllCrfData(midData.getJSONObject(familyLabel), inputInfo);
+                    List<DiagInfectious> diagInfectiouses = inputInfo.getBeHospitalizedDoc().getPastLabel().getDiagInfectiouses();
+                    if(ListUtil.isNotEmpty(flagDia) && ListUtil.isNotEmpty(diagInfectiouses)){
+                        for (DiagInfectious diagInfectiouse : diagInfectiouses) {
+                            flagDia.add(diagInfectiouse);
+                        }
+                    }else {
+                        if(ListUtil.isNotEmpty(diagInfectiouses)){
+                            flagDia = diagInfectiouses;
+                        }
+                    }
+                    beHospitalizedDocs.getPastLabel().setDiagInfectiouses(flagDia);
+                    inputInfo.setBeHospitalizedDoc(beHospitalizedDocs);
+                }
+            }
 
             /* 处理主诉 */
             if (beHospitalizedDoc.getChiefLabel() != null && beHospitalizedDoc.getChiefLabel().isCrfLabel()) {
@@ -222,6 +250,19 @@ public class BeHospitalizedAI extends ModelAI {
         System.out.println(FastJsonUtils.getBeanToJson(chiefLabel));
     }
 
+         public void EZAllCrfData(JSONObject jsonObject, InputInfo inputInfo) {
+        if (jsonObject == null) {
+            return;
+        }
+        JSONObject aiOut = jsonObject.getJSONObject(entityRelationObject).getJSONObject(BeHospitalizedAI.outputs);
+        if (aiOut == null) {
+            return;
+        }
+             EntityProcessEZaAll entityProcessEZaAll = new EntityProcessEZaAll();
+             BeHospitalizedDoc beHospitalizedDoc = entityProcessEZaAll.extractEntity(aiOut);
+             inputInfo.setBeHospitalizedDoc(beHospitalizedDoc);
+         }
+
     public void putPresentCrfData(JSONObject jsonObject, InputInfo inputInfo) {
         if (jsonObject == null) {
             return;

+ 86 - 0
structure-center/src/main/java/com/lantone/structure/ai/CaesareanSectionAI.java

@@ -0,0 +1,86 @@
+package com.lantone.structure.ai;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Lists;
+import com.lantone.common.util.CatalogueUtil;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.ai.process.EntityProcessCaesareanSection;
+import com.lantone.structure.client.CRFServiceClient;
+import com.lantone.structure.model.Content;
+import com.lantone.structure.model.InputInfo;
+import com.lantone.structure.model.doc.CaesareanSectionDoc;
+import com.lantone.structure.model.label.CaesareanSectionLabel;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @ClassName : CaesareanSectionAI
+ * @Description : 剖宫产手术
+ * @Author : wsy
+ * @Date: 2021-01-26 17:52
+ */
+public class CaesareanSectionAI extends ModelAI {
+
+    public static List<String> medicalTextType = Arrays.asList("Taizhou_Caesarean_section");
+    public static String entityRelationObject = "entity_relation_object";
+    public static String outputs = "outputs";
+    public static String content = "content";
+    public static List<String> mapKey = Lists.newArrayList("手术指征", "术中后诊断", "手术名称", "麻醉方式"
+            , "手术简要经过", "手术经过及处理", "术后注意事项");
+
+    public void medrec(InputInfo inputInfo, CRFServiceClient crfServiceClient) {
+        JSONArray crfContent = new JSONArray();
+        List<CaesareanSectionDoc> resultsDocs = inputInfo.getCaesareanSectionDocs();
+        for (int i = 0; i < resultsDocs.size(); i++) {
+            String content = resultsDocs.get(i).getText();
+            putContent(crfContent, medicalTextType.get(0), content, Content.caesareanSection);
+        }
+
+        JSONObject midData = loadAI(crfContent, crfServiceClient);//crf返回数据
+
+        for (int i = 0; i < resultsDocs.size(); i++) {
+            if (midData.get(Content.caesareanSection) == null) {
+                continue;
+            }
+            CaesareanSectionDoc caesareanSectionDoc = resultsDocs.get(i);
+            CaesareanSectionLabel caesareanSectionLabel = putCaesareanSectionCrfData(midData.getJSONObject(Content.caesareanSection));
+            if (caesareanSectionLabel != null) {
+                caesareanSectionDoc.setCaesareanSectionLabel(caesareanSectionLabel);
+            }
+        }
+    }
+
+    /**
+     * 处理剖宫产手术
+     *
+     * @param jsonObject
+     */
+    public CaesareanSectionLabel putCaesareanSectionCrfData(JSONObject jsonObject) {
+        CaesareanSectionLabel caesareanSectionLabel = new CaesareanSectionLabel();
+        if (jsonObject == null) {
+            return caesareanSectionLabel;
+        }
+        JSONObject aiOut = jsonObject.getJSONObject(entityRelationObject).getJSONObject(RescueAI.outputs);
+        if (aiOut == null) {
+            return caesareanSectionLabel;
+        }
+        EntityProcessCaesareanSection entityProcessCaesareanSection = new EntityProcessCaesareanSection();
+        caesareanSectionLabel = entityProcessCaesareanSection.extractEntity(aiOut);
+        return caesareanSectionLabel;
+    }
+
+    protected void putContent(JSONArray crfContent, String medicalTextType, String text, String sign) {
+        String move_text = CatalogueUtil.removeSpecialChar(text);
+        if (StringUtil.isEmpty(move_text)) {
+            return;
+        }
+        JSONObject detailContent = new JSONObject();
+        detailContent.put("medical_text_type", medicalTextType);
+        detailContent.put("content", move_text);
+        detailContent.put("detail_title", sign);
+        detailContent.put("originalText", text);
+        crfContent.add(detailContent);
+    }
+}

+ 85 - 0
structure-center/src/main/java/com/lantone/structure/ai/ClinicalbloodAI.java

@@ -0,0 +1,85 @@
+package com.lantone.structure.ai;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Lists;
+import com.lantone.common.util.CatalogueUtil;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.ai.process.EntityProcessBlood;
+import com.lantone.structure.model.Content;
+import com.lantone.structure.model.InputInfo;
+import com.lantone.structure.client.CRFServiceClient;
+import com.lantone.structure.model.doc.ClinicalBloodDoc;
+import com.lantone.structure.model.label.ClinicalBloodLabel;
+
+import java.util.*;
+
+/**
+ * @ClassName : ClinicalbloodAI
+ * @Description : 输血记录
+ * @Author : wsy
+ * @Date: 2021-01-19 17:16
+ */
+public class ClinicalbloodAI extends ModelAI {
+
+    public static List<String> medicalTextType = Arrays.asList("Taizhou_blood_record");
+    public static String entityRelationObject = "entity_relation_object";
+    public static String outputs = "outputs";
+    public static String content = "content";
+    public static List<String> mapKey = Lists.newArrayList("病历内容");
+
+    public void medrec(InputInfo inputInfo, CRFServiceClient crfServiceClient) {
+        JSONArray crfContent = new JSONArray();
+        List<ClinicalBloodDoc> resultsDocs = inputInfo.getClinicalBloodDocs();
+        for (int i = 0; i < resultsDocs.size(); i++) {
+            String content = resultsDocs.get(i).getText();
+            putContent(crfContent, medicalTextType.get(0), content, Content.bloodRecord);
+        }
+
+        JSONObject midData = loadAI(crfContent, crfServiceClient);//crf返回数据
+
+        for (int i = 0; i < resultsDocs.size(); i++) {
+            if (midData.get(Content.bloodRecord) == null) {
+                continue;
+            }
+            ClinicalBloodDoc resultsDoc = resultsDocs.get(i);
+            ClinicalBloodLabel clinicalBloodLabel = putBloodRecordCrfData(midData.getJSONObject(Content.bloodRecord), inputInfo);
+            if (clinicalBloodLabel != null) {
+                resultsDoc.setClinicalBloodLabel(clinicalBloodLabel);
+            }
+        }
+    }
+
+
+    /**
+     * 处理输血记录
+     *
+     * @param jsonObject
+     */
+    public ClinicalBloodLabel putBloodRecordCrfData(JSONObject jsonObject, InputInfo inputInfo) {
+        ClinicalBloodLabel clinicalBloodLabel = new ClinicalBloodLabel();
+        if (jsonObject == null) {
+            return clinicalBloodLabel;
+        }
+        JSONObject aiOut = jsonObject.getJSONObject(entityRelationObject).getJSONObject(BeHospitalizedAI.outputs);
+        if (aiOut == null) {
+            return clinicalBloodLabel;
+        }
+        EntityProcessBlood entityProcessBlood = new EntityProcessBlood();
+        clinicalBloodLabel = entityProcessBlood.extractEntity(aiOut);
+        return clinicalBloodLabel;
+    }
+
+    protected void putContent(JSONArray crfContent, String medicalTextType, String text, String sign) {
+        String move_text = CatalogueUtil.removeSpecialChar(text);
+        if (StringUtil.isEmpty(move_text)) {
+            return;
+        }
+        JSONObject detailContent = new JSONObject();
+        detailContent.put("medical_text_type", medicalTextType);
+        detailContent.put("content", move_text);
+        detailContent.put("detail_title", sign);
+        detailContent.put("originalText", text);
+        crfContent.add(detailContent);
+    }
+}

+ 33 - 8
structure-center/src/main/java/com/lantone/structure/ai/FirstCourseRecordAI.java

@@ -3,21 +3,18 @@ package com.lantone.structure.ai;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.google.common.collect.Lists;
+import com.lantone.common.util.ListUtil;
+import com.lantone.structure.ai.process.*;
 import com.lantone.structure.client.CRFServiceClient;
 import com.lantone.structure.client.SimilarityServiceClient;
-import com.lantone.structure.ai.process.EntityProcessClinic;
-import com.lantone.structure.ai.process.EntityProcessDiag;
-import com.lantone.structure.ai.process.EntityProcessDrug;
-import com.lantone.structure.ai.process.EntityProcessTreatPlan;
 import com.lantone.common.util.CatalogueUtil;
 import com.lantone.structure.model.Content;
 import com.lantone.structure.model.InputInfo;
+import com.lantone.structure.model.doc.DailyCourseRecordDoc;
 import com.lantone.structure.model.doc.FirstCourseRecordDoc;
 import com.lantone.structure.model.entity.Diag;
 import com.lantone.structure.model.entity.Drug;
-import com.lantone.structure.model.label.DrugLabel;
-import com.lantone.structure.model.label.PresentLabel;
-import com.lantone.structure.model.label.TreatPlanLabel;
+import com.lantone.structure.model.label.*;
 import com.lantone.common.util.StringUtil;
 import org.apache.commons.lang3.StringUtils;
 
@@ -36,7 +33,7 @@ public class FirstCourseRecordAI extends ModelAI {
      *
      */
     public static List<String> medicalTextType = Arrays.asList("FirstCoursera_cx", "Diagnoses_cx"
-            , "FirstCourseTreatment_cx", "CourseRecordSRR");
+            , "FirstCourseTreatment_cx", "CourseRecordSRR","Taizhou_daily_record");
     public static String entityRelationObject = "entity_relation_object";
     public static String outputs = "outputs";
     public static String content = "content";
@@ -44,6 +41,16 @@ public class FirstCourseRecordAI extends ModelAI {
     public void medrec(InputInfo inputInfo, CRFServiceClient crfServiceClient, SimilarityServiceClient similarityServiceClient) {
         JSONArray crfContent = new JSONArray();
         JSONArray similarContent = new JSONArray();
+        List<DailyCourseRecordDoc> dailyCourseRecordDocs  = inputInfo.getDailyCourseRecordDocs();
+        if (ListUtil.isNotEmpty(dailyCourseRecordDocs)) {
+            DailyCourseRecordDoc dailyCourseRecordDoc = dailyCourseRecordDocs.get(0);
+            if (dailyCourseRecordDoc != null) {
+                String text = dailyCourseRecordDoc.getText();
+                putContent(crfContent, medicalTextType.get(4), text, Content.doctorAdviceRecord);
+                JSONObject midData = loadAI(crfContent, crfServiceClient);//crf返回数据
+                dailyCourseRecordCrfData(midData.getJSONObject(Content.doctorAdviceRecord), inputInfo);
+            }
+        }
         FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
         if (firstCourseRecordDoc != null) {
             Map<String, String> structureMap = firstCourseRecordDoc.getStructureMap();
@@ -187,6 +194,24 @@ public class FirstCourseRecordAI extends ModelAI {
         inputInfo.getFirstCourseRecordDoc().getInitialDiagLabel().setDiags(diags);
     }
 
+    /**
+     * 处理日常病程记录
+     *
+     * @param jsonObject
+     */
+    public void dailyCourseRecordCrfData(JSONObject jsonObject, InputInfo inputInfo) {
+        if (jsonObject == null) {
+            return;
+        }
+        JSONObject aiOut = jsonObject.getJSONObject(entityRelationObject).getJSONObject(BeHospitalizedAI.outputs);
+        if (aiOut == null) {
+            return;
+        }
+        EntityDailyCourseRecord entityDailyCourseRecord = new EntityDailyCourseRecord();
+        DailyCourseRecordLabel dailyCourseRecordLabel = entityDailyCourseRecord.extractEntity(aiOut);
+        inputInfo.getDailyCourseRecordDocs().get(0).setDailyCourseRecordLabel(dailyCourseRecordLabel);
+    }
+
     /**
      * 诊断依据
      *

+ 2 - 1
structure-center/src/main/java/com/lantone/structure/ai/ModelAI.java

@@ -35,7 +35,7 @@ public class ModelAI {
     protected JSONObject loadAI(JSONArray crfContent, CRFServiceClient crfServiceClient) {
         JSONArray data = null;
         String classname = this.getClass().getName();
-        if (data == null) {
+        if (data == null || data.size() == 0) {
             //存储CRF完整所需结构数据
             CRFVo crfVo = new CRFVo();
             crfVo.setData(crfContent);
@@ -49,6 +49,7 @@ public class ModelAI {
         return midData;
     }
 
+
     protected JSONObject loadEntity(JSONObject jsonObject, String entityRelationObject, String outputs, String content) {
         if (jsonObject == null) {
             return new JSONObject();

+ 109 - 1
structure-center/src/main/java/com/lantone/structure/ai/OperationAI.java

@@ -3,6 +3,8 @@ package com.lantone.structure.ai;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.google.common.collect.Lists;
+import com.lantone.structure.ai.process.EntityOperationRecord;
+import com.lantone.structure.ai.process.EntityProcessOperation;
 import com.lantone.structure.client.CRFServiceClient;
 import com.lantone.structure.ai.process.EntityProcessDrug;
 import com.lantone.structure.ai.process.EntityProcessOperationDiscussion;
@@ -12,10 +14,12 @@ import com.lantone.structure.model.InputInfo;
 import com.lantone.structure.model.doc.operation.OperationDiscussionDoc;
 import com.lantone.structure.model.doc.operation.OperationDoc;
 import com.lantone.structure.model.doc.operation.OperationRecordDoc;
+import com.lantone.structure.model.doc.operation.PreoperativeDiscussionDoc;
 import com.lantone.structure.model.entity.Drug;
 import com.lantone.structure.model.label.OperationDiscussionLabel;
 import com.lantone.structure.model.label.OperationRecordLabel;
 import com.lantone.common.util.StringUtil;
+import com.lantone.structure.model.label.PreoperativeDiscussionLabel;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -32,7 +36,7 @@ public class OperationAI extends ModelAI {
     /**
      *
      */
-    public static List<String> medicalTextType = Arrays.asList("CourseAfterOperation_cx", "CourseRecordSRR");
+    public static List<String> medicalTextType = Arrays.asList("CourseAfterOperation_cx", "CourseRecordSRR", "Taizhou_before_surgery", "Taizhou_operation");
     public static String entityRelationObject = "entity_relation_object";
     public static String outputs = "outputs";
     public static String content = "content";
@@ -43,12 +47,55 @@ public class OperationAI extends ModelAI {
         JSONArray crfContent = new JSONArray();
         List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
         for (int i = 0; i < operationDocs.size(); i++) {
+            if (operationDocs.get(i).getPreoperativeDiscussionDoc() != null) {
+                PreoperativeDiscussionDoc preoperativeDiscussionDoc = operationDocs.get(i).getPreoperativeDiscussionDoc();
+                Map<String, String> structureMap = preoperativeDiscussionDoc.getStructureMap();
+                String text = preoperativeDiscussionDoc.getText();
+                //部位
+
+                StringBuffer sb = new StringBuffer();
+                if (StringUtil.isNotEmpty(structureMap.get("拟实施手术及操作名称"))) {
+                    String opName = "拟实施手术及操作名称:" + structureMap.get("拟实施手术及操作名称");
+                    putContent(crfContent, medicalTextType.get(2), opName, Content.surgicalSite);
+                }
+                //手术禁忌 = 手术指征 || 术前准备
+                //手术禁忌 = 诊断依据 || 术前准备 || "药物、食物过敏史
+                String opFlag = structureMap.get("手术指征");
+                if (StringUtil.isNotEmpty(opFlag)) {
+                    sb.append("手术指征:" + opFlag + "\n");
+                }
+
+                String preCase = structureMap.get("术前准备");
+                if (StringUtil.isNotEmpty(preCase)) {
+                    sb.append("术前准备:" + preCase + "\n");
+                }
+
+                String simCase = structureMap.get("诊断依据");
+                if (StringUtil.isNotEmpty(simCase)) {
+                    sb.append("简要病情:" + simCase + "\n");
+                }
+
+                String pillCase = structureMap.get("药物、食物过敏史");
+                if (StringUtil.isNotEmpty(pillCase) && StringUtil.isEmpty(simCase)) {
+                    sb.append("药物、食物过敏史:" + pillCase + "\n");
+                }
+
+                if (StringUtil.isNotEmpty(sb.toString())) {
+                    text = sb.toString();
+                    putContent(crfContent, medicalTextType.get(2), text, Content.preoperativeDiscussion);
+                }
+            }
             if (operationDocs.get(i).getOperationRecordDoc() != null) {
                 OperationRecordDoc operationRecordDoc = operationDocs.get(i).getOperationRecordDoc();
                 Map<String, String> structureMap = operationRecordDoc.getStructureMap();
                 //存放抓取的药品
                 String content = CatalogueUtil.structureMapJoin(structureMap, Lists.newArrayList("手术经过及处理", "手术中用药(化疗等药物)"));
                 putContent(crfContent, medicalTextType.get(1), content, "手术记录" + i + "药物");
+
+                /***************************** 后结构化数据处理(一般手术记录)****************************************/
+                if (operationRecordDoc.getStructureMap() != null) {
+                    putContent(crfContent, medicalTextType.get(3), operationRecordDoc.getStructureMap().get("手术过程描述"), Content.operationRecord);
+                }
             }
             if (operationDocs.get(i).getOperationDiscussionDoc() != null) {
                 OperationDiscussionDoc operationDiscussionDoc = operationDocs.get(i).getOperationDiscussionDoc();
@@ -63,6 +110,21 @@ public class OperationAI extends ModelAI {
 
         JSONObject midData = loadAI(crfContent, crfServiceClient);//crf返回数据
 
+        for (int i = 0; i < operationDocs.size(); i++) {
+            if (midData.get(Content.preoperativeDiscussion) == null) {
+                continue;
+            }
+            if (midData.get(Content.surgicalSite) == null) {
+                continue;
+            }
+            putPreoperativeDiscussionCrfData(midData.getJSONObject(Content.preoperativeDiscussion), inputInfo);
+            PreoperativeDiscussionLabel preoperativeDiscussionLabel = inputInfo.getOperationDocs().get(0).getPreoperativeDiscussionDoc().getPreoperativeDiscussionLabel();
+            putPreoperativeDiscussionCrfData(midData.getJSONObject(Content.surgicalSite), inputInfo);
+            PreoperativeDiscussionLabel preoperativeDiscussionLabelRe = inputInfo.getOperationDocs().get(0).getPreoperativeDiscussionDoc().getPreoperativeDiscussionLabel();
+            preoperativeDiscussionLabel.setOpBottomName(preoperativeDiscussionLabelRe.getOpBottomName());
+            inputInfo.getOperationDocs().get(0).getPreoperativeDiscussionDoc().setPreoperativeDiscussionLabel(preoperativeDiscussionLabel);
+        }
+
         for (int i = 0; i < operationDocs.size(); i++) {
             if (midData.get("手术记录" + i + "药物") != null) {
                 OperationRecordDoc operationRecordDoc = operationDocs.get(i).getOperationRecordDoc();
@@ -85,9 +147,37 @@ public class OperationAI extends ModelAI {
                     discussionLabel.setDrugs(putDrugCrfData(midData.getJSONObject(Content.operation_Discussion + i + "药物")));
                 }
             }
+
+            /***************************** 后结构化数据处理(一般手术记录)****************************************/
+            if (midData.get(Content.operationRecord) != null) {
+                OperationRecordDoc operationRecordDoc = operationDocs.get(i).getOperationRecordDoc();
+                OperationRecordLabel operationRecordLabel = putOperationRecordCrfData(midData.getJSONObject(Content.operationRecord), inputInfo);
+                if (operationRecordLabel != null) {
+                    operationRecordDoc.setOperationRecordLabel(operationRecordLabel);
+                }
+            }
         }
     }
 
+    /**
+     * 处理后结构化一般手术记录
+     *
+     * @param jsonObject
+     */
+    public OperationRecordLabel putOperationRecordCrfData(JSONObject jsonObject, InputInfo inputInfo) {
+        OperationRecordLabel operationRecordLabel = new OperationRecordLabel();
+        if (jsonObject == null) {
+            return operationRecordLabel;
+        }
+        JSONObject aiOut = jsonObject.getJSONObject(entityRelationObject).getJSONObject(BeHospitalizedAI.outputs);
+        if (aiOut == null) {
+            return operationRecordLabel;
+        }
+        EntityOperationRecord entityOperationRecord = new EntityOperationRecord();
+        operationRecordLabel = entityOperationRecord.extractEntity(aiOut);
+        return operationRecordLabel;
+    }
+
     /**
      * 处理手术记录
      *
@@ -118,6 +208,24 @@ public class OperationAI extends ModelAI {
         return drugs;
     }
 
+    /**
+     * 处理术前小结
+     *
+     * @param jsonObject
+     */
+    public void putPreoperativeDiscussionCrfData(JSONObject jsonObject, InputInfo inputInfo) {
+        if (jsonObject == null) {
+            return;
+        }
+        JSONObject aiOut = jsonObject.getJSONObject(entityRelationObject).getJSONObject(BeHospitalizedAI.outputs);
+        if (aiOut == null) {
+            return;
+        }
+        EntityProcessOperation entityProcessOperation = new EntityProcessOperation();
+        PreoperativeDiscussionLabel preoperativeDiscussionLabel = entityProcessOperation.extractEntity(aiOut);
+        inputInfo.getOperationDocs().get(0).getPreoperativeDiscussionDoc().setPreoperativeDiscussionLabel(preoperativeDiscussionLabel);
+    }
+
     protected void putContent(JSONArray crfContent, String medicalTextType, String text, String sign) {
         String move_text = CatalogueUtil.removeSpecialChar(text);
         if (StringUtil.isEmpty(move_text)) {

+ 86 - 0
structure-center/src/main/java/com/lantone/structure/ai/RescueAI.java

@@ -0,0 +1,86 @@
+package com.lantone.structure.ai;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Lists;
+import com.lantone.common.util.CatalogueUtil;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.ai.process.EntityProcessRescue;
+import com.lantone.structure.client.CRFServiceClient;
+import com.lantone.structure.model.Content;
+import com.lantone.structure.model.InputInfo;
+import com.lantone.structure.model.doc.RescueDoc;
+import com.lantone.structure.model.label.RescueLabel;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : RescueAI
+ * @Description :抢救记录
+ * @Author : wsy
+ * @Date: 2021-01-25 17:16
+ */
+public class RescueAI extends ModelAI {
+
+    public static List<String> medicalTextType = Arrays.asList("Taizhou_rescue_record");
+    public static String entityRelationObject = "entity_relation_object";
+    public static String outputs = "outputs";
+    public static String content = "content";
+    public static List<String> mapKey = Lists.newArrayList("抢救内容");
+
+    public void medrec(InputInfo inputInfo, CRFServiceClient crfServiceClient) {
+        JSONArray crfContent = new JSONArray();
+        List<RescueDoc> resultsDocs = inputInfo.getRescueDocs();
+        for (int i = 0; i < resultsDocs.size(); i++) {
+            String content = resultsDocs.get(i).getText();
+            putContent(crfContent, medicalTextType.get(0), content, Content.rescue);
+        }
+
+        JSONObject midData = loadAI(crfContent, crfServiceClient);//crf返回数据
+
+        for (int i = 0; i < resultsDocs.size(); i++) {
+            if (midData.get(Content.rescue) == null) {
+                continue;
+            }
+            RescueDoc resultsDoc = resultsDocs.get(i);
+            RescueLabel rescueLabel = putRescueCrfData(midData.getJSONObject(Content.rescue), inputInfo);
+            if (rescueLabel != null) {
+                resultsDoc.setRescueLabel(rescueLabel);
+            }
+        }
+    }
+
+
+    /**
+     * 处理抢救记录
+     *
+     * @param jsonObject
+     */
+    public RescueLabel putRescueCrfData(JSONObject jsonObject, InputInfo inputInfo) {
+        RescueLabel rescueLabel = new RescueLabel();
+        if (jsonObject == null) {
+            return rescueLabel;
+        }
+        JSONObject aiOut = jsonObject.getJSONObject(entityRelationObject).getJSONObject(RescueAI.outputs);
+        if (aiOut == null) {
+            return rescueLabel;
+        }
+        EntityProcessRescue entityProcessRescue = new EntityProcessRescue();
+        rescueLabel = entityProcessRescue.extractEntity(aiOut);
+        return rescueLabel;
+    }
+
+    protected void putContent(JSONArray crfContent, String medicalTextType, String text, String sign) {
+        String move_text = CatalogueUtil.removeSpecialChar(text);
+        if (StringUtil.isEmpty(move_text)) {
+            return;
+        }
+        JSONObject detailContent = new JSONObject();
+        detailContent.put("medical_text_type", medicalTextType);
+        detailContent.put("content", move_text);
+        detailContent.put("detail_title", sign);
+        crfContent.add(detailContent);
+    }
+}

+ 86 - 0
structure-center/src/main/java/com/lantone/structure/ai/StagesSummaryAI.java

@@ -0,0 +1,86 @@
+package com.lantone.structure.ai;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Lists;
+import com.lantone.common.util.CatalogueUtil;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.ai.process.EntityProcessStagesSummary;
+import com.lantone.structure.client.CRFServiceClient;
+import com.lantone.structure.model.Content;
+import com.lantone.structure.model.InputInfo;
+import com.lantone.structure.model.doc.StagesSummaryDoc;
+import com.lantone.structure.model.label.StagesSummaryLabel;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : StagesSummaryAI
+ * @Description : 阶段小结
+ * @Author : wsy
+ * @Date: 2021-01-25 17:16
+ */
+public class StagesSummaryAI extends ModelAI {
+
+    public static List<String> medicalTextType = Arrays.asList("Taizhou_summary");
+    public static String entityRelationObject = "entity_relation_object";
+    public static String outputs = "outputs";
+    public static String content = "content";
+    public static List<String> mapKey = Lists.newArrayList("病历内容","诊治经过");
+
+    public void medrec(InputInfo inputInfo, CRFServiceClient crfServiceClient) {
+        JSONArray crfContent = new JSONArray();
+        List<StagesSummaryDoc> resultsDocs = inputInfo.getStagesSummaryDocs();
+        for (int i = 0; i < resultsDocs.size(); i++) {
+            String content = resultsDocs.get(i).getText();
+            putContent(crfContent, medicalTextType.get(0), content, Content.stagesSummary);
+        }
+
+        JSONObject midData = loadAI(crfContent, crfServiceClient);//crf返回数据
+
+        for (int i = 0; i < resultsDocs.size(); i++) {
+            if (midData.get(Content.stagesSummary) == null) {
+                continue;
+            }
+            StagesSummaryDoc resultsDoc = resultsDocs.get(i);
+            StagesSummaryLabel stagesSummaryLabel = putStagesSummaryCrfData(midData.getJSONObject(Content.stagesSummary), inputInfo);
+            if (stagesSummaryLabel != null) {
+                resultsDoc.setStagesSummaryLabel(stagesSummaryLabel);
+            }
+        }
+    }
+
+
+    /**
+     * 处理阶段小结
+     *
+     * @param jsonObject
+     */
+    public StagesSummaryLabel putStagesSummaryCrfData(JSONObject jsonObject, InputInfo inputInfo) {
+        StagesSummaryLabel stagesSummaryLabel = new StagesSummaryLabel();
+        if (jsonObject == null) {
+            return stagesSummaryLabel;
+        }
+        JSONObject aiOut = jsonObject.getJSONObject(entityRelationObject).getJSONObject(StagesSummaryAI.outputs);
+        if (aiOut == null) {
+            return stagesSummaryLabel;
+        }
+        EntityProcessStagesSummary entityProcessStagesSummary = new EntityProcessStagesSummary();
+        stagesSummaryLabel = entityProcessStagesSummary.extractEntity(aiOut);
+        return stagesSummaryLabel;
+    }
+
+    protected void putContent(JSONArray crfContent, String medicalTextType, String text, String sign) {
+        String move_text = CatalogueUtil.removeSpecialChar(text);
+        if (StringUtil.isEmpty(move_text)) {
+            return;
+        }
+        JSONObject detailContent = new JSONObject();
+        detailContent.put("medical_text_type", medicalTextType);
+        detailContent.put("content", move_text);
+        detailContent.put("detail_title", sign);
+        crfContent.add(detailContent);
+    }
+}

+ 39 - 1
structure-center/src/main/java/com/lantone/structure/ai/ThreeLevelWardAI.java

@@ -11,6 +11,7 @@ import com.lantone.structure.model.InputInfo;
 import com.lantone.structure.model.doc.DifficultCaseDiscussDoc;
 import com.lantone.structure.model.doc.RescueDoc;
 import com.lantone.structure.model.doc.ThreeLevelWardDoc;
+import com.lantone.structure.model.doc.WardRecordDoc;
 import com.lantone.structure.model.doc.ward.AttendingDoctorWardDoc;
 import com.lantone.structure.model.doc.ward.DirectorDoctorWardDoc;
 import com.lantone.structure.model.label.ThreeLevelWardLabel;
@@ -37,7 +38,7 @@ public class ThreeLevelWardAI extends ModelAI {
     /**
      *
      */
-    public static List<String> medicalTextType = Arrays.asList("CourseRecord_cx", "CourseRecordLast_cx", "CourseRecordSRR");
+    public static List<String> medicalTextType = Arrays.asList("CourseRecord_cx", "CourseRecordLast_cx", "CourseRecordSRR","Taizhou_medical_order");
     public static String entityRelationObject = "entity_relation_object";
     public static String outputs = "outputs";
     public static String content = "content";
@@ -45,6 +46,23 @@ public class ThreeLevelWardAI extends ModelAI {
     public void medrec(InputInfo inputInfo, CRFServiceClient crfServiceClient) {
         JSONArray crfContent = new JSONArray();
         List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
+        //  "============恩泽医嘱crf单独处理================="
+        if (ListUtil.isNotEmpty(threeLevelWardDocs) && StringUtil.isNotEmpty(threeLevelWardDocs.get(0).getText())) {
+            Map<String, String> maps = threeLevelWardDocs.get(0).getStructureMap();
+            if(StringUtil.isNotEmpty(maps.get("诊疗计划")) && StringUtil.isNotEmpty(maps.get("诊疗计划").trim())){
+                String plan = maps.get("诊疗计划");
+                putContent(crfContent, medicalTextType.get(3), plan, Content.wardRecord);
+            JSONObject midData = loadAI(crfContent, crfServiceClient);//crf返回数据
+            for (int i = 0; i < threeLevelWardDocs.size(); i++) {
+                if (midData.get(Content.wardRecord) == null) {
+                    continue;
+                }
+                putRescueCrfData(midData.getJSONObject(Content.wardRecord), inputInfo);
+            }
+        }
+    }
+        //  "============恩泽医嘱crf单独处理完成================="
+
         if (threeLevelWardDocs.size() == 0) {
             return;
         }
@@ -145,6 +163,26 @@ public class ThreeLevelWardAI extends ModelAI {
 
     }
 
+    /**
+     * 处理查房记录
+     *
+     * @param jsonObject
+     */
+    public void putRescueCrfData(JSONObject jsonObject, InputInfo inputInfo) {
+        if (jsonObject == null) {
+            return;
+        }
+        JSONObject aiOut = jsonObject.getJSONObject(entityRelationObject).getJSONObject(ThreeLevelWardAI.outputs);
+        if (aiOut == null) {
+            return;
+        }
+        EntityProcessThreeLevelWard entityProcessThreeLevelWard = new EntityProcessThreeLevelWard();
+        ThreeLevelWardLabel threeLevelWardLabel = entityProcessThreeLevelWard.extractEntityLate(aiOut);
+        List<ThreeLevelWardLabel> threeLevelWardLabels = new ArrayList<>();
+        threeLevelWardLabels.add(threeLevelWardLabel);
+        inputInfo.getThreeLevelWardDocs().get(0).setThreeLevelWardLabel(threeLevelWardLabels);
+    }
+
     protected void putContent(JSONArray crfContent, String medicalTextType, String text, String sign, String wardDate) {
         String moveText = CatalogueUtil.removeSpecialChar(text);
         if (StringUtil.isEmpty(moveText)) {

+ 13 - 1
structure-center/src/main/java/com/lantone/structure/ai/model/EntityEnum.java

@@ -30,7 +30,19 @@ public enum EntityEnum {
     BETTER_FINDING("好转表现"), OUTCOME_TO_BETTER("转归情况-好转"), OUTCOME_CURE("转归情况-治愈"), POSITIVE_FINDING("阳性表现"),
     INSPECTION_ITEMS("检查项目"), DISCHARGE_MODE("出院方式"), LABORATORY_PACKAGE("实验室检查套餐"), LABORATORY_RESULTS("实验室检查结果"),
     AUXILIARY_EXAMINATION_RESULTS("辅检结果"), CONSUMPTION("用量-查房"), USAGE_WARD_ROUND("用法"), STOP("停用"),
-    REASONS_FOR_ANTIBIOTIC("抗生素使用原因"),CHECK_TIME("检查时间");
+    REASONS_FOR_ANTIBIOTIC("抗生素使用原因"), CHECK_TIME("检查时间"), INDICA_BLOOD("输血指征"), TYPE_BLOOD("输血类型"), AMOUNT_BLOOD("输血量"),
+    REASON_BLOOD("输血原因"), MEASURE_BLOOD("输血量计量单位"), START_TIME_BLOOD("输血开始时间"), END_TIME_BLOOD("输血结束时间"),
+    RESPONSE_TYPE_BLOOD("输血反应类型"), FREQUENCY_BLOOD("输血次数"), NEGATIVE_BLOOD("否认"), DRUG_NAME("药品"),DIAGNOSIS_NAME("疾病诊断名称"),
+    CONDITION("抢救病情"), OPERATION_OF_NAME("手术及操作名称"), OPERATION_OF_POSITION_NAME("手术及操作目标部位名称"), OPERATION_METHOD("操作方法"),
+    OPERATION_COUNT("操作次数"), AUXILIARY_TEST("辅检名称"), AUXILIARY_RESULT("辅检结果"),AUXILIARY_QUANTITATIVE("辅检定量结果"), SALVAGE_DRUG("抢救药品"),
+    INTERVENTION("介入物名称"), OPE_DIAGNOSIS_NAME("诊断名称"), ANESTHESIA_METHOD("麻醉方法"),ANESTHETIC_EFFECT("麻醉效果"), UTERUS_CONDITION("子宫情况"),
+    CHILDBIRTH_WAY("胎儿娩出方式"), AMNIOTIC_FLUID("羊水"), AMNIOTIC_FLUID_CHARACTER("羊水性状"),OPE_QUANTITY("量"), CHILDBIRTH_CONDITION("胎盘娩出情况"),
+    PLACENTA("胎盘"), VOLUME("体积"), WEIGHT("重量"),UMBILICALCORD("脐带"), EXTENT("长度"), CORD_AROUND_NECK("脐带绕颈"), CYLINDER_NUMBER("圈数"),
+    CORD_AROUND_BODY("脐带绕身"), UTERINE_WALL_SUTURE("子宫壁缝合情况"), UC_AGENT("宫缩剂名称"), UC_CONSUMPTION("宫缩剂用量"), UC_USAGE_WARD_ROUND("宫缩剂用法"),
+    UTERINE_CAVITY_ABNORMITY("宫腔探查异常情况描述"), UTERINE_CAVITY_DISPOSE("宫腔探查处理情况"), PUERPERA_CONDITION("手术时产妇情况"), HEMORRHAGE("术中出血"),
+    FLUID_INFUSION("补液"),BLOOD_PRESSURE("血压情况"), NEWBORN("新生儿"), APGAR_SCORE("Apgar评分"), SCORE("分数"), CAPUT_SUCCEDANEUM("产瘤"),
+    CAPUT_SUCCEDANEUM_PART("产瘤部位"), OPE_DRUG("手术用药名称"), OPE_CONSUMPTION("手术用药量"), OPE_USAGE_WARD_ROUND("手术用药方法"), TRANSFUSION("输血成分"), DOCTORADVICE_RECORD("医嘱内容"), ASSESSMENTPLAN("诊疗计划"),ALLERGYRECORD("过敏史"),OPCONTRAINDICATION("手术禁忌"),OPBOTTOMNAME("手术目标部位"),STOPNOW("停止"),CONTINUE("继续"),REPATE("复查"),OTHERREPATE("其他复查");
+
 
     private String value;
 

+ 218 - 0
structure-center/src/main/java/com/lantone/structure/ai/process/EntityDailyCourseRecord.java

@@ -0,0 +1,218 @@
+package com.lantone.structure.ai.process;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.lantone.common.util.ListUtil;
+import com.lantone.structure.ai.model.EntityEnum;
+import com.lantone.structure.ai.model.Lemma;
+import com.lantone.structure.model.label.DailyCourseRecordLabel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+/**
+ * 处理日常病程记录
+ */
+public class EntityDailyCourseRecord extends EntityProcess {
+    private Logger logger = LoggerFactory.getLogger(EntityDailyCourseRecord.class);
+
+    public DailyCourseRecordLabel extractEntity(JSONObject aiOut) {
+        DailyCourseRecordLabel dailyCourseRecordLabel= new DailyCourseRecordLabel();
+        try {
+            //医嘱信息
+            StringBuffer sb = new StringBuffer();
+            StringBuffer xb = new StringBuffer();
+            StringBuffer bb = new StringBuffer();
+            String drugNames = "",laboratorys,auxoiliarys;
+            //药品
+            List<Lemma> drugName = createEntityTree(aiOut, EntityEnum.DRUG_NAME.toString());
+            for (Lemma lemma : drugName) {
+                String text = lemma.getText();
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemmaRec : lemma.getRelationLemmas()) {
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.STOPNOW.toString())) {
+                            drugNames = relationLemmaRec.getText()+text;
+                            sb.append(drugNames+"、");
+                        }
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.CONTINUE.toString())) {
+                            drugNames = relationLemmaRec.getText()+text;
+                            sb.append(drugNames+"、");
+                        }
+                    }
+                }else{
+                    sb.append(text+" ");
+                }
+            }
+            Boolean sbxflag = false;
+            String str = sb.toString();
+            StringBuffer sbx = new StringBuffer();
+            StringBuffer sbxx = new StringBuffer();
+            if(str.contains("、")){
+                String[] split = str.split("、");
+                if(split.length>1){
+                    for (int i = 0; i < split.length; i++) {
+                        if(!(split[i].contains(EntityEnum.STOPNOW.toString()) || split[i].contains(EntityEnum.CONTINUE.toString()))){
+                            sbx.append(split[i]+"、");
+                        }else{
+                            sbxx.append(split[i]+"、");
+                        }
+                    }
+                }
+            }else{
+                sbxflag = true;
+            }
+            sb = new StringBuffer();
+            if(ListUtil.isNotEmpty(drugName)){
+                sb.append("药品:");
+            }
+            if(!sbxflag){
+                if(sbx.toString().endsWith("、")){
+                    sbx.deleteCharAt(sbx.toString().length()-1);
+                    sbx.append(";");
+                }
+                sb.append(sbx.toString());
+                sb.append(sbxx.toString());
+            }else{
+                sb.append(str);
+            }
+
+            str = sb.toString();
+            if(str.endsWith("、")){
+                sb.deleteCharAt(str.length()-1);
+            }
+            //实验室检查
+            List<Lemma> laboratory = createEntityTree(aiOut, EntityEnum.LABORATORY.toString());
+            for (Lemma lemma : laboratory) {
+                String text = lemma.getText();
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemmaRec : lemma.getRelationLemmas()) {
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.REPATE.toString())) {
+                            laboratorys = relationLemmaRec.getText()+text;
+                            xb.append(laboratorys+"、");
+                        }
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.OTHERREPATE.toString())) {
+                            laboratorys = relationLemmaRec.getText()+text;
+                            xb.append(laboratorys+"、");
+                        }
+                    }
+                }else{
+                    xb.append(text+" ");
+                }
+            }
+            String xtr = xb.toString();
+            StringBuffer xbx = new StringBuffer();
+            StringBuffer xbxx = new StringBuffer();
+            Boolean xbxflag = false;
+            if(xtr.contains("、")){
+                String[] split = xtr.split("、");
+                if(split.length>1){
+                    for (int i = 0; i < split.length; i++) {
+                        if(!(split[i].contains(EntityEnum.STOPNOW.toString()) || split[i].contains(EntityEnum.CONTINUE.toString()))){
+                            xbx.append(split[i]+"、");
+                        }else{
+                            xbxx.append(split[i]+"、");
+                        }
+                    }
+                }
+            }else{
+                xbxflag = true;
+            }
+            if(ListUtil.isNotEmpty(laboratory)){
+                sb.append("  实验室检查:");
+            }
+            if(!xbxflag){
+                if(xbx.toString().endsWith("、")){
+                    xbx.deleteCharAt(xbx.toString().length()-1);
+                    xbx.append(";");
+                }
+                sb.append(xbx.toString());
+                sb.append(xbxx.toString());
+            }else{
+                sb.append(xtr);
+            }
+
+            str = sb.toString();
+            if(str.endsWith("、")){
+                sb.deleteCharAt(str.length()-1);
+            }
+            //辅助检查
+            List<Lemma> auxoiliary = createEntityTree(aiOut, EntityEnum.AUXILIARY_EXAMINATION.toString());
+            for (Lemma lemma : auxoiliary) {
+                String text = lemma.getText();
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemmaRec : lemma.getRelationLemmas()) {
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.REPATE.toString())) {
+                            auxoiliarys = relationLemmaRec.getText()+text;
+                            bb.append(auxoiliarys+"、");
+                        }
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.OTHERREPATE.toString())) {
+                            auxoiliarys = relationLemmaRec.getText()+text;
+                            bb.append(auxoiliarys+"、");
+                        }
+                    }
+                }else{
+                    bb.append(text+" ");
+                }
+            }
+            Boolean bbxflag = false;
+            String btr = bb.toString();
+            StringBuffer bbx = new StringBuffer();
+            StringBuffer bbxx = new StringBuffer();
+            if(btr.contains("、")){
+                String[] split = xtr.split("、");
+                if(split.length>1){
+                    for (int i = 0; i < split.length; i++) {
+                        if(!(split[i].contains(EntityEnum.STOPNOW.toString()) || split[i].contains(EntityEnum.CONTINUE.toString()))){
+                            bbx.append(split[i]+"、");
+                        }else{
+                            bbxx.append(split[i]+"、");
+                        }
+                    }
+                }
+            }else{
+                bbxflag = true;
+            }
+            if(ListUtil.isNotEmpty(auxoiliary)){
+                sb.append("  辅助检查:");
+            }
+            if(!bbxflag){
+                if(bbx.toString().endsWith("、")){
+                    bbx.deleteCharAt(bbx.toString().length()-1);
+                    bbx.append(";");
+                }
+                sb.append(bbx.toString());
+                sb.append(bbxx.toString());
+            }else{
+                sb.append(btr);
+            }
+            str = sb.toString();
+            if(str.endsWith("、")){
+                sb.deleteCharAt(str.length()-1);
+            }
+
+            //手术名称
+            List<Lemma> operation = createEntityTree(aiOut, EntityEnum.OPERATION.toString());
+            if(ListUtil.isNotEmpty(operation)){
+                sb.append("  手术名称:");
+            }
+            for (Lemma lemma : operation) {
+                String text = lemma.getText();
+                sb.append(text+" ");
+            }
+            dailyCourseRecordLabel.setDoctorAdviceRecord(sb.toString());
+            //停止
+          //  List<Lemma> stop = createEntityTree(aiOut, EntityEnum.STOPNOW.toString());
+            //继续
+          //  List<Lemma> continues = createEntityTree(aiOut, EntityEnum.CONTINUE.toString());
+            //复查
+           // List<Lemma> repate = createEntityTree(aiOut, EntityEnum.REPATE.toString());
+            //其他复查
+           // List<Lemma> otherRepate = createEntityTree(aiOut, EntityEnum.OTHERREPATE.toString());
+        }catch (Exception e) {
+            e.printStackTrace();
+            logger.error(e.getMessage(), e);
+        }
+        return dailyCourseRecordLabel;
+    }
+}

+ 91 - 0
structure-center/src/main/java/com/lantone/structure/ai/process/EntityOperationRecord.java

@@ -0,0 +1,91 @@
+package com.lantone.structure.ai.process;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.lantone.structure.ai.model.Lemma;
+import com.lantone.structure.model.entity.*;
+import com.lantone.structure.model.label.OperationRecordLabel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 输血记录处理
+ */
+public class EntityOperationRecord extends EntityProcess {
+    private Logger logger = LoggerFactory.getLogger(EntityOperationRecord.class);
+
+    public OperationRecordLabel extractEntity(JSONObject aiOut) {
+        OperationRecordLabel operationRecordLabel = new OperationRecordLabel();
+        try {
+            //介入物名称
+            List<Lemma> interventionLemma = createEntityTree(aiOut, "介入物名称");
+            List<Intervention> interventionList = new ArrayList<>();
+            for (Lemma lemma : interventionLemma) {
+                Intervention intervention = new Intervention();
+                intervention.setName(lemma.getText());
+                interventionList.add(intervention);
+            }
+            operationRecordLabel.setInterventions(interventionList);
+
+            //皮肤消毒描述
+            operationRecordLabel.setSkinSterilize(findFirstT(createEntityTree(aiOut, "皮肤消毒描述"), new SkinSterilize()));
+
+            //手术切口描述
+            List<Lemma> operationIncisionLemma = createEntityTree(aiOut, "手术切口描述");
+            List<OperationIncision> operationIncisionList = new ArrayList<>();
+            for (Lemma lemma : operationIncisionLemma) {
+                OperationIncision operationIncision = new OperationIncision();
+                operationIncision.setName(lemma.getText());
+                operationIncisionList.add(operationIncision);
+            }
+            operationRecordLabel.setOperationIncision(operationIncisionList);
+
+            //输液量(mL)
+            operationRecordLabel.setTransfuseQuantity(findFirstT(createEntityTree(aiOut, "输液量"), new TransfuseQuantity()));
+
+            //术前用药
+            operationRecordLabel.setPreoperativeDrugs(findFirstT(createEntityTree(aiOut, "术前用药"), new PreoperativeDrugs()));
+
+            //术中用药
+            operationRecordLabel.setDuringDrugs(findFirstT(createEntityTree(aiOut, "药物名称"), new DuringDrugs()));
+
+            //引流材料名称
+            List<Lemma> drainageMaterialsNameLemma = createEntityTree(aiOut, "引流材料名称");
+            List<DrainageMaterialsName> drainageMaterialsNameList = new ArrayList<>();
+            for (Lemma lemma : drainageMaterialsNameLemma) {
+                DrainageMaterialsName drainageMaterialsName = new DrainageMaterialsName();
+                drainageMaterialsName.setName(lemma.getText());
+                drainageMaterialsNameList.add(drainageMaterialsName);
+            }
+            operationRecordLabel.setDrainageMaterialsNames(drainageMaterialsNameList);
+
+            //引流材料数目
+            List<Lemma> drainageMaterialsAmountLemma = createEntityTree(aiOut, "引流材料数目");
+            List<DrainageMaterialsAmount> drainageMaterialsAmountList = new ArrayList<>();
+            for (Lemma lemma : drainageMaterialsAmountLemma) {
+                DrainageMaterialsAmount drainageMaterialsAmount = new DrainageMaterialsAmount();
+                drainageMaterialsAmount.setName(lemma.getText());
+                drainageMaterialsAmountList.add(drainageMaterialsAmount);
+            }
+            operationRecordLabel.setDrainageMaterialsAmounts(drainageMaterialsAmountList);
+
+            //放置部位
+            List<Lemma> placePositionLemma = createEntityTree(aiOut, "放置部位");
+            List<PlacePosition> placePositionList = new ArrayList<>();
+            for (Lemma lemma : placePositionLemma) {
+                PlacePosition placePosition = new PlacePosition();
+                placePosition.setName(lemma.getText());
+                placePositionList.add(placePosition);
+            }
+            operationRecordLabel.setPlacePositions(placePositionList);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            logger.error(e.getMessage(), e);
+        }
+        return operationRecordLabel;
+    }
+}

+ 8 - 0
structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcess.java

@@ -237,6 +237,14 @@ public class EntityProcess {
         return null;
     }
 
+    protected <T> T findFirstT(List<Lemma> ListLemma, T t) throws Exception {
+        for (Lemma lemma : ListLemma) {
+            BeanUtils.copyProperty(t, "name", lemma.getText());
+            return t;
+        }
+        return null;
+    }
+
     /**
      * 只找出现在lemma实体位置之后的实体
      * @param detailLemma

+ 86 - 0
structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcessBlood.java

@@ -0,0 +1,86 @@
+package com.lantone.structure.ai.process;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.lantone.structure.ai.model.EntityEnum;
+import com.lantone.structure.ai.model.Lemma;
+import com.lantone.structure.model.entity.*;
+import com.lantone.structure.model.label.ClinicalBloodLabel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 输血记录处理
+ */
+public class EntityProcessBlood extends EntityProcess {
+    private Logger logger = LoggerFactory.getLogger(EntityProcessBlood.class);
+
+    public ClinicalBloodLabel extractEntity(JSONObject aiOut) {
+        ClinicalBloodLabel clinicalBloodLabel = new ClinicalBloodLabel();
+        try {
+//            Blood blood = new Blood();
+//            List<Blood> bloodList = new ArrayList<>();
+            //输血指征
+            List<Lemma> indicationBlood = createEntityTree(aiOut, EntityEnum.INDICA_BLOOD.toString());
+            List<Indication> indicationList = new ArrayList<>();
+            for (Lemma lemma : indicationBlood) {
+                Indication indication = new Indication();
+                indication.setName(lemma.getText());
+                indicationList.add(indication);
+            }
+            clinicalBloodLabel.setIndication(indicationList);
+
+            //输血类型
+            List<Lemma> typeBlood = createEntityTree(aiOut, EntityEnum.TYPE_BLOOD.toString());
+            for (Lemma lemma : typeBlood) {
+                Type type = new Type();
+                type.setName(lemma.getText());
+                List<Amount> amountList = new ArrayList<>();
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemma : lemma.getRelationLemmas()) {
+                        Amount amount = new Amount();
+                        if (relationLemma.getProperty().equals(EntityEnum.AMOUNT_BLOOD.toString())) {
+                            amount.setName(relationLemma.getText());
+                            MeasurementUnit measurementUnit = new MeasurementUnit();
+                            for (Lemma measureLemma : relationLemma.getRelationLemmas()) {
+                                if (measureLemma.getProperty().equals(EntityEnum.MEASURE_BLOOD.toString())) {
+                                    measurementUnit.setName(measureLemma.getText());
+                                }
+                            }
+                            amount.setMeasurementUnit(measurementUnit);
+                            amountList.add(amount);
+                        }
+                    }
+                }
+                type.setAmount(amountList);
+                clinicalBloodLabel.setType(type);
+            }
+            //输血原因
+            clinicalBloodLabel.setReason(findFirstT(createEntityTree(aiOut, EntityEnum.REASON_BLOOD.toString()),new Reason()));
+            //输血开始时间
+            clinicalBloodLabel.setStartTime(findFirstT(createEntityTree(aiOut, EntityEnum.START_TIME_BLOOD.toString()),new StartTime()));
+            //输血结束时间
+            clinicalBloodLabel.setEndTime(findFirstT(createEntityTree(aiOut, EntityEnum.END_TIME_BLOOD.toString()),new EndTime()));
+
+            //输血反应类型
+            List<Lemma> responseTypeBlood = createEntityTree(aiOut, EntityEnum.RESPONSE_TYPE_BLOOD.toString());
+            List<ResponseType> responseTypeList = new ArrayList<>();
+            for (Lemma lemma : responseTypeBlood) {
+                ResponseType responseType = new ResponseType();
+                responseType.setName(lemma.getText());
+                responseType.setNegative(findT(lemma, new Negative(), EntityEnum.NEGATIVE_BLOOD.toString()));
+                responseTypeList.add(responseType);
+            }
+            clinicalBloodLabel.setResponseType(responseTypeList);
+            //输血次数
+            clinicalBloodLabel.setFrequency(findFirstT(createEntityTree(aiOut, EntityEnum.FREQUENCY_BLOOD.toString()),new Frequency()));
+        } catch (Exception e) {
+            e.printStackTrace();
+            logger.error(e.getMessage(), e);
+        }
+        return clinicalBloodLabel;
+    }
+}

+ 242 - 0
structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcessCaesareanSection.java

@@ -0,0 +1,242 @@
+package com.lantone.structure.ai.process;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.lantone.structure.ai.model.EntityEnum;
+import com.lantone.structure.ai.model.Lemma;
+import com.lantone.structure.model.entity.*;
+import com.lantone.structure.model.label.CaesareanSectionLabel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 剖宫产手术处理
+ */
+public class EntityProcessCaesareanSection extends EntityProcess {
+    private Logger logger = LoggerFactory.getLogger(EntityProcessCaesareanSection.class);
+
+    public CaesareanSectionLabel extractEntity(JSONObject aiOut) {
+        CaesareanSectionLabel caesareanSectionLabel = new CaesareanSectionLabel();
+        try {
+            //诊断名称
+            List<Lemma> diagnosisLemma = createEntityTree(aiOut, EntityEnum.OPE_DIAGNOSIS_NAME.toString());
+            List<Diagnosis> diagnosisList = new ArrayList<>();
+            for (Lemma lemma : diagnosisLemma) {
+                Diagnosis diagnosis = new Diagnosis();
+                diagnosis.setName(lemma.getText());
+                diagnosisList.add(diagnosis);
+            }
+            caesareanSectionLabel.setDiagnosis(diagnosisList);
+
+            //麻醉方法
+            caesareanSectionLabel.setAnesthesiaMethod(findFirstT(createEntityTree(aiOut, EntityEnum.ANESTHESIA_METHOD.toString()),new AnesthesiaMethod()));
+
+            //麻醉效果
+            caesareanSectionLabel.setAnestheticEffect(findFirstT(createEntityTree(aiOut, EntityEnum.ANESTHETIC_EFFECT.toString()),new AnestheticEffect()));
+
+            //子宫情况
+            List<Lemma> uterusConditionLemma = createEntityTree(aiOut, EntityEnum.UTERUS_CONDITION.toString());
+            List<UterusCondition> uterusConditionList = new ArrayList<>();
+            for (Lemma lemma : uterusConditionLemma) {
+                UterusCondition uterusCondition = new UterusCondition();
+                uterusCondition.setName(lemma.getText());
+                uterusConditionList.add(uterusCondition);
+            }
+            caesareanSectionLabel.setUterusConditions(uterusConditionList);
+
+            //胎儿娩出方式
+            caesareanSectionLabel.setChildbirthWay(findFirstT(createEntityTree(aiOut, EntityEnum.CHILDBIRTH_WAY.toString()),new ChildbirthWay()));
+
+            //羊水
+            List<Lemma> amnioticFluidLemma = createEntityTree(aiOut, EntityEnum.AMNIOTIC_FLUID.toString());
+            AmnioticFluid amnioticFluid = new AmnioticFluid();
+            for (Lemma lemma : amnioticFluidLemma) {
+                amnioticFluid.setName(lemma.getText());
+                amnioticFluid.setAmnioticFluidCharacter(findT(lemma, new AmnioticFluidCharacter(), EntityEnum.AMNIOTIC_FLUID_CHARACTER.toString()));
+                amnioticFluid.setQuantity(findT(lemma, new Quantity(), EntityEnum.OPE_QUANTITY.toString()));
+            }
+            caesareanSectionLabel.setAmnioticFluid(amnioticFluid);
+
+            //胎盘娩出情况
+            List<Lemma> childbirthConditionLemma = createEntityTree(aiOut, EntityEnum.CHILDBIRTH_CONDITION.toString());
+            List<ChildbirthCondition> ChildbirthConditionList = new ArrayList<>();
+            for (Lemma lemma : childbirthConditionLemma) {
+                ChildbirthCondition childbirthCondition = new ChildbirthCondition();
+                childbirthCondition.setName(lemma.getText());
+                ChildbirthConditionList.add(childbirthCondition);
+            }
+            caesareanSectionLabel.setChildbirthConditions(ChildbirthConditionList);
+
+            //胎盘
+            List<Lemma> PlacentaLemma = createEntityTree(aiOut, EntityEnum.PLACENTA.toString());
+            Placenta placenta = new Placenta();
+            for (Lemma lemma : PlacentaLemma) {
+                placenta.setName(lemma.getText());
+                placenta.setVolume(findT(lemma, new Volume(), EntityEnum.VOLUME.toString()));
+                placenta.setWeight(findT(lemma, new Weight(), EntityEnum.WEIGHT.toString()));
+            }
+            caesareanSectionLabel.setPlacenta(placenta);
+
+            //脐带
+            List<Lemma> umbilicalCordLemma = createEntityTree(aiOut, EntityEnum.UMBILICALCORD.toString());
+            UmbilicalCord umbilicalCord = new UmbilicalCord();
+            for (Lemma lemma : umbilicalCordLemma) {
+                umbilicalCord.setName(lemma.getText());
+                umbilicalCord.setExtent(findT(lemma, new Extent(), EntityEnum.EXTENT.toString()));
+            }
+            caesareanSectionLabel.setUmbilicalCord(umbilicalCord);
+
+            //脐带绕颈
+            List<Lemma> CordAroundNeckLemma = createEntityTree(aiOut, EntityEnum.CORD_AROUND_NECK.toString());
+            CordAroundNeck cordAroundNeck = new CordAroundNeck();
+            for (Lemma lemma : CordAroundNeckLemma) {
+                cordAroundNeck.setName(lemma.getText());
+                cordAroundNeck.setNegative(findT(lemma, new Negative(), EntityEnum.NEGATIVE.toString()));
+                cordAroundNeck.setCylinderNumber(findT(lemma, new CylinderNumber(), EntityEnum.CYLINDER_NUMBER.toString()));
+            }
+            caesareanSectionLabel.setCordAroundNeck(cordAroundNeck);
+
+            //脐带绕身
+            List<Lemma> cordAroundBodyLemma = createEntityTree(aiOut, EntityEnum.CORD_AROUND_BODY.toString());
+            CordAroundBody cordAroundBody = new CordAroundBody();
+            for (Lemma lemma : cordAroundBodyLemma) {
+                cordAroundBody.setName(lemma.getText());
+                cordAroundBody.setNegative(findT(lemma, new Negative(), EntityEnum.NEGATIVE.toString()));
+                cordAroundBody.setCylinderNumber(findT(lemma, new CylinderNumber(), EntityEnum.CYLINDER_NUMBER.toString()));
+            }
+            caesareanSectionLabel.setCordAroundBody(cordAroundBody);
+
+            //子宫壁缝合情况
+            List<Lemma> uterineWallSutureLemma = createEntityTree(aiOut, EntityEnum.UTERINE_WALL_SUTURE.toString());
+            List<UterineWallSuture> uterineWallSutureList = new ArrayList<>();
+            for (Lemma lemma : uterineWallSutureLemma) {
+                UterineWallSuture uterineWallSuture = new UterineWallSuture();
+                uterineWallSuture.setName(lemma.getText());
+                uterineWallSutureList.add(uterineWallSuture);
+            }
+            caesareanSectionLabel.setUterineWallSutures(uterineWallSutureList);
+
+            //宫缩剂名称
+            List<Lemma> uCAgentLemma = createEntityTree(aiOut, EntityEnum.UC_AGENT.toString());
+            List<UCAgent> uCAgentList = new ArrayList<>();
+            for (Lemma lemma : uCAgentLemma) {
+                UCAgent uCAgent = new UCAgent();
+                uCAgent.setName(lemma.getText());
+                uCAgent.setConsumption(findT(lemma, new Consumption(), EntityEnum.UC_CONSUMPTION.toString()));
+                uCAgent.setUsageWardRound(findT(lemma, new UsageWardRound(), EntityEnum.UC_USAGE_WARD_ROUND.toString()));
+                uCAgentList.add(uCAgent);
+            }
+            caesareanSectionLabel.setUCAgents(uCAgentList);
+
+            //宫腔探查异常情况描述
+            List<Lemma> uterineCavityAbnormityLemma = createEntityTree(aiOut, EntityEnum.UTERINE_CAVITY_ABNORMITY.toString());
+            List<UterineCavityAbnormity> uterineCavityAbnormityList = new ArrayList<>();
+            for (Lemma lemma : uterineCavityAbnormityLemma) {
+                UterineCavityAbnormity uterineCavityAbnormity = new UterineCavityAbnormity();
+                uterineCavityAbnormity.setName(lemma.getText());
+                uterineCavityAbnormityList.add(uterineCavityAbnormity);
+            }
+            caesareanSectionLabel.setUterineCavityAbnormity(uterineCavityAbnormityList);
+
+            //宫腔探查处理情况
+            List<Lemma> uterineCavityDisposeLemma = createEntityTree(aiOut, EntityEnum.UTERINE_CAVITY_DISPOSE.toString());
+            List<UterineCavityDispose> uterineCavityDisposeList = new ArrayList<>();
+            for (Lemma lemma : uterineCavityDisposeLemma) {
+                UterineCavityDispose uterineCavityDispose = new UterineCavityDispose();
+                uterineCavityDispose.setName(lemma.getText());
+                uterineCavityDisposeList.add(uterineCavityDispose);
+            }
+            caesareanSectionLabel.setUterineCavityDispose(uterineCavityDisposeList);
+
+            //手术时产妇情况
+            List<Lemma> puerperaConditionLemma = createEntityTree(aiOut, EntityEnum.PUERPERA_CONDITION.toString());
+            List<PuerperaCondition> puerperaConditionList = new ArrayList<>();
+            for (Lemma lemma : puerperaConditionLemma) {
+                PuerperaCondition puerperaCondition = new PuerperaCondition();
+                puerperaCondition.setName(lemma.getText());
+                puerperaConditionList.add(puerperaCondition);
+            }
+            caesareanSectionLabel.setPuerperaCondition(puerperaConditionList);
+
+            //术中出血
+            List<Lemma> hemorrhageLemma = createEntityTree(aiOut, EntityEnum.HEMORRHAGE.toString());
+            Hemorrhage hemorrhage = new Hemorrhage();
+            for (Lemma lemma : hemorrhageLemma) {
+                hemorrhage.setName(lemma.getText());
+                hemorrhage.setQuantity(findT(lemma, new Quantity(), EntityEnum.OPE_QUANTITY.toString()));
+            }
+            caesareanSectionLabel.setHemorrhage(hemorrhage);
+
+            //补液
+            List<Lemma> fluidInfusionLemma = createEntityTree(aiOut, EntityEnum.FLUID_INFUSION.toString());
+            FluidInfusion fluidInfusion = new FluidInfusion();
+            for (Lemma lemma : fluidInfusionLemma) {
+                fluidInfusion.setName(lemma.getText());
+                fluidInfusion.setQuantity(findT(lemma, new Quantity(), EntityEnum.OPE_QUANTITY.toString()));
+            }
+            caesareanSectionLabel.setFluidInfusion(fluidInfusion);
+
+            //血压情况
+            caesareanSectionLabel.setBloodPressure(findFirstT(createEntityTree(aiOut, EntityEnum.BLOOD_PRESSURE.toString()),new BloodPressure()));
+
+            //新生儿
+            List<Lemma> newbornLemma = createEntityTree(aiOut, EntityEnum.NEWBORN.toString());
+            Newborn newborn = new Newborn();
+            for (Lemma lemma : newbornLemma) {
+                newborn.setName(lemma.getText());
+                newborn.setWeight(findT(lemma, new Weight(), EntityEnum.WEIGHT.toString()));
+                newborn.setExtent(findT(lemma, new Extent(), EntityEnum.EXTENT.toString()));
+            }
+            caesareanSectionLabel.setNewborn(newborn);
+
+            //Apgar评分
+            List<Lemma> apgarScoreLemma = createEntityTree(aiOut, EntityEnum.APGAR_SCORE.toString());
+            List<ApgarScore> apgarScoreList = new ArrayList<>();
+            for (Lemma lemma : apgarScoreLemma) {
+                ApgarScore apgarScore = new ApgarScore();
+                apgarScore.setName(lemma.getText());
+                apgarScore.setScore(findT(lemma, new Score(), EntityEnum.SCORE.toString()));
+                apgarScoreList.add(apgarScore);
+            }
+            caesareanSectionLabel.setApgarScores(apgarScoreList);
+
+            //产瘤
+            List<Lemma> caputSuccedaneumLemma = createEntityTree(aiOut, EntityEnum.CAPUT_SUCCEDANEUM.toString());
+            CaputSuccedaneum caputSuccedaneum = new CaputSuccedaneum();
+            for (Lemma lemma : caputSuccedaneumLemma) {
+                caputSuccedaneum.setName(lemma.getText());
+                caputSuccedaneum.setVolume(findT(lemma, new Volume(), EntityEnum.VOLUME.toString()));
+                caputSuccedaneum.setCaputSuccedaneumPart(findT(lemma, new CaputSuccedaneumPart(), EntityEnum.CAPUT_SUCCEDANEUM_PART.toString()));
+            }
+            caesareanSectionLabel.setCaputSuccedaneum(caputSuccedaneum);
+
+            //手术用药名称
+            List<Lemma> drugLemma = createEntityTree(aiOut, EntityEnum.OPE_DRUG.toString());
+            List<Drug> drugList = new ArrayList<>();
+            for (Lemma lemma : drugLemma) {
+                Drug drug = new Drug();
+                drug.setName(lemma.getText());
+                drug.setConsumption(findT(lemma, new Consumption(), EntityEnum.OPE_CONSUMPTION.toString())); //(手术用药量)
+                drug.setUsageWardRound(findT(lemma, new UsageWardRound(), EntityEnum.OPE_USAGE_WARD_ROUND.toString())); //(手术用药方法)
+                drugList.add(drug);
+            }
+            caesareanSectionLabel.setDrugs(drugList);
+
+            //输血成分
+            List<Lemma> transfusionLemma = createEntityTree(aiOut, EntityEnum.TRANSFUSION.toString());
+            Transfusion transfusion = new Transfusion();
+            for (Lemma lemma : transfusionLemma) {
+                transfusion.setName(lemma.getText());
+                transfusion.setQuantity(findT(lemma, new Quantity(), EntityEnum.OPE_QUANTITY.toString()));
+            }
+            caesareanSectionLabel.setTransfusion(transfusion);
+        } catch (Exception e) {
+            e.printStackTrace();
+            logger.error(e.getMessage(), e);
+        }
+        return caesareanSectionLabel;
+    }
+}

+ 332 - 0
structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcessEZaAll.java

@@ -0,0 +1,332 @@
+package com.lantone.structure.ai.process;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.lantone.common.util.ListUtil;
+import com.lantone.structure.ai.model.EntityEnum;
+import com.lantone.structure.ai.model.Lemma;
+import com.lantone.structure.model.doc.BeHospitalizedDoc;
+import com.lantone.structure.model.entity.*;
+import com.lantone.structure.model.label.PastLabel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+/**
+ * 恩泽过敏史、输血史、手术史、预防接种史、疾病史(含外伤)、传染病史
+ */
+public class EntityProcessEZaAll extends EntityProcess {
+    private Logger logger = LoggerFactory.getLogger(EntityProcessEZaAll.class);
+
+    public BeHospitalizedDoc extractEntity(JSONObject aiOut) {
+        BeHospitalizedDoc beHospitalizedDoc = new BeHospitalizedDoc();
+        PastLabel pastLabel= new PastLabel();
+        List<BloodTransfusion> bloodTransfusions = new ArrayList<>();//输血史
+        List<Vaccinate> vaccinates = new ArrayList<>();//预防接种史
+        List<Diag> diags = new ArrayList<>();//疾病史
+        List<Allergy> allergies = new ArrayList<>();//过敏史
+        List<Operation> operations = new ArrayList<>();//手术史
+        List<DiagInfectious> diagInfectiouses = new ArrayList<>();//传染病史
+
+        try {
+            //输血史-
+            List<Lemma> bloods = createEntityTree(aiOut, EntityEnum.NEGATIVE.toString());
+            for (Lemma lemma : bloods) {
+                BloodTransfusion bloodTransfusionFir = new BloodTransfusion();
+                String text = lemma.getText();
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemmaRec : lemma.getRelationLemmas()) {
+                        BloodTransfusion bloodTransfusionSec = new BloodTransfusion();
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.BLOOD_TRANSFUSION.toString())) {
+                            text = text+relationLemmaRec.getText();
+                            bloodTransfusionSec.setName(text);
+                            bloodTransfusions.add(bloodTransfusionSec);
+                        }
+                    }
+                }else{
+                    bloodTransfusionFir.setName(text);
+                    bloodTransfusions.add(bloodTransfusionFir);
+                }
+            }
+            //预防接种史-
+            List<Lemma> vaccinateList = createEntityTree(aiOut, EntityEnum.VACCINATION.toString());
+            for (Lemma lemma : vaccinateList) {
+                Vaccinate vaccinateFir = new Vaccinate();
+                String text = lemma.getText();
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemmaRec : lemma.getRelationLemmas()) {
+                        Vaccinate vaccinateSec = new Vaccinate();
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.NEGATIVE.toString())) {
+                            text = relationLemmaRec.getText()+text;
+                            vaccinateSec.setName(text);
+                            vaccinates.add(vaccinateSec);
+                        }
+                    }
+                }else{
+                    vaccinateFir.setName(text);
+                    vaccinates.add(vaccinateFir);
+                }
+            }
+
+
+            //疾病史  NEGATIVE-TIME  DIEASE
+            //否定
+            Set<String> diagSet = new HashSet<>();
+            Set<String> diagRetSet = new HashSet<>();
+            List<Lemma> diagList = createEntityTree(aiOut, EntityEnum.NEGATIVE.toString());
+           /* if( ListUtil.isEmpty(diagList)){
+                //时间
+                diagList = createEntityTree(aiOut, EntityEnum.TIME.toString());
+            }*/
+            for (Lemma lemma : diagList) {
+                Diag diagFir = new Diag();
+                String text = lemma.getText();
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemmaRec : lemma.getRelationLemmas()) {
+                        Diag diagSec = new Diag();
+                        //疾病名称
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.DIEASE.toString())||
+                            relationLemmaRec.getProperty().equals(EntityEnum.INJURY.toString())) {
+                            diagSet.add(relationLemmaRec.getText());
+                          String flagText = text+relationLemmaRec.getText();
+                            diagSec.setName(flagText);
+                            diags.add(diagSec);
+                        }
+                    }
+                }
+            }
+
+            //肯定
+            List<Lemma>  diaList = createEntityTree(aiOut, EntityEnum.DIEASE.toString());
+            List<Lemma>  diaTimeList = createEntityTree(aiOut, EntityEnum.TIME.toString());
+            if(ListUtil.isEmpty(diaList)){
+                diaList = createEntityTree(aiOut, EntityEnum.INJURY.toString());
+            }
+            for (Lemma lemma : diaList) {
+                    if(!diagSet.contains(lemma.getText())){
+                        if(diaTimeList.size()==1 && diaList.size()==1){
+                            diagRetSet.add(diaTimeList.get(0).getText()+lemma.getText());
+                        }
+                        diagRetSet.add(lemma.getText());
+                    }
+            }
+            if(null != diagRetSet && diagRetSet.size()>0){
+                for (String str : diagRetSet) {
+                    Diag diagSec = new Diag();
+                    diagSec.setName(str);
+                    diags.add(diagSec);
+                }
+            }
+
+
+            //过敏史-药物过敏原表现为使用后皮疹
+            //否定 NEGATIVE  过敏 ALLERGY 食物过敏原 FOOD_ALLERGY 药物过敏原 DRUG_ALLERGY
+            Set<String> allergieSet = new HashSet<>();
+            Set<String> allergieRetSet = new HashSet<>();
+            List<Lemma> allergieList = createEntityTree(aiOut, EntityEnum.NEGATIVE.toString());
+            for (Lemma lemma : allergieList) {
+                Allergy allergyFir = new Allergy();
+                String text = lemma.getText();
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemma : lemma.getRelationLemmas()) {
+                        Allergy allergySec= new Allergy();
+                        //过敏
+                        if (relationLemma.getProperty().equals(EntityEnum.ALLERGY.toString())) {
+                            String flagText = relationLemma.getText();
+                            String firText = text +relationLemma.getText();
+                                if(ListUtil.isEmpty(relationLemma.getRelationLemmas())){
+                                    allergySec.setName(firText);
+                                    allergies.add(allergySec);
+                                }
+                            for (Lemma relationLemmaRe : relationLemma.getRelationLemmas()) {
+                                Allergy allergyThr= new Allergy();
+                                //食物过敏原 - 药物过敏原-情况不详
+                                if (relationLemmaRe.getProperty().equals(EntityEnum.FOOD_ALLERGY.toString()) ||
+                                    relationLemmaRe.getProperty().equals(EntityEnum.DRUG_ALLERGY.toString())||
+                                    relationLemmaRe.getProperty().equals(EntityEnum.UNKNOWN.toString())) {
+                                    String secText = text+relationLemmaRe.getText()+flagText;
+                                    allergieSet.add(relationLemmaRe.getText()+flagText);
+                                    if(ListUtil.isEmpty(relationLemmaRe.getRelationLemmas())){
+                                        allergyThr.setName(secText);
+                                        allergies.add(allergyThr);
+                                    }
+                                    for (Lemma relationLemmaRec : relationLemmaRe.getRelationLemmas()) {
+                                        Allergy allergyFor = new Allergy();
+                                        //过敏表现
+                                        if (relationLemmaRec.getProperty().equals(EntityEnum.ALLERGY_SYMPTOM.toString())) {
+                                            String thrText = secText+relationLemmaRec.getText();
+                                            allergyFor.setName(thrText);
+                                            allergies.add(allergyFor);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }else{
+                    allergyFir.setName(text);
+                    allergies.add(allergyFir);
+                }
+            }
+            //确定
+            List<Lemma> allergieLists = createEntityTree(aiOut, EntityEnum.ALLERGY.toString());
+            for (Lemma lemma : allergieLists) {
+                Allergy allergyFir = new Allergy();
+                String text = lemma.getText();
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemma : lemma.getRelationLemmas()) {
+                //食物过敏原 - 药物过敏原-情况不详
+                if (relationLemma.getProperty().equals(EntityEnum.FOOD_ALLERGY.toString()) ||
+                        relationLemma.getProperty().equals(EntityEnum.DRUG_ALLERGY.toString())||
+                        relationLemma.getProperty().equals(EntityEnum.UNKNOWN.toString())) {
+                    String secText = relationLemma.getText()+text;
+                    if(null == relationLemma.getRelationLemmas() || relationLemma.getRelationLemmas().size()==0){
+                        if(!allergieSet.contains(secText)){
+                            allergieRetSet.add(secText);
+                        }
+                    }
+                        for (Lemma relationLemmaRec : relationLemma.getRelationLemmas()) {
+                         //   Allergy allergyFor = new Allergy();
+                            //过敏表现
+                            if (relationLemmaRec.getProperty().equals(EntityEnum.ALLERGY_SYMPTOM.toString())) {
+                                String thrText = secText+relationLemmaRec.getText();
+                                if(!allergieSet.contains(thrText)){
+                                    allergieRetSet.add(thrText);
+                                }
+                            }
+                        }
+
+                }
+            }
+        }else{
+            allergyFir.setName(text);
+            allergies.add(allergyFir);
+        }
+
+                if(null != allergieRetSet && allergieRetSet.size()>0){
+                    for (String allergySecs : allergieRetSet) {
+                        Allergy allergySec = new Allergy();
+                        allergySec.setName(allergySecs);
+                        String flagName = "";
+                        if(allergies.size()>0) {
+                            flagName = allergies.get(allergies.size() - 1).getName();
+                        }
+                        if(flagName.contains(allergySecs)){
+                            continue;
+                        }else {
+                            allergies.add(allergySec) ;
+                        }
+                    }
+                }
+}
+
+            //手术史
+            //否定 NEGATIVE  时间 TIME 手术名称 OPERATION
+            List<Lemma> operationList = createEntityTree(aiOut, EntityEnum.NEGATIVE.toString());
+            for (Lemma lemma : operationList) {
+                Operation operationFir = new Operation();
+                String text = lemma.getText();
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemmaRec : lemma.getRelationLemmas()) {
+                        Operation operationSec = new Operation();
+                        //手术史
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.OPERATION_KEYWORD.toString())) {
+                            text = text+relationLemmaRec.getText();
+                                operationSec.setName(text);
+                                operations.add(operationSec);
+                            for (Lemma relationLemmaThr : relationLemmaRec.getRelationLemmas()) {
+                                operations.remove(0);
+                                Operation operationThr = new Operation();
+                                //时间-情况不详
+                                if (relationLemmaThr.getProperty().equals(EntityEnum.TIME.toString()) ||
+                                    relationLemmaThr.getProperty().equals(EntityEnum.UNKNOWN.toString())) {
+                                    text =text+ relationLemmaThr.getText();
+                                        operationThr.setName(text);
+                                        operations.add(operationThr);
+                                    for (Lemma relationLemmaFor : relationLemmaThr.getRelationLemmas()) {
+                                        operations.remove(0);
+                                        Operation allergyFor = new Operation();
+                                        //手术名称
+                                        if (relationLemmaFor.getProperty().equals(EntityEnum.OPERATION.toString())) {
+                                            text = text+relationLemmaFor.getText();
+                                                allergyFor.setName(text);
+                                                operations.add(allergyFor);
+                                            for (Lemma relationLemmaFiv : relationLemmaFor.getRelationLemmas()) {
+                                                operations.remove(0);
+                                                Operation allergyFiv = new Operation();
+                                                //手术结果-情况不详
+                                                if (relationLemmaFiv.getProperty().equals(EntityEnum.OPERATION_RESULT.toString())||
+                                                    relationLemmaFiv.getProperty().equals(EntityEnum.UNKNOWN.toString())) {
+                                                    text = text+relationLemmaFiv.getText();
+                                                        allergyFiv.setName(text);
+                                                        operations.add(allergyFiv);
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }else{
+                    operationFir.setName(text);
+                    operations.add(operationFir);
+                }
+            }
+
+            //手术名称
+            List<Lemma> operationsList = createEntityTree(aiOut, EntityEnum.OPERATION.toString());
+                for (Lemma lemma : operationsList) {
+                    Operation operationFir = new Operation();
+                    String text = lemma.getText();
+                    if (lemma.isHaveChildren()) {
+                        for (Lemma relationLemmaRec : lemma.getRelationLemmas()) {
+                            Operation operationSec = new Operation();
+                            //手术史
+                            if (relationLemmaRec.getProperty().equals(EntityEnum.TIME.toString())) {
+                               String firText ="手术时间:"+relationLemmaRec.getText()+"、"+"手术:"+text;
+                                operationSec.setName(firText);
+                                operations.add(operationSec);
+                            }
+                        }}else{
+                        operationFir.setName(text);
+                        operations.add(operationFir);
+                    }
+                }
+
+            //传染病史-正向处理
+          //  否定 NEGATIVE 传染病史 INFECTIOUS_KEYWORD
+            List<Lemma> diagInfectiouList = createEntityTree(aiOut, EntityEnum.INFECTIOUS_KEYWORD.toString());
+            for (Lemma lemma : diagInfectiouList) {
+                DiagInfectious diagInfectiousFir = new DiagInfectious();
+                String text = lemma.getText();
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemmaRec : lemma.getRelationLemmas()) {
+                        DiagInfectious diagInfectiousSec = new DiagInfectious();
+                        //传染病史
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.NEGATIVE.toString())) {
+                            String FirText = relationLemmaRec.getText()+text;
+                            diagInfectiousSec.setName(FirText);
+                            diagInfectiouses.add(diagInfectiousSec);
+                        }
+                    }
+                } else{
+                    diagInfectiousFir.setName(text);
+                    diagInfectiouses.add(diagInfectiousFir);
+                }
+            }
+            pastLabel.setBloodTransfusions(bloodTransfusions);
+            pastLabel.setVaccinates(vaccinates);
+            pastLabel.setDiags(diags);
+            pastLabel.setOperations(operations);
+            pastLabel.setAllergies(allergies);
+            pastLabel.setDiagInfectiouses(diagInfectiouses);
+            beHospitalizedDoc.setPastLabel(pastLabel);
+        }     catch (Exception e) {
+        e.printStackTrace();
+        logger.error(e.getMessage(), e);
+    }
+        return beHospitalizedDoc;
+    }
+}

+ 69 - 0
structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcessOperation.java

@@ -0,0 +1,69 @@
+package com.lantone.structure.ai.process;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.lantone.structure.ai.model.EntityEnum;
+import com.lantone.structure.ai.model.Lemma;
+import com.lantone.structure.model.label.PreoperativeDiscussionLabel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.List;
+
+/**
+ * 术前小结处理
+ */
+public class EntityProcessOperation extends EntityProcess {
+    private Logger logger = LoggerFactory.getLogger(EntityProcessOperation.class);
+
+    public PreoperativeDiscussionLabel extractEntity(JSONObject aiOut) {
+        PreoperativeDiscussionLabel preoperativeDiscussionLabel= new PreoperativeDiscussionLabel();
+        try {
+
+            //过敏史
+            StringBuffer sbxx = new StringBuffer();
+            int allergy = 0;
+            List<Lemma> indicationAllergy = createEntityTree(aiOut, EntityEnum.ALLERGYRECORD.toString());
+            for (Lemma lemma : indicationAllergy) {
+                allergy++;
+                if(indicationAllergy.size()>1){
+                    sbxx.append(allergy+lemma.getText()+" ");
+                }else{
+                    sbxx.append(lemma.getText());
+                }
+            }
+            preoperativeDiscussionLabel.setAllergyRecord(sbxx.toString());
+
+            //手术禁忌症
+            StringBuffer sbx = new StringBuffer();
+            int opContrain = 0;
+            List<Lemma> indicationOpContrain = createEntityTree(aiOut, EntityEnum.OPCONTRAINDICATION.toString());
+            for (Lemma lemma : indicationOpContrain) {
+                opContrain++;
+                if(indicationOpContrain.size()>1){
+                    sbx.append(opContrain+lemma.getText()+" ");
+                }else{
+                    sbx.append(lemma.getText());
+                }
+            }
+            preoperativeDiscussionLabel.setOpContraindication(sbx.toString());
+
+            //拟实施手术目标部位名称
+          StringBuffer sb = new StringBuffer();
+            int count = 0;
+            List<Lemma> indicationOpBottom = createEntityTree(aiOut, EntityEnum.OPBOTTOMNAME.toString());
+            for (Lemma lemma : indicationOpBottom) {
+                count++;
+                if(indicationOpBottom.size()>1){
+                    sb.append(count+lemma.getText()+" ");
+                }else{
+                    sb.append(lemma.getText());
+                }
+            }
+            preoperativeDiscussionLabel.setOpBottomName(sb.toString());
+        } catch (Exception e) {
+            e.printStackTrace();
+            logger.error(e.getMessage(), e);
+        }
+        return preoperativeDiscussionLabel;
+    }
+}

+ 142 - 0
structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcessRescue.java

@@ -0,0 +1,142 @@
+package com.lantone.structure.ai.process;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.lantone.structure.ai.model.EntityEnum;
+import com.lantone.structure.ai.model.Lemma;
+import com.lantone.structure.model.entity.*;
+import com.lantone.structure.model.label.RescueLabel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 抢救记录处理
+ */
+public class EntityProcessRescue extends EntityProcess {
+    private Logger logger = LoggerFactory.getLogger(EntityProcessRescue.class);
+
+    public RescueLabel extractEntity(JSONObject aiOut) {
+        RescueLabel rescueLabel = new RescueLabel();
+        try {
+            //疾病诊断名称
+            List<Lemma> diagnosisLemma = createEntityTree(aiOut, EntityEnum.DIAGNOSIS_NAME.toString());
+            List<Diagnosis> diagnosisList = new ArrayList<>();
+            for (Lemma lemma : diagnosisLemma) {
+                Diagnosis diagnosis = new Diagnosis();
+                diagnosis.setName(lemma.getText());
+                diagnosisList.add(diagnosis);
+            }
+            rescueLabel.setDiagnosis(diagnosisList);
+
+            //抢救病情
+            List<Lemma> conditionLemma = createEntityTree(aiOut, EntityEnum.CONDITION.toString());
+            List<Condition> conditionList = new ArrayList<>();
+            for (Lemma lemma : conditionLemma) {
+                Condition condition = new Condition();
+                condition.setName(lemma.getText());
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemma : lemma.getRelationLemmas()) {
+                        if (relationLemma.getProperty().equals(EntityEnum.TIME.toString())) {
+                            condition.setPd(addPD(relationLemma));
+                        }
+                    }
+                }
+                conditionList.add(condition);
+            }
+            rescueLabel.setConditions(conditionList);
+
+            //手术及操作名称
+            List<Lemma> operationLemma = createEntityTree(aiOut, EntityEnum.OPERATION_OF_NAME.toString());
+            List<Operation> operationList = new ArrayList<>();
+            for (Lemma lemma : operationLemma) {
+                Operation operation = new Operation();
+                operation.setName(lemma.getText());
+                operation.setOperationLocation(findT(lemma, new OperationLocation(), EntityEnum.OPERATION_OF_POSITION_NAME.toString()));
+                operationList.add(operation);
+            }
+            rescueLabel.setOperations(operationList);
+
+            //操作方法
+            List<Lemma> methodLemma = createEntityTree(aiOut, EntityEnum.OPERATION_METHOD.toString());
+            List<Method> methodList = new ArrayList<>();
+            for (Lemma lemma : methodLemma) {
+                Method method = new Method();
+                method.setName(lemma.getText());
+                method.setCount(findT(lemma, new Count(), EntityEnum.OPERATION_COUNT.toString()));
+                methodList.add(method);
+            }
+            rescueLabel.setMethods(methodList);
+
+            //辅检名称
+            List<Lemma> auxiliaryTestLemma = createEntityTree(aiOut, EntityEnum.AUXILIARY_TEST.toString());
+            List<AuxiliaryTest> auxiliaryTestList = new ArrayList<>();
+            for (Lemma lemma : auxiliaryTestLemma) {
+                AuxiliaryTest auxiliaryTest = new AuxiliaryTest();
+                auxiliaryTest.setName(lemma.getText());
+                if (lemma.isHaveChildren()) {
+                    List<AuxiliaryResult> auxiliaryResultList = new ArrayList<>();
+                    for (Lemma relationLemma : lemma.getRelationLemmas()) {
+                        if (relationLemma.getProperty().equals(EntityEnum.AUXILIARY_RESULT.toString())) {
+                            AuxiliaryResult auxiliaryResult = new AuxiliaryResult();
+                            auxiliaryResult.setName(relationLemma.getText());
+                            auxiliaryResultList.add(auxiliaryResult);
+                        }
+                    }
+                    auxiliaryTest.setAuxiliaryResult(auxiliaryResultList);
+                }
+                auxiliaryTest.setAuxiliaryQuantitative(findT(lemma, new AuxiliaryQuantitative(), EntityEnum.AUXILIARY_QUANTITATIVE.toString()));
+                auxiliaryTestList.add(auxiliaryTest);
+            }
+            rescueLabel.setAuxiliaryTest(auxiliaryTestList);
+
+            //抢救药品
+            List<Lemma> drugLemma = createEntityTree(aiOut, EntityEnum.SALVAGE_DRUG.toString());
+            List<Drug> DrugList = new ArrayList<>();
+            for (Lemma lemma : drugLemma) {
+                Drug drug = new Drug();
+                drug.setName(lemma.getText());
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemma : lemma.getRelationLemmas()) {
+                        if (relationLemma.getProperty().equals(EntityEnum.TIME.toString())) {
+                            drug.setPd(addPD(relationLemma));
+                        }
+                    }
+                }
+                DrugList.add(drug);
+            }
+            rescueLabel.setDrugs(DrugList);
+
+            //介入物名称
+            List<Lemma> interventionLemma = createEntityTree(aiOut, EntityEnum.INTERVENTION.toString());
+            List<Intervention> interventionList = new ArrayList<>();
+            for (Lemma lemma : interventionLemma) {
+                Intervention intervention = new Intervention();
+                intervention.setName(lemma.getText());
+                interventionList.add(intervention);
+            }
+            rescueLabel.setInterventions(interventionList);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            logger.error(e.getMessage(), e);
+        }
+        return rescueLabel;
+    }
+
+
+    /**
+     * 时间
+     *
+     * @param timeLemma
+     * @return
+     */
+    private PD addPD(Lemma timeLemma) {
+        PD pd = new PD();
+        pd.setName(timeLemma.getText());
+        pd.setValue(timeLemma.getText());
+        return pd;
+    }
+}

+ 72 - 0
structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcessStagesSummary.java

@@ -0,0 +1,72 @@
+package com.lantone.structure.ai.process;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.lantone.structure.ai.model.EntityEnum;
+import com.lantone.structure.ai.model.Lemma;
+import com.lantone.structure.model.entity.AuxiliaryExamination;
+import com.lantone.structure.model.entity.Drug;
+import com.lantone.structure.model.entity.Laboratory;
+import com.lantone.structure.model.entity.Surgery;
+import com.lantone.structure.model.label.StagesSummaryLabel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 阶段小结处理
+ */
+public class EntityProcessStagesSummary extends EntityProcess {
+    private Logger logger = LoggerFactory.getLogger(EntityProcessStagesSummary.class);
+
+    public StagesSummaryLabel extractEntity(JSONObject aiOut) {
+        StagesSummaryLabel stagesSummaryLabel = new StagesSummaryLabel();
+        try {
+            //药品
+            List<Lemma> drugLemma = createEntityTree(aiOut, EntityEnum.DRUG_NAME.toString());
+            List<Drug> drugList = new ArrayList<>();
+            for (Lemma lemma : drugLemma) {
+                Drug drug = new Drug();
+                drug.setName(lemma.getText());
+                drugList.add(drug);
+            }
+            stagesSummaryLabel.setDrugs(drugList);
+
+            //手术名称
+            List<Lemma> surgeryLemma = createEntityTree(aiOut, EntityEnum.OPERATION.toString());
+            List<Surgery> surgeryList = new ArrayList<>();
+            for (Lemma lemma : surgeryLemma) {
+                Surgery surgery = new Surgery();
+                surgery.setName(lemma.getText());
+                surgeryList.add(surgery);
+            }
+            stagesSummaryLabel.setSurgerys(surgeryList);
+
+            //实验室检查
+            List<Lemma> examinationLemma = createEntityTree(aiOut, EntityEnum.LABORATORY.toString());
+            List<Laboratory> laboratoryList = new ArrayList<>();
+            for (Lemma lemma : examinationLemma) {
+                Laboratory examination = new Laboratory();
+                examination.setName(lemma.getText());
+                laboratoryList.add(examination);
+            }
+            stagesSummaryLabel.setLaboratory(laboratoryList);
+
+            //辅助检查
+            List<Lemma> auxiliaryExaminationLemma = createEntityTree(aiOut, EntityEnum.AUXILIARY_EXAMINATION.toString());
+            List<AuxiliaryExamination> auxiliaryExaminationList = new ArrayList<>();
+            for (Lemma lemma : auxiliaryExaminationLemma) {
+                AuxiliaryExamination auxiliaryExamination = new AuxiliaryExamination();
+                auxiliaryExamination.setName(lemma.getText());
+                auxiliaryExaminationList.add(auxiliaryExamination);
+            }
+            stagesSummaryLabel.setAuxiliaryExaminations(auxiliaryExaminationList);
+        } catch (Exception e) {
+            e.printStackTrace();
+            logger.error(e.getMessage(), e);
+        }
+        return stagesSummaryLabel;
+    }
+}

+ 195 - 0
structure-center/src/main/java/com/lantone/structure/ai/process/EntityProcessThreeLevelWard.java

@@ -1,12 +1,15 @@
 package com.lantone.structure.ai.process;
 
 import com.alibaba.fastjson.JSONObject;
+import com.lantone.common.util.ListUtil;
 import com.lantone.structure.ai.model.EntityEnum;
 import com.lantone.structure.ai.model.Lemma;
 import com.lantone.structure.model.entity.*;
 import com.lantone.structure.model.label.ThreeLevelWardLabel;
 import com.lantone.common.util.StringUtil;
 import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -28,6 +31,198 @@ public class EntityProcessThreeLevelWard extends EntityProcess {
             EntityEnum.TITLE_FOR_DIAG_BASIS.toString(),
             EntityEnum.TITLE_FOR_DIFF.toString(),
             EntityEnum.TITLE_FOR_TREAT.toString());
+    private Logger logger = LoggerFactory.getLogger(EntityProcessThreeLevelWard.class);
+
+    public ThreeLevelWardLabel extractEntityLate(JSONObject aiOut) {
+        ThreeLevelWardLabel threeLevelWardLabel = new ThreeLevelWardLabel();
+        try {
+            //医嘱信息
+            StringBuffer sb = new StringBuffer();
+            StringBuffer xb = new StringBuffer();
+            StringBuffer bb = new StringBuffer();
+            String drugNames = "",laboratorys,auxoiliarys;
+            //药品
+            List<Lemma> drugName = createEntityTree(aiOut, EntityEnum.DRUG_NAME.toString());
+            for (Lemma lemma : drugName) {
+                String text = lemma.getText();
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemmaRec : lemma.getRelationLemmas()) {
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.STOPNOW.toString())) {
+                            drugNames = relationLemmaRec.getText()+text;
+                            sb.append(drugNames+"、");
+                        }
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.CONTINUE.toString())) {
+                            drugNames = relationLemmaRec.getText()+text;
+                            sb.append(drugNames+"、");
+                        }
+                    }
+                }else{
+                    sb.append(text+" ");
+                }
+            }
+            Boolean sbxflag = false;
+            String str = sb.toString();
+            StringBuffer sbx = new StringBuffer();
+            StringBuffer sbxx = new StringBuffer();
+            if(str.contains("、")){
+                String[] split = str.split("、");
+                if(split.length>1){
+                    for (int i = 0; i < split.length; i++) {
+                        if(!(split[i].contains(EntityEnum.STOPNOW.toString()) || split[i].contains(EntityEnum.CONTINUE.toString()))){
+                            sbx.append(split[i]+"、");
+                        }else{
+                            sbxx.append(split[i]+"、");
+                        }
+                    }
+                }
+            }else{
+                sbxflag = true;
+            }
+            sb = new StringBuffer();
+            if(ListUtil.isNotEmpty(drugName)){
+                sb.append("药品:");
+            }
+            if(!sbxflag){
+                if(sbx.toString().endsWith("、")){
+                    sbx.deleteCharAt(sbx.toString().length()-1);
+                    sbx.append(";");
+                }
+                sb.append(sbx.toString());
+                sb.append(sbxx.toString());
+            }else{
+                sb.append(str);
+            }
+
+            str = sb.toString();
+            if(str.endsWith("、")){
+                sb.deleteCharAt(str.length()-1);
+            }
+            //实验室检查
+            List<Lemma> laboratory = createEntityTree(aiOut, EntityEnum.LABORATORY.toString());
+            for (Lemma lemma : laboratory) {
+                String text = lemma.getText();
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemmaRec : lemma.getRelationLemmas()) {
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.REPATE.toString())) {
+                            laboratorys = relationLemmaRec.getText()+text;
+                            xb.append(laboratorys+"、");
+                        }
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.OTHERREPATE.toString())) {
+                            laboratorys = relationLemmaRec.getText()+text;
+                            xb.append(laboratorys+"、");
+                        }
+                    }
+                }else{
+                    xb.append(text+" ");
+                }
+            }
+            String xtr = xb.toString();
+            StringBuffer xbx = new StringBuffer();
+            StringBuffer xbxx = new StringBuffer();
+            Boolean xbxflag = false;
+            if(xtr.contains("、")){
+                String[] split = xtr.split("、");
+                if(split.length>1){
+                    for (int i = 0; i < split.length; i++) {
+                        if(!(split[i].contains(EntityEnum.STOPNOW.toString()) || split[i].contains(EntityEnum.CONTINUE.toString()))){
+                            xbx.append(split[i]+"、");
+                        }else{
+                            xbxx.append(split[i]+"、");
+                        }
+                    }
+                }
+            }else{
+                xbxflag = true;
+            }
+            if(ListUtil.isNotEmpty(laboratory)){
+                sb.append("  实验室检查:");
+            }
+            if(!xbxflag){
+                if(xbx.toString().endsWith("、")){
+                    xbx.deleteCharAt(xbx.toString().length()-1);
+                    xbx.append(";");
+                }
+                sb.append(xbx.toString());
+                sb.append(xbxx.toString());
+            }else{
+                sb.append(xtr);
+            }
+
+            str = sb.toString();
+            if(str.endsWith("、")){
+                sb.deleteCharAt(str.length()-1);
+            }
+            //辅助检查
+            List<Lemma> auxoiliary = createEntityTree(aiOut, EntityEnum.AUXILIARY_EXAMINATION.toString());
+            for (Lemma lemma : auxoiliary) {
+                String text = lemma.getText();
+                if (lemma.isHaveChildren()) {
+                    for (Lemma relationLemmaRec : lemma.getRelationLemmas()) {
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.REPATE.toString())) {
+                            auxoiliarys = relationLemmaRec.getText()+text;
+                            bb.append(auxoiliarys+"、");
+                        }
+                        if (relationLemmaRec.getProperty().equals(EntityEnum.OTHERREPATE.toString())) {
+                            auxoiliarys = relationLemmaRec.getText()+text;
+                            bb.append(auxoiliarys+"、");
+                        }
+                    }
+                }else{
+                    bb.append(text+" ");
+                }
+            }
+            Boolean bbxflag = false;
+            String btr = bb.toString();
+            StringBuffer bbx = new StringBuffer();
+            StringBuffer bbxx = new StringBuffer();
+            if(btr.contains("、")){
+                String[] split = xtr.split("、");
+                if(split.length>1){
+                    for (int i = 0; i < split.length; i++) {
+                        if(!(split[i].contains(EntityEnum.STOPNOW.toString()) || split[i].contains(EntityEnum.CONTINUE.toString()))){
+                            bbx.append(split[i]+"、");
+                        }else{
+                            bbxx.append(split[i]+"、");
+                        }
+                    }
+                }
+            }else{
+                bbxflag = true;
+            }
+            if(ListUtil.isNotEmpty(auxoiliary)){
+                sb.append("  辅助检查:");
+            }
+            if(!bbxflag){
+                if(bbx.toString().endsWith("、")){
+                    bbx.deleteCharAt(bbx.toString().length()-1);
+                    bbx.append(";");
+                }
+                sb.append(bbx.toString());
+                sb.append(bbxx.toString());
+            }else{
+                sb.append(btr);
+            }
+            str = sb.toString();
+            if(str.endsWith("、")){
+                sb.deleteCharAt(str.length()-1);
+            }
+
+            //手术名称
+            List<Lemma> operation = createEntityTree(aiOut, EntityEnum.OPERATION.toString());
+            if(ListUtil.isNotEmpty(operation)){
+                sb.append("  手术名称:");
+            }
+            for (Lemma lemma : operation) {
+                String text = lemma.getText();
+                sb.append(text+" ");
+            }
+            threeLevelWardLabel.setDoctorAdviceRecord(sb.toString());
+        } catch (Exception e) {
+            e.printStackTrace();
+            logger.error(e.getMessage(), e);
+        }
+            return threeLevelWardLabel;
+    }
 
     public ThreeLevelWardLabel extractEntity(JSONObject aiOut) {
         ThreeLevelWardLabel threeLevelWardLabel = new ThreeLevelWardLabel();

+ 46 - 0
structure-center/src/main/java/com/lantone/structure/controller/StructureController.java

@@ -10,7 +10,13 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 
 @Api(value = "后结构化接口", tags = { "后结构化接口" })
 @RestController
@@ -26,4 +32,44 @@ public class StructureController {
         return RespDTO.onSuc(structureFacade.analysis(analysisVO));
     }
 
+    @ApiOperation(value = "解析(上传文件版)")
+    @PostMapping("analysisTest")
+    public RespDTO<AnalysisDTO> analysisTest(@RequestParam("file") MultipartFile file, String type) {
+        AnalysisVO analysisVO = new AnalysisVO();
+        analysisVO.setType(type);
+        StringBuffer sbf = new StringBuffer();
+        InputStream is = null;
+        InputStreamReader ir = null;
+        BufferedReader br = null;
+        try {
+            is = file.getInputStream();
+            ir = new InputStreamReader(is);
+            br = new BufferedReader(ir);
+            String line = null;
+            while ((line = br.readLine()) != null) {
+                line = line+"\n";
+                sbf.append(line);
+            }
+        } catch (Exception e) {
+
+        } finally {
+            try {
+                if (br != null) {
+                    br.close();
+                }
+                if (ir != null) {
+                    ir.close();
+                }
+                if (is != null) {
+                    is.close();
+                }
+            } catch (Exception e) {
+
+            }
+        }
+        analysisVO.setText(sbf.toString());
+        return RespDTO.onSuc(structureFacade.analysis(analysisVO));
+    }
+
+
 }

+ 1 - 1
structure-center/src/main/java/com/lantone/structure/dto/AnalysisDTO.java

@@ -7,6 +7,6 @@ import java.util.Map;
 @Data
 public class AnalysisDTO {
 
-    private Map<String, Object> result;
+    private Map<String, String> result;
 
 }

+ 105 - 39
structure-center/src/main/java/com/lantone/structure/facade/StructureFacade.java

@@ -1,17 +1,11 @@
 package com.lantone.structure.facade;
 
-import com.google.common.collect.Maps;
-import com.lantone.common.util.FastJsonUtils;
-import com.lantone.structure.ai.AIAnalyze;
-import com.lantone.structure.client.CRFServiceClient;
-import com.lantone.structure.client.SimilarityServiceClient;
+import com.lantone.common.util.StringUtil;
 import com.lantone.structure.dto.AnalysisDTO;
-import com.lantone.structure.model.InputInfo;
-import com.lantone.structure.model.doc.BeHospitalizedDoc;
-import com.lantone.structure.model.label.PresentLabel;
+import com.lantone.structure.facade.tran.*;
 import com.lantone.structure.vo.AnalysisVO;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.commons.collections.MapUtils;
 import org.springframework.stereotype.Component;
 
 import java.util.Map;
@@ -24,43 +18,115 @@ import java.util.Map;
 @Slf4j
 @Component
 public class StructureFacade {
-    @Autowired
-    CRFServiceClient crfServiceClient;
-    @Autowired
-    SimilarityServiceClient similarityServiceClient;
-
 
     public AnalysisDTO analysis(AnalysisVO analysisVO) {
-        if (!analysisVO.getType().equals("现病史")) {
-            return null;
-        }
         AnalysisDTO analysisDTO = new AnalysisDTO();
-        InputInfo inputInfo = new InputInfo();
-
-        BeHospitalizedDoc beHospitalizedDoc = new BeHospitalizedDoc();
-
-        PresentLabel presentLabel = new PresentLabel();
-        presentLabel.setText(analysisVO.getText());
-        beHospitalizedDoc.setPresentLabel(presentLabel);
-
-        inputInfo.setBeHospitalizedDoc(beHospitalizedDoc);
-
-        AIAnalyze aiAnalyze = new AIAnalyze(crfServiceClient, similarityServiceClient);
+        TargetTran targetTran = null;
+        switch (analysisVO.getType()) {
+            case "剖宫产记录":
+                targetTran = new CesareanSectionTran();
+                break;
+            case "输血记录":
+                targetTran = new ClinicalBloodTran();
+                break;
+            case "抢救记录":
+                targetTran = new RescueTran();
+                break;
+            case "阶段小结":
+                targetTran = new StagesSummaryTran();
+                break;
+            case "死亡病例讨论记录":
+                targetTran = new DeathCaseDiscussionTran();
+                break;
+            case "死亡记录":
+                targetTran = new DeathRecordTran();
+                break;
+            case "出院小结":
+                targetTran = new LeaveHospitalTran();
+                break;
+            case "术前小结":
+                targetTran = new PreoperativeDiscussionTran();
+                break;
+            case "转科记录":
+                targetTran = new TransferRecordTran();
+                break;
+            case "交接班记录":
+                targetTran = new DutyShiftSystemTran();
+                break;
+            case "疑难病例讨论记录":
+                targetTran = new DifficultCaseDiscussTran();
+                break;
+            case "上级医师查房记录":
+                targetTran = new ThreeLevelWardTran();
+                break;
+            case "入院记录":
+                targetTran = new BeHospitalizedTran();
+                break;
+            case "24h内入出院记录":
+                targetTran = new BeHospitalizedTran();
+                break;
+            case "24h内入院死亡记录":
+                targetTran = new DeathRecordTran();
+                break;
+            case "首次病程记录":
+                targetTran = new FirstCourseRecordTran();
+                break;
+            case "病危通知书":
+                targetTran = new CriticallyIllNoticeDocTran();
+                break;
+            case "手术知情同意书":
+                targetTran = new OperationInformedConsentDocTran();
+                break;
+            case "会诊记录":
+                targetTran = new ConsultationTran();
+                break;
+            case "其他知情告知同意书":
+                targetTran = new InformedConsentTran();
+                break;
+            case "输血治疗同意书":
+                targetTran = new ClinicBloodConsentDocTran();
+                break;
+            case "特殊检查及特殊治疗同意书":
+                targetTran = new SpecialCureConsentDocTran();
+                break;
+            case "一般手术记录":
+                targetTran = new OperationRecordDocTran();
+                break;
+            case "术前讨论":
+                targetTran = new PreoperativeDiscussionTran();
+                break;
+            case "术后首次病程记录":
+                targetTran = new OperationDiscussionTran();
+                break;
+            case "日常病程记录":
+                targetTran = new DailyCourseRecordTran();
+                break;
+            default:
+                break;
+        }
         try {
-            aiAnalyze.aiProcess(inputInfo);
+            Map<String, String> result = targetTran.convert(analysisVO.getText());
+            resultHandle(result);
+            analysisDTO.setResult(result);
         } catch (Exception e) {
-            log.error("AI模型执行错误:" + e.getMessage(), e);
+            log.error(e.getMessage(), e);
         }
-
-        Map<String, Object> map = Maps.newHashMap();
-        Map<String, Object> jsonMap = FastJsonUtils.getJsonToMap(FastJsonUtils.getBeanToJson(inputInfo.getBeHospitalizedDoc().getPresentLabel()));
-        jsonMap.remove("text");
-        jsonMap.remove("aiText");
-        jsonMap.remove("crfLabel");
-        jsonMap.remove("crfOutput");
-        map.put("现病史", jsonMap);
-        analysisDTO.setResult(map);
         return analysisDTO;
     }
 
+    private void resultHandle(Map<String, String> result) {
+        if (MapUtils.isEmpty(result)) {
+            return;
+        }
+        result.forEach((key, value) -> {
+            if (StringUtil.isNotBlank(value)) {
+                value = StringUtil.trim(value);
+                if (value.endsWith(";") || value.endsWith(";")) {
+                    value = value.substring(0, value.length() - 1);
+                }
+                result.put(key, value);
+            }
+        });
+    }
+
 }

Файловите разлики са ограничени, защото са твърде много
+ 1060 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/BeHospitalizedTran.java


+ 315 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/CesareanSectionTran.java

@@ -0,0 +1,315 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.DateUtil;
+import com.lantone.common.util.ListUtil;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.CaesareanSectionDoc;
+import com.lantone.structure.model.entity.ApgarScore;
+import com.lantone.structure.model.entity.Drug;
+import com.lantone.structure.model.entity.UCAgent;
+import com.lantone.structure.model.label.CaesareanSectionLabel;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2021/2/2 13:48
+ */
+@Slf4j
+public class CesareanSectionTran extends TargetTran {
+
+    @Override
+    public Map<String, String> convert(String text) {
+        List<CaesareanSectionDoc> caesareanSectionDocList = new ArrayList<>();
+        CaesareanSectionDoc caesareanSectionDoc = new CaesareanSectionDoc();
+        caesareanSectionDoc.setText(text);
+        caesareanSectionDocList.add(caesareanSectionDoc);
+        inputInfo.setCaesareanSectionDocs(caesareanSectionDocList);
+        aiProcess();
+
+        Map<String, String> sourceMap = cutWord(text);
+        insertCrf(sourceMap);
+        return sourceMap;
+    }
+
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> ret = Maps.newHashMap();
+        Map<String, String> sourceMap = Maps.newHashMap();
+        text = text.replace("第1次手术", "第1次手术:");
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("手术开始时间", "手术结束时间", "手术日期", "术前诊断", "手术名称", "术中诊断", "手 术 者",
+                        "麻 醉 者", "手术标本", "术中并发症", "术中失血量", "手术经过", "第1次手术"),
+                text
+        );
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        opeTimeHandle(sourceMap, ret);
+        ret.put("术前诊断", sourceMap.get("术前诊断"));
+        ret.put("剖宫产手术过程", sourceMap.get("手术经过").replace("(包括体位、切口处理经过,病理标本肉眼所见)", "").trim());
+        return ret;
+    }
+
+    private void opeTimeHandle(Map<String, String> sourceMap, Map<String, String> ret) {
+        try {
+            String opeStartTime = sourceMap.get("手术开始时间");
+            String opeEndTime = sourceMap.get("手术结束时间");
+            if (StringUtil.isNotBlank(sourceMap.get("手术日期"))) {
+                String[] arry = sourceMap.get("手术日期").split("-");
+                opeStartTime = StringUtil.removeBlank(arry[0].replaceAll("(开始时间)[::]", ""));
+                opeEndTime = StringUtil.removeBlank(arry[1].replaceAll("(结束时间)[::]", ""));
+            }
+            ret.put("手术开始日期时间", opeStartTime);
+            ret.put("手术结束日期时间", opeEndTime);
+            ret.put("手术全程时间(min)", (DateUtil.parseDate(opeEndTime, "yyyy年MM月dd日HH时mm分").getTime() - DateUtil.parseDate(opeStartTime, "yyyy年MM月dd日HH时mm分").getTime()) / 60000 + "min");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+    }
+
+    private void insertCrf(Map<String, String> sourceMap) {
+        List<CaesareanSectionDoc> caesareanSectionDocs = inputInfo.getCaesareanSectionDocs();
+        if (ListUtil.isEmpty(caesareanSectionDocs)) {
+            return;
+        }
+        CaesareanSectionDoc caesareanSectionDoc = caesareanSectionDocs.get(0);
+        CaesareanSectionLabel caesareanSectionLabel = caesareanSectionDoc != null ? caesareanSectionDoc.getCaesareanSectionLabel() : null;
+        if (caesareanSectionLabel == null) {
+            return;
+        }
+        StringBuffer value = new StringBuffer();
+
+        //手术指征
+        //        if (ListUtil.isNotEmpty(caesareanSectionLabel.getDiagnosis())) {
+        //            caesareanSectionLabel.getDiagnosis().stream().filter(i -> i != null && StringUtil.isNotBlank(i.getName())).forEach(i -> {
+        //                value.append(i.getName()).append(";");
+        //                ;
+        //            });
+        //            sourceMap.put("手术指征", value.toString());
+        //            value.setLength(0);
+        //        }
+
+        //麻醉体位
+        if (caesareanSectionLabel.getAnesthesiaMethod() != null) {
+            sourceMap.put("麻醉体位", caesareanSectionLabel.getAnesthesiaMethod().getName());
+        }
+
+        //麻醉效果
+        if (caesareanSectionLabel.getAnestheticEffect() != null) {
+            sourceMap.put("麻醉效果", caesareanSectionLabel.getAnestheticEffect().getName());
+        }
+
+        //子宫情况
+        if (ListUtil.isNotEmpty(caesareanSectionLabel.getUterusConditions())) {
+            caesareanSectionLabel.getUterusConditions().stream().filter(i -> i != null && StringUtil.isNotBlank(i.getName())).forEach(i -> {
+                value.append(i.getName()).append(";");
+                ;
+            });
+            sourceMap.put("子宫情况", value.toString());
+            value.setLength(0);
+        }
+
+        //胎儿娩出方式
+        if (caesareanSectionLabel.getChildbirthWay() != null) {
+            sourceMap.put("胎儿娩出方式", caesareanSectionLabel.getChildbirthWay().getName());
+        }
+
+        //羊水性状
+        //羊水量(mL)
+        if (caesareanSectionLabel.getAmnioticFluid() != null) {
+            if (caesareanSectionLabel.getAmnioticFluid().getAmnioticFluidCharacter() != null) {
+                sourceMap.put("羊水性状", caesareanSectionLabel.getAmnioticFluid().getAmnioticFluidCharacter().getName());
+            }
+            if (caesareanSectionLabel.getAmnioticFluid().getQuantity() != null) {
+                sourceMap.put("羊水量(mL)", caesareanSectionLabel.getAmnioticFluid().getQuantity().getName());
+            }
+        }
+
+        //胎盘娩出情况
+        if (ListUtil.isNotEmpty(caesareanSectionLabel.getChildbirthConditions())) {
+            caesareanSectionLabel.getChildbirthConditions().stream().filter(i -> i != null && StringUtil.isNotBlank(i.getName())).forEach(i -> {
+                value.append(i.getName()).append(";");
+            });
+            sourceMap.put("胎盘娩出情况", value.toString());
+            value.setLength(0);
+        }
+
+        //脐带长度(cm)
+        if (caesareanSectionLabel.getUmbilicalCord() != null) {
+            if (caesareanSectionLabel.getUmbilicalCord().getExtent() != null) {
+                sourceMap.put("脐带长度(cm)", caesareanSectionLabel.getUmbilicalCord().getExtent().getName());
+            }
+        }
+
+        //绕颈身(周)
+        if (caesareanSectionLabel.getCordAroundNeck() != null || caesareanSectionLabel.getCordAroundBody() != null) {
+            String rjValue = "";
+            if (caesareanSectionLabel.getCordAroundNeck() != null) {
+                if (caesareanSectionLabel.getCordAroundNeck().getNegative() != null) {
+                    if (StringUtil.isNotBlank(caesareanSectionLabel.getCordAroundNeck().getNegative().getName())) {
+                        rjValue += caesareanSectionLabel.getCordAroundNeck().getNegative().getName() + "绕颈";
+                    }
+                }
+                if (caesareanSectionLabel.getCordAroundNeck().getCylinderNumber() != null) {
+                    if (StringUtil.isNotBlank(caesareanSectionLabel.getCordAroundNeck().getCylinderNumber().getName())) {
+                        rjValue += caesareanSectionLabel.getCordAroundNeck().getCylinderNumber().getName();
+                    }
+                }
+                rjValue += " ";
+            }
+            if (caesareanSectionLabel.getCordAroundBody() != null) {
+                if (caesareanSectionLabel.getCordAroundBody().getNegative() != null) {
+                    if (StringUtil.isNotBlank(caesareanSectionLabel.getCordAroundBody().getNegative().getName())) {
+                        rjValue += caesareanSectionLabel.getCordAroundBody().getNegative().getName() + "绕身";
+                    }
+                }
+                if (caesareanSectionLabel.getCordAroundBody().getCylinderNumber() != null) {
+                    if (StringUtil.isNotBlank(caesareanSectionLabel.getCordAroundBody().getCylinderNumber().getName())) {
+                        rjValue += caesareanSectionLabel.getCordAroundBody().getCylinderNumber().getName();
+                    }
+                }
+            }
+            sourceMap.put("绕颈身(周)", rjValue.trim());
+        }
+
+        //子宫壁缝合情况
+        if (ListUtil.isNotEmpty(caesareanSectionLabel.getUterineWallSutures())) {
+            caesareanSectionLabel.getUterineWallSutures().stream().filter(i -> i != null && StringUtil.isNotBlank(i.getName())).forEach(i -> {
+                value.append(i.getName()).append(";");
+            });
+            sourceMap.put("子宫壁缝合情况", value.toString());
+            value.setLength(0);
+        }
+
+        //宫缩剂名称
+        //宫缩剂使用方法
+        if (ListUtil.isNotEmpty(caesareanSectionLabel.getUCAgents())) {
+            StringBuffer gsjName = new StringBuffer();
+            StringBuffer gsjMd = new StringBuffer();
+            List<UCAgent> uCAgents = caesareanSectionLabel.getUCAgents().stream()
+                    .filter(i -> i != null && StringUtil.isNotBlank(i.getName()))
+                    .collect(Collectors.toList());
+            uCAgents.forEach(i -> {
+                gsjName.append(i.getName()).append(";");
+                if (i.getConsumption() != null && StringUtil.isNotBlank(i.getConsumption().getName())) {
+                    gsjMd.append(i.getName()).append(" ").append(i.getConsumption().getName()).append(" ");
+                }
+                if (i.getUsageWardRound() != null && StringUtil.isNotBlank(i.getUsageWardRound().getName())) {
+                    gsjMd.append(i.getUsageWardRound().getName());
+                }
+                gsjMd.append(";");
+            });
+            sourceMap.put("宫缩剂名称", gsjName.toString());
+            sourceMap.put("宫缩剂使用方法", gsjMd.toString());
+        }
+
+        //宫腔探查异常情况描述
+        if (ListUtil.isNotEmpty(caesareanSectionLabel.getUterineCavityAbnormity())) {
+            caesareanSectionLabel.getUterineCavityAbnormity().stream().filter(i -> i != null && StringUtil.isNotBlank(i.getName())).forEach(i -> {
+                value.append(i.getName()).append(";");
+                ;
+            });
+            sourceMap.put("宫腔探查异常情况描述", value.toString());
+            value.setLength(0);
+        }
+
+        //宫腔探查处理情况
+        if (ListUtil.isNotEmpty(caesareanSectionLabel.getUterineCavityDispose())) {
+            caesareanSectionLabel.getUterineCavityDispose().stream().filter(i -> i != null && StringUtil.isNotBlank(i.getName())).forEach(i -> {
+                value.append(i.getName()).append(";");
+            });
+            sourceMap.put("宫腔探查处理情况", value.toString());
+            value.setLength(0);
+        }
+
+        //手术时产妇情况
+        if (ListUtil.isNotEmpty(caesareanSectionLabel.getPuerperaCondition())) {
+            caesareanSectionLabel.getPuerperaCondition().stream().filter(i -> i != null && StringUtil.isNotBlank(i.getName())).forEach(i -> {
+                value.append(i.getName()).append(";");
+            });
+            sourceMap.put("手术时产妇情况", value.toString());
+            value.setLength(0);
+        }
+
+        //出血量(mL)
+        if (caesareanSectionLabel.getHemorrhage() != null) {
+            if (caesareanSectionLabel.getHemorrhage().getQuantity() != null) {
+                sourceMap.put("出血量(mL)", caesareanSectionLabel.getHemorrhage().getQuantity().getName());
+            }
+        }
+
+        //输液量(mL)
+        if (caesareanSectionLabel.getFluidInfusion() != null) {
+            if (caesareanSectionLabel.getFluidInfusion().getQuantity() != null) {
+                sourceMap.put("输液量(mL)", caesareanSectionLabel.getFluidInfusion().getQuantity().getName());
+            }
+        }
+
+        //新生儿出生体重(g)
+        //新生儿出生身长(cm)
+        if (caesareanSectionLabel.getNewborn() != null) {
+            if (caesareanSectionLabel.getNewborn().getWeight() != null) {
+                sourceMap.put("新生儿出生体重(g)", caesareanSectionLabel.getNewborn().getWeight().getName());
+            }
+            if (caesareanSectionLabel.getNewborn().getExtent() != null) {
+                sourceMap.put("新生儿出生身长(cm)", caesareanSectionLabel.getNewborn().getExtent().getName());
+            }
+        }
+
+        //Apgar评分值
+        if (ListUtil.isNotEmpty(caesareanSectionLabel.getApgarScores())) {
+            List<ApgarScore> apgarScores = caesareanSectionLabel.getApgarScores().stream()
+                    .filter(i -> i != null && StringUtil.isNotBlank(i.getName()) && i.getScore() != null && StringUtil.isNotBlank(i.getScore().getName()))
+                    .collect(Collectors.toList());
+            if (ListUtil.isNotEmpty(apgarScores)) {
+                sourceMap.put("Apgar评分值", apgarScores.get(0).getScore().getName());
+            }
+        }
+
+        //产瘤大小
+        //产瘤部位
+        if (caesareanSectionLabel.getCaputSuccedaneum() != null) {
+            if (caesareanSectionLabel.getCaputSuccedaneum().getVolume() != null) {
+                sourceMap.put("产瘤大小", caesareanSectionLabel.getCaputSuccedaneum().getVolume().getName());
+            }
+            if (caesareanSectionLabel.getCaputSuccedaneum().getCaputSuccedaneumPart() != null) {
+                sourceMap.put("产瘤部位", caesareanSectionLabel.getCaputSuccedaneum().getCaputSuccedaneumPart().getName());
+            }
+        }
+
+        //手术用药
+        //手术用药量
+        if (ListUtil.isNotEmpty(caesareanSectionLabel.getDrugs())) {
+            StringBuffer drugName = new StringBuffer();
+            StringBuffer consumption = new StringBuffer();
+            List<Drug> drugs = caesareanSectionLabel.getDrugs().stream()
+                    .filter(i -> i != null && StringUtil.isNotBlank(i.getName()))
+                    .collect(Collectors.toList());
+            drugs.forEach(i -> {
+                drugName.append(i.getName()).append(";");
+                if (i.getConsumption() != null && StringUtil.isNotBlank(i.getConsumption().getName())) {
+                    consumption.append(i.getName()).append(" ").append(i.getConsumption().getName());
+                }
+                consumption.append(";");
+            });
+            sourceMap.put("手术用药", drugName.toString());
+            sourceMap.put("手术用药量", consumption.toString());
+        }
+
+        //输血成分
+        //输血量(mL)
+        if (caesareanSectionLabel.getTransfusion() != null) {
+            sourceMap.put("输血成分", caesareanSectionLabel.getTransfusion().getName());
+            if (caesareanSectionLabel.getTransfusion().getQuantity() != null) {
+                sourceMap.put("输血量(mL)", caesareanSectionLabel.getTransfusion().getQuantity().getName());
+            }
+        }
+    }
+
+}

+ 112 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/ClinicBloodConsentDocTran.java

@@ -0,0 +1,112 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 输血治疗同意书
+ * @author: wsy
+ * @time: 2021/3/09 14:49
+ */
+@Slf4j
+public class ClinicBloodConsentDocTran extends TargetTran {
+    @Override
+    public Map<String, String> convert(String text) {
+        Map<String, String> structureMap = cutWord(text);
+        Map<String, String> retMap = new HashMap<String, String>();
+        CommonAnalysisUtil.mapKeyContrastCommon(structureMap, keyContrasts, retMap);
+        retMap.entrySet().removeIf(entry -> StringUtil.isBlank(entry.getValue()));
+        retMap.entrySet().removeIf(entry ->
+                !entry.getValue().matches("[\\d]+年[\\d]+月[\\d]+日[\\d]+时[\\d]+分") && ("患者/法定代理人签名日期时间".equals(entry.getKey()) || "医师签名日期时间".equals(entry.getKey()))
+        );
+        return retMap;
+    }
+
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        String dataStr = "";
+        text = text.replace("年   月   日    时   分", "")
+                .replace("如果患者无法签署知情同意书,请其授权的亲属在此签名:", "")
+                .replace("3.我理解治疗后如果我不遵医嘱,可能影响治疗效果。", "")
+                .replace("_", "");
+
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("姓名", "性别", "年龄", "住院号", "床号", "病历号", "疾病介绍和治疗建议", "1.患者基本情况", "⒈患者基本情况", "(4)\t输血前检查",
+                        "输血前检查", "2.拟使用的血液制品", "2.拟实施的输血方案", "⒉拟实施的输血方案", "2.拟实施的输血/备血方案", "治疗潜在风险和对策", "2.我理解此治疗可能发生的风险",
+                        "医护人员陈述"),
+                text
+        );
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+
+        if (sourceMap != null) {
+            if (sourceMap.containsKey("医护人员陈述")) {
+
+                dataStr = sourceMap.get("医护人员陈述");
+                sourceMap.put("医护人员陈述", dataStr.substring(0, Math.max(0, dataStr.indexOf("医生签名"))));
+                List<String> listTitle = Lists.newArrayList(
+                        "医生签名", "患者、患者家属或患者的法定监护人、授权委托人意见", "患者/患者授权委托人签名", "患者签名", "患方签名", "代理人签名", "与患者关系", "医生陈述"
+                );
+                CommonAnalysisUtil.sortTitlesNoColon(listTitle, dataStr);
+                CommonAnalysisUtil.cutByTitlesNoColon(dataStr, listTitle, 0, sourceMap);
+            } else if (sourceMap.containsKey("2.我理解此治疗可能发生的风险")) {
+
+                dataStr = sourceMap.get("2.我理解此治疗可能发生的风险");
+                sourceMap.put("2.我理解此治疗可能发生的风险", dataStr.substring(0, Math.max(0, dataStr.indexOf("患者、患者家属或患者的法定监护人、授权委托人意见"))));
+                List<String> listTitle = Lists.newArrayList(
+                        "患者、患者家属或患者的法定监护人、授权委托人意见", "患者/患者授权委托人签名", "患者签名", "患方签名", "代理人签名", "患者授权亲属签名", "与患者关系", "医生陈述", "医生签名"
+                );
+                CommonAnalysisUtil.sortTitlesNoColon(listTitle, dataStr);
+                CommonAnalysisUtil.cutByTitlesNoColon(dataStr, listTitle, 0, sourceMap);
+            }
+
+            CommonAnalysisUtil.removeKey(sourceMap, "1.患者基本情况", "2.拟使用的血液制品", "⒈患者基本情况", "⒉拟实施的输血方案", "与患者关系",
+                    "2.拟实施的输血/备血方案", "2.拟实施的输血方案", "疾病介绍和治疗建议");
+
+            disDate(sourceMap, "住院号", "疾病介绍和治疗建议");
+            disDate(sourceMap, "医生签名", "签名日期");
+            disDate(sourceMap, "医生签名", "签名时间");
+            disDate(sourceMap, "患者/患者授权委托人签名", "签名日期");
+            disDate(sourceMap, "患者签名", "签名时间");
+            disDate(sourceMap, "患者签名", "签名日期");
+        }
+        return sourceMap;
+    }
+
+    private void disDate(Map sourceMap, String... args) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        if (sourceMap.containsKey(args[0]) && sourceMap_.get(args[0]).contains(args[1])) {
+            int index = sourceMap_.get(args[0]).indexOf(args[1]);
+            sourceMap.put(args[0], sourceMap_.get(args[0]).substring(0, index));
+            sourceMap.put(args[0] + args[1], sourceMap_.get(args[0]).substring(index).replace(args[1], "").replaceAll("[::]", ""));
+        }
+    }
+
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "病历号=住院号",
+            "姓名=患者姓名",
+            "年龄=年龄(岁)",
+            "床号=病床号",
+            "输血前检查=输血前有关检查项目及结果",
+            "2.我理解此治疗可能发生的风险=输血风险及可能发生的不良后果",
+            "医护人员陈述=医疗机构意见",
+            "患者、患者家属或患者的法定监护人、授权委托人意见=患者/法定代理人意见",
+            "医生签名=医师签名",
+            "医生签名签名日期=医师签名日期时间",
+            "医生签名签名时间=医师签名日期时间",
+            "患者/患者授权委托人签名=患者/法定代理人签名",
+            "患者/患者授权委托人签名签名日期=患者/法定代理人签名日期时间",
+            "住院号疾病介绍和治疗建议=疾病介绍和治疗建议",
+            "患者签名签名时间=患者/法定代理人签名日期时间",
+            "患者签名签名日期=患者/法定代理人签名日期时间",
+            "医生陈述=医疗机构意见"
+    );
+}

+ 153 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/ClinicalBloodTran.java

@@ -0,0 +1,153 @@
+package com.lantone.structure.facade.tran;
+import com.lantone.common.util.ListUtil;
+import com.lantone.structure.model.doc.ClinicalBloodDoc;
+import com.lantone.structure.model.entity.Amount;
+import com.lantone.structure.model.entity.Indication;
+import com.lantone.structure.model.entity.ResponseType;
+import com.lantone.structure.model.label.ClinicalBloodLabel;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2021/2/2 14:16
+ */
+@Slf4j
+public class ClinicalBloodTran extends TargetTran {
+
+    @Override
+    public Map<String, String> convert(String text) {
+        List<ClinicalBloodDoc> clinicalBloodDocList = new ArrayList<>();
+        ClinicalBloodDoc clinicalBloodDoc = new ClinicalBloodDoc();
+        clinicalBloodDoc.setText(text);
+        clinicalBloodDocList.add(clinicalBloodDoc);
+        inputInfo.setClinicalBloodDocs(clinicalBloodDocList);
+        aiProcess();
+        Map<String, String> structureMap = new HashMap<>();
+        bloodContrast(inputInfo.getClinicalBloodDocs(), structureMap);
+        return structureMap;
+    }
+
+        public void bloodContrast( List<ClinicalBloodDoc> clinicalBloodDocs, Map<String, String> retMap) {
+            if(ListUtil.isNotEmpty(clinicalBloodDocs)) clinicalBloodDocs.forEach(clinicalBloodDoc -> {
+                int indicationCount = 1;
+                int responseTypeCount = 1;
+                int amountCount = 1;
+                int measureCount = 1;
+                StringBuffer indicationString = new StringBuffer();
+                StringBuffer responseTypeString = new StringBuffer();
+                StringBuffer timeString = new StringBuffer();
+                StringBuffer amountString = new StringBuffer();
+                StringBuffer measureString = new StringBuffer();
+                StringBuffer bloodNoteString = new StringBuffer();
+                ClinicalBloodLabel clinicalBlood = clinicalBloodDoc.getClinicalBloodLabel();
+
+                if (ListUtil.isNotEmpty(clinicalBlood.getIndication())) {
+                    for (Indication indications : clinicalBlood.getIndication()) {
+                        if (StringUtils.isNotEmpty(indications.getName())) {
+                            if (clinicalBlood.getIndication().size() > 1) {
+                                indicationString.append((indicationCount++) + ".");
+                            }
+                            indicationString.append(indications.getName());
+                        }
+
+                    }
+                    retMap.put("输血指征", indicationString.toString());
+                }
+
+                if (clinicalBlood.getType() != null) {
+                    if (ListUtil.isNotEmpty(clinicalBlood.getType().getAmount())) {
+                        for (Amount amount : clinicalBlood.getType().getAmount()) {
+                            if (amount != null && StringUtils.isNotEmpty(amount.getName())) {
+                                if (clinicalBlood.getType().getAmount().size() > 1) {
+                                    amountString.append((amountCount++) + ".");
+                                }
+                                amountString.append(amount.getName());
+                                retMap.put("输血量(mL)", amountString.toString());
+                            }
+                            if (amount != null && amount.getMeasurementUnit() != null && StringUtils.isNotEmpty(amount.getMeasurementUnit().getName())) {
+                                if (clinicalBlood.getType().getAmount().size() > 1) {
+                                    measureString.append((measureCount++) + ".");
+                                }
+                                measureString.append(amount.getMeasurementUnit().getName());
+                                retMap.put("输血量计量单位", measureString.toString());
+                            }
+                            if (StringUtils.isNotEmpty(clinicalBlood.getType().getName())) {
+                                retMap.put("输血类型", clinicalBlood.getType().getName());
+                            }
+                        }
+                    }
+                }
+                if (clinicalBlood.getReason() != null && StringUtils.isNotEmpty(clinicalBlood.getReason().getName())) {
+                    retMap.put("输血原因", clinicalBlood.getReason().getName());
+                }
+                if (clinicalBlood.getStartTime() != null && StringUtils.isNotEmpty(clinicalBlood.getStartTime().getName())) {
+                    timeString.append("输血开始时间:" + clinicalBlood.getStartTime().getName() + ";");
+                    bloodNoteString.append("输血开始时间:" + clinicalBlood.getStartTime().getName() + ";");
+                }
+                if (clinicalBlood.getEndTime() != null && StringUtils.isNotEmpty(clinicalBlood.getEndTime().getName())) {
+                    timeString.append("输血结束时间:" + clinicalBlood.getEndTime().getName() + ";");
+                    bloodNoteString.append("输血结束时间:" + clinicalBlood.getEndTime().getName() + ";");
+
+                }
+                if (clinicalBlood.getStartTime() != null || clinicalBlood.getEndTime() != null) {
+                    String timeStr = timeString.toString();
+                    if(timeStr.endsWith(";")){
+                        timeStr = timeStr.substring(0, timeStr.lastIndexOf(";"));
+                    }
+                    retMap.put("输血日期时间", timeStr);
+                }
+
+                if (ListUtil.isNotEmpty(clinicalBlood.getResponseType())) {
+                    for (ResponseType responseTypes : clinicalBlood.getResponseType()) {
+                        if (StringUtils.isNotEmpty(responseTypes.getName())) {
+                            if (clinicalBlood.getResponseType().size() > 1) {
+                                responseTypeString.append((responseTypeCount++) + ".");
+                            }
+                            responseTypeString.append(responseTypes.getNegative().getName() + responseTypes.getName());
+                        }
+                    }
+                    retMap.put("输血反应类型", responseTypeString.toString());
+                    bloodNoteString.append("输血反应类型:" +  responseTypeString.toString() + ";");
+                }
+
+                if (null != clinicalBlood.getFrequency() && StringUtils.isNotEmpty(clinicalBlood.getFrequency().getName())) {
+                    retMap.put("输血次数", clinicalBlood.getFrequency().getName());
+                    bloodNoteString.append("输血次数:" +  clinicalBlood.getFrequency().getName() + ";");
+                }
+                if (!retMap.containsKey("输血次数") && StringUtils.isEmpty(retMap.get("输血次数"))) {
+                  if(StringUtils.isNotEmpty(retMap.get("输血量(mL)"))){
+                        String amountRet = retMap.get("输血量(mL)");
+                        int count = findString(amountRet, ".");
+                        if(count==0){
+                            count=1;
+                        }
+                        retMap.put("输血次数",(String.valueOf(count)+"次"));
+                      bloodNoteString.append("输血次数:" +  (String.valueOf(count)+"次") + ";");
+                   }
+                }
+                String bloodNoteStr = bloodNoteString.toString();
+                if(bloodNoteStr.endsWith(";")){
+                    bloodNoteStr = bloodNoteStr.substring(0, bloodNoteStr.lastIndexOf(";"));
+                }
+                retMap.put("输血过程记录",(bloodNoteStr));
+
+            });
+            }
+    public int findString(String source,String target){
+        //计数器
+        int count = 0;
+        //每次查询开始的位置
+        int fromIndex = 0;
+        while((fromIndex = source.indexOf(target, fromIndex)) != -1){
+            count ++;
+            fromIndex = fromIndex + target.length();
+        }
+        return count;
+    }
+}

+ 437 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/ConsultationTran.java

@@ -0,0 +1,437 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.consultation.ConsultationDoc;
+import com.lantone.structure.model.doc.consultation.ConsultationRecordDoc;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+/**
+ * @Description:会诊
+ * @author: cy
+ * @time: 2021/3/09 09:56
+ */
+@Slf4j
+public class ConsultationTran extends TargetTran {
+
+    @Override
+    public Map<String, String> convert(String text) {
+        List<ConsultationDoc> consultationDocs = new ArrayList<ConsultationDoc>();
+        ConsultationDoc consultationDoc = new ConsultationDoc();
+        ConsultationRecordDoc consultationRecordDoc = new ConsultationRecordDoc();
+        consultationRecordDoc .setText(text);
+        consultationDoc.setConsultationRecordDoc(consultationRecordDoc);
+        consultationDocs.add(consultationDoc);
+        inputInfo.setConsultationDocs(consultationDocs);
+        Map<String, String> structureMap = cutWord(text);
+        Map<String, String> retMap = new HashMap<String, String>();
+        consultationContrast(inputInfo.getConsultationDocs(), structureMap);
+        mapKeyContrastCommon(structureMap,stagesContrasts,retMap);
+        return retMap;
+    }
+
+    private List<String> stagesContrasts = Lists.newArrayList(
+            "病历摘要及诊疗经过=病历摘要",
+            "其病历简述如下=病历摘要",
+            "目前诊断=西医诊断名称",
+            "会诊目的及要求=会诊原因",
+            "会诊目的及要求=会诊目的",
+            "会诊理由=会诊原因",
+            "会诊结论=会诊意见",
+            "申请医师签名=会诊申请医师签名",
+            "会诊时间=会诊日期时间"
+    );
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("邀请","拟会诊日期","病历摘要及诊疗经过","申请医师签名","其病历简述如下","会诊理由","会诊目的",
+                        "会诊理由及目的","会诊目的及要求","日期","目前诊断","其他科情况","目前诊断考虑","会诊结论","会诊意见","会诊医师签名","会诊时间","科室"), text);
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        if(sourceMap.containsKey("日期") || sourceMap.containsKey("拟会诊日期")){
+            sourceMap.remove("日期");
+            sourceMap.remove("拟会诊日期");
+        }
+        return sourceMap;
+    }
+
+
+    public static void mapKeyContrastCommon(Map sourceMap, List<String> keyContrasts, Map<String, String> retMap) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        String[] arry = null;
+        String sourceKey = null, targetKey;
+        Set<String> removeKey = new HashSet<>();
+        for (String keyContrast : keyContrasts) {
+            arry = keyContrast.split("=");
+            sourceKey = arry[0];
+            if (arry.length == 1) {
+                targetKey = arry[0];
+            } else {
+                targetKey = arry[1];
+            }
+            if (StringUtil.isNotBlank(sourceMap_.get(sourceKey))
+                    && (!retMap.containsKey(targetKey) || StringUtil.isBlank(retMap.get(targetKey)))) {
+                retMap.put(targetKey, sourceMap_.get(sourceKey));
+            }
+            removeKey.add(sourceKey);
+        }
+        Set<String> keySet = retMap.keySet();
+        for (String key : sourceMap_.keySet()) {
+            if (!keySet.contains(key) && !removeKey.contains(key)) { // 如果之前已放过key就不用放了
+                retMap.put(key, sourceMap_.get(key));
+            }
+        }
+    }
+
+
+    public void consultationContrast( List<ConsultationDoc> consultationDocs, Map<String, String> retMap) {
+        if(consultationDocs != null) {
+            String text = consultationDocs.get(0).getConsultationRecordDoc().getText();
+            if(text.contains("\n")){
+                String[] split = text.split("\n");
+                for (int i = 0; i < split.length; i++) {
+                    String hero = split[i];
+                    if(hero.contains("医院") && hero.length()<10){
+                        if(StringUtil.isNotEmpty(hero)){
+                            retMap.put("会诊医师所在医疗机构名称",hero);
+                        }
+                    }if(hero.contains("日期:")){
+                        String firRet = hero.substring(hero.indexOf("日期:")+"日期:".length());
+                        if(StringUtil.isNotEmpty(firRet)){
+                            retMap.put("会诊日期时间",firRet);
+                        }
+                    }
+                }
+            }
+            if(StringUtil.isNotEmpty(retMap.get("会诊日期时间"))){
+                String date = retMap.get("会诊日期时间");
+                 date = extractDate(date);
+                if(StringUtil.isEmpty(date)){
+                    retMap.remove("会诊日期时间");
+                }
+            }
+            //会诊医师签名
+                String data = "";
+                String ret = "";
+                if(text.contains("科室:")){
+                data = text.substring(text.lastIndexOf("科室:")+"科室:".length());
+                    if(data.contains("医师:")){
+                        ret = data.substring(data.lastIndexOf("医师:")+"医师:".length());
+                    }
+            }
+            if(StringUtil.isNotEmpty(ret.trim())) {
+                retMap.put("会诊医师签名",ret);
+            }
+
+            //辅助检查结果
+            if(StringUtil.isNotEmpty(retMap.get("其病历简述如下"))) {
+                String specical = retMap.get("其病历简述如下");
+                String retStr = "";
+                if (specical.contains("辅助检查:")) {
+                    String[] split = specical.split("辅助检查:");
+                    if (split.length > 1) {
+                        retStr = split[1];
+                    }
+
+                if(StringUtil.isNotEmpty(retStr)){
+                    retMap.put("辅助检查结果",retStr);
+                }
+                }
+            }
+            //西医诊断名称
+            if(StringUtil.isNotEmpty(retMap.get("目前诊断考虑"))) {
+                String firStr = retMap.get("目前诊断考虑");
+                retMap.put("西医诊断名称",firStr);
+            }else{
+                if(StringUtil.isNotEmpty(retMap.get("其病历简述如下"))){
+                    String specical = retMap.get("其病历简述如下");
+                    String retStr = "";
+                    if (specical.contains("诊断为:")) {
+                         retStr = specical.substring( specical.lastIndexOf("诊断为:")+"诊断为:".length());
+                    }
+                    if (specical.contains("辅助检查:")) {
+                        retStr = retStr.substring(0,retStr.lastIndexOf("辅助检查:"));
+                    }
+                    if(StringUtil.isNotEmpty(retStr)) {
+                        retMap.put("西医诊断名称",retStr);
+                    }
+                }
+            }
+
+
+           // 会诊意见
+            if(StringUtil.isEmpty(retMap.get("会诊意见")) && StringUtil.isNotEmpty(retMap.get("会诊结论"))) {
+                String result = retMap.get("会诊结论");
+                String firStr = text.substring(text.lastIndexOf("会诊结论:")+"会诊结论:".length(), text.lastIndexOf("科室:"));
+                String tip = "";
+                if(firStr.contains("\n")){
+                    String[] split = firStr.split("\n");
+                    for (int i = 0; i < split.length; i++) {
+                       if( split[i].contains("医院")){
+                           tip =  split[i];
+                       }
+                    }
+                }
+                if(StringUtil.isNotEmpty(tip)){
+                    String retData = result.substring(0, result.lastIndexOf(tip));
+                    retMap.put("会诊意见",retData);
+                }
+
+                    retMap.remove("会诊结论");
+            }
+
+            String[] firSplit = text.split("\n");
+
+            //区别
+            if(firSplit.length>0){
+                String deptStr = "";
+                for (int i = 0; i < firSplit.length; i++) {
+                    String firStr = firSplit[i];
+                    if(firStr.contains("日期")){
+                         firStr = firStr.split("日期")[0];
+                    }
+                    if(firStr.contains("请求")){
+                         deptStr = firStr.substring(firStr.indexOf("请求")+"请求".length());
+                    }
+                    if(deptStr.contains(" ")){
+                        String[] split = deptStr.split(" ");
+                        if(split.length>=2 && StringUtil.isNotEmpty(deptStr)){
+                            deptStr =deptStr.trim();
+                        }
+                    }
+
+                    if(StringUtil.isNotEmpty(deptStr)){
+                        retMap.put("会诊科室名称",deptStr);
+                    }
+                }
+
+                for (int i = 0; i < firSplit.length-4; i++) {
+                    String firStr = firSplit[i];
+                    if(firStr.contains("医师:")){
+                        String firRet = firStr.substring(0, firStr.indexOf("医师:"));
+                        String retStr = "";
+                        Boolean flag = true;
+                        if(flag && firRet.contains("科")){
+                            retStr = firRet.substring(0, firRet.indexOf("科")+"科".length());
+                           if(firRet.contains(")")){
+                               retStr = firRet.substring(0, firRet.indexOf(")")+")".length());
+                            }
+                           flag = false;
+                        }
+                        if( flag && firRet.contains("区")){
+                            retStr = firRet.substring(0, firRet.indexOf("区")+"区".length());
+                            if(firRet.contains(")")){
+                                retStr = firRet.substring(0, firRet.indexOf(")")+")".length());
+                            }
+                        }
+                        if( flag && firRet.contains("房")){
+                            retStr = firRet.substring(0, firRet.indexOf("房")+"房".length());
+                            if(firRet.contains(")")){
+                                retStr = firRet.substring(0, firRet.indexOf(")")+")".length());
+                            }
+                        }
+
+                        if(StringUtil.isNotEmpty(retStr)) {
+                            retMap.put("会诊申请科室",retStr);
+                        }
+                    }
+                }
+
+                if(StringUtil.isNotEmpty(retMap.get("会诊目的")) && StringUtil.isNotEmpty(retMap.get("会诊申请科室")) ){
+                    String firStr = retMap.get("会诊目的");
+                    String secStr = retMap.get("会诊申请科室");
+                    if(firStr.contains(secStr)){
+                        String retData = firStr.substring(0, firStr.lastIndexOf(secStr));
+                        if(StringUtil.isNotEmpty(retData)){
+                            retMap.put("会诊目的",retData);
+                        }
+                    }
+                }
+
+                if(StringUtil.isEmpty(retMap.get("会诊目的")) || StringUtil.isEmpty(retMap.get("会诊理由")) && StringUtil.isNotEmpty(retMap.get("会诊理由及目的"))) {
+                    String firStr = retMap.get("会诊理由及目的");
+                    String specialName = retMap.get("会诊申请科室");
+                    if(StringUtil.isNotEmpty(firStr) && StringUtil.isNotEmpty(specialName) &&  firStr.contains(specialName)){
+                         firStr = firStr.substring(0, firStr.lastIndexOf(specialName));
+                        retMap.put("会诊目的",firStr);
+                        retMap.put("会诊理由",firStr);
+                    }
+
+                }
+                retMap.remove("会诊理由及目的");
+            }
+
+            if(StringUtil.isNotEmpty("日期")){
+                retMap.remove("日期");
+            }
+            if(StringUtil.isNotEmpty("科室")){
+                retMap.remove("科室");
+            }
+            if(StringUtil.isEmpty(retMap.get("会诊意见"))){
+                retMap.remove("会诊意见");
+
+            }
+            if(StringUtil.isEmpty(retMap.get("会诊结论"))){
+                retMap.remove("会诊结论");
+            }
+            //===============兼容模板===================
+                if(text.contains("科室:") && text.contains("床号:")){
+                    String subStr = text.substring(text.indexOf("科室:") + "科室:".length(), text.indexOf("床号:"));
+                    if(StringUtil.isNotEmpty(subStr)) {
+                        retMap.put("会诊申请科室",subStr);
+                    }
+                }
+
+            if(StringUtil.isNotEmpty(retMap.get("申请医师签名"))){
+                String sign = retMap.get("申请医师签名");
+                if(sign.contains("会诊")){
+                    sign = sign.substring(0, sign.lastIndexOf("会诊"));
+                    if(StringUtil.isNotEmpty(sign)){
+                        retMap.put("申请医师签名",sign);
+                    }else{
+                        retMap.remove("申请医师签名");
+                    }
+                }
+            }
+
+            if(StringUtil.isEmpty(retMap.get("会诊医师签名")) || StringUtil.isEmpty(retMap.get("会诊医师签名").trim())){
+                retMap.remove("会诊医师签名");
+            }
+
+            if(StringUtil.isNotEmpty(retMap.get("会诊时间"))){
+                String date = retMap.get("会诊时间");
+                String dateRet = extractDate(date);
+                if(StringUtil.isNotEmpty(dateRet)){
+                    retMap.put("会诊时间",dateRet);
+                }else{
+                    retMap.remove("会诊时间");
+                }
+            }
+            if(StringUtil.isNotEmpty(retMap.get("目前诊断"))){
+                String strFir = retMap.get("病历摘要及诊疗经过");
+                String str = retMap.get("目前诊断");
+                String strThr = retMap.get("其他科情况");
+                if(StringUtil.isNotEmpty(str) && StringUtil.isNotEmpty(strThr)){
+                    strFir = strFir+str+strThr;
+                }else{
+                    if(StringUtil.isNotEmpty(str)&& StringUtil.isEmpty(strThr)){
+                        strFir = strFir+str;
+                    }
+                    if(StringUtil.isEmpty(str)&& StringUtil.isNotEmpty(strThr)){
+                        strFir = strFir+strThr;
+                    }
+                }
+                retMap.put("病历摘要及诊疗经过",strFir);
+                if(str.contains("、")){
+                    String[] split = str.split("、");
+                    for (int i = 1; i < split.length; i++) {
+                       String retStr = split[i].trim();
+                       Boolean flag = false;
+                        try {
+                            String strInt = String.valueOf(retStr.charAt(retStr.length() - 1));
+                            int num = Integer.parseInt(strInt);
+                            flag = true;
+                        } catch (Exception e) {
+                            log.error(e.getMessage());
+                        }
+                        if(!flag){
+                            String flagRet = split[i - 1];
+                            String sub = str.substring(str.indexOf(flagRet));
+                            if(sub.contains("。")){
+                                String flagFir = sub.split("。")[0];
+                                 flagFir = str.substring(0, str.indexOf(flagFir) + flagFir.length());
+                                retMap.put("目前诊断",flagFir);
+                            }
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if(StringUtil.isNotEmpty(retMap.get("病历摘要及诊疗经过"))){
+                String firStr = retMap.get("病历摘要及诊疗经过");
+                if(StringUtil.isNotEmpty(retMap.get("目前诊断"))){
+                    String caseStr = retMap.get("目前诊断");
+                    if(firStr.contains(caseStr)){
+                        String subStr= firStr.substring(firStr.lastIndexOf(caseStr) + caseStr.length() + 1);
+                        if(StringUtil.isNotEmpty(subStr)){
+                            retMap.put("诊疗过程描述",subStr);
+                        }
+                    }
+                }
+            }
+            if(StringUtil.isNotEmpty(retMap.get("邀请"))){
+                String interFace = retMap.get("邀请");
+                String falgFir = interFace;
+                String retStr = "";
+                if(interFace.contains("医院")){
+                    interFace = interFace.substring(0, interFace.lastIndexOf("医院")+"医院".length());
+                    falgFir = falgFir.substring(falgFir.lastIndexOf("医院")+"医院".length());
+                }
+                if( falgFir.contains("科")){
+                    retStr = falgFir.substring(0, falgFir.indexOf("科")+"科".length());
+                    if(falgFir.contains(")")){
+                        retStr = falgFir.substring(0, falgFir.indexOf(")")+")".length());
+                    }
+                }
+                if( falgFir.contains("区")){
+                    retStr = falgFir.substring(0, falgFir.indexOf("科")+"科".length());
+                    if(falgFir.contains(")")){
+                        retStr = falgFir.substring(0, falgFir.indexOf(")")+")".length());
+                    }
+                }
+                if( falgFir.contains("房")){
+                    retStr = falgFir.substring(0, falgFir.indexOf("科")+"科".length());
+                    if(falgFir.contains(")")){
+                        retStr = falgFir.substring(0, falgFir.indexOf(")")+")".length());
+                    }
+                }
+                if(StringUtil.isNotEmpty(retStr)) {
+                    retMap.put("会诊科室名称",retStr);
+                }
+                if(StringUtil.isNotEmpty(interFace)) {
+                    retMap.put("会诊医师所在医疗机构名称",interFace);
+                }
+            }
+              retMap.remove("邀请");
+            retMap.remove("其他科情况");
+        }
+    }
+
+    // 取/前
+    public static String parseStr(String text){
+        if(text.contains("/")){
+            text = text.substring(0,text.lastIndexOf("/"));
+            text= parseStr(text);
+        }
+        return text;
+    }
+
+    /**
+     * 抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String extractDate(String top) {
+        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        } else {
+            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日");
+            Matcher m1 = p1.matcher(top);
+            if (m1.find()) {
+                return m1.group(0);
+            }
+        }
+        return null;
+    }
+}

+ 101 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/CriticallyIllNoticeDocTran.java

@@ -0,0 +1,101 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.*;
+
+/**
+ * @Description:病危通知书
+ * @author: wsy
+ * @time: 2021/3/08 11:29
+ */
+@Slf4j
+public class CriticallyIllNoticeDocTran extends TargetTran {
+    @Override
+    public Map<String, String> convert(String text) {
+        Map<String, String> structureMap = cutWord(text);
+        Map<String, String> retMap = new HashMap<String, String>();
+        CommonAnalysisUtil.mapKeyContrastCommon(structureMap, keyContrasts, retMap);
+        retMap.entrySet().removeIf(entry -> StringUtil.isBlank(entry.getValue()));
+        retMap.entrySet().removeIf(entry ->
+                !entry.getValue().matches("[\\d]+年[\\d]+月[\\d]+日[\\d]+时[\\d]+分") && ("病危(重)通知日期时间".equals(entry.getKey()) || "法定代理人签名日期时间".equals(entry.getKey()))
+        );
+        return retMap;
+    }
+
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        String dateStr = "";
+        text = text.replace("年   月   日   时   分", "")
+                .replace("年 月 日  时  分","");
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("科别", "住院号", "入院日期", "入住院日期", "姓名", "性别", "年龄", "职业", "临床诊断","病危通知书", "病情概要", "病重情况", "病情危重情况", "主要抢救措施"),
+                text
+        );
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        List<String> keys = Lists.newArrayList("病情概要", "主要抢救措施");
+        if (sourceMap != null) {
+            if (sourceMap.containsKey("主要抢救措施")) {
+                dateStr = sourceMap.get("主要抢救措施");
+                sourceMap.put("主要抢救措施", dateStr.substring(0, Math.max(0, dateStr.indexOf("病人家属签名"))));
+            }else if(sourceMap.containsKey("病危通知书")){
+                dateStr = sourceMap.get("病危通知书");
+                sourceMap.put("病危通知书", dateStr.substring(0, Math.max(0, dateStr.indexOf("病人家属签名"))));
+            }
+            joinWord(sourceMap, keys);
+            List<String> listTitle = Lists.newArrayList(
+                    "病人家属签名", "关系", "签名日期", "通知时间", "经治医师", "科主任"
+            );
+            CommonAnalysisUtil.cutByTitlesNoColon(dateStr, listTitle, 0, sourceMap);
+            CommonAnalysisUtil.removeKey(sourceMap, "病情概要", "主要抢救措施");
+            //判断日期是否正确
+
+            disDate(sourceMap, "关系", "时间");
+        }
+        return sourceMap;
+    }
+
+    private void disDate(Map sourceMap, String... args) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        if (sourceMap.containsKey(args[0]) && sourceMap_.get(args[0]).contains(args[1])) {
+            int index = sourceMap_.get(args[0]).indexOf(args[1]);
+            sourceMap.put(args[0], sourceMap_.get(args[0]).substring(0, index));
+            sourceMap.put(args[0] + args[1], sourceMap_.get(args[0]).substring(index).replace(args[1], "").replaceAll("[::]", ""));
+        }
+    }
+
+
+    private void joinWord(Map<String, String> sourceMap, List<String> keys) {
+        StringBuffer sb = new StringBuffer();
+        for (String key : keys) {
+            if (sourceMap.containsKey(key)) {
+                sb.append(key + ":" + sourceMap.get(key)).append("\r\n");
+            }
+        }
+        sourceMap.put("病情概况及主要抢救措施", sb.toString());
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "科别=病区名称",
+            "科室=科室名称",
+            "姓名=患者姓名",
+            "病房=病房号",
+            "病床=病床号",
+            "年龄=年龄(岁)",
+            "病重情况=病危(重)通知内容",
+            "病危通知书=病危(重)通知内容",
+            "病情危重情况=病危(重)通知内容",
+            "通知时间=病危(重)通知日期时间",
+            "病人家属签名=法定代理人签名",
+            "关系=法定代理人与患者关系",
+            "时间=法定代理人签名日期时间",
+            "关系时间=法定代理人签名日期时间",
+            "签名日期=法定代理人签名日期时间",
+            "经治医师=医师签名"
+    );
+}

+ 196 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/DailyCourseRecordTran.java

@@ -0,0 +1,196 @@
+package com.lantone.structure.facade.tran;
+
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.model.doc.DailyCourseRecordDoc;
+import com.lantone.structure.model.label.DailyCourseRecordLabel;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description:日常病程记录
+ * @author: cy
+ * @time: 2021/3/16 17:23
+ */
+@Slf4j
+public class DailyCourseRecordTran extends TargetTran {
+
+    @Override
+    public Map<String, String> convert(String text) {
+        List<DailyCourseRecordDoc> dailyCourseRecordDocs = new ArrayList<>();
+        DailyCourseRecordDoc dailyCourseRecordDoc  = new DailyCourseRecordDoc();
+        dailyCourseRecordDoc.setText(text);
+        dailyCourseRecordDocs.add(dailyCourseRecordDoc);
+        inputInfo.setDailyCourseRecordDocs(dailyCourseRecordDocs);
+        Map<String, String> structureMap = new HashMap<String, String>();
+        dailyCourseContrast(inputInfo.getDailyCourseRecordDocs(), structureMap);
+        dailyCourseRecordDoc.setStructureMap(structureMap);
+        aiProcess();
+        lastSovle(inputInfo.getDailyCourseRecordDocs(),structureMap);
+        return structureMap;
+    }
+
+    public void dailyCourseContrast(List<DailyCourseRecordDoc> dailyCourseRecordDocs,Map<String, String> retMap) {
+        String text = dailyCourseRecordDocs.get(0).getText();
+        String file = text;
+        String str = extractDate(file);
+            if(StringUtil.isNotEmpty(str)){
+                retMap.put("记录日期时间",str);
+        }
+
+        String signDate = "签名日期";
+        if(file.contains("签字日期")){
+            signDate = "签字日期";
+        }
+        if(file.contains(signDate)){
+            String date = file.substring(file.lastIndexOf(signDate));
+            date = extractDate(date);
+            if(StringUtil.isNotEmpty(date)){
+                retMap.put("签名日期时间",date);
+            }
+        }
+        String signName= parseString(file);
+        signName = signName.replace("\n", "").replace(" ","").trim();
+        if(StringUtil.isNotEmpty(signName) && signName.length()<15){
+            retMap.put("医师签名",signName);
+        }
+        String ret = text;
+        if(StringUtil.isNotEmpty(str)){
+            String[] split = text.split(str);
+            ret = text.substring(text.lastIndexOf(split[1]));
+            String[] notes = ret.split("记录");
+            ret = ret.substring(ret.lastIndexOf(notes[1]));
+        }
+            if(StringUtil.isNotEmpty(retMap.get("医师签名")) && ret.contains(retMap.get("医师签名"))){
+                ret = ret.substring(0, ret.lastIndexOf(retMap.get("医师签名")));
+            }
+            String flag  = "/";
+            if(ret.endsWith("//")){
+                flag = "//";
+            }
+
+        String flagStr = "注意事项:";
+        if(file.contains("处理意见:")){
+            flagStr = "处理意见:";
+        }
+        if(!file.contains(flagStr) && file.contains("查房指出")){
+            flagStr = "查房指出";
+        }
+        if(!file.contains(flagStr) && file.contains("查房后指出:")){
+            flagStr = "查房后指出:";
+        }
+        if(!file.contains(flagStr) && file.contains("拟今予")){
+            flagStr = "拟今予";
+        }
+        if(!file.contains(flagStr) && file.contains("今予")){
+            flagStr = "今予";
+        }
+        if(!file.contains(flagStr) && file.contains("拟今日")){
+            flagStr = "拟今日";
+        }
+        if(!file.contains(flagStr) && file.contains("继续予")){
+            flagStr = "继续予";
+        }
+        if(file.contains(flagStr)){
+            String doctorAdvice = file.substring(file.lastIndexOf(flagStr)+flagStr.length());
+            if(file.contains("拟今日")||file.contains("拟今予")){
+                 doctorAdvice = file.substring(file.lastIndexOf(flagStr));
+            }
+            if(StringUtil.isNotEmpty(retMap.get("医师签名")) && doctorAdvice.contains(retMap.get("医师签名"))){
+                doctorAdvice = doctorAdvice.substring(0, doctorAdvice.lastIndexOf(retMap.get("医师签名")));
+            }
+                if(doctorAdvice.endsWith(flag)){
+                    doctorAdvice =  doctorAdvice.substring(0,doctorAdvice.lastIndexOf(flag));
+                }
+                if(doctorAdvice.contains("修正诊断")){
+                    doctorAdvice =  doctorAdvice.substring(0,doctorAdvice.lastIndexOf("修正诊断"));
+                }
+                if(doctorAdvice.contains("补充诊断")){
+                    doctorAdvice =  doctorAdvice.substring(0,doctorAdvice.lastIndexOf("补充诊断"));
+                }
+            if(doctorAdvice.contains("AE及合并用药")){
+                doctorAdvice =  doctorAdvice.substring(0,doctorAdvice.lastIndexOf("AE及合并用药"));
+                if(doctorAdvice.contains("。")){
+                    doctorAdvice =  doctorAdvice.substring(0,doctorAdvice.lastIndexOf("。"));
+                }
+            }
+            if(doctorAdvice.contains("药物号:")){
+                doctorAdvice =  doctorAdvice.substring(0,doctorAdvice.lastIndexOf("药物号:"));
+                String sub = file.substring(file.lastIndexOf("药物号:"));
+                if(sub.contains("。")){
+                    sub =  sub.split("。")[0];
+                    doctorAdvice = doctorAdvice+sub;
+                }
+            }
+                if(doctorAdvice.startsWith(",")){
+                    doctorAdvice =  doctorAdvice.substring(",".length());
+                }
+            retMap.put("医嘱内容",doctorAdvice);
+            if(StringUtils.isNotEmpty(retMap.get("医嘱内容")) && retMap.get("医嘱内容").replace("\n","").replace(" ","").trim().equals("。")){
+                retMap.remove("医嘱内容");
+            }
+        }
+            if(ret.endsWith(flag)){
+                ret =  ret.substring(0,ret.lastIndexOf(flag));
+            }
+            if(StringUtil.isNotEmpty(ret)){
+                retMap.put("住院病程",ret);
+            }
+    }
+
+    public static void lastSovle(List<DailyCourseRecordDoc> dailyCourseRecordDocs , Map<String,String> rep) {
+        if(!dailyCourseRecordDocs.isEmpty() && dailyCourseRecordDocs.get(0)!=null && dailyCourseRecordDocs.get(0)
+                .getDailyCourseRecordLabel()!=null){
+            DailyCourseRecordLabel dailyCourseRecordLabel = dailyCourseRecordDocs.get(0).getDailyCourseRecordLabel();
+            String doctorAdviceRecord = dailyCourseRecordLabel.getDoctorAdviceRecord();
+            if(StringUtil.isNotEmpty(doctorAdviceRecord)){
+                if(StringUtil.isEmpty(rep.get("医嘱内容"))){
+                    rep.put("医嘱内容",doctorAdviceRecord);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String extractDate (String top){
+        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        } else {
+            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日");
+            Matcher m1 = p1.matcher(top);
+            if (m1.find()) {
+                return m1.group(0);
+            }
+        }
+        return null;
+    }
+
+    // 取/后
+    public static String parseString(String text){
+        if(text.contains("/")){
+            text = text.substring(text.lastIndexOf("/")+1);
+            text= parseString(text);
+        }
+        return text;
+    }
+
+    // 取/前
+    public static String parseStr(String text){
+        if(text.contains("/")){
+            text = text.substring(0,text.lastIndexOf("/"));
+            text= parseStr(text);
+        }
+        return text;
+    }
+}

+ 390 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/DeathCaseDiscussionTran.java

@@ -0,0 +1,390 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.DeathCaseDiscussDoc;
+
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.time.DateUtils;
+
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description:死亡病例讨论记录
+ * @author: cy
+ * @time: 2021/2/23 09:15
+ */
+@Slf4j
+public class DeathCaseDiscussionTran extends TargetTran {
+
+    @Override
+    public Map<String, String> convert(String text) {
+        DeathCaseDiscussDoc deathCaseDiscussDoc = new DeathCaseDiscussDoc();
+        deathCaseDiscussDoc.setText(text);
+        inputInfo.setDeathCaseDiscussDoc(deathCaseDiscussDoc);
+        Map<String, String> structureMap = cutWord(text);
+        Map<String, String> retMap = new HashMap<String, String>();
+        deathCaseDiscussContrast(inputInfo.getDeathCaseDiscussDoc(), structureMap);
+        mapKeyContrastCommon(structureMap,stagesContrasts,retMap);
+        return retMap;
+    }
+
+    private List<String> stagesContrasts = Lists.newArrayList(
+            "姓名=患者姓名",
+            "讨论时间=讨论日期时间",
+            "讨论主持人=主持人姓名",
+            "参加人员=参加讨论人员名单",
+            "死亡诊断=死亡诊断名称",
+            "讨论摘要=死亡讨论记录",
+            "主持人总结=主持人总结意见"
+
+    );
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("姓名","性别","年龄","床号","讨论时间", "讨论地点","讨论主持人","参加人员","汇报病史",
+                        "死亡诊断","讨论摘要","主持人总结"),
+                text
+        );
+        //单独处理参加人员(截取依据:护士不会汇报病史,而且汇报病史的人会出现在参加人员中,所以会有一个人的名字出现两次)
+        List<String> ftitles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("﹙副﹚主任医师","主治医师","医师","护士","汇报病史"),
+                text
+        );
+
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        CommonAnalysisUtil.cutByTitles(text, ftitles, 0, sourceMap);
+        if(sourceMap.containsKey("性别")||sourceMap.containsKey("床号")||sourceMap.containsKey("汇报病史")||sourceMap.containsKey("护士")){
+            sourceMap.remove("性别");
+            sourceMap.remove("床号");
+            sourceMap.remove("汇报病史");
+        }
+
+        return sourceMap;
+    }
+
+    public static String parseString(String text){
+        if(text.contains("/")){
+            text = text.substring(0,text.lastIndexOf("/"));
+            text= parseString(text);
+        }
+        return text;
+    }
+
+    public static void mapKeyContrastCommon(Map sourceMap, List<String> keyContrasts, Map<String, String> retMap) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        String[] arry = null;
+        String sourceKey = null, targetKey;
+        Set<String> removeKey = new HashSet<>();
+        for (String keyContrast : keyContrasts) {
+            arry = keyContrast.split("=");
+            sourceKey = arry[0];
+            if (arry.length == 1) {
+                targetKey = arry[0];
+            } else {
+                targetKey = arry[1];
+            }
+            if (StringUtil.isNotBlank(sourceMap_.get(sourceKey))
+                    && (!retMap.containsKey(targetKey) || StringUtil.isBlank(retMap.get(targetKey)))) {
+                retMap.put(targetKey, sourceMap_.get(sourceKey));
+            }
+            removeKey.add(sourceKey);
+        }
+        Set<String> keySet = retMap.keySet();
+        for (String key : sourceMap_.keySet()) {
+            if (!keySet.contains(key) && !removeKey.contains(key)) { // 如果之前已放过key就不用放了
+                retMap.put(key, sourceMap_.get(key));
+            }
+        }
+    }
+
+
+    /**
+     * 抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String extractDate(String top) {
+        Pattern pattern = Pattern.compile("[0-9]{4}");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        }
+        return null;
+    }
+
+    public void deathCaseDiscussContrast( DeathCaseDiscussDoc deathCaseDiscussDoc, Map<String, String> retMap) {
+        if(deathCaseDiscussDoc != null){
+            //姓名
+            if(StringUtil.isNotEmpty(retMap.get("姓名"))){
+                String value= resultHandle(retMap.get("姓名"));
+                retMap.put("姓名",value);
+            }
+
+            //年龄
+         if(StringUtil.isNotEmpty(retMap.get("年龄"))){
+             String value= resultHandle(retMap.get("年龄"));
+             if (value.contains("岁")) {
+                 retMap.put("年龄(岁)",value);
+                 retMap.remove("年龄");
+             }
+             if(value.contains("月")){
+                 retMap.put("年龄(月)",value);
+                 retMap.remove("年龄");
+             }
+         }
+
+            //主持人姓名去职称
+            List<String>titleStr = Lists.newArrayList("﹙副﹚主任医师","(副)主任医师","副主任医师", "主治医师","主任医师",
+                    "住院医师","医师", "护士");
+            for (String timeName : titleStr) {
+                String dirName = retMap.get("讨论主持人");
+                if (StringUtil.isNotEmpty(dirName)) {
+                    if (dirName.contains(timeName)) {
+                        retMap.put("讨论主持人", dirName.split(timeName)[0]);
+                        break;
+                    }
+                }
+            }
+
+            //参加讨论人员名单
+
+         // 去掉最后无法识别的名字,例如 徐金印医师汇报病史    该名会出现在参加人员名单上排除法处理
+            // 兼容参加人员无护士-写法抛弃截取换行即可
+            List<String> attendNames = new ArrayList<>();
+            StringBuffer targetRet = new StringBuffer();
+            if(StringUtil.isNotEmpty(retMap.get("参加人员"))){
+                String  retData = "";
+                String  replace = "";
+                String attendName = retMap.get("参加人员");
+                    if(StringUtil.isNotEmpty(retMap.get("﹙副﹚主任医师"))) {
+                        String rName = retMap.get("﹙副﹚主任医师");
+                        transAdd(rName, attendNames);
+                        retMap.remove("﹙副﹚主任医师");
+                    }
+                    if(StringUtil.isNotEmpty(retMap.get("主治医师"))) {
+                        String rName = retMap.get("主治医师");
+                        transAdd(rName, attendNames);
+                    }
+                    if(StringUtil.isNotEmpty(retMap.get("医师"))) {
+                        String rName = retMap.get("医师");
+                        if(StringUtil.isEmpty(retMap.get("护士"))) {
+                            rName =  rName.substring(0,rName.lastIndexOf("、") + 3);
+                            transAdd(rName, attendNames);
+                            String newRname =  retMap.get("医师").substring( retMap.get("医师").lastIndexOf("、") + 3);
+                            for (String name : attendNames) {
+                               if(newRname.contains(name)){
+                                   retMap.put("医师", retMap.get("医师").substring(0,retMap.get("医师").lastIndexOf(name)));
+                                    retData =attendName.substring(0, attendName.lastIndexOf(name));
+                                    replace = retData;
+                               }
+                            }
+                        }else{
+                            transAdd(rName, attendNames);
+                        }
+                    }
+
+                if(StringUtil.isNotEmpty(retMap.get("护士"))) {
+                    String spiltString = attendName.substring(attendName.indexOf("护士")+2, attendName.lastIndexOf("医师"));
+                    for (String name : attendNames) {
+                        if(spiltString.contains(name)){
+                            retData = attendName.substring(0, attendName.lastIndexOf(name));
+                            replace = retData;
+                        }
+                    }
+                }
+
+                //职称与姓名空格区分
+                if( retData.contains("主治医师:")){
+                    retData = retData.substring(0,retData.indexOf("主治医师:"));
+                    if(StringUtil.isNotEmpty(retData)){
+                        targetRet.append(retData+" ");
+                    }
+                    if(StringUtil.isNotEmpty(retMap.get("主治医师"))){
+                        targetRet.append("主治医师:"+retMap.get("主治医师")+" ");
+                    }
+                    if(StringUtil.isNotEmpty(retMap.get("医师"))){
+                        targetRet.append("医师:"+retMap.get("医师")+" ");
+                    }
+                    String rec = "";
+
+                    if( replace.contains("护士:")){
+                        rec = replace.substring(replace.lastIndexOf("护士:"));
+                    }
+                    if(StringUtil.isNotEmpty(rec)){
+                        targetRet.append(rec);
+                        retMap.remove("护士");
+                    }
+                }
+
+
+                    retMap.remove("主治医师");
+                    retMap.remove("医师");
+                    retMap.put("参加人员",targetRet.toString());
+                }
+
+
+            //直接死亡原因名称
+            if(StringUtil.isNotEmpty(retMap.get("死亡诊断"))){
+                String deathDiagnosislName = retMap.get("死亡诊断");
+                comatible(deathDiagnosislName,retMap);
+            }
+
+            //主持人签名
+            if(StringUtil.isNotEmpty(retMap.get("主持人总结"))){
+                String directSummary = retMap.get("主持人总结");
+
+                //签名日期时间
+                if(directSummary.contains("记录者(签名)")) {
+                    String sginTime= lastTime(directSummary);
+                    if(StringUtil.isNotEmpty(sginTime)){
+                        retMap.put("签名日期时间", sginTime);
+                    }
+
+                String trueRet = "";
+                if(directSummary.contains("主持人(签名)") && directSummary.contains("记录者(签名)")){
+                    trueRet = directSummary.substring( directSummary.indexOf("主持人(签名)")+7, directSummary.indexOf("记录者(签名)")).trim();
+                }
+                if(directSummary.contains(" 记录者(签名)")){
+                    String signTimme = retMap.get("签名日期时间");
+                    if(StringUtil.isNotEmpty(signTimme)){
+                        String recordRet = directSummary.substring(directSummary.indexOf("记录者(签名)")+7,directSummary.indexOf( signTimme.split("年")[0])).trim();
+                        retMap.put("主治医师签名",recordRet);
+                    }
+                }
+
+                if(StringUtil.isNotEmpty(trueRet)){
+                    retMap.put("主任医师签名",trueRet);
+                }
+                }
+            }
+
+            //主持人总结
+            if(StringUtil.isNotEmpty(retMap.get("主持人总结"))){
+                String directSummary = retMap.get("主持人总结");
+                String trueRet = "";
+                if(directSummary.contains("主持人(签名)")){
+                    trueRet = directSummary.substring(0, directSummary.indexOf("主持人(签名)"));
+                }
+                retMap.put("主持人总结",trueRet);
+            }
+        }
+
+    }
+
+    public static void comatible(String deathDiagnosislName,Map<String,String>retMap){
+        String trueRet = "";
+        if (deathDiagnosislName.contains("2.")) {
+            trueRet = deathDiagnosislName.substring(0, deathDiagnosislName.indexOf("2."));
+            if (trueRet.contains("1.")) {
+                trueRet = trueRet.substring(2);
+            }
+        }else{
+            if (deathDiagnosislName.contains("1.")) {
+                trueRet = deathDiagnosislName;
+            }else{
+                trueRet=  deathDiagnosislName.trim().split(" ")[0];
+            }
+        }
+
+        if(StringUtil.isNotEmpty(trueRet)){
+            retMap.put("直接死亡原因名称", trueRet);
+        }
+    }
+
+
+    /**
+     * 抽取文本中的最后时间
+     *
+     * @param top
+     * @return
+     */
+    public static String lastTime(String top) {
+        int length = top.trim().length();
+        String substring = top.trim().substring(length - 22, length);
+        String stringDate = "";
+        if( substring.contains("年")){
+           String[] time = substring.split("年");
+           String timeYear = time[0].trim();
+                  timeYear = extractDate(timeYear);
+            if( substring.contains("月")){
+               String[] timeLater = time[1].split("月");
+               String timeMouth = timeLater[0].trim();
+               if(substring.contains("日")){
+                   String[] timeLast = timeLater[1].split("日");
+                   String timeDate = timeLast[0].trim();
+                   if(StringUtil.isNotEmpty(timeYear) && StringUtil.isNotEmpty(timeMouth) && StringUtil.isNotEmpty(timeDate)){
+                       stringDate = timeYear + "年" + timeMouth + "月" + timeDate + "日" ;
+                   }
+               }
+           }
+       }
+        Date date = null;
+        try {
+            date = DateUtils.parseDate(stringDate, StringUtil.dateFormats);
+        } catch (Exception e) {
+            log.error(e.getMessage(),e);
+        }
+        if(date!= null){
+            return stringDate;
+        }else{
+            return "";
+        }
+    }
+
+    private String resultHandle(String value) {
+            if (StringUtil.isNotBlank(value)) {
+                value = StringUtil.trim(value);
+                if (value.endsWith(",") || value.endsWith(",")) {
+                    value = value.substring(0, value.length() - 1);
+                }
+            }
+        return value;
+    }
+    //递归添加到集合
+    public void transAdd(String name, List<String> attendName){
+          if(name.contains("、") || name.contains(" ")){
+              String value = "";
+              if(name.contains("、")){
+                   value = name.substring(name.lastIndexOf("、")+1);
+                   name = name.substring(0,name.lastIndexOf("、"));
+              }
+              if(name.contains(" ")){
+                   value = name.substring(name.lastIndexOf(" ")+1);
+                   name = name.substring(0,name.lastIndexOf(" "));
+              }
+              if(StringUtil.isNotEmpty(value)){
+                  if(value.contains("主任")){
+                      value = value.substring(0, value.indexOf("主任"));
+                  }
+                  if(value.contains("主治")) {
+                      value = value.substring(0, value.indexOf("主治"));
+                  }
+                  if(value.contains("医师")){
+                      value = value.substring(0,value.indexOf("医师"));
+                  }
+                  attendName.add(value);
+              }
+              transAdd(name, attendName);
+          }else{
+              if(name.contains("主任")){
+                  name = name.substring(0, name.indexOf("主任"));
+              }
+              if(name.contains("主治")) {
+                  name = name.substring(0, name.indexOf("主治"));
+              }
+              if(name.contains("医师")){
+                  name = name.substring(0,name.indexOf("医师"));
+              }
+              attendName.add(name);
+          }
+    }
+
+}

+ 321 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/DeathRecordTran.java

@@ -0,0 +1,321 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.DeathRecordDoc;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.time.DateUtils;
+
+
+import java.util.*;
+
+
+/**
+ * @Description:死亡记录
+ * @author: cy
+ * @time: 2021/2/24 09:33
+ */
+@Slf4j
+public class DeathRecordTran extends TargetTran {
+
+    @Override
+    public Map<String, String> convert(String text) {
+        DeathRecordDoc deathRecordDoc = new DeathRecordDoc();
+        deathRecordDoc.setText(text);
+        inputInfo.setDeathRecordDoc(deathRecordDoc);
+        Map<String, String> structureMap = cutWord(text);
+        Map<String, String> retMap = new HashMap<String, String>();
+        deathRecordContrast(inputInfo.getDeathRecordDoc(), structureMap);
+        mapKeyContrastCommon(structureMap,stagesContrasts,retMap);
+        return retMap;
+    }
+
+    private List<String> stagesContrasts = Lists.newArrayList(
+            "姓名=患者姓名",
+            "入院日期=入院日期时间",
+            "入院时间=入院日期时间",
+            "诊疗经过=诊疗过程描述",
+            "死亡日期=死亡日期时间",
+            "死亡时间=死亡日期时间",
+            "死亡诊断=死亡诊断名称"
+    );
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                //
+                Lists.newArrayList("姓名","姓    名","性别","性    别","年龄","年    龄","职业"," 职    业","入院日期","入院时间","入院诊断", "死亡日期","死亡时间","主    诉",
+                        "住院天数","死亡诊断","最后诊断","入院情况","流行病史","表格<诊断>内容","诊疗经过", "治疗经过","抢救措施","死亡原因","死亡原因(包括死亡讨论结果)"),
+                text
+        );
+
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        if(sourceMap.containsKey("住院天数")||sourceMap.containsKey("入院诊断")  ||sourceMap.containsKey("流行病史")  ||sourceMap.containsKey("补充诊断")){
+            sourceMap.remove("住院天数");
+            sourceMap.remove("入院诊断");
+            sourceMap.remove("流行病史");
+            sourceMap.remove("补充诊断");
+        }
+        return sourceMap;
+    }
+
+
+    public static void mapKeyContrastCommon(Map sourceMap, List<String> keyContrasts, Map<String, String> retMap) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        String[] arry = null;
+        String sourceKey = null, targetKey;
+        Set<String> removeKey = new HashSet<>();
+        for (String keyContrast : keyContrasts) {
+            arry = keyContrast.split("=");
+            sourceKey = arry[0];
+            if (arry.length == 1) {
+                targetKey = arry[0];
+            } else {
+                targetKey = arry[1];
+            }
+            if (StringUtil.isNotBlank(sourceMap_.get(sourceKey))
+                    && (!retMap.containsKey(targetKey) || StringUtil.isBlank(retMap.get(targetKey)))) {
+                retMap.put(targetKey, sourceMap_.get(sourceKey));
+            }
+            removeKey.add(sourceKey);
+        }
+        Set<String> keySet = retMap.keySet();
+        for (String key : sourceMap_.keySet()) {
+            if (!keySet.contains(key) && !removeKey.contains(key)) { // 如果之前已放过key就不用放了
+                retMap.put(key, sourceMap_.get(key));
+            }
+        }
+    }
+
+
+    /**
+     * 抽取文本中的最后时间
+     *
+     * @param top
+     * @return
+     */
+    public static String lastTime(String top) {
+        int length = top.trim().length();
+        String stringDate = top.trim().substring(length - 11, length);
+        Date date = null;
+        try {
+             date = DateUtils.parseDate(stringDate, StringUtil.dateFormats);
+        } catch (Exception e) {
+           log.error(e.getMessage(),e);
+        }
+        if(date!= null){
+            return stringDate;
+        }else{
+            return "";
+        }
+    }
+
+
+    public void deathRecordContrast(  DeathRecordDoc deathRecordDoc, Map<String, String> retMap) {
+        if(deathRecordDoc != null) {
+            //年龄
+            if (StringUtil.isNotEmpty(retMap.get("年龄"))) {
+                String value = retMap.get("年龄");
+                if (value.contains("岁")) {
+                    retMap.put("年龄(岁)", value);
+                    retMap.remove("年龄");
+                }
+                if (value.contains("月")) {
+                    retMap.put("年龄(月)", value);
+                    retMap.remove("年龄");
+                }
+            }
+
+
+
+            //直接死亡原因名称
+            if (StringUtil.isNotEmpty(retMap.get("死亡诊断"))) {
+                String deathDiagnosislName = retMap.get("死亡诊断");
+               Boolean flag = false;
+                if(deathDiagnosislName.contains("/")){
+                     deathDiagnosislName = deathDiagnosislName.substring(0, deathDiagnosislName.lastIndexOf("/"));
+                     flag = true;
+                }
+                if(deathDiagnosislName.contains("管理员")){
+                    deathDiagnosislName = deathDiagnosislName.substring(0, deathDiagnosislName.lastIndexOf("管理员"));
+                    flag = true;
+                }
+                if(deathDiagnosislName.contains("      ")){
+                    String[] split = deathDiagnosislName.split("      ");
+                    if(split.length>2){
+                        deathDiagnosislName =  split[0];
+                        flag = true;
+                    }
+                }
+                if(flag && StringUtil.isNotEmpty(deathDiagnosislName)){
+                retMap.put("死亡诊断",deathDiagnosislName);
+                retMap.put("死亡诊断-西医诊断名称",deathDiagnosislName);
+                }else{
+                    retMap.remove("死亡诊断");
+                }
+                comatible(deathDiagnosislName,retMap);
+            }
+
+            //死亡诊断名称兼容最后诊断
+            if (StringUtil.isNotEmpty(retMap.get("最后诊断"))) {
+                String deathDiagnosislName = retMap.get("最后诊断");
+                comatible(deathDiagnosislName,retMap);
+                retMap.put("死亡诊断名称",retMap.get("最后诊断"));
+                retMap.remove("最后诊断");
+            }
+
+            //如果诊疗经过为空则取治疗经过  需要拼接抢救措施
+            if (StringUtil.isEmpty(retMap.get("诊疗经过"))) {
+                if (StringUtil.isNotEmpty(retMap.get("治疗经过"))) {
+                    retMap.put("诊疗过程描述",retMap.get("治疗经过"));
+                    if (StringUtil.isNotEmpty(retMap.get("抢救措施"))) {
+                        retMap.put("诊疗过程描述",retMap.get("治疗经过")+" "+"抢救措施:"+retMap.get("抢救措施"));
+                        retMap.remove("治疗经过");
+                        retMap.remove("抢救措施");
+                    }
+                }
+            }else{
+                String str = retMap.get("诊疗经过");
+                if (StringUtil.isNotEmpty(retMap.get("抢救措施"))) {
+                    retMap.put("诊疗经过",str+" "+"抢救措施:"+retMap.get("抢救措施"));
+                    retMap.remove("抢救措施");
+                }
+            }
+
+            //签名日期时间
+            if(StringUtil.isNotEmpty(retMap.get("死亡原因(包括死亡讨论结果)"))){
+                String lastText = retMap.get("死亡原因(包括死亡讨论结果)");
+                String sginTime= lastTime(lastText);
+                if(StringUtil.isNotEmpty(sginTime)){
+                    retMap.put("签名日期时间", sginTime);
+                }
+                retMap.remove("死亡原因(包括死亡讨论结果)");
+            }
+
+            //兼容日间
+            //主诉
+            if (StringUtil.isEmpty(retMap.get("主诉"))) {
+                retMap.remove("主诉");
+            }
+
+            //入院情况
+            if (StringUtil.isEmpty(retMap.get("入院情况"))) {
+                retMap.remove("入院情况");
+            }else{
+                String firStr = retMap.get("入院情况");
+                if(firStr.contains("初步诊断:")){
+                    String str = firStr.substring(0, firStr.lastIndexOf("初步诊断:"));
+                    if(StringUtil.isNotEmpty(str)){
+                    retMap.put("入院情况",str);
+                    }else{
+                        retMap.remove("入院情况");
+                    }
+                }
+            }
+            //死亡时间
+            if (StringUtil.isEmpty(retMap.get("死亡时间"))) {
+                retMap.remove("死亡时间");
+            }
+
+            //死亡原因
+            if (StringUtil.isEmpty(retMap.get("死亡原因"))) {
+                retMap.remove("死亡原因");
+            }
+
+            //初步诊断
+            if (StringUtil.isNotEmpty(retMap.get("表格<诊断>内容"))) {
+                String firStr = retMap.get("表格<诊断>内容");
+                String retStr = "";
+                if(firStr.contains("初步诊断:")){
+
+                    retStr = firStr.substring(firStr.lastIndexOf("初步诊断:")+"初步诊断:".length());
+                }
+                if(retStr.contains("补充诊断:")){
+                    retStr = retStr.split("补充诊断:")[0];
+                }
+                if(StringUtil.isNotEmpty(retStr.trim()) && retStr.contains("医师签名")){
+                    retStr= retStr.substring(0,retStr.lastIndexOf("医师签名"));
+                }else{
+                    if( !retStr.contains("日  期") && retStr.contains("年") && retStr.contains("月")){
+                        String date = lastTime(retStr);
+                        if(StringUtil.isNotEmpty(date)) {
+                            retStr= retStr.substring(retStr.lastIndexOf("初步诊断:")+"初步诊断:".length(),retStr.lastIndexOf(date));
+                        }
+                    }
+                }
+
+                if (StringUtil.isNotEmpty(retStr.trim())) {
+                    retMap.put("入院诊断-西医诊断名称",retStr);
+                }
+                retMap.remove("表格<诊断>内容");
+            }else{
+                retMap.remove("表格<诊断>内容");
+            }
+
+
+            //入院时间
+            if (StringUtil.isEmpty(retMap.get("入院时间"))) {
+                retMap.remove("入院时间");
+            }
+      /*      String text = deathRecordDoc.getText();
+            String[] split = text.split("\n");
+            for (int i = 0; i < split.length; i++) {
+                if( split[i].contains("姓    名:")){
+                    String nameStr = split[i].substring(split[i].indexOf("姓    名:")+"姓    名:".length());
+                    if (StringUtil.isNotEmpty(nameStr) && StringUtil.isEmpty(retMap.get("姓名"))) {
+                        retMap.put("姓名",nameStr);
+                    }
+                }
+                if( split[i].contains("性    别:")){
+                    String nameStr = split[i].substring(split[i].indexOf("性    别:")+"性    别:".length());
+                    if (StringUtil.isNotEmpty(nameStr) && StringUtil.isEmpty(retMap.get("性别"))) {
+                        retMap.put("性别",nameStr);
+                    }
+                }
+
+                if( split[i].contains("年    龄:")){
+                    String nameStr = split[i].substring(split[i].indexOf("年    龄:")+"年    龄:".length());
+                    if (StringUtil.isNotEmpty(nameStr) && StringUtil.isEmpty(retMap.get("年龄(岁)"))|| StringUtil.isEmpty(retMap.get("年龄(月)"))) {
+                        if (nameStr.contains("岁")) {
+                            retMap.put("年龄(岁)", nameStr);
+                            retMap.remove("年龄");
+                        }
+                        if (nameStr.contains("月")) {
+                            retMap.put("年龄(月)", nameStr);
+                            retMap.remove("年龄");
+                        }
+                    }
+                }
+
+                if( split[i].contains("职    业:")){
+                    String nameStr = split[i].substring(split[i].indexOf("职    业:")+"职    业:".length());
+                    if (StringUtil.isNotEmpty(nameStr) && StringUtil.isEmpty(retMap.get("职业"))) {
+                        retMap.put("职业",nameStr);
+                    }
+                }
+
+            }*/
+        }
+    }
+
+    public static void comatible(String deathDiagnosislName,Map<String,String>retMap){
+        String trueRet = "";
+        if (deathDiagnosislName.contains("2.")) {
+            trueRet = deathDiagnosislName.substring(0, deathDiagnosislName.indexOf("2."));
+            if (trueRet.contains("1.")) {
+                trueRet = trueRet.substring(2);
+            }
+        }else{
+            if (deathDiagnosislName.contains("1.")) {
+                trueRet = deathDiagnosislName;
+            }else{
+                trueRet=  deathDiagnosislName.trim().split(" ")[0];
+            }
+        }
+       if(StringUtil.isNotEmpty(trueRet)){
+            retMap.put("直接死亡原因名称", trueRet);
+        }
+    }
+}

+ 209 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/DifficultCaseDiscussTran.java

@@ -0,0 +1,209 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.DifficultCaseDiscussDoc;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.time.DateUtils;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description:疑难病例讨论记录
+ * @author: cy
+ * @time: 2021/3/02 09:53
+ */
+@Slf4j
+public class DifficultCaseDiscussTran extends TargetTran {
+    @Override
+    public Map<String, String> convert(String text) {
+        List<DifficultCaseDiscussDoc> difficultCaseDiscussDocs = new ArrayList<>();
+        DifficultCaseDiscussDoc difficultCaseDiscussDoc = new DifficultCaseDiscussDoc();
+        difficultCaseDiscussDoc.setText(text);
+        difficultCaseDiscussDocs.add(difficultCaseDiscussDoc);
+        inputInfo.setDifficultCaseDiscussDocs(difficultCaseDiscussDocs);
+        Map<String, String> structureMap = cutWord(text);
+        Map<String, String> retMap = new HashMap<String, String>();
+        dDContrast(inputInfo.getDifficultCaseDiscussDocs(), structureMap);
+        mapKeyContrastCommon(structureMap,stagesContrasts,retMap);
+        return retMap;
+    }
+
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("讨论时间","讨论地点","讨论主持人","参加人员","汇报","讨论摘要","主持人总结"),
+                text
+        );
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        if(sourceMap.containsKey("汇报")){
+            sourceMap.remove("汇报");
+        }
+        return sourceMap;
+    }
+
+
+    private List<String> stagesContrasts = Lists.newArrayList(
+            "讨论时间=讨论日期时间",
+            "讨论主持人=主持人姓名",
+            "讨论摘要=讨论意见",
+            "参加人员=参加讨论人员名单",
+            "主持人总结=主持人总结意见"
+    );
+
+    public void dDContrast ( List<DifficultCaseDiscussDoc> difficultCaseDiscussDocs,Map<String, String> retMap) {
+        String text = difficultCaseDiscussDocs.get(0).getText();
+
+        //主持人姓名去职称
+        List<String>titleStr = Lists.newArrayList("﹙副﹚主任医师","(副)主任医师","副主任医师", "主治医师","主任医师",
+                "住院医师","医师", "护士");
+        for (String timeName : titleStr) {
+            String dirName = retMap.get("讨论主持人");
+            if (StringUtil.isNotEmpty(dirName)) {
+                if (dirName.contains(timeName)) {
+                    retMap.put("讨论主持人", dirName.split(timeName)[0]);
+                    break;
+                }
+            }
+        }
+        if(StringUtil.isNotEmpty(retMap.get("主持人总结"))){
+            String dirSum = retMap.get("主持人总结");
+            if(dirSum.contains("主持人(签名)")){
+                String substring = dirSum.substring(0, dirSum.lastIndexOf("主持人(签名)"));
+                if(StringUtil.isNotEmpty(substring)){
+                    retMap.put("主持人总结",substring);
+                }
+            }
+        }
+
+        if(StringUtil.isNotEmpty(retMap.get("参加人员"))){
+            String fir = text.substring(text.indexOf("参加人员:")+5, text.lastIndexOf("汇报病史"));
+            String[] split = fir.split("\n");
+            StringBuffer sb = new StringBuffer();
+            for (int i = 0; i < split.length-1; i++) {
+                sb.append(split[i]).append("  ");
+            }
+            retMap.put("参加人员",sb.toString());
+        }
+
+        String trueRet = "";
+        if(text.contains("主持人(签名)") && text.contains("记录者(签名)")){
+            trueRet = text.substring( text.indexOf("主持人(签名)")+7, text.indexOf("记录者(签名)")).trim();
+        }
+        if(StringUtil.isNotEmpty(trueRet)){
+            retMap.put("主任医师签名",trueRet);
+        }
+
+        if(text.contains(" 记录者(签名)")){
+          String  record = text.substring(text.indexOf("记录者(签名)")+7);
+            StringBuffer sb = new StringBuffer();
+
+            String[] split = record.split(" ");
+            sb.append(split[0].trim()).append(split[1].trim()).append(split[2].trim());
+            if(StringUtil.isNotEmpty(sb.toString())){
+            retMap.put("主治医师签名",sb.toString());
+           }
+        }
+    }
+
+    public static void mapKeyContrastCommon(Map sourceMap, List<String> keyContrasts, Map<String, String> retMap) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        String[] arry = null;
+        String sourceKey = null, targetKey;
+        Set<String> removeKey = new HashSet<>();
+        for (String keyContrast : keyContrasts) {
+            arry = keyContrast.split("=");
+            sourceKey = arry[0];
+            if (arry.length == 1) {
+                targetKey = arry[0];
+            } else {
+                targetKey = arry[1];
+            }
+            if (StringUtil.isNotBlank(sourceMap_.get(sourceKey))
+                    && (!retMap.containsKey(targetKey) || StringUtil.isBlank(retMap.get(targetKey)))) {
+                retMap.put(targetKey, sourceMap_.get(sourceKey));
+            }
+            removeKey.add(sourceKey);
+        }
+        Set<String> keySet = retMap.keySet();
+        for (String key : sourceMap_.keySet()) {
+            if (!keySet.contains(key) && !removeKey.contains(key)) { // 如果之前已放过key就不用放了
+                retMap.put(key, sourceMap_.get(key));
+            }
+        }
+    }
+
+
+    /**
+     * 抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String extractDate(String top) {
+        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        } else {
+            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日");
+            Matcher m1 = p1.matcher(top);
+            if (m1.find()) {
+                return m1.group(0);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 抽取文本中的最后时间
+     *
+     * @param top
+     * @return
+     */
+    public static String lastTime(String top) {
+        int length = top.trim().length();
+        String substring = top.trim().substring(length - 22, length);
+        String stringDate = "";
+        if( substring.contains("年")){
+            String[] time = substring.split("年");
+            String timeYear = time[0].trim();
+            timeYear = extractDate(timeYear);
+            if( substring.contains("月")){
+                String[] timeLater = time[1].split("月");
+                String timeMouth = timeLater[0].trim();
+                if(substring.contains("日")){
+                    String[] timeLast = timeLater[1].split("日");
+                    String timeDate = timeLast[0].trim();
+                    if(StringUtil.isNotEmpty(timeYear) && StringUtil.isNotEmpty(timeMouth) && StringUtil.isNotEmpty(timeDate)){
+                        stringDate = timeYear + "年" + timeMouth + "月" + timeDate + "日" ;
+                    }
+                }
+            }
+        }
+        Date date = null;
+        try {
+            date = DateUtils.parseDate(stringDate, StringUtil.dateFormats);
+        } catch (Exception e) {
+            log.error(e.getMessage(),e);
+        }
+        if(date!= null){
+            return stringDate;
+        }else{
+            return "";
+        }
+    }
+
+    public static String parseString(String text){
+        if(text.contains("/")){
+            text = text.substring(text.lastIndexOf("/")+1);
+            text= parseString(text);
+        }
+        return text;
+    }
+}

+ 161 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/DutyShiftSystemTran.java

@@ -0,0 +1,161 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.DutyShiftSystemDoc;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description:交接班记录
+ * @author: cy
+ * @time: 2021/3/01 18:52
+ */
+@Slf4j
+public class DutyShiftSystemTran extends TargetTran {
+    @Override
+    public Map<String, String> convert(String text) {
+        List<DutyShiftSystemDoc> dutyShiftSystemDocs = new ArrayList<>();
+        DutyShiftSystemDoc dutyShiftSystemDoc = new DutyShiftSystemDoc();
+        dutyShiftSystemDoc.setText(text);
+        dutyShiftSystemDocs.add(dutyShiftSystemDoc);
+        inputInfo.setDutyShiftSystemDocs(dutyShiftSystemDocs);
+        Map<String, String> structureMap = cutWord(text);
+        Map<String, String> retMap = new HashMap<String, String>();
+        dutyShiftSystemContrast(inputInfo.getDutyShiftSystemDocs(), structureMap);
+        mapKeyContrastCommon(structureMap,stagesContrasts,retMap);
+        return retMap;
+    }
+
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("入院日期","交班日期","接班日期","主    诉","入院情况","入院诊断","诊治经过","目前诊断", "治疗情况", "诊疗计划","交班注意事项"),
+                text
+        );
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        if(sourceMap.containsKey("入院诊断") ||sourceMap.containsKey("目前诊断")){
+            sourceMap.remove("入院诊断");
+            sourceMap.remove("目前诊断");
+        }
+        return sourceMap;
+    }
+
+
+    private List<String> stagesContrasts = Lists.newArrayList(
+            "入院日期=入院日期时间",
+            "交班日期=交班日期时间",
+            "接班日期=接班日期时间",
+            "主    诉=主诉",
+            "诊治经过=诊疗过程描述",
+            "治疗情况=目前情况",
+            "交班注意事项=注意事项",
+            "诊疗计划=接班诊疗计划"
+    );
+
+    public void dutyShiftSystemContrast ( List<DutyShiftSystemDoc> dutyShiftSystemDocs,Map<String, String> retMap) {
+        String text = dutyShiftSystemDocs.get(0).getText();
+        String fir = text;
+        if(StringUtil.isNotEmpty(retMap.get("诊疗计划"))){
+            String subStr = text.substring(text.indexOf("诊疗计划:")+"诊疗计划:".length());
+            String planRet = retMap.get("诊疗计划");
+            String planSignDate = "";
+            if(subStr.contains("/")){
+                planSignDate = parseString(planRet);
+                planRet = parseStr(planRet);
+            }
+            retMap.put("诊疗计划",planRet);
+            if(fir.contains("接班记录") && StringUtil.isNotEmpty(planSignDate.trim())){
+                retMap.put("接班者签名",planSignDate);
+            }
+        }
+
+        if(StringUtil.isNotEmpty(retMap.get("交班注意事项"))){
+            String subStr = text.substring(text.indexOf("交班注意事项:")+"交班注意事项:".length());
+            String planRet = retMap.get("交班注意事项");
+            String planSignDate = "";
+            if(subStr.contains("/")){
+                planSignDate = parseString(planRet);
+                 planRet = parseStr(planRet);
+            }
+
+            retMap.put("交班注意事项",planRet);
+            if(fir.contains("交班记录") && StringUtil.isNotEmpty(planSignDate.trim())){
+                    retMap.put("交班者签名",planSignDate);
+            }
+        }
+    }
+
+    public static void mapKeyContrastCommon(Map sourceMap, List<String> keyContrasts, Map<String, String> retMap) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        String[] arry = null;
+        String sourceKey = null, targetKey;
+        Set<String> removeKey = new HashSet<>();
+        for (String keyContrast : keyContrasts) {
+            arry = keyContrast.split("=");
+            sourceKey = arry[0];
+            if (arry.length == 1) {
+                targetKey = arry[0];
+            } else {
+                targetKey = arry[1];
+            }
+            if (StringUtil.isNotBlank(sourceMap_.get(sourceKey))
+                    && (!retMap.containsKey(targetKey) || StringUtil.isBlank(retMap.get(targetKey)))) {
+                retMap.put(targetKey, sourceMap_.get(sourceKey));
+            }
+            removeKey.add(sourceKey);
+        }
+        Set<String> keySet = retMap.keySet();
+        for (String key : sourceMap_.keySet()) {
+            if (!keySet.contains(key) && !removeKey.contains(key)) { // 如果之前已放过key就不用放了
+                retMap.put(key, sourceMap_.get(key));
+            }
+        }
+    }
+
+
+    /**
+     * 抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String extractDate(String top) {
+        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        } else {
+            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日");
+            Matcher m1 = p1.matcher(top);
+            if (m1.find()) {
+                return m1.group(0);
+            }
+        }
+        return null;
+    }
+
+    // 取/后
+    public static String parseString(String text){
+        if(text.contains("/")){
+            text = text.substring(text.lastIndexOf("/")+1);
+            text= parseString(text);
+        }
+        return text;
+    }
+
+    // 取/前
+    public static String parseStr(String text){
+        if(text.contains("/")){
+            text = text.substring(0,text.lastIndexOf("/"));
+            text= parseStr(text);
+        }
+        return text;
+    }
+}

+ 234 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/FirstCourseRecordTran.java

@@ -0,0 +1,234 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.FirstCourseRecordDoc;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.time.DateUtils;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+/**
+ * @Description:首次病程记录
+ * @author: cy
+ * @time: 2021/2/24 09:33
+ */
+@Slf4j
+public class FirstCourseRecordTran extends TargetTran {
+
+    @Override
+    public Map<String, String> convert(String text) {
+        FirstCourseRecordDoc firstCourseRecordDoc = new FirstCourseRecordDoc();
+        firstCourseRecordDoc.setText(text);
+        inputInfo.setFirstCourseRecordDoc(firstCourseRecordDoc);
+        Map<String, String> structureMap = cutWord(text);
+        Map<String, String> retMap = new HashMap<String, String>();
+        firstCourseContrast(inputInfo.getFirstCourseRecordDoc(), structureMap);
+        mapKeyContrastCommon(structureMap,stagesContrasts,retMap);
+        return retMap;
+    }
+
+    private List<String> stagesContrasts = Lists.newArrayList(
+            "姓名=患者姓名",
+            "入院诊断=鉴别诊断-西医诊断名称"
+    );
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("病例特点","入院诊断","诊断依据","鉴别诊断","诊疗计划"), text);
+
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        return sourceMap;
+    }
+
+
+    public static void mapKeyContrastCommon(Map sourceMap, List<String> keyContrasts, Map<String, String> retMap) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        String[] arry = null;
+        String sourceKey = null, targetKey;
+        Set<String> removeKey = new HashSet<>();
+        for (String keyContrast : keyContrasts) {
+            arry = keyContrast.split("=");
+            sourceKey = arry[0];
+            if (arry.length == 1) {
+                targetKey = arry[0];
+            } else {
+                targetKey = arry[1];
+            }
+            if (StringUtil.isNotBlank(sourceMap_.get(sourceKey))
+                    && (!retMap.containsKey(targetKey) || StringUtil.isBlank(retMap.get(targetKey)))) {
+                retMap.put(targetKey, sourceMap_.get(sourceKey));
+            }
+            removeKey.add(sourceKey);
+        }
+        Set<String> keySet = retMap.keySet();
+        for (String key : sourceMap_.keySet()) {
+            if (!keySet.contains(key) && !removeKey.contains(key)) { // 如果之前已放过key就不用放了
+                retMap.put(key, sourceMap_.get(key));
+            }
+        }
+    }
+
+
+    /**
+     * 抽取文本中的最后时间
+     *
+     * @param top
+     * @return
+     */
+    public static String lastTime(String top) {
+        int length = top.trim().length();
+        String stringDate = top.trim().substring(length - 11, length);
+        Date date = null;
+        try {
+             date = DateUtils.parseDate(stringDate, StringUtil.dateFormats);
+        } catch (Exception e) {
+           log.error(e.getMessage(),e);
+        }
+        if(date!= null){
+            return stringDate;
+        }else{
+            return "";
+        }
+    }
+
+
+    public void firstCourseContrast( FirstCourseRecordDoc firstCourseRecordDoc, Map<String, String> retMap) {
+        if(firstCourseRecordDoc != null) {
+            String text = firstCourseRecordDoc.getText();
+         if(text.contains("病例特点:")){
+             String str = text.substring(0, text.indexOf("病例特点:"));
+             str = extractDate(str);
+             if(StringUtil.isNotEmpty(str)){
+                 retMap.put("记录日期时间",str);
+             }
+         }
+            if(StringUtil.isNotEmpty(retMap.get("病例特点"))) {
+                String specical = retMap.get("病例特点");
+                String flagName = "因“";
+                if (specical.contains(flagName)) {
+                    specical = specical.substring(specical.indexOf(flagName));
+                }
+                String retStr = "";
+                if (specical.contains("“")) {
+                    String[] split = specical.split("“");
+                    if (split.length > 1) {
+                        retStr = split[1];
+                    }
+                if (retStr.contains("”")) {
+                    String[] splits = retStr.split("”");
+                    if (splits.length > 1) {
+                        retStr = splits[0];
+                    }
+                }
+                if(StringUtil.isNotEmpty(retStr)){
+                    retMap.put("主诉",retStr);
+                }
+
+                }
+            }
+
+         if(text.contains("诊疗计划:")){
+             String plan = retMap.get("诊疗计划");
+             plan = text.substring(text.lastIndexOf("诊疗计划:") + "诊疗计划:".length());
+            String str = text.substring(text.lastIndexOf("诊疗计划:") + "诊疗计划:".length());
+            String flagName = "";
+             if(str.contains("\n")){
+                 String[] split = str.split("\n");
+                 for (int i = 0; i < split.length; i++) {
+                     if(split[i].contains("/") && split[i].length()<=15){
+                         flagName = split[i];
+                     }else{
+                         String date = extractDate(split[i]);
+                         if(StringUtil.isNotEmpty(date)){
+                             flagName = split[i];
+                         }else{
+                             if(split[i].contains("年") && split[i].contains("月")&& split[i].contains("日")){
+                                 flagName = split[i];
+                             }
+                         }
+                     }
+                     if(StringUtil.isNotEmpty(flagName) && plan.contains(flagName)){
+                          plan = plan.substring(0, plan.lastIndexOf(flagName));
+                         retMap.put("诊疗计划",plan);
+                     }
+                 }
+             }
+         }
+
+         StringBuffer sb = new StringBuffer();
+            if(StringUtil.isEmpty(retMap.get("入院诊断")) && text.contains("鉴别诊断:")){
+                String str = text.substring(text.lastIndexOf("鉴别诊断:") + "鉴别诊断:".length());
+                if(str.contains("问题小结:")){
+                    str = str.split("问题小结:")[0];
+                }
+                if(str.contains("康复目标:")){
+                    str = str.split("康复目标:")[0];
+                }
+                if(str.contains("诊疗计划:")){
+                    str = str.split("诊疗计划:")[0];
+                }
+                 Boolean flag = true;
+                if(str.contains("\n")){
+                    String[] split = str.split("\n");
+                    for (int i = 0; i < split.length; i++) {
+                        if(split[i].contains(":")){
+                            String[] splits = split[i].split(":");
+                            sb.append(splits[0]);
+                            flag = false;
+                        }else if(split[i].contains(":")){
+                            String[] splits = split[i].split(":");
+                            sb.append(splits[0]);
+                            flag = false;
+                        }
+                    }
+                }
+                if(StringUtil.isNotEmpty(sb.toString())){
+                    retMap.put("鉴别诊断-西医诊断名称",sb.toString());
+                }
+
+                if(flag){
+                    String firStr = retMap.get("鉴别诊断");
+                    retMap.put("鉴别诊断-西医诊断名称",firStr);
+                }
+            }
+            retMap.remove("鉴别诊断");
+        }
+    }
+
+    // 取/前
+    public static String parseStr(String text){
+        if(text.contains("/")){
+            text = text.substring(0,text.lastIndexOf("/"));
+            text= parseStr(text);
+        }
+        return text;
+    }
+
+    /**
+     * 抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String extractDate(String top) {
+        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        } else {
+            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日");
+            Matcher m1 = p1.matcher(top);
+            if (m1.find()) {
+                return m1.group(0);
+            }
+        }
+        return null;
+    }
+}

+ 437 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/InformedConsentTran.java

@@ -0,0 +1,437 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.InformedConsentDoc;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+/**
+ * @Description:其他知情告知同意书
+ * @author: cy
+ * @time: 2021/3/10 10:12
+ */
+@Slf4j
+public class InformedConsentTran extends TargetTran {
+
+    @Override
+    public Map<String, String> convert(String text) {
+        InformedConsentDoc informedConsentDoc = new InformedConsentDoc();
+        informedConsentDoc .setText(text);
+        inputInfo.setInformedConsentDoc(informedConsentDoc);
+        Map<String, String> structureMap = cutWord(text);
+        Map<String, String> retMap = new HashMap<String, String>();
+        informedConsentContrast(inputInfo.getInformedConsentDoc(), structureMap);
+        mapKeyContrastCommon(structureMap,stagesContrasts,retMap);
+        return retMap;
+    }
+
+    private List<String> stagesContrasts = Lists.newArrayList(
+            "科别=科室名称",
+            "科别=病区名称",
+            "科室=科室名称",
+            "科室=病区名称",
+            "床号=病房号",
+            "床号=病床号",
+            "病情告知=知情同意内容",
+            "知情选择=医疗机构意见",
+            "具体如下=知情同意内容"
+           // "具体如下=医疗机构意见"
+    );
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("科别","科室","床号","病历号","住院号","住院号码","联系地址","具体如下","病情告知","知情选择","医师签名","医生签字"), text);
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        if(sourceMap.containsKey("联系地址") || sourceMap.containsKey("医生签字")|| sourceMap.containsKey("医师签名")
+                || sourceMap.containsKey("住院号")|| sourceMap.containsKey("住院号码")|| sourceMap.containsKey("病历号")){
+            sourceMap.remove("联系地址");
+            sourceMap.remove("医生签字");
+            sourceMap.remove("医师签名");
+            sourceMap.remove("住院号");
+            sourceMap.remove("住院号码");
+            sourceMap.remove("病历号");
+        }
+        return sourceMap;
+    }
+
+
+    public static void mapKeyContrastCommon(Map sourceMap, List<String> keyContrasts, Map<String, String> retMap) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        String[] arry = null;
+        String sourceKey = null, targetKey;
+        Set<String> removeKey = new HashSet<>();
+        for (String keyContrast : keyContrasts) {
+            arry = keyContrast.split("=");
+            sourceKey = arry[0];
+            if (arry.length == 1) {
+                targetKey = arry[0];
+            } else {
+                targetKey = arry[1];
+            }
+            if (StringUtil.isNotBlank(sourceMap_.get(sourceKey))
+                    && (!retMap.containsKey(targetKey) || StringUtil.isBlank(retMap.get(targetKey)))) {
+                retMap.put(targetKey, sourceMap_.get(sourceKey));
+            }
+            removeKey.add(sourceKey);
+        }
+        Set<String> keySet = retMap.keySet();
+        for (String key : sourceMap_.keySet()) {
+            if (!keySet.contains(key) && !removeKey.contains(key)) { // 如果之前已放过key就不用放了
+                retMap.put(key, sourceMap_.get(key));
+            }
+        }
+    }
+
+
+    public void informedConsentContrast( InformedConsentDoc informedConsentDoc, Map<String, String> retMap) {
+        if(informedConsentDoc != null) {
+            String text = informedConsentDoc.getText();
+            String flag = " ";
+            if (text.contains("\n")) {
+                String[] split = text.split("\n");
+                for (int i = 0; i < split.length; i++) {
+                    String hero = split[i];
+                    if(i == 0 ){
+                        if (!hero.contains(flag)) {
+                            flag = "_";
+                        }
+                    if ( hero.contains(flag)) {
+                        String[] motton = hero.split(flag);
+                        String firStr = motton[0];
+                        String secStr = "";
+                        if (StringUtil.isNotEmpty(firStr)) {
+                             secStr = hero.substring(hero.lastIndexOf(firStr) + firStr.length());
+                            if(firStr.contains("_")){
+                                 firStr = firStr.substring(0, firStr.lastIndexOf("_"));
+                            }
+                            if(secStr.contains("_")){
+                                secStr = secStr.substring(secStr.lastIndexOf("_")+"_".length());
+                            }
+                            retMap.put("知情同意书编号", firStr);
+                        }
+                        if (StringUtil.isNotEmpty(secStr)) {
+                            retMap.put("知情同意书名称", secStr);
+                        }
+                    }
+                }
+                    String doctorSign = "医生签字:";
+                    if (hero.contains("医生签名")) {
+                        doctorSign = "医生签名";
+                    }
+                    if (hero.contains("医生签名:")) {
+                        doctorSign = "医生签名:";
+                    }
+                    if (hero.contains("医生签名:")) {
+                        doctorSign = "医生签名:";
+                    }
+                    if (hero.contains("医生签字:")) {
+                        doctorSign = "医生签字:";
+                    }
+                    if (hero.contains("医师签名:")) {
+                        doctorSign = "医师签名:";
+                    }
+                    if (hero.contains("医师签名:")) {
+                        doctorSign = "医师签名:";
+                    }
+                    String signDate = "签名时间";
+                    if (hero.contains("签名日期")) {
+                        signDate = "签名日期";
+                    }
+                    if (hero.contains(doctorSign)) {
+                        if (StringUtil.isNotEmpty(hero)) {
+                            String firRet = doctorSign;
+                            String firStr = hero.substring(hero.lastIndexOf(firRet) + firRet.length());
+                            String date = extractDate(firStr);
+                            String secStr = "";
+                            if (StringUtil.isNotEmpty(date)) {
+                                retMap.put("医师签名日期时间", date);
+                                secStr = hero.substring(hero.lastIndexOf(firRet) + firRet.length(), hero.lastIndexOf(date));
+                            } else {
+                                if (firStr.contains("年")) {
+                                    secStr = firStr.substring(0, firStr.lastIndexOf("年"));
+                                }
+                            }
+                            if(hero.contains(signDate)){
+                                secStr = hero.substring(hero.lastIndexOf(firRet) + firRet.length(), hero.lastIndexOf(signDate));
+                            }
+                            if (StringUtil.isNotEmpty(secStr)) {
+                                secStr = parseString(secStr.trim());
+                                if (StringUtil.isNotEmpty(secStr) && StringUtil.isNotEmpty(secStr.trim())) {
+                                retMap.put("医师签名", secStr);
+                            }
+                            }
+                        }
+                    }
+
+                    String hitSign = "患方签字:";
+
+                    if (hero.contains("患者签名")) {
+                        hitSign = "患者签名";
+                    }
+                    if (hero.contains("患方签字:")) {
+                        hitSign = "患方签字:";
+                    }
+                    if (hero.contains("患方签名:")) {
+                        hitSign = "患方签名:";
+                    }
+                    if (hero.contains("患方签名:")) {
+                        hitSign = "患方签名:";
+                    }
+                    if (hero.contains("患者授权亲属签名")) {
+                        hitSign = "患者授权亲属签名";
+                    }
+                    if (hero.contains(hitSign)) {
+                        String firRet = hitSign;
+                        String firStr = hero.substring(hero.lastIndexOf(firRet) + firRet.length());
+                        String date = extractDate(firStr);
+                        if (StringUtil.isNotEmpty(date)) {
+                            retMap.put("患者/法定代理人签名日期时间", date);
+                        }
+                    }
+                }
+            }
+
+                //知情同意内容&&医疗机构意见
+            if (StringUtil.isNotEmpty(retMap.get("病情告知")) && StringUtil.isNotEmpty(retMap.get("病情告知").trim())) {
+                String tell = retMap.get("病情告知");
+                       tell = repalce(tell);
+                retMap.put("病情告知",tell);
+            }
+                if (StringUtil.isNotEmpty(retMap.get("知情选择"))&& StringUtil.isNotEmpty(retMap.get("知情选择").trim())) {
+                    String choose = retMap.get("知情选择");
+                    choose = repalce(choose);
+                    retMap.put("知情选择",choose);
+                    if (StringUtil.isNotEmpty(retMap.get("病情告知")) && StringUtil.isNotEmpty(retMap.get("病情告知").trim())) {
+                        String tell = retMap.get("病情告知");
+                        retMap.put("病情告知",tell+"  知情选择: "+choose);
+                    }
+                    /*else{
+                        retMap.put("病情告知",choose);
+                    }*/
+                }
+
+                if (StringUtil.isNotEmpty(retMap.get("具体如下"))&& StringUtil.isNotEmpty(retMap.get("具体如下").trim())) {
+                    String tell = retMap.get("具体如下");
+                    if(tell.contains("医生签字")){
+                        tell = tell.substring(0, tell.lastIndexOf("医生签字"));
+                    }
+                    String choose = "";
+                    if (text.contains("患者知情选择")) {
+                        choose = text.substring(text.indexOf("患者知情选择")+"患者知情选择".length());
+                    }
+                    if (choose.contains("患方签名")) {
+                        choose = choose.substring(0,choose.indexOf("患方签名"));
+                    }
+                    if (choose.contains("医生签字")) {
+                        choose = choose.substring(0,choose.indexOf("医生签字"));
+                    }
+                    if(StringUtil.isNotEmpty(choose)){
+                        retMap.put("病情告知",tell+"  患者知情选择:"+choose);
+                        retMap.put("医疗机构意见", choose);
+                    }
+                    else{
+                        retMap.put("病情告知",tell);
+                    }
+                    retMap.remove("具体如下");
+                }else{
+                    String choose = "";
+                    if (text.contains("患者知情选择")) {
+                        choose = text.substring(text.indexOf("患者知情选择")+"患者知情选择".length());
+                    }
+                    if (choose.contains("患方签名")) {
+                        choose = choose.substring(0,choose.indexOf("患方签名"));
+                    }
+                    if(StringUtil.isNotEmpty(choose)){
+                        retMap.put("病情告知",choose);
+                    }
+                }
+
+                //镇静镇痛谈话 && 阿片类药物治疗知情同意书
+            if(text.contains("疾病介绍和治疗建议")){
+                String advice = "";
+                if (text.contains("疾病介绍和治疗建议")) {
+                    advice = text.substring(text.indexOf("疾病介绍和治疗建议")+"疾病介绍和治疗建议".length());
+                }
+                String replaceName = "患方签名";
+                if (advice.contains("患者签名")) {
+                    replaceName = "患者签名";
+                }
+                if (advice.contains(replaceName)) {
+                    advice = advice.substring(0,advice.indexOf(replaceName));
+                }
+                if(StringUtil.isNotEmpty(advice)){
+                    retMap.put("病情告知",advice);
+                }
+            }
+
+            //输血血液制品治疗知情同意书
+            if(text.contains("授权委托人意见:")){
+                String advice = "";
+                if (text.contains("授权委托人意见:")) {
+                    advice = text.substring(text.indexOf("授权委托人意见:")+"授权委托人意见:".length());
+                }
+                String replaceName = "患方签名";
+                if (advice.contains("患者签名")) {
+                    replaceName = "患者签名";
+                }
+                if (advice.contains(replaceName)) {
+                    advice = advice.split(replaceName)[0];
+                }
+                if(StringUtil.isNotEmpty(advice)){
+                    retMap.put("患者/法定代理人意见",advice);
+                }
+            }
+             String flagName = "医护人员陈述:";
+            if(text.contains("医护人员陈述:")){
+                flagName = "医护人员陈述:";
+            }
+            if(text.contains("医生陈述")){
+                flagName = "医生陈述";
+            }
+            if(text.contains("医生陈述:")){
+                flagName = "医生陈述:";
+            }
+            if(text.contains("医生陈述:")){
+                flagName = "医生陈述:";
+            }
+            if(text.contains(flagName)){
+                String advice = "";
+                if (text.contains(flagName)) {
+                    advice = text.substring(text.indexOf(flagName)+flagName.length());
+                }
+                String replaceName = "医生签名";
+                if (advice.contains(replaceName)) {
+                    advice = advice.split(replaceName)[0];
+                }
+                if(StringUtil.isNotEmpty(advice)){
+                    retMap.put("医疗机构意见",advice);
+                    retMap.remove("具体如下");
+                    retMap.remove("知情选择");
+                }
+            }
+
+            //特殊医用材料使用知情同意书
+            if(text.contains("材料内容")){
+                String record = "";
+                if (text.contains("材料内容")) {
+                    record = text.substring(text.indexOf("材料内容")+"材料内容".length());
+                }
+                if (record.contains("患者(或授权人)签字")) {
+                    record = record.substring(0,record.indexOf("患者(或授权人)签字"));
+                }
+                if(StringUtil.isNotEmpty(record)){
+                    retMap.put("病情告知",record);
+                }
+            }
+
+            if(StringUtil.isNotEmpty(retMap.get("病情告知"))){
+                String tell = retMap.get("病情告知");
+                       tell = lineFeed(tell);
+                       tell = strFirLast(tell);
+                    if(StringUtil.isNotEmpty(tell)){
+                        retMap.put("病情告知",tell);
+                    }
+                }
+            }
+        }
+
+    // 取/前
+    public static String parseStr(String text){
+        if(text.contains("/")){
+            text = text.substring(0,text.lastIndexOf("/"));
+            text= parseStr(text);
+        }
+        return text;
+    }
+
+    // 取/后
+    public static String parseString(String text){
+        if(text.contains("/")){
+            text = text.substring(text.lastIndexOf("/")+1);
+            text= parseString(text);
+        }
+        return text;
+    }
+
+    //去换行符
+    public static String lineFeed(String firStr){
+        if(StringUtil.isNotEmpty(firStr)){
+            if(firStr.contains("\n")){
+                StringBuffer sb = new StringBuffer();
+                String[] split = firStr.split("\n");
+                for (int i = 0; i < split.length; i++) {
+                    sb.append(split[i]+"  ");
+                }
+                if(StringUtil.isNotEmpty(sb.toString())){
+                    return sb.toString();
+                }
+            }
+            return firStr;
+        }
+        return null;
+    }
+
+    //去首尾字符串字符
+    public static String strFirLast(String firStr){
+        if(StringUtil.isNotEmpty(firStr)){
+            String flag = ":";
+            String flagReplace = ":";
+            StringBuffer sb = new StringBuffer();
+            for (int i = 0; i < firStr.length(); i++) {
+                String str = String.valueOf(firStr.charAt(i));
+                if(i <=2 && str.contains(flag)||str.contains(flagReplace)){
+                    continue;
+                }
+                if(i<=firStr.length()-1 && i>2 && str.contains(flag)||str.contains(flagReplace)){
+                    continue;
+                }
+                sb.append(str);
+            }
+        return sb.toString();
+        }
+        return null;
+    }
+
+    /**
+     * 抽取文本中的第一个时间
+     * @param top
+     * @return
+     */
+    public static String extractDate(String top) {
+        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        } else {
+            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日");
+            Matcher m1 = p1.matcher(top);
+            if (m1.find()) {
+                return m1.group(0);
+            }
+        }
+        return null;
+    }
+    public static String repalce(String choose) {
+       if(choose.contains("医生签字")){
+        choose = choose.substring(0, choose.lastIndexOf("医生签字"));
+    }
+                    if(choose.contains("医生签名")){
+        choose = choose.substring(0, choose.lastIndexOf("医生签名"));
+    }
+                    if(choose.contains("医师签字")){
+        choose = choose.substring(0, choose.lastIndexOf("医师签字"));
+    }
+                    if(choose.contains("医师签名")){
+        choose = choose.substring(0, choose.lastIndexOf("医师签名"));
+         }
+        return choose;
+    }
+}

+ 229 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/LeaveHospitalTran.java

@@ -0,0 +1,229 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.LeaveHospitalDoc;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.time.DateUtils;
+
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description:出院小结
+ * @author: cy
+ * @time: 2021/2/24 09:33
+ */
+@Slf4j
+public class LeaveHospitalTran extends TargetTran {
+
+    @Override
+    public Map<String, String> convert(String text) {
+        LeaveHospitalDoc leaveHospitalDoc = new LeaveHospitalDoc();
+        leaveHospitalDoc.setText(text);
+        inputInfo.setLeaveHospitalDoc(leaveHospitalDoc);
+        Map<String, String> structureMap = cutWord(text);
+        Map<String, String> retMap = new HashMap<String, String>();
+        leaveHospitalContrast(inputInfo.getLeaveHospitalDoc(), structureMap);
+        mapKeyContrastCommon(structureMap,stagesContrasts,retMap);
+        return retMap;
+    }
+
+    private List<String> stagesContrasts = Lists.newArrayList(
+            "入院日期=入院日期时间",
+            "出院日期=出院日期时间",
+            "阳性结果=阳性辅助检查结果",
+            "治疗经过=诊疗过程描述",
+            "诊疗经过=诊疗过程描述",
+            "经治/主治医师=住院医师签名",
+            "首席医师=上级医师签名",
+            "填写日期=签名日期时间"
+    );
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("入院日期","出院日期","入院诊断","入院情况","主要阳性结果","主要阴性结果","阳性结果","阴性结果","住院期间的辅助检查","治疗经过","诊疗经过","出院情况","并发症","治疗效果","出院医嘱","营养指导","出院注意事项","首席医师",
+                      "经治/主治医师:", "经治/主治医师","填写日期"),
+                text
+        );
+
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        if(sourceMap.containsKey("入院诊断")||(sourceMap.containsKey("住院期间的辅助检查"))||(sourceMap.containsKey("出院注意事项"))||sourceMap.containsKey("阴性结果")||sourceMap.containsKey("主要阴性结果")||sourceMap.containsKey("营养指导")){
+            sourceMap.remove("入院诊断");
+            sourceMap.remove("住院期间的辅助检查");
+            sourceMap.remove("出院注意事项");
+            sourceMap.remove("阴性结果");
+            sourceMap.remove("主要阴性结果");
+            sourceMap.remove("营养指导");
+        }
+        return sourceMap;
+    }
+
+
+    public static void mapKeyContrastCommon(Map sourceMap, List<String> keyContrasts, Map<String, String> retMap) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        String[] arry = null;
+        String sourceKey = null, targetKey;
+        Set<String> removeKey = new HashSet<>();
+        for (String keyContrast : keyContrasts) {
+            arry = keyContrast.split("=");
+            sourceKey = arry[0];
+            if (arry.length == 1) {
+                targetKey = arry[0];
+            } else {
+                targetKey = arry[1];
+            }
+            if (StringUtil.isNotBlank(sourceMap_.get(sourceKey))
+                    && (!retMap.containsKey(targetKey) || StringUtil.isBlank(retMap.get(targetKey)))) {
+                retMap.put(targetKey, sourceMap_.get(sourceKey));
+            }
+            removeKey.add(sourceKey);
+        }
+        Set<String> keySet = retMap.keySet();
+        for (String key : sourceMap_.keySet()) {
+            if (!keySet.contains(key) && !removeKey.contains(key)) { // 如果之前已放过key就不用放了
+                retMap.put(key, sourceMap_.get(key));
+            }
+        }
+    }
+
+
+
+
+
+    public void leaveHospitalContrast( LeaveHospitalDoc leaveHospitalDoc, Map<String, String> retMap) {
+        if (leaveHospitalDoc != null) {
+            if (StringUtil.isNotEmpty(retMap.get("出院日期"))) {
+                String value = retMap.get("出院日期");
+                if (value.contains("日")) {
+                    String[] targetStr = value.split("日");
+                    retMap.put("出院日期", targetStr[0]+"日");
+                    retMap.put("实际住院天数", targetStr[1]);
+                }
+            }
+
+        if (StringUtil.isNotEmpty(retMap.get("出院医嘱"))) {
+            String doctorAdvice = retMap.get("出院医嘱");
+           if(doctorAdvice.contains("出院带药")){
+               doctorAdvice =  doctorAdvice.substring(doctorAdvice.indexOf("出院带药")+5);
+               retMap.put("出院医嘱", doctorAdvice);
+           }
+        }
+
+        //阳性辅助检查结果
+            if (StringUtil.isEmpty(retMap.get("阳性结果"))) {
+                if (StringUtil.isNotEmpty(retMap.get("主要阳性结果"))) {
+                    String manRes = retMap.get("主要阳性结果");
+                    retMap.put("阳性辅助检查结果", manRes);
+                    retMap.remove("主要阳性结果");
+                }
+            }
+
+            if (StringUtil.isNotEmpty(retMap.get("出院情况"))) {
+                retMap.put("出院时症状与体征", retMap.get("出院情况"));
+                if (StringUtil.isNotEmpty(retMap.get("并发症"))) {
+                    retMap.put("出院情况", retMap.get("出院情况")+"并发症:"+retMap.get("并发症"));
+                }
+                if (StringUtil.isNotEmpty(retMap.get("治疗效果"))) {
+                    retMap.put("出院情况", retMap.get("出院情况")+"治疗效果:"+retMap.get("治疗效果"));
+                }
+                retMap.remove("并发症");
+                retMap.remove("治疗效果");
+
+            }
+
+            if (StringUtil.isNotEmpty(retMap.get("首席医师")) &&StringUtil.isNotEmpty(retMap.get("首席医师").trim())) {
+                String firDoctor = retMap.get("首席医师");
+                if(firDoctor.contains("经治/主治医师")){
+                    String ote = firDoctor.split("经治/主治医师")[0];
+                    if(StringUtil.isNotEmpty(ote) && StringUtil.isNotEmpty(ote.trim())){
+                        firDoctor = ote.trim();
+                        retMap.put("首席医师",firDoctor);
+                    }else{
+                        retMap.remove("首席医师");
+                    }
+                    String otc = firDoctor.split("经治/主治医师")[1];
+                    if(StringUtil.isNotEmpty(otc) && StringUtil.isNotEmpty(otc.trim())){
+                        String value =otc.trim();
+                        if(value.contains(":")){
+                            value =  value.substring(value.indexOf(":")+1);
+                        }
+                        retMap.put("经治/主治医师",value);
+                    }
+                }
+            }else{
+                retMap.remove("首席医师");
+            }
+
+            if (StringUtil.isNotEmpty(retMap.get("填写日期"))) {
+                String fileDate = retMap.get("填写日期");
+                String sginTime= lastTime(fileDate);
+                retMap.put("填写日期",sginTime);
+            }
+
+            if (StringUtil.isNotEmpty(retMap.get("经治/主治医师"))) {
+                String value = retMap.get("经治/主治医师");
+                String retValue = parseString(value);
+                retMap.put("经治/主治医师",retValue);
+            }
+        }
+    }
+
+    public static String parseString(String text){
+        if(text.contains("/")){
+            text = text.substring(text.lastIndexOf("/")+1);
+            text= parseString(text);
+        }
+        return text;
+    }
+
+    /**
+     * 抽取文本中的最后时间
+     *
+     * @param top
+     * @return
+     */
+    public static String lastTime(String top) {
+        Date date = null;
+        try {
+            date = DateUtils.parseDate(top, StringUtil.dateFormats);
+        } catch (Exception e) {
+            log.error(e.getMessage(),e);
+        }
+        if(date!= null){
+            return top;
+        }else{
+            if(top.contains("年") && top.contains("月") && top.contains("日")){
+               top = extractDate(top);
+                 lastTime(top);
+            }
+            return top;
+        }
+    }
+
+    /**
+     * 抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String extractDate(String top) {
+        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        } else {
+            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日");
+            Matcher m1 = p1.matcher(top);
+            if (m1.find()) {
+                return m1.group(0);
+            }
+        }
+        return null;
+    }
+}

+ 240 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/OperationDiscussionTran.java

@@ -0,0 +1,240 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.operation.OperationDiscussionDoc;
+import com.lantone.structure.model.doc.operation.OperationDoc;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description:术后首次病程
+ * @author: cy
+ * @time: 2021/3/16 14:12
+ */
+@Slf4j
+public class OperationDiscussionTran extends TargetTran {
+
+    @Override
+    public Map<String, String> convert(String text) {
+         List<OperationDoc> operationDocs = new ArrayList<>();
+        OperationDoc operationDoc  = new OperationDoc();
+        OperationDiscussionDoc operationDiscussionDoc  = new OperationDiscussionDoc();
+        operationDiscussionDoc.setText(text);
+        operationDoc.setOperationDiscussionDoc(operationDiscussionDoc);
+        operationDocs.add(operationDoc);
+        inputInfo.setOperationDocs(operationDocs);
+        Map<String, String> structureMap = new HashMap<String, String>();
+        Map<String, String> retMap = new HashMap<String, String>();
+            structureMap = cutWord(text);
+        oDContrast(inputInfo.getOperationDocs(), structureMap);
+        mapKeyContrastCommon(structureMap,stagesContrasts,retMap);
+        return retMap;
+    }
+
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("简要病情"),
+                text
+        );
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        if( sourceMap.containsKey("术前诊断")){
+            sourceMap.remove("术前诊断");
+        }
+        return sourceMap;
+    }
+
+    private List<String> stagesContrasts = Lists.newArrayList(
+            "手术指征=手术指征",
+            "手术指征=手术适应证"
+    );
+
+    public void oDContrast(List<OperationDoc> operationDocs,Map<String, String> retMap) {
+        String text = operationDocs.get(0).getOperationDiscussionDoc().getText();
+        if(text.contains("\n")){
+            String[] split = text.split("\n");
+            for (int i = 0; i < split.length; i++) {
+                if(i<=1){
+                    String date= extractDate(split[i]);
+                    if(StringUtil.isNotEmpty(date)){
+                        retMap.put("记录日期时间",date);
+                    }
+                }
+            }
+        }
+        String flagTitle = "患者诊断";
+        if(text.contains("修正诊断")){
+            flagTitle = "修正诊断";
+        }
+        if(text.contains("术后诊断")){
+            flagTitle = "术后诊断";
+        }
+        if(text.contains("术后诊断:")){
+            flagTitle = "术后诊断:";
+        }
+        if(text.contains("目前诊断")){
+            flagTitle = "目前诊断";
+        }
+        if(text.contains("目前诊断考虑")){
+            flagTitle = "目前诊断考虑";
+        }
+        if(text.contains("诊断为")){
+            flagTitle = "诊断为";
+        }
+
+        String flagTitleFir = "分析病历特点:";
+         if(text.contains("查房:")){
+            flagTitleFir = "查房:";
+        }if(text.contains("查房后指出")){
+            flagTitleFir = "查房后指出";
+        }if(text.contains("术中诊断")){
+            flagTitleFir = "术中诊断";
+        }
+        String flagTitleSec = "诊疗计划";
+        String flagTitleThr = "注意事项";
+        //诊断依据
+        if(text.contains(flagTitleFir)){
+            String strSec = text.substring(text.indexOf(flagTitleFir) + flagTitleFir.length());
+            if(strSec.contains(flagTitleSec)){
+                strSec = strSec.substring(0,strSec.indexOf(flagTitleSec));
+            }
+            if(strSec.contains("术后诊断:")){
+                strSec = strSec.substring(0,strSec.indexOf("术后诊断:"));
+            }
+            if(StringUtil.isNotEmpty(strSec)){
+                retMap.put("诊断依据",strSec);
+            }
+        }
+
+        if(text.contains(flagTitle)){
+            String sureStr = text.substring(text.indexOf(flagTitle) + flagTitle.length());
+
+            //注意事项
+            if(sureStr.contains("注意观察")){
+                flagTitleThr = "注意观察";
+            }
+            if(sureStr.contains(flagTitleThr)){
+                String strSec = sureStr.substring(sureStr.indexOf(flagTitleThr) + flagTitleThr.length());
+                if(flagTitleThr.equals("注意观察")){
+                    strSec = sureStr.substring(sureStr.indexOf(flagTitleThr));
+                }
+                if(strSec.contains("/")){
+                    strSec = strSec.substring(0,strSec.indexOf("/"));
+                }
+                if(strSec.contains("。今")){
+                    strSec = strSec.substring(0,strSec.indexOf("。今"));
+                }
+                if(StringUtil.isNotEmpty(strSec)){
+                    retMap.put("注意事项",strSec);
+                }
+            }
+            if(sureStr.contains("鉴别诊断")){
+                sureStr = sureStr.substring(0,sureStr.indexOf("鉴别诊断"));
+            }
+            if(sureStr.contains("禁忌症")){
+                sureStr = sureStr.substring(0,sureStr.indexOf("禁忌症"));
+            }
+            if(sureStr.contains("手术指征")){
+                sureStr = sureStr.substring(0,sureStr.indexOf("手术指征"));
+            }
+            if(sureStr.contains("明确")){
+                sureStr = sureStr.substring(0,sureStr.indexOf("明确"));
+            }if(sureStr.contains("“") && sureStr.contains("”")){
+                sureStr = sureStr.substring(sureStr.indexOf("“")+"“".length(),sureStr.indexOf("”"));
+            }
+            if (sureStr.contains("。")) {
+                sureStr = sureStr.split("。")[0];
+            }
+            retMap.put("术后诊断名称",sureStr);
+        }
+        String notion = "注意";
+       if(text.contains("注意观察")){
+            notion = "注意观察";
+        }
+        if(text.contains(notion) && StringUtil.isEmpty(retMap.get("注意事项"))){
+            String sureStr = text.substring(text.indexOf(notion));
+            if(sureStr.contains("评分:")){
+                sureStr = sureStr.substring(0,sureStr.indexOf("评分:"));
+            }
+            if(sureStr.contains("。")){
+                sureStr = sureStr.substring(0,sureStr.lastIndexOf("。"));
+            }
+            retMap.put("注意事项",sureStr);
+        }
+        String signName= parseString(text);
+        if(StringUtil.isNotEmpty(signName)&& !signName.contains(text) && signName.length()<=15){
+            retMap.put("医师签名",signName);
+        }
+        if(StringUtil.isEmpty(retMap.get("医师签名")) ||StringUtil.isEmpty(retMap.get("医师签名").trim())){
+            retMap.remove("医师签名");
+        }
+
+    }
+
+    public static void mapKeyContrastCommon(Map sourceMap, List<String> keyContrasts, Map<String, String> retMap) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        String[] arry = null;
+        String sourceKey = null, targetKey;
+        Set<String> removeKey = new HashSet<>();
+        for (String keyContrast : keyContrasts) {
+            arry = keyContrast.split("=");
+            sourceKey = arry[0];
+            if (arry.length == 1) {
+                targetKey = arry[0];
+            } else {
+                targetKey = arry[1];
+            }
+            if (StringUtil.isNotBlank(sourceMap_.get(sourceKey))
+                    && (!retMap.containsKey(targetKey) || StringUtil.isBlank(retMap.get(targetKey)))) {
+                retMap.put(targetKey, sourceMap_.get(sourceKey));
+            }
+            removeKey.add(sourceKey);
+        }
+        Set<String> keySet = retMap.keySet();
+        for (String key : sourceMap_.keySet()) {
+            if (!keySet.contains(key) && !removeKey.contains(key)) { // 如果之前已放过key就不用放了
+                retMap.put(key, sourceMap_.get(key));
+            }
+        }
+    }
+
+    /**
+     * 抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String extractDate (String top){
+        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        } else {
+            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日");
+            Matcher m1 = p1.matcher(top);
+            if (m1.find()) {
+                return m1.group(0);
+            }
+        }
+        return null;
+    }
+
+    // 取/后
+    public static String parseString(String text){
+        if(text.contains("/")){
+            text = text.substring(text.lastIndexOf("/")+1);
+            text= parseString(text);
+        }
+        return text;
+
+
+
+    }
+}

+ 106 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/OperationInformedConsentDocTran.java

@@ -0,0 +1,106 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:手术知情同意书
+ * @author: wsy
+ * @time: 2021/3/08 15:29
+ */
+@Slf4j
+public class OperationInformedConsentDocTran extends TargetTran {
+    @Override
+    public Map<String, String> convert(String text) {
+        Map<String, String> structureMap = cutWord(text);
+        Map<String, String> retMap = new HashMap<String, String>();
+        CommonAnalysisUtil.mapKeyContrastCommon(structureMap, keyContrasts, retMap);
+        retMap.entrySet().removeIf(entry -> StringUtil.isBlank(entry.getValue()));
+        retMap.entrySet().removeIf(entry ->
+                !entry.getValue().matches("[\\d]+年[\\d]+月[\\d]+日[\\d]+时[\\d]+分") && ("患者/法定代理人签名日期时间".equals(entry.getKey()) || "医师签名日期时间".equals(entry.getKey()))
+        );
+        return retMap;
+    }
+
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        if (text.contains("九、术中知情谈话记录")) {
+            text = text.substring(0, text.indexOf("九、术中知情谈话记录"));
+        }
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("二、您的主刀医师是", "三、术前诊断", "拟实施手术名称", "手术指征", "四、医师会用通俗易懂的语言向您解释", "(1)告知可能发生的意外、并发症或风险",
+                        "(2)告知手术后可能出现 的意外和并发症", "(2)告知手术后可能出现的意外和并发症", "手术后可能出现的意外和并发症", "3.特殊风险或主要高危因素", "(3)特殊风险或主要高危因素", "针对上述情况医师将采取的防范措施", "五、替代治疗方案及优缺点", "患者及家属要求手术治疗,并签字为证",
+                        "七、医师声明", "书写者签名", "主刀医师签名", "医生签名", "八、患方意见", "患者(代理人)签名", "患方签名", "患者签名", "患方签字", "如果患者无法签署知情同意书, 请其授权的代理人在此签名",
+                        "代理人签名", "与患者关系"),
+                text
+        );
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        if (sourceMap != null) {
+            disDate(sourceMap, "书写者签名", "签名时间");
+            disDate(sourceMap, "患者(代理人)签名", "签名时间");
+            disDate(sourceMap, "患方签名", "签名时间");
+            disDate(sourceMap, "患者签名", "签名时间");
+            disDate(sourceMap, "患方签字", "签名时间");
+            disDate(sourceMap, "患者及家属要求手术治疗,并签字为证", "七、医师声明");
+            disDate(sourceMap, "主刀医师签名", "八、患方意见");
+            disDate(sourceMap, "主刀医师签名", "签名时间");
+            disDate(sourceMap, "医生签名", "签名时间");
+            disDate(sourceMap, "与患者关系", "签名时间");
+            if (sourceMap.containsKey("五、替代治疗方案及优缺点") && sourceMap.get("五、替代治疗方案及优缺点").contains("六、医学是一门科学")) {
+                sourceMap.put("五、替代治疗方案及优缺点", sourceMap.get("五、替代治疗方案及优缺点").substring(0, sourceMap.get("五、替代治疗方案及优缺点").indexOf("六、医学是一门科学")));
+            }
+            if (sourceMap.containsKey("手术指征") && sourceMap.get("手术指征").contains("麦默通手术主要用于")) {
+                sourceMap.put("手术指征", sourceMap.get("手术指征").substring(0, sourceMap.get("手术指征").indexOf("麦默通手术主要用于")));
+            }
+            CommonAnalysisUtil.removeKey(sourceMap, "二、您的主刀医师是", "四、医师会用通俗易懂的语言向您解释", "3.特殊风险或主要高危因素", "(3)特殊风险或主要高危因素", "针对上述情况医师将采取的防范措施");
+        }
+        return sourceMap;
+    }
+
+    private void disDate(Map sourceMap, String... args) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        if (sourceMap.containsKey(args[0]) && sourceMap_.get(args[0]).contains(args[1])) {
+            int index = sourceMap_.get(args[0]).indexOf(args[1]);
+            sourceMap.put(args[0], sourceMap_.get(args[0]).substring(0, index));
+            sourceMap.put(args[0] + args[1], sourceMap_.get(args[0]).substring(index).replace(args[1], "").replaceAll("[::]", ""));
+        }
+    }
+
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "三、术前诊断=术前诊断",
+            "拟实施手术名称=拟实施手术及操作日期时间",
+            "(1)告知可能发生的意外、并发症或风险=手术中可能出现的意外及风险",
+            "(2)告知手术后可能出现的意外和并发症=手术后可能出现的意外及并发症",
+            "(2)告知手术后可能出现 的意外和并发症=手术后可能出现的意外及并发症",
+            "五、替代治疗方案及优缺点=替代方案",
+            "患者(代理人)签名=患者签名",
+            "患方签名=患者签名",
+            "患方签字=患者签名",
+            "患者(代理人)签名=法定代理人签名",
+            "主刀医师签名=手术者签名",
+            "医生签名=手术者签名",
+            "书写者签名=经治医师签名",
+            "书写者签名签名时间=医师签名日期时间",
+            "患者(代理人)签名签名时间=患者/法定代理人签名日期时间",
+            "患方签名签名时间=患者/法定代理人签名日期时间",
+            "患方签字签名时间=患者/法定代理人签名日期时间",
+            "患者签名签名时间=患者/法定代理人签名日期时间",
+            "七、医师声明=医疗机构意见",
+            "患者及家属要求手术治疗,并签字为证七、医师声明=医疗机构意见",
+            "主刀医师签名八、患方意见=患者/法定代理人意见",
+            "八、患方意见=患者/法定代理人意见",
+            "主刀医师签名签名时间=医师签名日期时间",
+            "医生签名签名时间=医师签名日期时间",
+            "手术后可能出现的意外和并发症=手术后可能出现的意外及并发症",
+            "与患者关系签名时间=患者/法定代理人签名日期时间"
+    );
+}

+ 296 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/OperationRecordDocTran.java

@@ -0,0 +1,296 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.ListUtil;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.operation.OperationDoc;
+import com.lantone.structure.model.doc.operation.OperationRecordDoc;
+import com.lantone.structure.model.entity.*;
+import com.lantone.structure.model.label.OperationRecordLabel;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description: 一般手术记录
+ * @author: wsy
+ * @time: 2021/3/11 15:49
+ */
+@Slf4j
+public class OperationRecordDocTran extends TargetTran {
+    @Override
+    public Map<String, String> convert(String text) {
+        List<OperationDoc> operationDocs = new ArrayList<OperationDoc>();
+        OperationDoc operationDoc = new OperationDoc();
+        OperationRecordDoc operationRecordDoc = new OperationRecordDoc();
+        operationRecordDoc.setText(text);
+        Map<String, String> structureMap = cutWord(text);
+        Map<String, String> retMap = new HashMap<String, String>();
+        CommonAnalysisUtil.mapKeyContrastCommon(structureMap, keyContrasts, retMap);
+        operationRecordDoc.setStructureMap(retMap);
+        operationDoc.setOperationRecordDoc(operationRecordDoc);
+        operationDocs.add(operationDoc);
+        inputInfo.setOperationDocs(operationDocs);
+
+        aiProcess();
+        fetchModelData(inputInfo.getOperationDocs(), retMap);
+        retMap.entrySet().removeIf(entry -> StringUtil.isBlank(entry.getValue()));
+        retMap.entrySet().removeIf(entry -> !entry.getValue().matches("[\\d]+年[\\d]+月[\\d]+日[\\d]+时[\\d]+分") && "医师签名日期时间".equals(entry.getKey()));
+        return retMap;
+    }
+
+    private void fetchModelData(List<OperationDoc> operationDocs, Map<String, String> retMap) {
+        if (ListUtil.isNotEmpty(operationDocs)) operationDocs.forEach(operationDoc -> {
+            OperationRecordDoc operationRecordDoc = operationDoc.getOperationRecordDoc();
+            if (operationRecordDoc != null) {
+                int interventionCount = 1;
+                int operationIncisionCount = 1;
+                int drainageMaterialsNameCount = 1;
+                int drainageMaterialsAmountCount = 1;
+                int placePositionCount = 1;
+                StringBuffer interventionString = new StringBuffer();
+                StringBuffer operationIncisionString = new StringBuffer();
+                StringBuffer drainageMaterialsNameString = new StringBuffer();
+                StringBuffer drainageMaterialsAmountString = new StringBuffer();
+                StringBuffer placePositionString = new StringBuffer();
+                OperationRecordLabel operationRecordLabel = operationRecordDoc.getOperationRecordLabel();
+                if (operationRecordLabel == null) {
+                    return;
+                }
+
+                //介入物名称
+                if (ListUtil.isNotEmpty(operationRecordLabel.getInterventions())) {
+                    for (Intervention interventions : operationRecordLabel.getInterventions()) {
+                        if (StringUtils.isNotEmpty(interventions.getName())) {
+                            if (operationRecordLabel.getInterventions().size() > 1) {
+                                interventionString.append((interventionCount++) + ".");
+                            }
+                            interventionString.append(interventions.getName());
+                        }
+
+                    }
+                    retMap.put("介入物名称", interventionString.toString());
+                }
+
+                //皮肤消毒描述
+                if (operationRecordLabel.getSkinSterilize() != null && StringUtils.isNotEmpty(operationRecordLabel.getSkinSterilize().getName())) {
+                    retMap.put("皮肤消毒描述", operationRecordLabel.getSkinSterilize().getName());
+                }
+
+                //手术切口描述
+                if (ListUtil.isNotEmpty(operationRecordLabel.getOperationIncision())) {
+                    for (OperationIncision operationIncisions : operationRecordLabel.getOperationIncision()) {
+                        if (StringUtils.isNotEmpty(operationIncisions.getName())) {
+                            if (operationRecordLabel.getOperationIncision().size() > 1) {
+                                operationIncisionString.append((operationIncisionCount++) + ".");
+                            }
+                            operationIncisionString.append(operationIncisions.getName());
+                        }
+
+                    }
+                    retMap.put("手术切口描述", operationIncisionString.toString());
+                }
+
+                //输液量(mL)
+                if (operationRecordLabel.getTransfuseQuantity() != null && StringUtils.isNotEmpty(operationRecordLabel.getTransfuseQuantity().getName())) {
+                    retMap.put("输液量(mL)", operationRecordLabel.getTransfuseQuantity().getName());
+                }
+
+                //术前用药
+                if (operationRecordLabel.getPreoperativeDrugs() != null && StringUtils.isNotEmpty(operationRecordLabel.getPreoperativeDrugs().getName())) {
+                    retMap.put("术前用药", operationRecordLabel.getPreoperativeDrugs().getName());
+                }
+
+                //术中用药
+                if (operationRecordLabel.getDuringDrugs() != null && StringUtils.isNotEmpty(operationRecordLabel.getDuringDrugs().getName())) {
+                    retMap.put("术中用药", operationRecordLabel.getDuringDrugs().getName());
+                }
+
+                //引流材料名称
+                if (ListUtil.isNotEmpty(operationRecordLabel.getDrainageMaterialsNames())) {
+                    for (DrainageMaterialsName drainageMaterialsNames : operationRecordLabel.getDrainageMaterialsNames()) {
+                        if (StringUtils.isNotEmpty(drainageMaterialsNames.getName())) {
+                            if (operationRecordLabel.getDrainageMaterialsNames().size() > 1) {
+                                drainageMaterialsNameString.append((drainageMaterialsNameCount++) + ".");
+                            }
+                            drainageMaterialsNameString.append(drainageMaterialsNames.getName());
+                        }
+
+                    }
+                    retMap.put("引流材料名称", drainageMaterialsNameString.toString());
+                }
+//                if (operationRecordLabel.getDrainageMaterialsName() != null && StringUtils.isNotEmpty(operationRecordLabel.getDrainageMaterialsName().getName())) {
+//                    retMap.put("引流材料名称", operationRecordLabel.getDrainageMaterialsName().getName());
+//                }
+                //放置部位
+                if (ListUtil.isNotEmpty(operationRecordLabel.getPlacePositions())) {
+                    for (PlacePosition PlacePositions : operationRecordLabel.getPlacePositions()) {
+                        if (StringUtils.isNotEmpty(PlacePositions.getName())) {
+                            if (operationRecordLabel.getPlacePositions().size() > 1) {
+                                placePositionString.append((placePositionCount++) + ".");
+                            }
+                            placePositionString.append(PlacePositions.getName());
+                        }
+
+                    }
+                    retMap.put("放置部位", placePositionString.toString());
+                }
+//                if (operationRecordLabel.getPlacePosition() != null && StringUtils.isNotEmpty(operationRecordLabel.getPlacePosition().getName())) {
+//                    retMap.put("放置部位", operationRecordLabel.getPlacePosition().getName());
+//                }
+
+                //引流材料数目
+                if (ListUtil.isNotEmpty(operationRecordLabel.getDrainageMaterialsAmounts())) {
+                    for (DrainageMaterialsAmount drainageMaterialsAmounts : operationRecordLabel.getDrainageMaterialsAmounts()) {
+                        if (StringUtils.isNotEmpty(drainageMaterialsAmounts.getName())) {
+//                            if (operationRecordLabel.getDrainageMaterialsAmounts().size() > 1) {
+//                                drainageMaterialsAmountString.append((placePositionCount++) + ".");
+//                            }
+
+                            drainageMaterialsAmountString.append(drainageMaterialsAmounts.getName() + "、");
+                        }
+                    }
+                    Integer integer = addAmount(drainageMaterialsAmountString);
+                    if(null != integer){
+                        retMap.put("引流材料数目",integer+"根");
+                    }
+                }
+//                if (operationRecordLabel.getDrainageMaterialsAmount() != null && StringUtils.isNotEmpty(operationRecordLabel.getDrainageMaterialsAmount().getName())) {
+//                    retMap.put("引流材料数目", operationRecordLabel.getDrainageMaterialsAmount().getName());
+//                }
+
+
+            }
+        });
+    }
+
+        private Integer addAmount(StringBuffer sb) {
+            if(StringUtil.isNotEmpty(sb.toString())){
+            List<Integer> list = new ArrayList<>();
+            String str = sb.toString();
+            if(str.contains("、")){
+                String[] split = str.split("、");
+                for (int i = 0; i < split.length; i++) {
+                    String sc = parseStr(split[i]);
+                    try {
+                        Integer integer = Integer.valueOf(sc);
+                        list.add(integer);
+                    } catch (NumberFormatException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+            return list.stream().reduce(Integer::sum).get();
+        }
+            return null;
+    }
+
+    private String parseStr(String sb) {
+       sb = sb.replace("根", "");
+       if(sb.equals("十")){
+           sb = "10";
+       }
+        if(sb.equals("二十")){
+            sb = "20";
+        }
+        sb =  sb.replace("二十", "2").replace("十", "1").replace("一", "1").replace("二", "2").replace("三", "3").replace("四", "4").replace("五", "5").replace("六", "6").replace("七", "7").replace("八", "8").replace("九", "9");
+        return sb;
+    }
+
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        text = text.replace("年  月  日  时  分", "").replace("第1次手术", "")
+                .replace("(包括体位、切口处理经过,病理标本肉眼所见)", "");
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("手术开始时间", "手术结束时间", "术前诊断", "手术名称", "术中诊断", "手 术 者", "手术人员", "助手",
+                        "麻醉方法", "麻醉方式", "麻 醉 者", "麻醉医师", "手术标本", "手术切除标本", "术中并发症", "术中失血量", "术中输血量", "手术简要经过(包括“术中所见”)",
+                        "手术经过", "术后情况及诊疗计划", "术后注意事项", "记录者", "主刀医生", "医生签名", "主刀医师签名", "记录时间", "患者或代理人签名", "与病人关系"),
+                text
+        );
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        if (sourceMap != null) {
+            if (sourceMap.containsKey("主刀医生")) {
+                String dataStr = sourceMap.get("主刀医生");
+                String date = extractDate(dataStr);
+                if (StringUtil.isNotBlank(date)) {
+                    sourceMap.put("主刀医生", dataStr.replace(date, ""));
+                    sourceMap.put("签名日期时间", date);
+                }else{
+                    if(dataStr.contains("年 月 日 时 分")){
+                        sourceMap.put("主刀医生", dataStr.replace("年 月 日 时 分", ""));
+                    }
+                }
+            } else if (sourceMap.containsKey("医生签名")) {
+                String dataStr = sourceMap.get("医生签名");
+                String date = extractDate(dataStr);
+                if (StringUtil.isNotBlank(date)) {
+                    sourceMap.put("医生签名", dataStr.replace(date, ""));
+                    sourceMap.put("签名日期时间", date);
+                }
+            }
+
+            //其他模块使用
+            if (sourceMap.containsKey("手术开始时间") && sourceMap.containsKey("手术结束时间")) {
+                sourceMap.put("手术日期时间", sourceMap.get("手术开始时间") + "-" + sourceMap.get("手术结束时间"));
+            }
+
+            CommonAnalysisUtil.removeKey(sourceMap, "术前诊断", "术中诊断", "⒈患者基本情况", "⒉拟实施的输血方案", "手术标本", "手术切除标本", "术中并发症",
+                    "与病人关系", "术后情况及诊疗计划", "术后注意事项");
+        }
+        return sourceMap;
+    }
+
+    /**
+     * 抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    private String extractDate(String top) {
+        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        } else {
+            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日 [0-9]+时[0-9]+分");
+            Matcher m1 = p1.matcher(top);
+            if (m1.find()) {
+                return m1.group(0);
+            }
+        }
+        return null;
+    }
+
+    private void disDate(Map sourceMap, String... args) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        if (sourceMap.containsKey(args[0]) && sourceMap_.get(args[0]).contains(args[1])) {
+            int index = sourceMap_.get(args[0]).indexOf(args[1]);
+            sourceMap.put(args[0], sourceMap_.get(args[0]).substring(0, index));
+            sourceMap.put(args[0] + args[1], sourceMap_.get(args[0]).substring(index).replace(args[1], "").replaceAll("[::]", ""));
+        }
+    }
+
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "手术开始时间=手术开始日期时间",
+            "手术结束时间=手术结束日期时间",
+            "手术简要经过(包括“术中所见”)=手术过程描述",
+            "手术经过=手术过程描述",
+            "手术者=手术者姓名",
+            "手术人员=手术者姓名",
+            "麻醉者=麻醉医师姓名",
+            "麻醉医师=麻醉医师姓名",
+            "医护人员陈述=手术者签名",
+            "主刀医生=手术者签名",
+            "术中失血量=出血量(mL)",
+            "术中输血量=输血量(mL)",
+            "主刀医师签名=手术者签名",
+            "记录时间=签名日期时间"
+    );
+}

+ 427 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/PreoperativeDiscussionTran.java

@@ -0,0 +1,427 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.operation.OperationDoc;
+import com.lantone.structure.model.doc.operation.PreoperativeDiscussionDoc;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description:术前小结、术前讨论
+ * @author: cy
+ * @time: 2021/2/26 14:52
+ */
+@Slf4j
+public class PreoperativeDiscussionTran extends TargetTran {
+
+    @Override
+    public Map<String, String> convert(String text) {
+         List<OperationDoc> operationDocs = new ArrayList<>();
+        OperationDoc operationDoc = new OperationDoc();
+        PreoperativeDiscussionDoc preoperativeDiscussionDoc = new  PreoperativeDiscussionDoc();
+        preoperativeDiscussionDoc.setText(text);
+        operationDoc.setPreoperativeDiscussionDoc(preoperativeDiscussionDoc);
+        operationDocs.add(operationDoc);
+        inputInfo.setOperationDocs(operationDocs);
+        Map<String, String> structureMap = new HashMap<String, String>();
+        Map<String, String> retMap = new HashMap<String, String>();
+        Boolean falg = false;
+        String file = text.split("\n")[0];
+        //术前小结-术前讨论
+        if(file.contains("讨论记录") || file.contains("术前讨论")){
+            structureMap = cutWordRe(text);
+            falg = true;
+        }else{
+            structureMap = cutWord(text);
+        }
+        pDContrast(falg,inputInfo.getOperationDocs(), structureMap);
+        mapKeyContrastCommon(structureMap,stagesContrasts,retMap);
+        preoperativeDiscussionDoc.setStructureMap(retMap);
+        aiProcess();
+        lastSovle(inputInfo.getOperationDocs(),retMap);
+        return retMap;
+    }
+
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("简要病情","药物、食物过敏史","目前服用的药物","月经史","一般情况","入院后辅助检查","术前诊断","手术指征","手术禁忌",
+                        "拟实施手术名称","手术方式","拟施手术名称和方式","拟实施麻醉方式","拟施麻醉方式","术前准备","其他术前相关情况","注意事项","防范措施","诊疗计划","手术审批医师","医师签名"),
+                text
+        );
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        if( sourceMap.containsKey("术前诊断") || sourceMap.containsKey("月经史")|| sourceMap.containsKey("其他术前相关情况")
+        || sourceMap.containsKey("一般情况") || sourceMap.containsKey("目前服用的药物") || sourceMap.containsKey("诊疗计划")){
+            sourceMap.remove("术前诊断");
+            sourceMap.remove("月经史");
+            sourceMap.remove("一般情况");
+            sourceMap.remove("其他术前相关情况");
+            sourceMap.remove("目前服用的药物");
+            sourceMap.remove("诊疗计划");
+        }
+        return sourceMap;
+    }
+
+    private Map<String, String> cutWordRe(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titleReplace = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("讨论时间","讨论地点","讨论主持人","参加人员","参加讨论人员","情况如下","术前诊断","讨论摘要","主持人总结","医师总结"),
+                text
+        );
+        CommonAnalysisUtil.cutByTitles(text, titleReplace, 0, sourceMap);
+        if(sourceMap.containsKey("术前诊断")){
+            sourceMap.remove("术前诊断");
+        }
+        return sourceMap;
+    }
+
+
+
+    private List<String> stagesContrasts = Lists.newArrayList(
+            "讨论时间=讨论日期时间",
+            "讨论主持人=主持人姓名",
+            "手术指征=手术指征",
+            "手术指征=手术适应证",
+            "手术禁忌=手术禁忌症",
+            "参加人员=参加讨论人员名单",
+            "拟实施手术名称=拟实施手术及操作名称",
+            "拟施手术名称和方式=拟实施手术及操作名称",
+            "防范措施=注意事项",
+            "防范措施=手术要点",
+            "主持人总结=讨论结论",
+            "讨论摘要=讨论意见",
+            "手术审批医师=手术者签名",
+            "药物、食物过敏史=过敏史"
+    );
+
+    public void pDContrast(Boolean flag,List<OperationDoc> operationDocs,Map<String, String> retMap) {
+        String text = operationDocs.get(0).getPreoperativeDiscussionDoc().getText();
+        if(flag == false){
+        //小结日期时间
+            if(text.contains("简要病情")){
+                String caseFile = text.substring(0,text.indexOf("简要病情:"));
+                String sumdDate = extractDate(caseFile);
+                if(StringUtil.isNotEmpty(sumdDate)){
+                    retMap.put("小结日期时间",sumdDate);
+                }
+            }
+
+
+        //病历摘要   诊断依据
+        if(StringUtil.isNotEmpty(retMap.get("简要病情"))) {
+            String simCaseRet = retMap.get("简要病情");
+            retMap.put("病历摘要",simCaseRet);
+            retMap.put("诊断依据",simCaseRet);
+            if(StringUtil.isNotEmpty(retMap.get("入院后辅助检查"))) {
+                retMap.put("病历摘要",simCaseRet+" "+"入院后辅助检查:"+retMap.get("入院后辅助检查"));
+            }
+        }
+
+    //辅助检查结果
+        if(StringUtil.isNotEmpty(retMap.get("简要病情"))) {
+            String simCase = retMap.get("简要病情");
+            String helpSee = "";
+            if(simCase.contains("辅助检查:")) {
+                 helpSee = simCase.substring(simCase.indexOf("辅助检查:")+5);
+                retMap.put("辅助检查结果",helpSee);
+            }
+            if(StringUtil.isNotEmpty(retMap.get("入院后辅助检查"))) {
+                retMap.put("辅助检查结果",helpSee+" "+"入院后辅助检查:"+retMap.get("入院后辅助检查"));
+            }
+        }
+        if(StringUtil.isNotEmpty(retMap.get("简要病情"))) {
+            retMap.remove("简要病情");
+        }
+        if(StringUtil.isNotEmpty(retMap.get("入院后辅助检查"))) {
+            retMap.remove("入院后辅助检查");
+        }
+
+        //手术禁忌
+        if(text.contains("手术禁忌:")) {
+            String opration = text.substring(text.indexOf("手术禁忌:") + 5);
+            String s = opration.split("\n")[0];
+            retMap.put("手术禁忌",s);
+        }
+
+        //手术指征
+        if(text.contains("手术指征:")) {
+            String opration = text.substring(text.indexOf("手术指征:") + 5);
+            if(opration.contains("拟实施手术名称")){
+                   opration = opration.substring(0,opration.indexOf("拟实施手术名称"));
+            }
+            if(opration.contains("主刀医生")){
+                opration = opration.substring(0,opration.indexOf("主刀医生"));
+            }
+            String[] split = opration.split("\n");
+            if(StringUtil.isNotEmpty(split[0])){
+                retMap.put("手术指征",split[0]);
+            }
+        }
+
+        //拟实施手术及操作日期时间
+        if(text.contains("拟定于")) {
+            String opration = text.substring(text.indexOf("拟定于"));
+            String date = extractDate(opration);
+            retMap.put("拟实施手术及操作日期时间",date);
+        }
+
+        //手术审批医师
+        String oprationDoc = "";
+        if(text.contains("手术审批医师:")){
+             oprationDoc =  text.substring(text.indexOf("手术审批医师:" )+ 7).trim();
+        }
+        if(StringUtil.isEmpty(retMap.get("手术审批医师"))) {
+            String oprationSign = "";
+            if(oprationDoc.contains("医师签名")){
+                 oprationSign = text.substring(text.indexOf("手术审批医师:") + 7, text.indexOf("医师签名")).trim();
+            }else{
+                if(oprationDoc.contains("年") ||oprationDoc.contains( "-")){
+                    String subStr= text.substring(text.indexOf("手术审批医师:")+7);
+                    oprationSign = subStr.split("\n")[0].trim();
+                }
+            }
+                retMap.put("手术审批医师",oprationSign);
+        }else{
+            String trim = "";
+            if(oprationDoc.contains("医师签名")){
+                trim = oprationDoc.substring(0, oprationDoc.indexOf("医师签名")).trim();
+            }else{
+                trim = oprationDoc.split("\n")[0].trim();
+            }
+            if(StringUtil.isNotEmpty(trim) && (trim.contains("年") || trim.contains("-"))){
+                String trimDate = extractDate(trim);
+                if(StringUtil.isNotEmpty(trimDate)){
+                    trim = oprationDoc.substring(0, oprationDoc.indexOf(trim)).trim();
+                }else{
+                    trim = oprationDoc.substring(0, oprationDoc.indexOf("年")).trim();
+                }
+            }
+                retMap.put("手术审批医师",trim);
+
+            if(StringUtil.isEmpty(retMap.get("手术审批医师").trim())){
+                retMap.remove("手术审批医师");
+            }
+
+        }
+
+        //医师签名
+        if(text.contains("医师签名:")) {
+            String sign =  text.substring(text.indexOf("医师签名:")+5).trim();
+            if(sign.contains("年") ||sign.contains( "-")){
+                String subStr= text.substring(text.indexOf("医师签名:")+5);
+                sign = subStr.split("\n")[0].trim();
+            }
+            if(StringUtil.isNotEmpty(sign)){
+                retMap.put("医师签名",sign);
+            }else{
+                retMap.remove("医师签名");
+            }
+        }
+        String date = "";
+        String sub = "";
+        if(text.contains("手术审批医师:")){
+             sub = text.substring(text.lastIndexOf("手术审批医师:"));
+        }else{
+            if(text.contains("诊疗计划:")){
+             sub = text.substring(text.lastIndexOf("诊疗计划:"));
+            }
+        }
+        date = extractDate(sub);
+        if(StringUtil.isNotEmpty(date)){
+            retMap.put("签名日期时间",date);
+        }
+
+            StringBuffer sbx = new StringBuffer();
+            if(StringUtil.isNotEmpty(retMap.get("拟实施手术名称"))){
+                String plan = retMap.get("拟实施手术名称");
+                sbx.append("拟实施手术名称:"+plan+" ");
+            }
+            if(StringUtil.isNotEmpty(retMap.get("手术方式"))){
+                String plan = retMap.get("手术方式");
+                sbx.append("手术方式:"+plan+" ");
+            }
+            if(StringUtil.isNotEmpty(retMap.get("拟实施麻醉方式"))){
+                String plan = retMap.get("拟实施麻醉方式");
+                sbx.append("拟实施麻醉方式:"+plan+" ");
+            }
+            if(StringUtil.isNotEmpty(sbx.toString())){
+                retMap.put("手术方案",sbx.toString());
+            }
+        }
+
+//        ===========================术前讨论===================================
+
+/*
+        if(text.contains("\n")){
+            String[] split = text.split("\n");
+            for (int i = 0; i < split.length-1; i++) {
+                if(i == 0 && split[i].contains("讨论记录")){
+                   flag = true;
+
+                   break;
+                    }
+                }
+            }
+*/
+
+        //参加人员
+        if(flag){
+            //主持人姓名去职称
+            List<String>titleStr = Lists.newArrayList("﹙副﹚主任医师","(副)主任医师","副主任医师", "主治医师","主任医师",
+                    "住院医师","医师", "护士");
+            for (String timeName : titleStr) {
+                String dirName = retMap.get("讨论主持人");
+                if (StringUtil.isNotEmpty(dirName)) {
+                    if (dirName.contains(timeName)) {
+                        retMap.put("讨论主持人", dirName.split(timeName)[0]);
+                        break;
+                    }
+                }
+            }
+
+            if(StringUtil.isEmpty(retMap.get("讨论摘要"))){
+                if(StringUtil.isNotEmpty(retMap.get("情况如下"))){
+                    String caseFir = retMap.get("情况如下");
+                    if(caseFir.contains("医师:")){
+                        String flagCase = caseFir.split("医师:")[1];
+                        if(flagCase.contains(":")){
+                            flagCase = caseFir.split(":")[0];
+                            if(flagCase.contains("。")){
+                                flagCase = caseFir.substring(0,caseFir.lastIndexOf("。"));
+                            }
+                        }
+                        if(StringUtil.isNotEmpty(flagCase)){
+                            retMap.put("讨论摘要",flagCase);
+                        }
+                    }
+                }
+            }
+                String fir = "";
+                if(StringUtil.isNotEmpty(retMap.get("参加人员"))){
+                    fir = text.substring(text.indexOf("参加人员:")+"参加人员:".length(), text.lastIndexOf("汇报病史"));
+                }
+                if(StringUtil.isNotEmpty(retMap.get("参加讨论人员"))){
+                    retMap.remove("参加讨论人员");
+                    fir = text.substring(text.indexOf("参加讨论人员:")+"参加讨论人员:".length(), text.lastIndexOf("情况如下:"));
+                }
+                String[] split = fir.split("\n");
+                StringBuffer sb = new StringBuffer();
+                for (int i = 0; i < split.length-1; i++) {
+                    sb.append(split[i]).append("  ");
+                }
+            if(StringUtil.isNotEmpty(sb.toString())){
+                retMap.put("参加人员",sb.toString());
+            }
+
+            if(StringUtil.isNotEmpty(retMap.get("主持人总结"))||StringUtil.isNotEmpty(retMap.get("医师总结"))){
+                String dirSum = retMap.get("主持人总结");
+                if(StringUtil.isEmpty(dirSum)){
+                    dirSum = retMap.get("医师总结");
+                }
+                String date = extractDate(dirSum);
+                String signName = "";
+                if(dirSum.contains("记录者(签名)")){
+                    signName = dirSum.substring(dirSum.lastIndexOf("记录者(签名)")+"记录者(签名)".length());
+                }
+                if (StringUtil.isNotEmpty(date)) {
+                    retMap.put("签名日期时间",date);
+                    if( signName.contains(date)){
+                        signName = signName.substring(0, signName.lastIndexOf(date));
+                    }
+                }
+                if (StringUtil.isNotEmpty(signName) && StringUtil.isNotEmpty(signName.trim())) {
+                    retMap.put("医师签名",signName);
+                }
+                if(dirSum.contains("主持人(签名)")){
+                    dirSum = dirSum.substring(0, dirSum.lastIndexOf("主持人(签名)"));
+                }
+                if(dirSum.contains("主持人:")){
+                    dirSum = dirSum.substring(0, dirSum.lastIndexOf("主持人:"));
+                }
+                retMap.put("主持人总结",dirSum);
+            }
+            retMap.remove("参加讨论人员");
+            retMap.remove("情况如下");
+            retMap.remove("医师总结");
+        }
+        retMap.remove("手术方式");
+        retMap.remove("拟实施麻醉方式");
+        retMap.remove("拟施麻醉方式");
+    }
+
+    public static void mapKeyContrastCommon(Map sourceMap, List<String> keyContrasts, Map<String, String> retMap) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        String[] arry = null;
+        String sourceKey = null, targetKey;
+        Set<String> removeKey = new HashSet<>();
+        for (String keyContrast : keyContrasts) {
+            arry = keyContrast.split("=");
+            sourceKey = arry[0];
+            if (arry.length == 1) {
+                targetKey = arry[0];
+            } else {
+                targetKey = arry[1];
+            }
+            if (StringUtil.isNotBlank(sourceMap_.get(sourceKey))
+                    && (!retMap.containsKey(targetKey) || StringUtil.isBlank(retMap.get(targetKey)))) {
+                retMap.put(targetKey, sourceMap_.get(sourceKey));
+            }
+            removeKey.add(sourceKey);
+        }
+        Set<String> keySet = retMap.keySet();
+        for (String key : sourceMap_.keySet()) {
+            if (!keySet.contains(key) && !removeKey.contains(key)) { // 如果之前已放过key就不用放了
+                retMap.put(key, sourceMap_.get(key));
+            }
+        }
+    }
+
+
+    /**
+     * 抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String extractDate(String top) {
+        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        } else {
+            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日");
+            Matcher m1 = p1.matcher(top);
+            if (m1.find()) {
+                return m1.group(0);
+            }
+        }
+        return null;
+    }
+
+
+    public static void lastSovle(List<OperationDoc> operationDocs , Map<String,String> rep) {
+        if(!operationDocs.isEmpty() && operationDocs.get(0)!=null && operationDocs.get(0)
+                .getPreoperativeDiscussionDoc()!=null&& operationDocs.get(0)
+                .getPreoperativeDiscussionDoc().getPreoperativeDiscussionLabel()!=null){
+            PreoperativeDiscussionDoc preoperativeDiscussionDoc = operationDocs.get(0).getPreoperativeDiscussionDoc();
+            String allergyRecord = preoperativeDiscussionDoc.getPreoperativeDiscussionLabel().getAllergyRecord();
+            String opBottomName = preoperativeDiscussionDoc.getPreoperativeDiscussionLabel().getOpBottomName();
+            String opContraindication = preoperativeDiscussionDoc.getPreoperativeDiscussionLabel().getOpContraindication();
+            if(StringUtil.isEmpty(rep.get("药物、食物过敏史")) && StringUtil.isNotEmpty(allergyRecord)){
+                rep.put("过敏史",allergyRecord);
+            }
+            if(StringUtil.isNotEmpty(opBottomName)){
+                rep.put("拟实施手术目标部位名称",opBottomName);
+            }
+            if(StringUtil.isEmpty(rep.get("手术禁忌症")) && StringUtil.isNotEmpty(opContraindication)){
+                rep.put("手术禁忌症",opContraindication);
+            }
+        }
+    }
+}

+ 250 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/RescueTran.java

@@ -0,0 +1,250 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.ListUtil;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.RescueDoc;
+import com.lantone.structure.model.entity.*;
+import com.lantone.structure.model.label.RescueLabel;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2021/2/2 14:14
+ */
+@Slf4j
+public class RescueTran extends TargetTran {
+
+    @Override
+    public Map<String, String> convert(String text) {
+        List<RescueDoc> rescueDocList = new ArrayList<>();
+        RescueDoc rescueDoc = new RescueDoc();
+        rescueDoc.setText(text);
+        rescueDocList.add(rescueDoc);
+        inputInfo.setRescueDocs(rescueDocList);
+        aiProcess();
+        Map<String, String> structureMap = cutWord(text);
+        rescueContrast(inputInfo.getRescueDocs(), structureMap);
+        return structureMap;
+    }
+
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("抢救措施","参与现场抢救的医务人员","注意事项"),
+                text
+        );
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        if(sourceMap.containsKey("参与现场抢救的医务人员")){
+            sourceMap.remove("参与现场抢救的医务人员");
+        }
+        return sourceMap;
+    }
+
+
+    public void rescueContrast( List<RescueDoc> rescueDocs,Map<String, String> retMap) {
+        if(ListUtil.isNotEmpty(rescueDocs)){
+            rescueDocs.forEach(rescueDoc -> {
+                int auxiliaryCount = 1;
+                int auxiliaryResultCount = 1;
+                int operationsCount = 1;
+                int operationLocationCount = 1;
+                int methodsCount = 1;
+                int count = 1;
+                int interventionCount = 1;
+                int conditionsCount = 1;
+                int diagnosisCount = 1;
+                int drugsCount = 1;
+                StringBuffer auxiliaryTestString = new StringBuffer();
+                StringBuffer auxiliaryResultString  = new StringBuffer();
+                StringBuffer operationsString = new StringBuffer();
+                StringBuffer operationLocationString = new StringBuffer();
+                StringBuffer methodsString = new StringBuffer();
+                StringBuffer countString = new StringBuffer();
+                StringBuffer conditionsString = new StringBuffer();
+                StringBuffer diagnosisString = new StringBuffer();
+                StringBuffer interventionString = new StringBuffer();
+                StringBuffer drugsString = new StringBuffer();
+                StringBuffer resMedString = new StringBuffer();
+
+                RescueLabel rescueLabel = rescueDoc.getRescueLabel();
+                    if(ListUtil.isNotEmpty( rescueLabel.getAuxiliaryTest())){
+                        for (AuxiliaryTest auxiliaryTest : rescueLabel.getAuxiliaryTest()) {
+                                for (AuxiliaryResult auxiliaryResult : auxiliaryTest.getAuxiliaryResult()) {
+                                    if(StringUtils.isNotEmpty( auxiliaryResult.getName())){
+                                        if(auxiliaryTest.getAuxiliaryResult().size()>1){
+                                            auxiliaryResultString.append((auxiliaryResultCount++) + ".");
+                                        }
+                                        auxiliaryResultString.append(auxiliaryResult.getName());
+                                    }
+                                }
+
+                            if(StringUtils.isNotEmpty(auxiliaryTest.getName())){
+                                if(rescueLabel.getAuxiliaryTest().size()>1) {
+                                    auxiliaryTestString.append((auxiliaryCount++) + ".");
+                                }
+                                auxiliaryTestString.append(auxiliaryTest.getName());
+                            }
+
+                        }
+                        if(StringUtil.isNotEmpty(auxiliaryTestString.toString())){
+                            retMap.put("检查/检验项目名称", auxiliaryTestString.toString());
+                        }
+
+                        if(StringUtil.isNotEmpty(auxiliaryResultString.toString())){
+                            retMap.put("检查/检验结果", auxiliaryResultString.toString());
+                        }
+                       }
+
+                    if(ListUtil.isNotEmpty( rescueLabel.getOperations())){
+                        for (Operation operations : rescueLabel.getOperations()) {
+                            if(operations.getOperationLocation()!=null && StringUtils.isNotEmpty( operations.getOperationLocation().getName())){
+                                if(rescueLabel.getOperations().size()>1){
+                                    operationLocationString.append((operationLocationCount++) + ".");
+                                }
+                                operationLocationString.append(operations.getOperationLocation().getName());
+                            }
+                            if(StringUtils.isNotEmpty(operations.getName())){
+                                if(rescueLabel.getOperations().size()>1){
+                                    operationsString.append((operationsCount++) + ".");
+                                }
+                                operationsString.append( operations.getName());
+                            }
+
+                        }
+                        if(StringUtil.isNotEmpty(operationsString.toString())){
+                            retMap.put("手术及操作名称", operationsString.toString());
+                        }
+
+                        if(StringUtil.isNotEmpty(operationLocationString.toString())){
+                            retMap.put("手术及操作目标部位名称", operationLocationString.toString());
+                        }
+                        if(StringUtils.isNotEmpty(retMap.get("手术及操作名称"))){
+                            resMedString.append("手术及操作名称"+":"+retMap.get("手术及操作名称")+";");
+                        }
+
+                        if(StringUtils.isNotEmpty(retMap.get("手术及操作目标部位名称"))){
+                            resMedString.append("手术及操作目标部位名称"+":"+retMap.get("手术及操作目标部位名称")+";");
+                        }
+
+                  }
+
+                    if(ListUtil.isNotEmpty(rescueLabel.getMethods())){
+                        for (Method methods : rescueLabel.getMethods()) {
+                            if(StringUtils.isNotEmpty(methods.getName())){
+                                if(rescueLabel.getMethods().size()>1){
+                                    methodsString.append((methodsCount++) + ".");
+                                }
+                                methodsString.append( methods.getName());
+                            }
+                            if( methods.getCount() != null){
+                                if(rescueLabel.getMethods().size()>1){
+                                    countString.append((count++) + ".");
+                                }
+                                countString.append(methods.getName()+methods.getCount().getName());
+                            }
+                        }
+                        if(StringUtil.isNotEmpty(methodsString.toString())){
+                            retMap.put("操作方法", methodsString.toString());
+                        }
+                        if(StringUtil.isNotEmpty(countString.toString())){
+                            retMap.put("操作次数", countString.toString());
+                        }
+
+                        if(StringUtils.isNotEmpty(retMap.get("操作方法"))){
+                            resMedString.append("操作方法"+":"+retMap.get("操作方法")+";");
+                        }
+                        if(StringUtils.isNotEmpty(retMap.get("操作次数"))){
+                            resMedString.append("操作次数"+":"+retMap.get("操作次数")+";");
+                        }
+
+                        }
+
+                    if(ListUtil.isNotEmpty(rescueLabel.getInterventions())){
+                        for (Intervention intervention : rescueLabel.getInterventions()) {
+                            if(StringUtils.isNotEmpty(intervention.getName())){
+                                if(rescueLabel.getInterventions().size()>1){
+                                    interventionString.append((interventionCount++) + ".");
+                                }
+                                interventionString.append(intervention.getName());
+                            }
+                        }
+                        if(StringUtil.isNotEmpty(interventionString.toString())){
+                            retMap.put("介入物名称",interventionString.toString());
+                        }
+                    }
+
+                    if(ListUtil.isNotEmpty(rescueLabel.getConditions())){
+                        //抢救病情长度1时间没有,大于1时间开始取最初 结束取最后
+                        if(rescueLabel.getConditions().size()>1){
+                            if( null != (rescueLabel.getConditions().get(0).getPd()) && StringUtils.isNotEmpty(rescueLabel.getConditions().get(0).getPd().getValue())){
+                                retMap.put("抢救开始日期时间",rescueLabel.getConditions().get(0).getPd().getValue());
+                            }
+
+                            if( null != (rescueLabel.getConditions().get(rescueLabel.getConditions().size()-1).getPd()) && StringUtils.isNotEmpty(rescueLabel.getConditions().get(rescueLabel.getConditions().size()-1).getPd().getValue())){
+                                retMap.put("抢救开始日期时间",rescueLabel.getConditions().get(rescueLabel.getConditions().size()-1).getPd().getValue());
+                            }
+                        }
+                    for (Condition conditions : rescueLabel.getConditions()) {
+                        if(StringUtils.isNotEmpty(conditions.getName())){
+                            if(rescueLabel.getInterventions().size()>1){
+                                conditionsString.append((conditionsCount++) + ".");
+                            }
+                            conditionsString.append(conditions.getName());
+                        }
+
+                    }
+                        if(StringUtil.isNotEmpty(conditionsString.toString())){
+                            retMap.put("病情变化情况",conditionsString.toString());
+                        }
+                  }
+
+                    if(ListUtil.isNotEmpty(rescueLabel.getDiagnosis())){
+                    for (Diagnosis diagnosis : rescueLabel.getDiagnosis()) {
+                        if(StringUtils.isNotEmpty(diagnosis.getName())){
+                            if(rescueLabel.getInterventions().size()>1){
+                                diagnosisString.append((diagnosisCount++) + ".");
+                            }
+                            diagnosisString.append(diagnosis.getName());
+                        }
+                    }
+                        if(StringUtil.isNotEmpty(conditionsString.toString())){
+                            retMap.put("疾病诊断名称", diagnosisString.toString());
+                        }
+                  }
+
+
+                if(!retMap.containsKey("抢救措施")&&StringUtils.isEmpty(retMap.get("抢救措施"))){
+                    //抢救药品只会出现在抢救措施里面
+                    if(ListUtil.isNotEmpty(rescueLabel.getDrugs())){
+                        for (Drug drugs : rescueLabel.getDrugs()) {
+                            if(StringUtils.isNotEmpty(drugs.getName())){
+                                if(rescueLabel.getDrugs().size()>1){
+                                    drugsString.append((drugsCount++) + ".");
+                                }
+                                drugsString.append(drugs.getName());
+                            }
+                        }
+                        if(StringUtils.isNotEmpty( drugsString.toString())){
+                            resMedString.append("抢救药品"+":"+ drugsString.toString()+";");
+                        }
+                    }
+                    if(StringUtils.isNotEmpty( drugsString.toString())){
+                        String resMedStr = resMedString.toString();
+                        if(resMedStr.endsWith(";")){
+                            resMedStr = resMedStr.substring(0, resMedStr.lastIndexOf(";"));
+                        }
+                        retMap.put("抢救措施",resMedStr);
+                    }
+                }
+            });
+        }
+    }
+}

Файловите разлики са ограничени, защото са твърде много
+ 122 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/SpecialCureConsentDocTran.java


+ 239 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/StagesSummaryTran.java

@@ -0,0 +1,239 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.ListUtil;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.StagesSummaryDoc;
+import com.lantone.structure.model.entity.AuxiliaryExamination;
+import com.lantone.structure.model.entity.Drug;
+import com.lantone.structure.model.entity.Laboratory;
+import com.lantone.structure.model.entity.Surgery;
+import com.lantone.structure.model.label.StagesSummaryLabel;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2021/2/2 14:15
+ */
+@Slf4j
+public class StagesSummaryTran extends TargetTran {
+
+    @Override
+    public Map<String, String> convert(String text) {
+        List<StagesSummaryDoc> stagesSummaryDocList = new ArrayList<>();
+        StagesSummaryDoc stagesSummaryDoc = new StagesSummaryDoc();
+        stagesSummaryDoc.setText(text);
+        stagesSummaryDocList.add(stagesSummaryDoc);
+        inputInfo.setStagesSummaryDocs(stagesSummaryDocList);
+        aiProcess();
+        Map<String, String> structureMap = cutWord(text);
+        Map<String, String> retMap = new HashMap<String, String>();
+        stagesContrast(inputInfo.getStagesSummaryDocs(), structureMap);
+        mapKeyContrastCommon(structureMap,stagesContrasts,retMap);
+        return retMap;
+    }
+
+    private List<String> stagesContrasts = Lists.newArrayList(
+            "诊疗经过=诊疗过程描述",
+            "诊疗计划=今后治疗方案"
+    );
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("入院情况","入院诊断","辅助检查", "诊疗经过", "目前情况","目前诊断", "诊疗计划"),
+                text
+        );
+        String retStr = parseBook(text);
+        sourceMap.put("主诉",retStr);
+        String stringDate =extractDate(text) ;
+        if(StringUtils.isNotEmpty(stringDate)){
+            sourceMap.put("小结日期时间",stringDate);
+        }
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        if(sourceMap.containsKey("辅助检查")||sourceMap.containsKey("目前诊断")||sourceMap.containsKey("入院诊断")){
+            sourceMap.remove("入院诊断");
+            sourceMap.remove("辅助检查");
+            sourceMap.remove("目前诊断");
+        }
+        if(sourceMap.containsKey("诊疗计划")&&StringUtil.isNotEmpty(sourceMap.get("诊疗计划"))){
+            String retString = sourceMap.get("诊疗计划");
+            String Data = parseString(retString);
+            sourceMap.put("诊疗计划",Data);
+
+        }
+        return sourceMap;
+    }
+
+    // 取/前
+    public static String parseString(String text){
+        if(text.contains("/")){
+            text = text.substring(0,text.lastIndexOf("/"));
+            text= parseString(text);
+        }
+        return text;
+    }
+    public static String parseBook(String text){
+        String[] sourceStr = text.split("因");
+        String[] targetStr = {""};
+        String retStr = "";
+        if(sourceStr!=null&&sourceStr.length>1){
+                 retStr = sourceStr[1].substring( sourceStr[1].indexOf("”")+1);
+              if(retStr.contains("”")){
+                   retStr = retStr.substring(0, retStr.indexOf("”"));
+                   return retStr;
+              }else{
+                  retStr = "";
+              }
+              if(StringUtil.isEmpty(retStr)){
+                  targetStr = sourceStr[1].split("于");
+              }
+        }
+        if(targetStr!=null&&targetStr.length>1){
+             retStr = targetStr[0];
+        }
+        return retStr;
+    };
+
+    public static void mapKeyContrastCommon(Map sourceMap, List<String> keyContrasts, Map<String, String> retMap) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        String[] arry = null;
+        String sourceKey = null, targetKey;
+        Set<String> removeKey = new HashSet<>();
+        for (String keyContrast : keyContrasts) {
+            arry = keyContrast.split("=");
+            sourceKey = arry[0];
+            if (arry.length == 1) {
+                targetKey = arry[0];
+            } else {
+                targetKey = arry[1];
+            }
+            if (StringUtil.isNotBlank(sourceMap_.get(sourceKey))
+                    && (!retMap.containsKey(targetKey) || StringUtil.isBlank(retMap.get(targetKey)))) {
+                retMap.put(targetKey, sourceMap_.get(sourceKey));
+            }
+            removeKey.add(sourceKey);
+        }
+        Set<String> keySet = retMap.keySet();
+        for (String key : sourceMap_.keySet()) {
+            if (!keySet.contains(key) && !removeKey.contains(key)) { // 如果之前已放过key就不用放了
+                retMap.put(key, sourceMap_.get(key));
+            }
+        }
+    }
+
+
+    /**
+     * 抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String extractDate(String top) {
+        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}([ ][0-9]{1,2}[:][0-9]{1,2}([:][0-9]{1,2})?)?");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        } else {
+            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日[0-9]+时[0-9]+分");
+            Matcher m1 = p1.matcher(top);
+            if (m1.find()) {
+                return m1.group(0);
+            }
+        }
+        return null;
+    }
+
+    public void stagesContrast( List<StagesSummaryDoc> stagesSummaryDocs, Map<String, String> retMap) {
+        if(ListUtil.isNotEmpty(stagesSummaryDocs)){
+            stagesSummaryDocs.forEach(stagesSummaryDoc -> {
+                int auxCount = 1;
+                int laboratoryCount = 1;
+                int surgerysCount = 1;
+                int drugsCount = 1;
+                StringBuffer adviceString = new StringBuffer();
+                StagesSummaryLabel stagesSummaryLabe = stagesSummaryDoc.getStagesSummaryLabel();
+                if (ListUtil.isNotEmpty(stagesSummaryLabe.getAuxiliaryExaminations())) {
+                        if (ListUtil.isNotEmpty(stagesSummaryLabe.getAuxiliaryExaminations())) {
+                            adviceString.append( "辅助检查" + ":");
+                            for (AuxiliaryExamination auxiliaryExaminations : stagesSummaryLabe.getAuxiliaryExaminations()) {
+                                if(StringUtils.isNotEmpty( auxiliaryExaminations.getName())){
+                                    if(stagesSummaryLabe.getAuxiliaryExaminations().size()>1){
+                                        adviceString.append((auxCount++) + ".");
+                                    }
+                                    adviceString.append(auxiliaryExaminations.getName());
+                                }
+                            }
+                            adviceString.append(";");
+                        }
+
+                }
+
+                if (ListUtil.isNotEmpty(stagesSummaryLabe.getLaboratory())) {
+                        if (ListUtil.isNotEmpty(stagesSummaryLabe.getLaboratory())) {
+                            adviceString.append( "实验室检查"+ ":");
+                            for (Laboratory laboratory : stagesSummaryLabe.getLaboratory()) {
+                                if(StringUtils.isNotEmpty( laboratory.getName())){
+                                    if(stagesSummaryLabe.getLaboratory().size()>1){
+                                        adviceString.append((laboratoryCount++)+ ".");
+                                    }
+                                    adviceString.append(laboratory.getName());
+                                }
+
+                            }
+                            adviceString.append(";");
+                        }
+
+                }
+
+                if (ListUtil.isNotEmpty(stagesSummaryLabe.getSurgerys())) {
+                        if (ListUtil.isNotEmpty(stagesSummaryLabe.getSurgerys())) {
+                            adviceString.append("手术名称" + ":");
+                            for (Surgery surgerys : stagesSummaryLabe.getSurgerys()) {
+                                if(StringUtils.isNotEmpty( surgerys.getName())){
+                                    if(stagesSummaryLabe.getSurgerys().size()>1){
+                                        adviceString.append((surgerysCount++)+ ".");
+                                    }
+                                    adviceString.append(surgerys.getName());
+                                }
+
+                            }
+                            adviceString.append(";");
+                        }
+
+                }
+                if (ListUtil.isNotEmpty(stagesSummaryLabe.getDrugs())) {
+                    if (ListUtil.isNotEmpty(stagesSummaryLabe.getDrugs())) {
+                        adviceString.append( "抢救药品"+ ":");
+                        for (Drug drugs : stagesSummaryLabe.getDrugs()) {
+                            if(StringUtils.isNotEmpty( drugs.getName())){
+                                if(stagesSummaryLabe.getDrugs().size()>1){
+                                    adviceString.append((drugsCount++)+ ".");
+                                }
+                                adviceString.append(drugs.getName());
+                            }
+
+                        }
+                        adviceString.append(";");
+                    }
+
+            }
+                String adviceStr = adviceString.toString();
+                if(adviceStr.endsWith(";")){
+                    adviceStr = adviceStr.substring(0, adviceStr.lastIndexOf(";"));
+                }
+                retMap.put("医嘱内容",adviceStr);
+            });
+        }
+    }
+
+
+}

+ 41 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/TargetTran.java

@@ -0,0 +1,41 @@
+package com.lantone.structure.facade.tran;
+
+import com.lantone.structure.ai.AIAnalyze;
+import com.lantone.structure.client.CRFServiceClient;
+import com.lantone.structure.client.SimilarityServiceClient;
+import com.lantone.structure.model.InputInfo;
+import com.lantone.structure.util.SpringContextUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2021/2/2 13:49
+ */
+@Slf4j
+public abstract class TargetTran {
+
+    InputInfo inputInfo;
+    SimilarityServiceClient similarityServiceClient;
+    CRFServiceClient crfServiceClient;
+
+    public abstract Map<String, String> convert(String text);
+
+    public TargetTran() {
+        this.inputInfo = new InputInfo();
+        similarityServiceClient = SpringContextUtil.getBean(SimilarityServiceClient.class);
+        crfServiceClient = SpringContextUtil.getBean(CRFServiceClient.class);
+    }
+
+    public void aiProcess() {
+        AIAnalyze aiAnalyze = new AIAnalyze(crfServiceClient, similarityServiceClient);
+        try {
+            aiAnalyze.aiProcess(inputInfo);
+        } catch (Exception e) {
+            log.error("AI模型执行错误:" + e.getMessage(), e);
+        }
+    }
+
+}

+ 170 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/ThreeLevelWardTran.java

@@ -0,0 +1,170 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.ListUtil;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.ThreeLevelWardDoc;
+import com.lantone.structure.model.label.ThreeLevelWardLabel;
+import lombok.extern.slf4j.Slf4j;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description:上级医师查房记录
+ * @author: cy
+ * @time: 2021/2/20 14:07
+ */
+@Slf4j
+public class ThreeLevelWardTran extends TargetTran {
+
+    @Override
+    public Map<String, String> convert(String text) {
+        List<ThreeLevelWardDoc> wardRecordDocList = new ArrayList<>();
+        ThreeLevelWardDoc wardRecordDoc = new ThreeLevelWardDoc();
+        wardRecordDoc.setText(text);
+        wardRecordDocList.add(wardRecordDoc);
+        inputInfo.setThreeLevelWardDocs(wardRecordDocList);
+        Map<String, String> structureMap = cutWord(text);
+        wardRecordContrast(inputInfo.getThreeLevelWardDocs(), structureMap);
+        wardRecordDoc.setStructureMap(structureMap);
+        aiProcess();
+        lastSovle(inputInfo.getThreeLevelWardDocs(),structureMap);
+        return structureMap;
+    }
+
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("鉴别诊断","诊疗计划","诊断考虑","补充诊断","Caprini评分为","注意事项"),
+                text
+        );
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        sourceMap.entrySet().removeIf(entry -> entry.getKey().equals("鉴别诊断") || entry.getKey().equals("补充诊断") || entry.getKey().equals("注意事项") || entry.getKey().equals("Caprini评分为") || entry.getKey().equals("诊断考虑"));
+        return sourceMap;
+    }
+
+
+    public void wardRecordContrast( List<ThreeLevelWardDoc> wardRecordDoc,Map<String, String> retMap) {
+        String text = wardRecordDoc.get(0).getText();
+        String fir = text;
+        //查房日期时间
+        String sumdDate = extractDate(text);
+        if(StringUtil.isNotEmpty(sumdDate)){
+            retMap.put("查房日期时间",sumdDate);
+        }
+
+        String signName= parseString(text);
+        if(StringUtil.isNotEmpty(signName) && StringUtil.isNotEmpty(signName.trim()) && signName.length()<15){
+            retMap.put("记录人签名",signName);
+        }
+
+        if(StringUtil.isNotEmpty(sumdDate)){
+            String[] split = text.split(sumdDate);
+            fir = text.substring(text.lastIndexOf(split[1]));
+            String[] notes = fir.split("查房记录");
+            if(notes.length<=1){
+                notes = fir.split("日常查房");
+            }
+            if(notes.length<=1){
+                notes = fir.split("查房录");
+            }
+            fir = fir.substring(fir.lastIndexOf(notes[1]));
+        }
+
+        if( StringUtil.isNotEmpty(signName.trim()) && signName.length()<15){
+            fir = fir.substring(0,fir.lastIndexOf(signName));
+            String flag  = "/";
+            if(fir.endsWith("//")){
+                flag = "//";
+            }
+            fir = fir.substring(0,fir.lastIndexOf(flag));
+        }
+
+        if(StringUtil.isNotEmpty(fir)){
+            retMap.put("查房记录",fir);
+        }
+
+        if(StringUtil.isNotEmpty(retMap.get("诊疗计划"))){
+            String plan = retMap.get("诊疗计划");
+            if(StringUtil.isNotEmpty( retMap.get("记录人签名")) && StringUtil.isNotEmpty( retMap.get("记录人签名").trim())){
+                String name = retMap.get("记录人签名").trim();
+                if(plan.contains(name)){
+                plan = plan.substring(0,plan.lastIndexOf(name));
+                }
+                if(plan.endsWith("今予")){
+                    plan = plan.substring(0,plan.lastIndexOf("今予"));
+                }
+            }
+            if(plan.contains("诊断考虑:")){
+                plan = plan.substring(0,plan.lastIndexOf("诊断考虑:"));
+            }
+            if(plan.contains("VTE风险评估")){
+                plan = plan.substring(0,plan.lastIndexOf("。")+"。".length());
+            }
+            String flag  = "/";
+            if(fir.endsWith("//")){
+                flag = "//";
+            }
+            if(plan.endsWith(flag)){
+                plan = plan.substring(0,plan.lastIndexOf(flag));
+            }
+            if(plan.endsWith(",")){
+                plan = plan.substring(0,plan.lastIndexOf(","));
+            }
+               retMap.put("诊疗计划",plan);
+           }
+        }
+
+    // 取/后
+    public static String parseString(String text){
+        if(text.contains("/")){
+            text = text.substring(text.lastIndexOf("/")+1);
+            text= parseString(text);
+        }
+        return text;
+    }
+
+    // 取/前
+    public static String parseStr(String text){
+        if(text.contains("/")){
+            text = text.substring(0,text.lastIndexOf("/"));
+            text= parseStr(text);
+        }
+        return text;
+    }
+
+    /**
+     * 抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String extractDate(String top) {
+        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        } else {
+            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日");
+            Matcher m1 = p1.matcher(top);
+            if (m1.find()) {
+                return m1.group(0);
+            }
+        }
+        return null;
+    }
+
+    public static void lastSovle(List<ThreeLevelWardDoc> threeLevelWardDocs, Map<String,String> structureMap) {
+        if(ListUtil.isNotEmpty(threeLevelWardDocs) && threeLevelWardDocs.get(0)!=null && threeLevelWardDocs.get(0)
+                .getThreeLevelWardLabel().size()>0 && threeLevelWardDocs.get(0).getThreeLevelWardLabel().get(0)!=null){
+            ThreeLevelWardLabel threeLevelWardLabel = threeLevelWardDocs.get(0).getThreeLevelWardLabel().get(0);
+            String doctorAdviceRecord = threeLevelWardLabel.getDoctorAdviceRecord();
+            if(StringUtil.isNotEmpty(doctorAdviceRecord)){
+                structureMap.put("医嘱内容",doctorAdviceRecord);
+            }
+        }
+    }
+}

+ 214 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/TransferRecordTran.java

@@ -0,0 +1,214 @@
+package com.lantone.structure.facade.tran;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.facade.tran.util.CommonAnalysisUtil;
+import com.lantone.structure.model.doc.transferrecord.TransferRecordDoc;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description:转科记录
+ * @author: cy
+ * @time: 2021/3/01 16:50
+ */
+@Slf4j
+public class TransferRecordTran extends TargetTran {
+    @Override
+    public Map<String, String> convert(String text) {
+        TransferRecordDoc transferRecordDocs = new TransferRecordDoc();
+        transferRecordDocs.setText(text);
+        inputInfo.setTransferRecordDocs(transferRecordDocs);
+        Map<String, String> structureMap = cutWord(text);
+        Map<String, String> retMap = new HashMap<String, String>();
+        transferRecordContrast(inputInfo.getTransferRecordDocs(), structureMap);
+        mapKeyContrastCommon(structureMap,stagesContrasts,retMap);
+        return retMap;
+    }
+
+    private Map<String, String> cutWord(String text) {
+        Map<String, String> sourceMap = Maps.newHashMap();
+        List<String> titles = CommonAnalysisUtil.sortTitles(
+                Lists.newArrayList("转出日期","转出科室","转入科室","入院情况","简要病情","入院诊断","诊疗经过","转科理由", "目前情况","目前诊断", "转入诊断","转入诊疗计划","下一步治疗方案","转科目的及其注意事项","医生签名","签名时间","患者或代理人签名","签名时间"),
+                text
+        );
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+        if(sourceMap.containsKey("入院诊断") ||sourceMap.containsKey("目前诊断") ||sourceMap.containsKey("转入诊断")
+                ||sourceMap.containsKey("签名时间") ||sourceMap.containsKey("患者或代理人签名")){
+            sourceMap.remove("入院诊断");
+            sourceMap.remove("目前诊断");
+            sourceMap.remove("转入诊断");
+            sourceMap.remove("签名时间");
+            sourceMap.remove("患者或代理人签名");
+        }
+        return sourceMap;
+    }
+
+
+    private List<String> stagesContrasts = Lists.newArrayList(
+            "简要病情=入院情况",
+            "诊疗经过=诊疗过程描述",
+            "转科理由=转科目的",
+            "转科目的及其注意事项=转科目的",
+            "转科目的及其注意事项=注意事项",
+            "防范措施=注意事项",
+            "防范措施=手术要点",
+            "医生签名=转出医师签名",
+            "下一步治疗方案=转入诊疗计划"
+    );
+
+    public void transferRecordContrast (TransferRecordDoc transferRecordDocs,Map<String, String> retMap) {
+        //转入日期时间取第一时间
+        String text = transferRecordDocs.getText();
+        String fileName = "转入记录";
+        if(text.contains("转科记录")){
+            fileName = "转科记录";
+        }
+        String[] split = text.split(fileName);
+        String fir = split[0]+fileName;
+        String planText = "";
+        if(text.contains("转入诊疗计划:")){
+            planText = text.substring( text.indexOf("转入诊疗计划:"));
+        }
+        if(text.contains("下一步治疗方案:")){
+            planText = text.substring( text.indexOf("下一步治疗方案:"));
+        }
+
+        if(!(text.contains("简要病情") || text.contains("入院情况"))){
+            if(text.contains("入院诊断") && (StringUtil.isEmpty(retMap.get("入院情况")) || StringUtil.isEmpty(
+                    retMap.get("简要病情")))){
+                String ret = text.substring( text.indexOf(fir)+fir.length(),text.lastIndexOf("入院诊断"));
+                retMap.put("入院情况",ret);
+            }
+        }
+
+        if(fir.contains("转入记录")){
+            String date = extractDate(fir);
+            if(StringUtil.isNotEmpty(date)){
+                retMap.put("转入日期时间",date);
+            }
+        }
+        if(StringUtil.isNotEmpty(retMap.get("医生签名"))){
+            String signName = retMap.get("医生签名");
+            if(signName.contains("签名时间")){
+                retMap.remove("医生签名");
+                signName = signName.substring(0, signName.lastIndexOf("签名时间"));
+                if(StringUtil.isNotEmpty(signName)){
+                    retMap.put("医生签名",signName);
+                }
+            }
+        }
+
+        if(fir.contains("转科记录")){
+            if(StringUtil.isNotEmpty(retMap.get("转出日期"))){
+                 fir = retMap.get("转出日期");
+                String date = extractDate(fir);
+            if(StringUtil.isNotEmpty(date)){
+                retMap.put("转出日期时间",date);
+                retMap.remove("转出日期");
+            }
+            }
+        }
+
+        String innerSignName = parseString(planText);
+        if(StringUtil.isNotEmpty(innerSignName.trim()) && planText.contains("/")){
+            retMap.put("转入医师签名",innerSignName.trim());
+        }
+
+        if(text.contains("转入诊疗计划:")){
+            String inFir = text.substring(text.indexOf("转入诊疗计划:") + 7);
+            String innerPlanRet = inFir.split("\n")[0];
+            if(innerPlanRet.contains("/")){
+                innerPlanRet = parseStr(innerPlanRet);
+            }
+            retMap.put("转入诊疗计划",innerPlanRet);
+        }
+
+        if(text.contains("下一步治疗方案:") && StringUtil.isEmpty(retMap.get("转入诊疗计划"))){
+            String  plan = text.substring( text.indexOf("下一步治疗方案:")+"下一步治疗方案:".length());
+            String planRet = plan.split("\n")[0];
+            if(planRet.contains("/")){
+                planRet = parseStr(planRet);
+            }
+            retMap.put("下一步治疗方案",planRet);
+        }
+
+        if(StringUtil.isNotEmpty(retMap.get("医生签名"))){
+            String innerPlan = retMap.get("医生签名").trim();
+            if(StringUtil.isEmpty(innerPlan)){
+                retMap.remove("医生签名");
+            }
+        }
+    }
+
+    public static void mapKeyContrastCommon(Map sourceMap, List<String> keyContrasts, Map<String, String> retMap) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        String[] arry = null;
+        String sourceKey = null, targetKey;
+        Set<String> removeKey = new HashSet<>();
+        for (String keyContrast : keyContrasts) {
+            arry = keyContrast.split("=");
+            sourceKey = arry[0];
+            if (arry.length == 1) {
+                targetKey = arry[0];
+            } else {
+                targetKey = arry[1];
+            }
+            if (StringUtil.isNotBlank(sourceMap_.get(sourceKey))
+                    && (!retMap.containsKey(targetKey) || StringUtil.isBlank(retMap.get(targetKey)))) {
+                retMap.put(targetKey, sourceMap_.get(sourceKey));
+            }
+            removeKey.add(sourceKey);
+        }
+        Set<String> keySet = retMap.keySet();
+        for (String key : sourceMap_.keySet()) {
+            if (!keySet.contains(key) && !removeKey.contains(key)) { // 如果之前已放过key就不用放了
+                retMap.put(key, sourceMap_.get(key));
+            }
+        }
+    }
+
+
+    /**
+     * 抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String extractDate(String top) {
+        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        } else {
+            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日");
+            Matcher m1 = p1.matcher(top);
+            if (m1.find()) {
+                return m1.group(0);
+            }
+        }
+        return null;
+    }
+
+    public static String parseString(String text){
+        if(text.contains("/")){
+            text = text.substring(text.lastIndexOf("/")+1);
+            text= parseString(text);
+        }
+        return text;
+    }
+
+    // 取/前
+    public static String parseStr(String text){
+        if(text.contains("/")){
+            text = text.substring(0,text.lastIndexOf("/"));
+            text= parseStr(text);
+        }
+        return text;
+    }
+}

+ 295 - 0
structure-center/src/main/java/com/lantone/structure/facade/tran/util/CommonAnalysisUtil.java

@@ -0,0 +1,295 @@
+package com.lantone.structure.facade.tran.util;
+
+import com.google.common.collect.Lists;
+import com.lantone.common.util.StringUtil;
+import com.lantone.structure.util.MapUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description :
+ * @Author : HUJING
+ * @Date: 2020/9/10 13:48
+ */
+@Slf4j
+public class CommonAnalysisUtil {
+
+
+    public static void html2StructureMap(List<String> titles, String htmlText, Map<String, String> structureMap) {
+        List<String> sortTitles = sortTitles(titles, htmlText);
+        cutByTitles(htmlText, sortTitles, 0, structureMap);
+    }
+
+
+    /**
+     * 将list中html内容转换成structureMap
+     *
+     * @param titles       文书各标题
+     * @param htmlText     html内容以行的形式存储list
+     * @param structureMap
+     * @return
+     */
+    public void html2StructureMap(List<String> titles, List<String> htmlText, Map<String, String> structureMap) {
+        StringBuffer sb = new StringBuffer();
+        for (String line : htmlText) {
+            String text = line.replaceAll("[   ]", " ");
+            if (text.length() == 0) {
+                continue;
+            }
+            sb.append(text).append("\n");
+        }
+        html2StructureMap(titles, sb.toString(), structureMap);
+    }
+
+    /**
+     * 根据文书各标题截取相应文本,存入structmap中
+     *
+     * @param line         原始文本
+     * @param titles       文书各标题
+     * @param depth        递归深度,也就是titles取值时的下标值
+     * @param structureMap 存储结构化数据
+     */
+    public static void cutByTitles(String line, List<String> titles, int depth, Map<String, String> structureMap) {
+        if (depth > titles.size() || titles.size() == 0) {
+            return;
+        }
+        String beforeTitle = null, title = null, newTitle = null, value = null;
+        beforeTitle = StringUtil.removeBlank(titles.get(Math.max(depth - 1, 0)));
+        title = titles.get(Math.min(depth, titles.size() - 1));
+        if (depth == titles.size()) {
+            /*if (line.contains("\n")) {
+                line = line.split("\n")[0];
+            }
+            */
+            value = line.replace("\n", "");
+            if (StringUtil.isBlank(structureMap.get(beforeTitle))) {
+                structureMap.put(beforeTitle, StringUtil.trim(value));
+            }
+            return;
+        }
+        if (line.contains(title + ":") || line.contains(title + ":")) {
+            if (line.contains(title + ":")) {
+                newTitle = title + ":";
+            } else {
+                newTitle = title + ":";
+            }
+            if (depth > 0) {
+                value = line.substring(0, line.indexOf(newTitle));
+                if (StringUtil.isBlank(structureMap.get(beforeTitle))) {
+                    structureMap.put(beforeTitle, StringUtil.trim(value).replace("\n", ""));
+                }
+            }
+            line = line.substring(line.indexOf(newTitle) + newTitle.length());
+            depth++;
+        } else {
+            titles.remove(depth);
+        }
+        cutByTitles(line, titles, depth, structureMap);
+    }
+
+    /**
+     * 将title根据在文本中的位置排序
+     *
+     * @param titles
+     * @param content
+     * @return
+     */
+    public static List<String> sortTitles(List<String> titles, String content) {
+        Map<Integer, String> titleIndex = new TreeMap<>();
+        int index, index_1, index_2;
+        for (String title : titles) {
+            index_1 = content.indexOf(title + ":");
+            index_2 = content.indexOf(title + ":");
+            index = Math.max(index_1, index_2);
+            if (index != -1) {
+                titleIndex.put(index, title);
+                StringBuffer sb = new StringBuffer(title.length());
+                for (int i = 0; i < title.length(); i++) {
+                    sb.append('*');
+                }
+                content = content.substring(0, index) + sb.toString() + content.substring(index + title.length() + 1);
+                //                content = content.substring(0, index) + content.substring(index + title.length() + 1);
+            }
+        }
+        titles = Lists.newArrayList(titleIndex.values());
+        return titles;
+    }
+
+    /**
+     * 标题没有冒号版本
+     */
+    public static void html2StructureMapNoColon(List<String> titles, String htmlText, Map<String, String> structureMap) {
+        List<String> sortTitlesNoColon = sortTitlesNoColon(titles, htmlText);
+        cutByTitlesNoColon(htmlText, sortTitlesNoColon, 0, structureMap);
+    }
+
+    /**
+     * 标题没有冒号版本
+     */
+    public static void cutByTitlesNoColon(String line, List<String> titles, int depth, Map<String, String> structureMap) {
+        if (depth > titles.size() || titles.size() == 0) {
+            return;
+        }
+        String beforeTitle = null, title = null, newTitle = null, value = null;
+        beforeTitle = StringUtil.removeBlank(titles.get(Math.max(depth - 1, 0)));
+        title = titles.get(Math.min(depth, titles.size() - 1));
+        if (depth == titles.size()) {
+            value = line;
+            value = value.trim();
+            if (value.startsWith(":") || value.startsWith(":")) {
+                value = value.replaceFirst("[::]", "");
+            }
+            if (StringUtil.isBlank(structureMap.get(beforeTitle))) {
+                structureMap.put(beforeTitle, StringUtil.trim(value).replace("\n", ""));
+            }
+            return;
+        }
+        if (line.contains(title)) {
+            newTitle = title;
+            if (depth > 0) {
+                value = line.substring(0, line.indexOf(newTitle));
+                value = value.trim();
+                if (value.startsWith(":") || value.startsWith(":")) {
+                    value = value.replaceFirst("[::]", "");
+                }
+                if (StringUtil.isBlank(structureMap.get(beforeTitle))) {
+                    structureMap.put(beforeTitle, StringUtil.trim(value).replace("\n", ""));
+                }
+            }
+            line = line.substring(line.indexOf(newTitle) + newTitle.length());
+            depth++;
+        } else {
+            titles.remove(depth);
+        }
+        cutByTitlesNoColon(line, titles, depth, structureMap);
+    }
+
+    /**
+     * 标题没有冒号版本
+     */
+    public static List<String> sortTitlesNoColon(List<String> titles, String content) {
+        Map<Integer, String> titleIndex = new TreeMap<>();
+        int index;
+        for (String title : titles) {
+            index = content.indexOf(title);
+            if (index != -1) {
+                titleIndex.put(index, title);
+                content = content.replace(title, "");
+            }
+        }
+        titles = Lists.newArrayList(titleIndex.values());
+        return titles;
+    }
+
+    /**
+     * 抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String extractDate(String top) {
+        Pattern pattern = Pattern.compile("[0-9]{4}[-][0-9]{1,2}[-][0-9]{1,2}([ ][0-9]{1,2}[:][0-9]{1,2}([:][0-9]{1,2})?)?");
+        Matcher matcher = pattern.matcher(top);
+        if (matcher.find()) {
+            return matcher.group(0);
+        } else {
+            Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日[0-9]+时[0-9]+分");
+            Matcher m1 = p1.matcher(top);
+            if (m1.find()) {
+                return m1.group(0);
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * 若内容中是包含选择框(会诊类型:     急会诊       普通会诊         请院外会诊),特殊处理
+     *
+     * @param structureMap
+     */
+    public static void processType(Map<String, String> structureMap, String title) {
+        if (structureMap.containsKey(title)) {
+            String type = structureMap.get(title);
+            String[] types = type.split(" ");
+            for (String t : types) {
+                if (t.contains("\uF0FE")) {
+                    structureMap.put(title, t.replace("\uF0FE", ""));
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * 若list中其中一个元素包含之后第二个、第三个元素的文本,则把这个元素删除
+     *
+     * @param htmlList
+     */
+    public static void removeRepeat(List<String> htmlList) {
+        List<Integer> index = Lists.newArrayList();
+        if (htmlList.size() < 3) {
+            return;
+        }
+        String str1 = null, str2 = null, str3 = null;
+        for (int i = 0; i < htmlList.size() - 2; i++) {
+            str1 = htmlList.get(i);
+            str2 = htmlList.get(i + 1);
+            str3 = htmlList.get(i + 2);
+            if (str1.contains(str2) && str1.contains(str3)) {
+                index.add(i);
+            }
+        }
+
+        for (int i = 0; i < index.size(); i++) {
+            htmlList.remove(index.get(i) - i);
+        }
+    }
+
+    public static void makeEmpty(Map<String, String> structureMap, String... key) {
+        for (String k : key) {
+            if (structureMap.containsKey(k)) {
+                structureMap.put(k, "");
+            }
+        }
+    }
+
+
+    public static void removeKey(Map<String, String> sourceMap, String... args) {
+        for (String dateStr : args) {
+            if (sourceMap.containsKey(dateStr)) {
+                sourceMap.remove(dateStr);
+            }
+        }
+    }
+
+    public static void mapKeyContrastCommon(Map sourceMap, List<String> keyContrasts, Map<String, String> retMap) {
+        Map<String, String> sourceMap_ = MapUtil.copyMap(sourceMap);
+        String[] arry = null;
+        String sourceKey = null, targetKey;
+        Set<String> removeKey = new HashSet<>();
+        for (String keyContrast : keyContrasts) {
+            arry = keyContrast.split("=");
+            sourceKey = arry[0];
+            if (arry.length == 1) {
+                targetKey = arry[0];
+            } else {
+                targetKey = arry[1];
+            }
+            if (sourceMap_.get(sourceKey) != null
+                    && (!retMap.containsKey(targetKey) || StringUtil.isBlank(retMap.get(targetKey)))) {
+                retMap.put(targetKey, sourceMap_.get(sourceKey));
+            }
+            removeKey.add(sourceKey);
+        }
+        Set<String> keySet = retMap.keySet();
+        for (String key : sourceMap_.keySet()) {
+            if (!keySet.contains(key) && !removeKey.contains(key)) { // 如果之前已放过key就不用放了
+                retMap.put(key, sourceMap_.get(key));
+            }
+        }
+    }
+}

+ 11 - 0
structure-center/src/main/java/com/lantone/structure/model/Content.java

@@ -250,6 +250,17 @@ public class Content {
     public static final String stayLength = "住院天数";//出院小结用
 
     public static final String timestamp = "timestamp";
+    public static final String  preoperativeDiscussion = "过敏、禁忌症";
+    public static final String  surgicalSite = "手术目标部位";
+    public static final String  pastLabel = "既往史";
+    public static final String  familyLabel = "家族史";
+    public static final String  doctorAdviceRecord = "医嘱内容";
+    public static final String bloodRecord = "输血记录";
+    public static final String stagesSummary = "阶段小结";
+    public static final String rescue = "抢救记录";
+    public static final String wardRecord = "上级医师查房记录";
+    public static final String caesareanSection = "剖宫产手术";
+    public static final String operationRecord = "一般手术记录";
 
     public static String[] dateFormats = {
             "yyyy年MM月dd日HH时mm分",

+ 2 - 0
structure-center/src/main/java/com/lantone/structure/model/InputInfo.java

@@ -93,6 +93,8 @@ public class InputInfo {
     private List<PathologyShipDoc> pathologyShipDocs = new ArrayList<>();
     //诊疗合理性
     private List<ReasonableDiagnosisDoc> reasonableDiagnosisDocs = new ArrayList<>();
+    //剖宫产手术
+    private List<CaesareanSectionDoc> caesareanSectionDocs = new ArrayList<>();
     //日常病程录
     private List<DailyCourseRecordDoc> dailyCourseRecordDocs = Lists.newArrayList();
     //住院病历信息

+ 16 - 0
structure-center/src/main/java/com/lantone/structure/model/doc/CaesareanSectionDoc.java

@@ -0,0 +1,16 @@
+package com.lantone.structure.model.doc;
+
+import com.lantone.structure.model.label.CaesareanSectionLabel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @Description: 剖宫产手术
+ * @author: wsy
+ * @time: 2021/1/27 9:45
+ */
+@Getter
+@Setter
+public class CaesareanSectionDoc extends ModelDoc {
+    private CaesareanSectionLabel caesareanSectionLabel;
+}

+ 2 - 0
structure-center/src/main/java/com/lantone/structure/model/doc/ClinicalBloodDoc.java

@@ -1,5 +1,6 @@
 package com.lantone.structure.model.doc;
 
+import com.lantone.structure.model.label.ClinicalBloodLabel;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -12,4 +13,5 @@ import lombok.Setter;
 @Getter
 @Setter
 public class ClinicalBloodDoc extends ModelDoc {
+    private ClinicalBloodLabel clinicalBloodLabel;
 }

+ 2 - 0
structure-center/src/main/java/com/lantone/structure/model/doc/DailyCourseRecordDoc.java

@@ -1,5 +1,6 @@
 package com.lantone.structure.model.doc;
 
+import com.lantone.structure.model.label.DailyCourseRecordLabel;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -12,4 +13,5 @@ import lombok.Setter;
 @Setter
 @Getter
 public class DailyCourseRecordDoc extends ModelDoc {
+    DailyCourseRecordLabel dailyCourseRecordLabel;
 }

+ 2 - 0
structure-center/src/main/java/com/lantone/structure/model/doc/RescueDoc.java

@@ -1,5 +1,6 @@
 package com.lantone.structure.model.doc;
 
+import com.lantone.structure.model.label.RescueLabel;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -12,4 +13,5 @@ import lombok.Setter;
 @Setter
 @Getter
 public class RescueDoc extends ModelDoc {
+    private RescueLabel rescueLabel;
 }

+ 2 - 0
structure-center/src/main/java/com/lantone/structure/model/doc/StagesSummaryDoc.java

@@ -1,5 +1,6 @@
 package com.lantone.structure.model.doc;
 
+import com.lantone.structure.model.label.StagesSummaryLabel;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -11,4 +12,5 @@ import lombok.Setter;
 @Getter
 @Setter
 public class StagesSummaryDoc extends ModelDoc {
+    private StagesSummaryLabel stagesSummaryLabel;
 }

+ 17 - 0
structure-center/src/main/java/com/lantone/structure/model/doc/WardRecordDoc.java

@@ -0,0 +1,17 @@
+package com.lantone.structure.model.doc;
+
+import com.lantone.structure.model.label.ThreeLevelWardLabel;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : WardRecordDoc
+ * @Description : 查房记录
+ * @Author : cy
+ * @Date: 2021-02-20 15:43
+ */
+@Getter
+@Setter
+public class WardRecordDoc extends ModelDoc {
+    private ThreeLevelWardLabel threeLevelWardLabel;
+}

+ 3 - 0
structure-center/src/main/java/com/lantone/structure/model/doc/operation/PreoperativeDiscussionDoc.java

@@ -1,6 +1,7 @@
 package com.lantone.structure.model.doc.operation;
 
 import com.lantone.structure.model.doc.ModelDoc;
+import com.lantone.structure.model.label.PreoperativeDiscussionLabel;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -14,4 +15,6 @@ import lombok.Setter;
 @Setter
 public class PreoperativeDiscussionDoc extends ModelDoc {
     private String operationName;
+    private PreoperativeDiscussionLabel preoperativeDiscussionLabel;
+
 }

+ 17 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/AmnioticFluid.java

@@ -0,0 +1,17 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : AmnioticFluid
+ * @Description : 羊水
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class AmnioticFluid extends General {
+    private AmnioticFluidCharacter amnioticFluidCharacter;  //羊水性状
+    private Quantity quantity;  //量
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/AmnioticFluidCharacter.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : AmnioticFluidCharacter
+ * @Description : 羊水性状
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class AmnioticFluidCharacter extends General {
+}

+ 16 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/Amount.java

@@ -0,0 +1,16 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : Amount
+ * @Description : 输血量
+ * @Author : wsy
+ * @Date: 2021-01-20 10:09
+ */
+@Setter
+@Getter
+public class Amount extends General {
+    private MeasurementUnit measurementUnit;//输血量计量单位
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/AnesthesiaMethod.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : AnesthesiaMethod
+ * @Description : 麻醉方法
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class AnesthesiaMethod extends General {
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/AnestheticEffect.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : AnestheticEffect
+ * @Description : 麻醉效果
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class AnestheticEffect extends General {
+}

+ 16 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/ApgarScore.java

@@ -0,0 +1,16 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : ApgarScore
+ * @Description : Apgar评分
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class ApgarScore extends General {
+    private Score score;      //分数
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/AuxiliaryQuantitative.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : AuxiliaryQuantitative
+ * @Description : 辅检定量结果
+ * @Author : wsy
+ * @Date: 2021-01-25 20:19
+ */
+@Setter
+@Getter
+public class AuxiliaryQuantitative extends General {
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/AuxiliaryResult.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : AuxiliaryResult
+ * @Description : 辅检结果
+ * @Author : wsy
+ * @Date: 2021-01-25 19:15
+ */
+@Setter
+@Getter
+public class AuxiliaryResult extends General {
+}

+ 20 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/AuxiliaryTest.java

@@ -0,0 +1,20 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ClassName : AuxiliaryTest
+ * @Description : 辅检名称
+ * @Author : wsy
+ * @Date: 2021-01-25 19:15
+ */
+@Setter
+@Getter
+public class AuxiliaryTest extends General {
+    private List<AuxiliaryResult> auxiliaryResult = new ArrayList<>();  //辅检结果
+    private AuxiliaryQuantitative auxiliaryQuantitative;                //辅检定量结果
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/BleedQuantity.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : BleedQuantity
+ * @Description : 出血量(mL)
+ * @Author : wsy
+ * @Date: 2021-03-15 10:09
+ */
+@Setter
+@Getter
+public class BleedQuantity extends General {
+}

+ 22 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/Blood.java

@@ -0,0 +1,22 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 输血记录
+ */
+@Setter
+@Getter
+public class Blood extends General {
+    private List<Indication> indication = new ArrayList<>();    //输血指征
+    private Type type;                                          //输血类型
+    private Reason reason;                                      //输血原因
+    private StartTime startTime;                                //输血开始时间
+    private EndTime endTime;                                    //输血结束时间
+    private List<ResponseType> responseType = new ArrayList<>();//输血反应类型
+    private Frequency frequency;                                //输血次数
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/BloodPressure.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : BloodPressure
+ * @Description : 血压情况
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class BloodPressure extends General {
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/BloodQuantity.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : BloodQuantity
+ * @Description : 输血量(mL)
+ * @Author : wsy
+ * @Date: 2021-03-15 10:09
+ */
+@Setter
+@Getter
+public class BloodQuantity extends General {
+}

+ 17 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/CaputSuccedaneum.java

@@ -0,0 +1,17 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : CaputSuccedaneum
+ * @Description : 产瘤
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class CaputSuccedaneum extends General {
+    private Volume volume;                                  //体积
+    private CaputSuccedaneumPart caputSuccedaneumPart;      //产瘤部位
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/CaputSuccedaneumPart.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : CaputSuccedaneumPart
+ * @Description : 产瘤部位
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class CaputSuccedaneumPart extends General {
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/ChildbirthCondition.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : ChildbirthCondition
+ * @Description : 胎盘娩出情况
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class ChildbirthCondition extends General {
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/ChildbirthWay.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : ChildbirthWay
+ * @Description : 胎儿娩出方式
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class ChildbirthWay extends General {
+}

+ 17 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/Condition.java

@@ -0,0 +1,17 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : Condition
+ * @Description : 抢救病情
+ * @Author : wsy
+ * @Date: 2021-01-25 19:15
+ */
+
+@Setter
+@Getter
+public class Condition extends General {
+    private PD pd; //时间
+}

+ 17 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/CordAroundBody.java

@@ -0,0 +1,17 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : CordAroundBody
+ * @Description : 脐带绕身
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class CordAroundBody extends General {
+    private Negative negative;              //否定
+    private CylinderNumber cylinderNumber;  //圈数
+}

+ 17 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/CordAroundNeck.java

@@ -0,0 +1,17 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : CordAroundNeck
+ * @Description : 脐带绕颈
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class CordAroundNeck extends General {
+    private Negative negative;              //否定
+    private CylinderNumber cylinderNumber;  //圈数
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/Count.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : Count
+ * @Description : 操作次数
+ * @Author : wsy
+ * @Date: 2021-01-25 19:15
+ */
+@Setter
+@Getter
+public class Count extends General {
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/CylinderNumber.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : CylinderNumber
+ * @Description : 圈数
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class CylinderNumber extends General {
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/Diagnosis.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : Diagnosis
+ * @Description : 疾病诊断名称
+ * @Author : wsy
+ * @Date: 2021-01-25 19:15
+ */
+@Setter
+@Getter
+public class Diagnosis extends General {
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/DrainageMaterialsAmount.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : DrainageMaterialsAmount
+ * @Description : 引流材料数目
+ * @Author : wsy
+ * @Date: 2021-03-15 10:09
+ */
+@Setter
+@Getter
+public class DrainageMaterialsAmount extends General {
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/DrainageMaterialsName.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : DrainageMaterialsName
+ * @Description : 引流材料名称
+ * @Author : wsy
+ * @Date: 2021-03-15 10:09
+ */
+@Setter
+@Getter
+public class DrainageMaterialsName extends General {
+}

+ 1 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/Drug.java

@@ -17,4 +17,5 @@ public class Drug extends General {
     private Frequency frequency;            //频率
     private Stop stop;                      //停用
     private ReasonsForAntibiotic reasonsForAntibiotic;  //抗生素使用原因
+    private PD pd;                          //时间
 }

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/DuringDrugs.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : DuringDrugs
+ * @Description : 术中用药
+ * @Author : wsy
+ * @Date: 2021-03-15 10:09
+ */
+@Setter
+@Getter
+public class DuringDrugs extends General {
+}

+ 16 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/EndTime.java

@@ -0,0 +1,16 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : EndTime
+ * @Description : 输血结束时间
+ * @Author : wsy
+ * @Date: 2021-01-20 10:09
+ */
+@Setter
+@Getter
+public class EndTime extends General {
+    
+}

+ 15 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/Extent.java

@@ -0,0 +1,15 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : Extent
+ * @Description : 长度
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class Extent extends General {
+}

+ 16 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/FluidInfusion.java

@@ -0,0 +1,16 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : FluidInfusion
+ * @Description : 补液
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class FluidInfusion extends General {
+    private Quantity quantity;  //量
+}

+ 16 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/Hemorrhage.java

@@ -0,0 +1,16 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : Hemorrhage
+ * @Description : 术中出血
+ * @Author : wsy
+ * @Date: 2021-01-27 11:24
+ */
+@Setter
+@Getter
+public class Hemorrhage extends General {
+    private Quantity quantity;  //量
+}

+ 16 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/Indication.java

@@ -0,0 +1,16 @@
+package com.lantone.structure.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @ClassName : Indication
+ * @Description : 输血指征
+ * @Author : wsy
+ * @Date: 2021-01-20 10:09
+ */
+@Setter
+@Getter
+public class Indication extends General {
+    
+}

+ 0 - 0
structure-center/src/main/java/com/lantone/structure/model/entity/Intervention.java


Някои файлове не бяха показани, защото твърде много файлове са промени