Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/hb/beilun' into hb/debug

# Conflicts:
#	dbanaly/src/main/resources/application-local.yml
wangsy 3 gadi atpakaļ
vecāks
revīzija
56c2bf57a4
100 mainītis faili ar 62213 papildinājumiem un 80 dzēšanām
  1. 152 0
      dbanaly/src/main/java/com/lantone/qc/dbanaly/facade/qdnzyy/QdnzyyXmlUtil.java
  2. 4 5
      dbanaly/src/main/resources/application-dev.yml
  3. 6 6
      dbanaly/src/main/resources/application-local.yml
  4. 16 0
      dbanaly/src/main/resources/rebel.xml
  5. 1 1
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH0009.java
  6. 5 5
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH02966.java
  7. 2 2
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/firstpagerecord/FIRP0162.java
  8. 50 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/firstpagerecord/FIRP03229.java
  9. 2 2
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/changshaxy/behospitalized/BEH02966.java
  10. 1 11
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/clinicalblood/CLI0571.java
  11. 149 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/preoperativediscussion/PRE0328.java
  12. 13 14
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/threelevelward/THR0144.java
  13. 16 7
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/threelevelward/THR02900.java
  14. 4 4
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ninghaifuyou/behospitalized/BEH02966.java
  15. 68 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/firstpagerecord/FIRP0190.java
  16. 2 2
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/leavehospital/LEA02968.java
  17. 4 4
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR02967.java
  18. 1 1
      kernel/src/main/resources/bootstrap.yml
  19. 84 0
      kernel/src/main/resources/cache/38/concept_clinic_bodypart_properties.dict
  20. 25358 0
      kernel/src/main/resources/cache/38/concept_diag_properties.dict
  21. 25358 0
      kernel/src/main/resources/cache/38/hospital_diag_info.dict
  22. 3123 0
      kernel/src/main/resources/cache/38/hospital_doctor_info.dict
  23. 16 0
      kernel/src/main/resources/rebel.xml
  24. 16 0
      nlp/src/main/java/rebel.xml
  25. 16 0
      public/src/main/java/rebel.xml
  26. 16 0
      security/src/main/java/rebel.xml
  27. 7 16
      trans/src/main/java/com/lantone/qc/trans/beilun/util/BeiLunInvasiveOperationHtmlAnalysis.java
  28. 52 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/ADLGradeDocTrans.java
  29. 38 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/AnesthesiaRecordDocTrans.java
  30. 74 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/BeHospitalizedDocTrans.java
  31. 73 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/ClinicBloodEffectDocTrans.java
  32. 77 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/ClinicalBloodDocTrans.java
  33. 278 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/ConsultationDocTrans.java
  34. 36 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/CrisisInfoDocTrans.java
  35. 72 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/CrisisValueReportDocTrans.java
  36. 79 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/CriticallyIllNoticeDocTrans.java
  37. 61 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DeathCaseDiscussDocTrans.java
  38. 65 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DeathRecordDocTrans.java
  39. 93 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DifficultCaseDiscussDocTrans.java
  40. 36 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DoctorAdviceDocTrans.java
  41. 72 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DutyShiftSystemDocTrans.java
  42. 83 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/FirstCourseRecordDocTrans.java
  43. 54 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/FirstPageRecordDocTrans.java
  44. 287 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/HangzhoufubaoDocTrans.java
  45. 75 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/InvasiveOperationDocTrans.java
  46. 69 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/LeaveHospitalDocTrans.java
  47. 36 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/LisDocTrans.java
  48. 26 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/MedicalRecordInfoDocTrans.java
  49. 396 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/OperationDocTrans.java
  50. 40 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/OutDepDocTrans.java
  51. 36 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/PacsDocTrans.java
  52. 73 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/RescueDocTrans.java
  53. 73 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/StagesSummaryDocTrans.java
  54. 368 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/ThreeLevelWardDocTrans.java
  55. 305 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/TransferRecordDocTrans.java
  56. 52 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/VTEGradeDocTrans.java
  57. 41 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ADLGradeHtmlAnalysis.java
  58. 142 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/BeHospitalizedHtmlAnalysis.java
  59. 55 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ClinicBloodEffectHtmlAnalysis.java
  60. 57 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ClinicalBloodHtmlAnalysis.java
  61. 120 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ConsultationHtmlAnalysis.java
  62. 56 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ConsultationRecordHtmlAnalysis.java
  63. 51 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/CrisisValueReportHtmlAnalysis.java
  64. 70 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/CriticallyIllNoticeHtmlAnalysis.java
  65. 56 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/DeathCaseDiscussHtmlAnalysis.java
  66. 51 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/DeathRecordHtmlAnalysis.java
  67. 87 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/DifficultCaseDiscussHtmlAnalysis.java
  68. 56 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/DutyShiftSystemHtmlAnalysis.java
  69. 78 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/FirstCourseRecordHtmlAnalysis.java
  70. 641 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/HangzhoufubaoCommonAnalysisUtil.java
  71. 56 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/HangzhoufubaoFirstCourseRecordHtmlAnalysis.java
  72. 137 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/HangzhoufubaoTranUtils.java
  73. 14 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/HtmlAnalysis.java
  74. 243 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/HtmlAnalysisUtil.java
  75. 60 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/LeaveHospitalHtmlAnalysis.java
  76. 101 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/OperationHtmlAnalysis.java
  77. 80 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/OperationRecordHtmlAnalysis.java
  78. 87 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/PreoperativeHtmlAnalysis.java
  79. 54 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/RescueHtmlAnalysis.java
  80. 56 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/StagesSummaryHtmlAnalysis.java
  81. 133 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ThreeLevelWardHtmlAnalysis.java
  82. 53 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/TransferIntoHtmlAnalysis.java
  83. 61 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/TransferOutHtmlAnalysis.java
  84. 41 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/VTEGradeHtmlAnalysis.java
  85. 12 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ez/EzAnalysis.java
  86. 41 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ez/EzClinicalBloodAnalysis.java
  87. 21 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ez/EzDeathCaseDiscussAnalysis.java
  88. 40 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ez/EzOperationRecordAnalysis.java
  89. 337 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ez/EzXmlAnalysis.java
  90. 143 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ez/util/EzXmlUtil.java
  91. 292 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/hangzhoufubaoHtmlAnalysisUtil.java
  92. 420 0
      trans/src/main/java/com/lantone/qc/trans/qdnzyy/BeHospitalizedDocTrans.java
  93. 58 0
      trans/src/main/java/com/lantone/qc/trans/qdnzyy/ClinicBloodEffectDocTrans.java
  94. 76 0
      trans/src/main/java/com/lantone/qc/trans/qdnzyy/ClinicalBloodDocTrans.java
  95. 242 0
      trans/src/main/java/com/lantone/qc/trans/qdnzyy/ConsultationDocTrans.java
  96. 54 0
      trans/src/main/java/com/lantone/qc/trans/qdnzyy/CrisisValueReportDocTrans.java
  97. 58 0
      trans/src/main/java/com/lantone/qc/trans/qdnzyy/CriticallyIllNoticeDocTrans.java
  98. 59 0
      trans/src/main/java/com/lantone/qc/trans/qdnzyy/DeathCaseDiscussDocTrans.java
  99. 54 0
      trans/src/main/java/com/lantone/qc/trans/qdnzyy/DeathRecordDocTrans.java
  100. 0 0
      trans/src/main/java/com/lantone/qc/trans/qdnzyy/DifficultCaseDiscussDocTrans.java

+ 152 - 0
dbanaly/src/main/java/com/lantone/qc/dbanaly/facade/qdnzyy/QdnzyyXmlUtil.java

@@ -0,0 +1,152 @@
+package com.lantone.qc.dbanaly.facade.qdnzyy;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.util.FileUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: xml解析工具
+ * @author: rengb
+ * @time: 2020/3/28 14:23
+ */
+@Slf4j
+public class QdnzyyXmlUtil {
+
+    public static Map<String, String> xmlToMap(String xml) {
+        Map<String, String> map = Maps.newHashMap();
+        try {
+            Document doc = DocumentHelper.parseText(xml);
+            Element root = (Element) doc.selectSingleNode("//XTextDocument/XElements/Element[@xsi:type='XTextBody']/XElements");
+            findElement(root, "XInputField").forEach(i -> {
+                xInputField(map, i, null);
+            });
+            findElement(root, "XTextTable").forEach(tableElement -> {
+                String tablePreTxt = getElementPreVal(tableElement);
+                findElement(tableElement.element("XElements"), "XTextTableRow").forEach(rowElement -> {
+                    findElement(rowElement.element("XElements"), "XTextTableCell").forEach(cellElement -> {
+                        findElement(cellElement.element("XElements"), "XInputField").forEach(xInputFieldElement -> {
+                            xInputField(map, xInputFieldElement, tablePreTxt);
+                        });
+                    });
+                });
+            });
+            Element bodyTextElement = (Element) doc.selectSingleNode("//XTextDocument/BodyText");
+            String bodyText = bodyTextElement.getText();
+            map.put("原始文本", bodyText);
+        } catch (Exception e) {
+            e.printStackTrace();
+            map.clear();
+        }
+//        map.keySet().forEach(key -> {
+//            System.out.println(key + "----" + map.get(key));
+//        });
+        return map;
+    }
+
+    public static List<Element> findElement(Element element, String attual) {
+        List<Element> ret = Lists.newArrayList();
+        ((List<Element>) (element.elements())).forEach(i -> {
+            if (StringUtil.isNotBlank(i.attributeValue("type")) && i.attributeValue("type").equals(attual)) {
+                ret.add(i);
+            }
+        });
+        return ret;
+    }
+
+    public static void xInputField(Map<String, String> map, Element xInputFieldElement, String tablePreTxt) {
+        String value = getXInputFieldValue(xInputFieldElement);
+        if (value == null) {
+            return;
+        }
+        String key = getXInputFieldKey(xInputFieldElement, tablePreTxt);
+        if (StringUtil.isNotBlank(key)) {
+            if (map.containsKey(key)) {
+                value = map.get(key) + " " + value;
+            }
+            map.put(key, value);
+        }
+    }
+
+    //获取 XInputField 的键
+    private static String getXInputFieldKey(Element xInputFieldElement, String tablePreTxt) {
+        String key = null;
+        String[] elementNames = {"Name","BackgroundText", "ToolTip" };
+        for (String elementName : elementNames) {
+            key = xInputFieldElement.elementTextTrim(elementName);
+            if (StringUtil.isNotBlank(key)) {
+                break;
+            }
+        }
+        if (StringUtil.isBlank(key)) {
+            key = getElementPreVal(xInputFieldElement);
+        }
+        if (StringUtil.isBlank(key)) {
+            key = tablePreTxt;
+        }
+        if (StringUtil.isBlank(key)) {
+            key = "病历内容";
+        }
+        return keyHandle(key);
+    }
+
+    //获取 XInputField 的值
+    private static String getXInputFieldValue(Element xInputFieldElement) {
+        String value = null;
+        Element innerValueElement = xInputFieldElement.element("InnerValue");
+        if (innerValueElement != null) {
+            value = innerValueElement.getTextTrim();
+        }
+        if (StringUtil.isBlank(value)) {
+            Element xElementsElement = xInputFieldElement.element("XElements");
+            if (xElementsElement != null) {
+                List<Element> elements = findElement(xElementsElement, "XString");
+                if (elements.size() > 0) {
+                    value = "";
+                    for (Element element : elements) {
+                        Element text = element.element("Text");
+                        if (text != null) {
+                            value += text.getTextTrim();
+                        }
+                    }
+                }
+            }
+        }
+        return value;
+    }
+
+    //获取前面文本信息作为key
+    private static String getElementPreVal(Element xInputFieldElement) {
+        String ret = "";
+        List<Element> sonElements = xInputFieldElement.getParent().elements();
+        int index = sonElements.indexOf(xInputFieldElement);
+        for (int i = index - 1; i >= 0; i--) {
+            Element sonElement = sonElements.get(i);
+            if (sonElement.attributeValue("type").equals("XTextTable") || sonElement.attributeValue("type").equals("XInputField")) {
+                break;
+            }
+            if (sonElement.attributeValue("type").equals("XString")) {
+                ret = sonElement.elementTextTrim("Text") + ret;
+            }
+        }
+        return ret;
+    }
+
+    //针对key的一些特殊处理
+    private static String keyHandle(String key) {
+        key = StringUtil.removeBlank(key).replaceAll("[::]", "");
+        return key;
+    }
+
+    public static void main(String[] args) {
+        xmlToMap(FileUtil.fileRead("C:\\Users\\Administrator\\Desktop\\义务\\jiexi\\n5.xml"));
+    }
+
+}

+ 4 - 5
dbanaly/src/main/resources/application-dev.yml

@@ -5,9 +5,9 @@ spring:
     druid:
       lantone:
         driver-class-name: com.mysql.jdbc.Driver
-        url: jdbc:mysql://192.168.2.125:3307/qc?useUnicode=true&characterEncoding=utf8&useSSL=false
+        url: jdbc:mysql://192.168.2.237:3307/qc?useUnicode=true&characterEncoding=utf8&useSSL=false
         username: root
-        password: LangT0ng@lt
+        password: lantone
         initial-size: 8
         min-idle: 1
         max-active: 20
@@ -24,14 +24,13 @@ spring:
         filters: stat
         connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
         use-global-data-source-stat: true
-  #redis
   redis:
     database:
       cache: 10 # cache索引
       token: 10 # Token索引
-    host: 192.168.2.125  #Redis服务器地址
+    host: 127.0.0.1  #Redis服务器地址
     port: 6379 # Redis服务器连接端口(本地环境端口6378,其他环境端口是6379)
-    password: lantone # Redis服务器连接密码(默认为空)
+    password:  # Redis服务器连接密码(默认为空)
     lettuce:
       pool:
         max-active: 8 # 连接池最大连接数(使用负值表示没有限制)

+ 6 - 6
dbanaly/src/main/resources/application-local.yml

@@ -5,7 +5,7 @@ spring:
     druid:
       lantone:
         driver-class-name: com.mysql.jdbc.Driver
-        url: jdbc:mysql://192.168.2.237:3307/qc_xszyy?useUnicode=true&characterEncoding=utf8&useSSL=false
+        url: jdbc:mysql://192.168.2.237:3307/qc?useUnicode=true&characterEncoding=utf8&useSSL=false
         username: root
         password: lantone
         initial-size: 8
@@ -42,16 +42,16 @@ spring:
 xml-is-encryped: true
 
 CRF:
-  url: http://192.168.2.234:3456/api/mr_info_ex/entity_predict
+  url: http://10.68.24.42:13456/api/mr_info_ex/entity_predict
 
 Similarity:
-  url: http://192.168.2.234:3456/api/mr_info_ex/similarity
+  url: http://10.68.24.42:13456/api/mr_info_ex/similarity
 
 NewSimilarity:
-  url: http://192.168.2.234:23232/api/similarity
+  url: http://10.68.24.42:12323/api/similarity
 
 NewBatchSimilarity:
-  url: http://192.168.2.234:23232/api/similarity_batch
+  url: http://10.68.24.42:12323/api/similarity_batch
 
 ChiefPresentSimilarity:
-  url: http://192.168.2.234:3456/api/mr_info_ex/chief_present_similarity
+  url: http://10.68.24.42:13456/api/mr_info_ex/chief_present_similarity

+ 16 - 0
dbanaly/src/main/resources/rebel.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
+  Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
+-->
+<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
+
+	<id>dbanaly</id>
+
+	<classpath>
+		<dir name="C:/Users/10185/Desktop/work/后端/aiPlat/qc/dbanaly/target/classes">
+		</dir>
+	</classpath>
+
+</application>

+ 1 - 1
kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH0009.java

@@ -22,7 +22,7 @@ import java.util.List;
 @Component
 public class BEH0009 extends QCCatalogue {
     private List<String> containList = Arrays.asList("检查", "术后", "药物", "发现", "误服", "确诊", "经", "异常", "诊断"
-            , "示", "超", "伤", "术", "复查", "体检", "血透", "血液透析","孕","农药");
+            , "示", "超", "伤", "术", "复查", "体检", "血透", "血液透析", "孕", "农药", "呻吟");
 
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
         if (inputInfo.getBeHospitalizedDoc() == null) {

+ 5 - 5
kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH02966.java

@@ -35,11 +35,11 @@ public class BEH02966 extends QCCatalogue {
         if (gender.contains("男")) {
             /* 男性不合理词 */
             noMatchWords = Lists.newArrayList("阴道", "宫颈", "子宫", "宫底", "胎位", "胎数", "胎心",
-                    "宫缩", "宫口", "输卵管", "卵巢", "输卵管", "阴唇", "阴蒂", "阴道前庭", "前庭大腺", "处女膜");
+                    "宫缩", "宫口", "输卵管", "卵巢", "输卵管", "阴唇", "阴蒂", "阴道前庭", "前庭大腺", "处女膜", "女");
         } else if (gender.contains("女")) {
             /* 女性不合理词 */
             noMatchWords = Lists.newArrayList("睾丸", "阴茎", "精索", "包皮", "输精管",
-                    "射精管", "尿道海绵体", "冠状沟", "精阜", "精囊腺", "阴囊");
+                    "射精管", "尿道海绵体", "冠状沟", "精阜", "精囊腺", "阴囊", "男");
         }
         if (noMatchWords == null || noMatchWords.size() == 0) {
             return;
@@ -48,11 +48,11 @@ public class BEH02966 extends QCCatalogue {
         List<String> keys = Lists.newArrayList("主诉", "现病史", "既往史", "体格检查", "一般情况"
                 , "初步诊断", "专科体格检查", "神经系统检查", "实验室检查", "影像学检查");
         String text = CatalogueUtil.structureMapJoin(beHospitalStructureMap, keys);
-        String rex="(?<!((母孕期|母亲|妈妈|分娩期|分娩|出生时|母亲怀孕|怀孕时|孕期)[^。,;。、,;]{0,15}))(阴道|宫颈|子宫|宫底|胎位|胎数|胎心|宫缩|宫口|卵巢|输卵管|阴唇|阴蒂|阴道前庭|前庭大腺|处女膜)";
+        String rex = "(?<!((母孕期|母亲|妈妈|分娩期|分娩|出生时|母亲怀孕|怀孕时|孕期)[^。,;。、,;]{0,15}))(阴道|宫颈|子宫|宫底|胎位|胎数|胎心|宫缩|宫口|卵巢|输卵管|阴唇|阴蒂|阴道前庭|前庭大腺|处女膜)";
         for (String noMatchWord : noMatchWords) {
             if (text.contains(noMatchWord)) {
-                if(gender.contains("男")){
-                    if(!text.matches(rex)){
+                if (gender.contains("男")) {
+                    if (!text.matches(rex)) {
                         status.set("0");
                         return;
                     }

+ 2 - 2
kernel/src/main/java/com/lantone/qc/kernel/catalogue/firstpagerecord/FIRP0162.java

@@ -19,14 +19,14 @@ import java.util.Map;
  */
 @Component
 public class FIRP0162 extends QCCatalogue {
-    private List<String> containList = Arrays.asList("-", "—", "拒", "无", "不详", "未上户口","提供");
+    private List<String> containList = Arrays.asList("-", "—", "拒", "无", "不详", "未上户口", "提供");
 
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
         status.set("0");
         if (inputInfo.getFirstPageRecordDoc() != null && inputInfo.getFirstPageRecordDoc().getStructureMap() != null) {
             Map<String, String> firstpageStructureMap = inputInfo.getFirstPageRecordDoc().getStructureMap();
             String nationality = firstpageStructureMap.get(Content.nationality);
-            if(StringUtil.isNotBlank(nationality) && !"中国".equals(nationality)){
+            if (StringUtil.isNotBlank(nationality) && !"中国".equals(nationality)) {
                 return;
             }
             String idNumber = firstpageStructureMap.get(Content.idNumber);

+ 50 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/firstpagerecord/FIRP03229.java

@@ -0,0 +1,50 @@
+package com.lantone.qc.kernel.catalogue.firstpagerecord;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.pub.Content;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @ClassName : FIRP03229
+ * @Description : 身份证号与性别不符合
+ * @Author : wsy
+ * @Date: 2022-04-12 16:13
+ */
+@Component
+public class FIRP03229 extends QCCatalogue {
+    /**
+     * 1.获取病案首页的患者性别和身份证号,若任一不存在则通过
+     * 2.根据18位数的身份证号码的第十七位(倒数第二位)判断性别,如果为奇数则为男性,偶数则为女性
+     * 3.校验首页填写的性别是否和身份证性别一致
+     */
+
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        if (inputInfo.getFirstPageRecordDoc() == null) {
+            return;
+        }
+        if (inputInfo.getFirstPageRecordDoc().getStructureMap() != null) {
+            Map<String, String> firstPageStructureMap = inputInfo.getFirstPageRecordDoc().getStructureMap();
+            String idNumber = firstPageStructureMap.get(Content.idNumber);//身份证号
+            String gender = firstPageStructureMap.get(Content.gender);//性别
+            if (StringUtil.isBlank(idNumber) || StringUtil.isBlank(gender)) {
+                return;
+            }
+            if (idNumber.length() > 17) {
+                int num = Integer.parseInt(idNumber.substring(16, 17));
+                //奇数表示男性,偶数表示女性;
+                if (gender.contains("男") && num % 2 == 0) {
+                    status.set("-1");
+                }
+                if (gender.contains("女") && num % 2 == 1) {
+                    status.set("-1");
+                }
+            }
+        }
+    }
+}

+ 2 - 2
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/changshaxy/behospitalized/BEH02966.java

@@ -51,11 +51,11 @@ public class BEH02966 extends QCCatalogue {
         if (gender.contains("男")) {
             /* 男性不合理词 */
             noMatchWords = Lists.newArrayList("阴道", "宫颈", "子宫", "宫底", "胎位", "胎数", "胎心",
-                    "宫缩", "宫口", "输卵管", "卵巢", "输卵管", "阴唇", "阴蒂", "阴道前庭", "前庭大腺", "处女膜");
+                    "宫缩", "宫口", "输卵管", "卵巢", "输卵管", "阴唇", "阴蒂", "阴道前庭", "前庭大腺", "处女膜", "女");
         } else if (gender.contains("女")) {
             /* 女性不合理词 */
             noMatchWords = Lists.newArrayList("睾丸", "阴茎", "精索", "包皮", "附睾", "输精管",
-                    "射精管", "尿道海绵体", "冠状沟", "精阜", "精囊腺", "阴囊");
+                    "射精管", "尿道海绵体", "冠状沟", "精阜", "精囊腺", "阴囊", "男");
         }
         if (noMatchWords == null || noMatchWords.size() == 0) {
             return;

+ 1 - 11
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/clinicalblood/CLI0571.java

@@ -26,16 +26,6 @@ public class CLI0571 extends QCCatalogue {
             status.set("0");
             return;
         }
-        if (clinicalBloodDocs!=null && clinicalBloodDocs.size()>0){
-            for (ClinicalBloodDoc cliB : clinicalBloodDocs) {
-                Map<String, String> cliBStructureMap = cliB.getStructureMap();
-                //台州
-                if (StringUtils.isNotEmpty(cliBStructureMap.get("Rh血型"))) {
-                    status.set("0");
-                    return;
-                }
-            }
-        }
         if (clinicalBloodDocs != null && clinicalBloodDocs.size() > 0) {
             for (ClinicalBloodDoc cliB : clinicalBloodDocs) {
                 Map<String, String> cliBStructureMap = cliB.getStructureMap();
@@ -43,7 +33,7 @@ public class CLI0571 extends QCCatalogue {
                     String bloodType = cliBStructureMap.get("病历内容");
                     if (StringUtil.isNotBlank(bloodType)) {
                         if (bloodType.contains("Rh") || bloodType.contains("RH")
-                                || bloodType.contains("蛋白")) {
+                                || bloodType.contains("蛋白")) {
                             status.set("0");
                             return;
                         }

+ 149 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/preoperativediscussion/PRE0328.java

@@ -0,0 +1,149 @@
+package com.lantone.qc.kernel.catalogue.hospital.ningbozhongyi.preoperativediscussion;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.util.CatalogueUtil;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.DoctorAdviceDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationRecordDoc;
+import com.lantone.qc.pub.util.DateUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 手术患者无术前讨论记录
+ * @author: rengb
+ * @time: 2020/3/23 15:09
+ */
+@Component
+public class PRE0328 extends QCCatalogue {
+
+    @Override
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo) throws ParseException {
+        /**
+         * 1:如果急诊手术【入院时间-手术开始时间小于30分钟】则可不用写术前小结。
+         * 2:如果入院时间-手术开始时间小于30分钟,则术前讨论、术前小结次数+1。
+         * 3:如果手术记录次数(第一次手术的日期内有其他手术不算次数) 大于 术前讨论、术前小结次数,则出错
+         */
+        status.set("0");
+       // List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
+        List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+        if (operationDocs == null || operationDocs.size() == 0) {
+            return;
+        }
+        boolean emergencyOperation = false;
+        if (inputInfo.getBeHospitalizedDoc() != null) {
+            Map<String, String> beHospitalStructureMap = inputInfo.getBeHospitalizedDoc().getStructureMap();
+            String admisTime = beHospitalStructureMap.get("入院日期");
+            //取手术记录第一次手术开始时间和入院时间比较,相差30分钟内不报缺陷
+            OperationRecordDoc operationRecordDoc = operationDocs.get(0).getOperationRecordDoc();
+            String startTime = "";
+            if (operationRecordDoc != null) {
+                startTime = operationRecordDoc.getStructureMap().get("手术开始时间");
+                if(StringUtil.isBlank(startTime)){
+                    startTime = operationRecordDoc.getStructureMap().get("手术日期").replace(" 时","时");
+                }
+            }
+            if (StringUtil.isNotBlank(startTime) && StringUtil.isNotBlank(admisTime) &&
+                    StringUtil.parseDateTime(startTime) != null) {
+                if (!CatalogueUtil.compareTime(
+                        StringUtil.parseDateTime(admisTime),
+                        StringUtil.parseDateTime(startTime),
+                        Long.valueOf(30))) {//入院到手术未超过30分钟,则可不用写术前小结
+                    emergencyOperation = true;
+                }
+            }
+        }
+
+        int i = getOperationSum(operationDocs); // 获取手术记录次数
+        int j = 0;  // 获取术前讨论、术前小结次数
+        for (OperationDoc operationDoc : operationDocs) {
+            if (operationDoc.getPreoperativeDiscussionDoc() != null) {
+                j++;
+            }
+        }
+        /* 如果入院时间-手术开始时间小于30分钟,则术前讨论、术前小结次数+1*/
+        if (emergencyOperation) {
+            if (j == 0) {
+                j++;
+            }
+        }
+        //医嘱中包含“冠状动脉造影术”,且无术前讨论.则报规则
+//        for (DoctorAdviceDoc doctorAdviceDoc : doctorAdviceDocs) {
+//            Map<String, String> doctorAdviceStructuerMap = doctorAdviceDoc.getStructureMap();
+//            String advicename = doctorAdviceStructuerMap.get("医嘱项目名称");
+//            if (StringUtil.isNotBlank(advicename) && advicename.contains("冠状动脉造影术") && j == 0) {
+//                status.set("-1");
+//                info.set("手术记录不一致");
+//            }
+//        }
+
+//        if (i == 0 && i < j) {
+//            status.set("0");
+//            info.set("无手术记录");
+//        }
+        if (i != 0 && i > j){
+            status.set("-1");
+            info.set("手术次数和术前小结次数不一致");
+        }
+    }
+
+    /**
+     * 获取手术记录次数
+     *
+     * @param operationDocs
+     * @return
+     */
+    private int getOperationSum(List<OperationDoc> operationDocs) {
+        List<Map<String, Date>> operationDateList = new ArrayList<>();
+        Map<String, Date> operationDate = null;
+        for (OperationDoc operationDoc : operationDocs) {
+            OperationRecordDoc operationRecordDoc = operationDoc.getOperationRecordDoc();
+            if (operationRecordDoc == null) {
+                continue;
+            }
+            Map<String, String> structureMap = operationRecordDoc.getStructureMap();
+            String operationStartDateStr = structureMap.get("手术开始时间");
+            if(StringUtil.isBlank(operationStartDateStr)){
+                operationStartDateStr = operationRecordDoc.getStructureMap().get("手术日期").replace(" 时","时");
+            }
+            if (StringUtil.isNotBlank(operationStartDateStr) && StringUtil.parseDateTime(operationStartDateStr) != null) {
+                Date operationStartDate = StringUtil.parseDateTime(operationStartDateStr);
+                operationStartDate = DateUtil.dateZeroClear(operationStartDate);
+                if (operationStartDate != null) {
+                    /* 放第一个手术记录的日期到operationDateList */
+                    if (operationDateList.size() == 0) {
+                        operationDate = new HashMap<>();
+                        operationDate.put("手术开始时间", operationStartDate);
+                        operationDateList.add(operationDate);
+                        continue;
+                    }
+                    /* 如果其中一个手术记录的开始时间到结束时间之间还包含另一个手术,就不往operationDateList里加 */
+                    boolean findInnerOperation = false;
+                    for (Map<String, Date> date : operationDateList) {
+                        Date listStartDate = DateUtil.dateZeroClear(date.get("手术开始时间"));
+                        if (listStartDate.equals(operationStartDate)) {
+                            findInnerOperation = true;
+                            break;
+                        }
+                    }
+                    if (!findInnerOperation) {
+                        operationDate = new HashMap<>();
+                        operationDate.put("手术开始时间", operationStartDate);
+                        operationDateList.add(operationDate);
+                    }
+                }
+            }
+        }
+        return operationDateList.size();
+    }
+
+}

+ 13 - 14
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/threelevelward/THR0144.java

@@ -22,6 +22,7 @@ import java.util.Map;
 @Component
 public class THR0144 extends QCCatalogue {
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+
         MedicalRecordInfoDoc medicalRecordInfoDoc = inputInfo.getMedicalRecordInfoDoc();
         if (medicalRecordInfoDoc != null && medicalRecordInfoDoc.getStructureMap() != null) {
             //入院日期
@@ -32,7 +33,6 @@ public class THR0144 extends QCCatalogue {
                 status.set("0");
                 return;
             }
-
             if (!CatalogueUtil.compareTime(
                     StringUtil.parseDateTime(admisTime),
                     StringUtil.parseDateTime(DateUtil.nowString()),
@@ -41,15 +41,15 @@ public class THR0144 extends QCCatalogue {
                 return;
             }
             //如果住院天数小于2天则不判断该条规则
-            if (DateUtil.parseDate(dischargeTime) != null &&
-                    !CatalogueUtil.compareTime(StringUtil.parseDateTime(admisTime), StringUtil.parseDateTime(dischargeTime), (long) (48 * 60))) {
-                status.set("0");
+           if (DateUtil.parseDate(dischargeTime) != null &&
+                   !CatalogueUtil.compareTime(StringUtil.parseDateTime(admisTime), StringUtil.parseDateTime(dischargeTime), (long) (48 * 60))) {
+               status.set("0");
                 return;
             } else {
-                if (inputInfo.getThreeLevelWardDocs().size() == 0) {
+               if (inputInfo.getThreeLevelWardDocs().size() == 0) {
                     status.set("-1");
-                    return;
-                }
+                   return;
+               }
             }
         }
 
@@ -66,7 +66,7 @@ public class THR0144 extends QCCatalogue {
             status.set("0");
             return;
         }
-        int j = 0; //最后次查房记录
+        int j = 0; //最后次查房记录
         Boolean lastFlag = true;
         for (int i = allDoctorWradDocs.size() - 1; i >= 0 && j < 2; i--) {
             j++;
@@ -75,8 +75,7 @@ public class THR0144 extends QCCatalogue {
             String conditionRecord = structureMap.get("病情记录");
             String treatmentPlan = structureMap.get("治疗计划和措施");
             String title = structureMap.get("查房标题");
-            //|| title.contains("病理记录") || title.contains("病理诊断")
-            if (StringUtil.isBlank(title) || title.contains("病理报告") || title.contains("化验记录")) {
+            if (StringUtil.isBlank(title) || title.contains("病理报告") || title.contains("病理记录") || title.contains("化验记录")) {
                 continue;
             }
             conditionRecord = StringUtil.isBlank(conditionRecord) ? "" : conditionRecord;
@@ -91,15 +90,15 @@ public class THR0144 extends QCCatalogue {
                 return;
             }
             //普通查房 内容需要包含“上级”和“出院”
-            if (StringUtil.isBlank(title)
+            if (StringUtil.isNotBlank(title)
                     || (title.contains("日常查房记录") || title.contains("普通查房记录") || title.contains("日常病程记录"))
                     && (title.contains("上级") || conditionRecord.contains("上级"))
                     && (conditionRecord.contains("出院") || treatmentPlan.contains("出院"))) {
                 status.set("0");
                 return;
             }
-            // 添加硬规则,最后一个记录包含“医院”或 “离院”就不报错  || conditionRecord.contains("出院")
-            if (lastFlag==true) {
+            if (lastFlag == true) {
+                // 添加硬规则,最后一个记录包含“医院”或 “离院”就不报错
                 if (conditionRecord.contains("医院") || conditionRecord.contains("离院")) {
                     status.set("0");
                     return;
@@ -108,4 +107,4 @@ public class THR0144 extends QCCatalogue {
             }
         }
     }
-}
+}

+ 16 - 7
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/threelevelward/THR02900.java

@@ -51,22 +51,28 @@ public class THR02900 extends QCCatalogue {
                 continue;
             }
             Map<String, String> structureMap = operationRecordDoc.getStructureMap();
-            String opeAssName = structureMap.get("手术人员");
+            String opeAssName = structureMap.get("手术名称");
+            firstAssistant = structureMap.get("一助");
+            if(StringUtil.isBlank(firstAssistant)){
+                firstAssistant = structureMap.get("助手(一、二)");
+            }
             if (StringUtil.isNotBlank(opeAssName)) {
                 split = opeAssName.split(" ");
-                firstAssistant = structureMap.get("助手");
                 opeEndTime = structureMap.get("手术日期");
             } else {
-                firstAssistant = structureMap.get("一助");
                 //取得手术时间截取结束时间(格式 2020-07-24 10:30-2020-07-24 11:45)
                 String key = getKeyByHospitalId();
                 opeEndTime = structureMap.get(key);
                 opeEndTime = getTime(opeEndTime, structureMap);
             }
             String chiefSurgeon = structureMap.get("主刀医师");
+            if(StringUtil.isBlank(chiefSurgeon)){
+                chiefSurgeon = structureMap.get("手术者");
+            }
             if (opeEndTime.contains("年月日")) {
                 continue;
             }
+            opeEndTime = opeEndTime.replace(" 时","时");
             Date opeEndDate = CatalogueUtil.parseStringDate(opeEndTime);
             if (opeEndDate == null) {
                 continue;
@@ -74,14 +80,17 @@ public class THR02900 extends QCCatalogue {
             if (!CatalogueUtil.compareTime(
                     StringUtil.parseDateTime(opeEndTime),
                     StringUtil.parseDateTime(DateUtil.nowString()),
-                    Long.valueOf(24 * 60))) {//如果接收未超过6小时,规则不判断
+                    Long.valueOf(24 * 60))) {//如果接收未超过24小时,规则不判断
                 return;
-            } else {
+            }else {
                 if ((StringUtil.isNotEmpty(chiefSurgeon) || StringUtil.isNotEmpty(firstAssistant)) && ListUtil.isEmpty(allDoctorWradDocs)) {
                     status.set("-1");
                     return;
                 }
             }
+            // if (StringUtil.isNotBlank(chiefSurgeon) || StringUtil.isNotBlank(firstAssistant) && allDoctorWradDocs.size()==0){
+            //                    return;
+            //                }
             if (ListUtil.isNotEmpty(allDoctorWradDocs)) {
                 for (ThreeLevelWardDoc wardDoc : allDoctorWradDocs) {
                     Map<String, String> wardStructureMap = wardDoc.getStructureMap();
@@ -93,7 +102,7 @@ public class THR02900 extends QCCatalogue {
                     if (StringUtil.isBlank(recordTitle) || StringUtil.isBlank(pathography) || recordDate == null) {
                         continue;
                     }
-                    if (opeEndDate.before(recordDate) && !CatalogueUtil.compareTime(opeEndDate, recordDate, 24 * 60L)) {
+                    if (recordDate.before(opeEndDate) && !CatalogueUtil.compareTime(opeEndDate, recordDate, 24 * 60L)) {
                         allTitle += recordTitle;
                         allPathography += pathography;
                         if (StringUtil.isNotBlank(writTitle)) {
@@ -116,7 +125,7 @@ public class THR02900 extends QCCatalogue {
                     StringUtil.isNotBlank(firstAssistant) && !allTitle.contains(firstAssistant)) {
                 status.set("-1");
                 return;
-            } else if (StringUtil.isBlank(chiefSurgeon) && StringUtil.isBlank(firstAssistant) && split != null && split.length > 1) {
+            } else if (StringUtil.isBlank(chiefSurgeon) && StringUtil.isBlank(firstAssistant) && split != null && split.length > 1 && StringUtil.isNotBlank(opeAssName)) {
                 for (int i = 0; i < split.length; i++) {
                     if (allTitle.contains(split[i])) {
                         return;

+ 4 - 4
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ninghaifuyou/behospitalized/BEH02966.java

@@ -27,9 +27,9 @@ public class BEH02966 extends QCCatalogue {
         }
 
         //宁还妇幼新生儿不判断此规则
-        if(inputInfo.getFirstPageRecordDoc() != null){
+        if (inputInfo.getFirstPageRecordDoc() != null) {
             Map<String, String> firstPageRecordStructureMap = inputInfo.getFirstPageRecordDoc().getStructureMap();
-            if(StringUtil.isNotBlank(firstPageRecordStructureMap.get("新生儿出生天数"))){
+            if (StringUtil.isNotBlank(firstPageRecordStructureMap.get("新生儿出生天数"))) {
                 return;
             }
         }
@@ -43,11 +43,11 @@ public class BEH02966 extends QCCatalogue {
         if (gender.contains("男")) {
             /* 男性不合理词 */
             noMatchWords = Lists.newArrayList("阴道", "宫颈", "子宫", "宫底", "胎位", "胎数", "胎心",
-                    "宫缩", "宫口", "输卵管", "卵巢", "输卵管", "阴唇", "阴蒂", "阴道前庭", "前庭大腺", "处女膜");
+                    "宫缩", "宫口", "输卵管", "卵巢", "输卵管", "阴唇", "阴蒂", "阴道前庭", "前庭大腺", "处女膜", "女");
         } else if (gender.contains("女")) {
             /* 女性不合理词 */
             noMatchWords = Lists.newArrayList("睾丸", "阴茎", "精索", "包皮", "附睾", "输精管",
-                    "射精管", "尿道海绵体", "冠状沟", "精阜", "精囊腺");
+                    "射精管", "尿道海绵体", "冠状沟", "精阜", "精囊腺", "男");
         }
         if (noMatchWords == null || noMatchWords.size() == 0) {
             return;

+ 68 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/firstpagerecord/FIRP0190.java

@@ -0,0 +1,68 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.firstpagerecord;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.util.CatalogueUtil;
+import com.lantone.qc.pub.Content;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.ClinicalBloodDoc;
+import com.lantone.qc.pub.util.StringUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : FIRP0190
+ * @Description :Rh填写错误
+ * @Author : 胡敬
+ * @Date: 2020-03-18 13:35
+ */
+@Component
+public class FIRP0190 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        if (inputInfo.getFirstPageRecordDoc() == null || inputInfo.getFirstPageRecordDoc().getStructureMap() == null
+                || inputInfo.getClinicalBloodDocs().size() == 0) {
+            return;
+        }
+        Map<String, String> firstpageStructureMap = inputInfo.getFirstPageRecordDoc().getStructureMap();
+        List<ClinicalBloodDoc> clinicalBloodDocList = inputInfo.getClinicalBloodDocs();
+        String rhFactor = firstpageStructureMap.get(Content.rhFactor);
+        if (CatalogueUtil.isEmpty(rhFactor)) {
+            return;
+        }
+        int matchSum = 0, noRhSum = 0;
+        for (ClinicalBloodDoc clinicalBloodDoc : clinicalBloodDocList) {
+            String bloodType = clinicalBloodDoc.getText();
+            if (StringUtil.isBlank(bloodType)) {
+                // 台州无“输注种类、血型、数量”,匹配“Rh血型”
+                bloodType = clinicalBloodDoc.getStructureMap().get("Rh血型");
+            }
+            if (StringUtils.isEmpty(bloodType)) {
+                continue;
+            }
+            if (!bloodType.contains("阴") && !bloodType.contains("阳")) {
+                noRhSum++;
+            }
+            if (bloodType.contains("白蛋白") || bloodType.contains("凝血酶原复合物")) {
+                continue;
+            }
+            bloodType = bloodType.toUpperCase();
+            String rh = Content.rhFactor.toUpperCase();
+            if (bloodType.contains(rh) ||
+                    bloodType.contains(CatalogueUtil.removeSpecialChar(rhFactor))) {
+                matchSum++;
+                return;
+            }
+        }
+        /* 如果所有输血记录都没有rh记录(阴、阳),则不报错 */
+        if (noRhSum == clinicalBloodDocList.size()) {
+            return;
+        }
+        if (matchSum == 0) {
+            status.set("-1");
+        }
+    }
+}

+ 2 - 2
kernel/src/main/java/com/lantone/qc/kernel/catalogue/leavehospital/LEA02968.java

@@ -36,11 +36,11 @@ public class LEA02968 extends QCCatalogue {
         if (gender.contains("男")) {
             /* 男性不合理词 */
             noMatchWords = Lists.newArrayList("阴道", "宫颈", "子宫", "宫底", "胎位", "胎数", "胎心",
-                    "宫缩", "宫口", "输卵管", "卵巢", "输卵管", "阴唇", "阴蒂", "阴道前庭", "前庭大腺", "处女膜");
+                    "宫缩", "宫口", "输卵管", "卵巢", "输卵管", "阴唇", "阴蒂", "阴道前庭", "前庭大腺", "处女膜", "女");
         } else if (gender.contains("女")) {
             /* 女性不合理词 */
             noMatchWords = Lists.newArrayList("睾丸", "阴茎", "精索", "包皮", "附睾", "输精管",
-                    "射精管", "尿道海绵体", "冠状沟", "精阜", "精囊腺");
+                    "射精管", "尿道海绵体", "冠状沟", "精阜", "精囊腺", "男");
         }
 
         if (noMatchWords == null || noMatchWords.size() == 0) {

+ 4 - 4
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR02967.java

@@ -15,7 +15,7 @@ import java.util.Map;
 
 /**
  * @ClassName : THR02967
- * @Description :  查房记录中查体与性别不匹配
+ * @Description :  患者病历描述与性别不符
  * @Author : 胡敬
  * @Date: 2020-06-13 16:13
  */
@@ -36,11 +36,11 @@ public class THR02967 extends QCCatalogue {
         if (gender.contains("男")) {
             /* 男性不合理词 */
             noMatchWords = Lists.newArrayList("阴道", "宫颈", "子宫", "宫底", "胎位", "胎数", "胎心",
-                    "宫缩", "宫口", "输卵管", "卵巢", "输卵管", "阴唇", "阴蒂", "阴道前庭", "前庭大腺", "处女膜");
+                    "宫缩", "宫口", "输卵管", "卵巢", "输卵管", "阴唇", "阴蒂", "阴道前庭", "前庭大腺", "处女膜", "女");
         } else if (gender.contains("女")) {
             /* 女性不合理词 */
             noMatchWords = Lists.newArrayList("睾丸", "阴茎", "精索", "包皮", "附睾", "输精管",
-                    "射精管", "尿道海绵体", "冠状沟", "精阜", "精囊腺");
+                    "射精管", "尿道海绵体", "冠状沟", "精阜", "精囊腺", "男");
         }
 
         if (noMatchWords == null || noMatchWords.size() == 0) {
@@ -51,7 +51,7 @@ public class THR02967 extends QCCatalogue {
             Map<String, String> structureMap = threeLevelWardDoc.getStructureMap();
             String text = CatalogueUtil.structureMapJoin(structureMap, keys);
             for (String noMatchWord : noMatchWords) {
-                if (noMatchWord.contains("附睾") && text.contains("附睾")&&"7".equals(Content.hospital_Id)) {
+                if (noMatchWord.contains("附睾") && text.contains("附睾") && "7".equals(Content.hospital_Id)) {
                     int index = text.indexOf("附睾");
                     String substring = text.substring(Math.max(0, index - 5), Math.min(index + 7, text.length()));
                     if (text.contains("附睾蛋白") || substring.contains("蛋白")) {

+ 1 - 1
kernel/src/main/resources/bootstrap.yml

@@ -18,7 +18,7 @@ spring:
   resources:
     static-locations: classpath:/
   profiles:
-    active: local
+    active: dev
 
 qc:
   hospital_id: 1,2,3,4,5,6,7,8,10,11,13,15,20,34,35,36

+ 84 - 0
kernel/src/main/resources/cache/38/concept_clinic_bodypart_properties.dict

@@ -0,0 +1,84 @@
+sjwPlFuzwYtdGy/Xru8l0w==
+sjwPlFuzwYuOwjk+wlafMb496h/s94Lp
+GaEOqMDeIR/A3JPjaU/OYQ==
+KUZ84E/l6BtIxYdpVp2d2udw4JKVz6fxOAPHyqzXUMY=
+ClvKDL868eyBa0I3oBBXTiLG5UIUjigm
+cpVuhYfN0VLL15lmAanTHLudBba0KZdGSmARnfpRl/s=
+tgLfZiBNXVfe46uqWooJfQ==
++elokrz+5ZZ4nftSAgjXeP9VC/9mRBPm
+u18AKL/dfo8=
+FXYCcRyAS3o=
+1y8RNUzpzDDA3JPjaU/OYQ==
+GDAzhKkwugqOwjk+wlafMb496h/s94Lp
+vVsbjXwCHtKFIWuMj59JFg==
+S00FGSMpzFYRJHHOrCiJIw==
+LQ4RQ5c6TvEfVJH7s8MZNQ==
+KkqtLy22gBtRq6Y4vkNXyQ==
+FpNKk6eB+A78k09Y7waUfQ==
+55LO8f+DGuqsZzaaPHDG7A==
+anCWsr9KEAcfVJH7s8MZNQ==
+Ms4itbwo4woHjnX6dZF4Ew==
+eE2lKBuqkGwbZW204O8pbL496h/s94Lp
+KPTiLOQlvfcHjnX6dZF4Ew==
+EHYxrOGlbsJINCuQrfA+Qw==
+IoIoNIGjGAkfVJH7s8MZNQ==
+TkKCqeWSukdcNzQgT7Qg/y/95Ux1UGf/
+5sS2G/r6ssUfVJH7s8MZNQ==
+Fz6WuGDyOlM=
+6BJE0DCYV4PN7oAmfhVFQqHIcEkBIHl+SmARnfpRl/s=
+ClvKDL868ewfVJH7s8MZNQ==
+IoIoNIGjGAmt+3FIqYSLwA==
+qjVzhjIuUT4fVJH7s8MZNQ==
+fAvCqq32iRGYkjXG21GhdA==
+Qz54IR1t0pxhD8mu55a07QB9XVjkemQO
+VDAaAfFpalOc8iRXg5Txmg==
+v2wP8zYN7yUfVJH7s8MZNQ==
+2O+0+BuTK7hnAFNeF32DwQ==
+LRQ8TiPskP8=
+MHWWVpSYUhZp84i3DCFu/g==
+4a+BNcRWzuwuxVbFLjJEww==
+yWJqJiL6qWQskpnR2QjFRA==
+LkBZ8uh2sivD7O64F4fyYD26Q3FauFTq
+vU9OSQNfzsdHGRV53JQHXTZxIOEr6XT/
+Z0A2kuK86msFZwSJa38bOw==
+qglFhT75KVY=
+J47wTSKVIotrynAbi7Nl7g==
+PSCtbA3GBCLqcUHlnbz5ig==
+pGzYL5VYctXxzUrAtKDMFg==
+J47wTSKVIotWP8N6Zu8teQ==
+hnOhzeqPs7c=
+FpNKk6eB+A60ivUVDCQonmb0NA6xAPvZ
+6eB67p+u3VA=
+38rBhrBd2ZA=
+WlxWJO1bvWM=
+/UTzDiOxLWpNfh/SNay22g==
+PLBt3Oha1AAOSE8k2YZYMw==
+cA6kPjEpsoKKXDwNc4sbZv9VC/9mRBPm
+ubvY7WEHsf0HjnX6dZF4Ew==
+NI9su0Z8kvY=
+z5dpaPXQysM+03JbZpPE8K74oEbqwDfN
+e7OvqkV6Qx5DhU/YuJZA4A==
+vnSKQ0o1HZO5fhcvExqbXw==
+5j32mrEC41Q=
+teXiWF5i95089VmH6nOntT26Q3FauFTq
+C5DNXPfJ3MsXUKrj9yaJVQ==
+aBDrcQGdFjgXTO+Ia0kzAA==
+EyuDTtt1Nh1c5OTNuAf37Q==
+0NhZqdATkZ4=
+1IKx7GtShHg=
+h/OwYNYyciw=
+kGg6y+QB2f8=
+et0S9LyTiS4MhEBuylTk2g==
+goFZ0v8zcPc=
+cA6kPjEpsoJc5OTNuAf37Q==
+BZNVMNz30Z00iPLsFnfW9Q==
+FUNtEl6WjOUfVJH7s8MZNQ==
+1boew8BvzsDzIpTnzy5Qnw==
+/CIzubCbNzzkzFf+CBlT64JiFWxfW6DV
+teXiWF5i953EeSAoaVSW+wBBqlZ1ciHqSmARnfpRl/s=
+CTNjqF5g7EIfVJH7s8MZNQ==
+OOQuqjL/h5M16D9aZjbrRw==
+ZfWBQ/To1p1p84i3DCFu/g==
+Q449MTqnm/c=
+xmHl5DY7FyM=
+hV3gMCbT8x+fXEA0j/uq7Q==

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 25358 - 0
kernel/src/main/resources/cache/38/concept_diag_properties.dict


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 25358 - 0
kernel/src/main/resources/cache/38/hospital_diag_info.dict


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 3123 - 0
kernel/src/main/resources/cache/38/hospital_doctor_info.dict


+ 16 - 0
kernel/src/main/resources/rebel.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
+  Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
+-->
+<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
+
+	<id>kernel</id>
+
+	<classpath>
+		<dir name="C:/Users/10185/Desktop/work/后端/aiPlat/qc/kernel/target/classes">
+		</dir>
+	</classpath>
+
+</application>

+ 16 - 0
nlp/src/main/java/rebel.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
+  Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
+-->
+<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
+
+	<id>nlp</id>
+
+	<classpath>
+		<dir name="C:/Users/10185/Desktop/work/后端/aiPlat/qc/nlp/target/classes">
+		</dir>
+	</classpath>
+
+</application>

+ 16 - 0
public/src/main/java/rebel.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
+  Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
+-->
+<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
+
+	<id>public</id>
+
+	<classpath>
+		<dir name="C:/Users/10185/Desktop/work/后端/aiPlat/qc/public/target/classes">
+		</dir>
+	</classpath>
+
+</application>

+ 16 - 0
security/src/main/java/rebel.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  This is the JRebel configuration file. It maps the running application to your IDE workspace, enabling JRebel reloading for this project.
+  Refer to https://manuals.jrebel.com/jrebel/standalone/config.html for more information.
+-->
+<application generated-by="intellij" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_3.xsd">
+
+	<id>security</id>
+
+	<classpath>
+		<dir name="C:/Users/10185/Desktop/work/后端/aiPlat/qc/security/target/classes">
+		</dir>
+	</classpath>
+
+</application>

+ 7 - 16
trans/src/main/java/com/lantone/qc/trans/beilun/util/BeiLunInvasiveOperationHtmlAnalysis.java

@@ -4,6 +4,7 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
 import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.HangzhoufubaoTranUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -30,28 +31,18 @@ public class BeiLunInvasiveOperationHtmlAnalysis implements BeiLunHtmlAnalysis {
         Map<String, String> structureMap = Maps.newLinkedHashMap();
         try {
             List<String> titles = Lists.newArrayList(
-                    "操作时间",
-                    "操作医生",
-                    "麻醉方法",
                     "操作名称",
-                    "操作简要经过(包括术中有无并发症及具体描述和处理)",
-                    "标本送检",
+                    "操作时间",
+                    "操作人员",
+                    "操作过程、结果及患者一般情况",
                     "术后注意事项",
-                    "记录者签名");
+                    "操作医师签名");
             String html = args[0];
             String recTitle = args[1];
             String recTypeId = args[2];
             Document doc = Jsoup.parse(html);
-            String htmlContent = BeiLunHtmlAnalysisUtil.blockDivToStr(doc.selectFirst("body").child(0), false);
-                CommonAnalysisUtil.html2StructureMap(titles, htmlContent, structureMap);
-            if (MapUtils.isNotEmpty(structureMap)) {
-                structureMap = OrdinaryAssistant.mapKeyContrast(structureMap, keyContrasts);
-            }
-            String cases = getKeyCut(structureMap.get("术后注意"));
-            if(StringUtils.isNotBlank(cases)){
-                structureMap.put("术后注意",cases);
-            }
-            structureMap = preSolve(htmlContent, structureMap);
+            String htmlContent = BeiLunHtmlAnalysisUtil.blockDivToStr(doc.selectFirst("body").child(0), true);
+            HangzhoufubaoTranUtils.getStructureMapSplitCommonCutByList(structureMap, htmlContent, recTitle, titles);
             BeiLunHtmlAnalysisUtil.insertModuleId(modeId, recTypeId, structureMap);
         } catch (Exception e) {
             log.error(e.getMessage(), e);

+ 52 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/ADLGradeDocTrans.java

@@ -0,0 +1,52 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.lantone.qc.pub.model.doc.ADLGradeDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.hangzhoufubao.util.ADLGradeHtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName: ADLGradeDocTrans
+ * @Description: ADL评分
+ * @Author songxl
+ * @Date 2021/3/9
+ * @Version 1.0
+ */
+@Slf4j
+public class ADLGradeDocTrans extends ModelDocTrans {
+    @Override
+    public ADLGradeDoc extract(MedrecVo medrecVo) {
+        ADLGradeDoc adlGradeDoc = null;
+        try {
+            Map<String, Object> contentMap = ((List<Map>) medrecVo.getContent().get("content")).get(0);
+            String content = contentMap.get("xmlText").toString();
+            Map<String, String> structureMap = null;
+            if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+                structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+            } else {
+                String recTitle = contentMap.get("recTitle").toString();
+                String recTypeId = contentMap.get("recTypeId").toString();
+                ADLGradeHtmlAnalysis adlGradeHtmlAnalysis = new ADLGradeHtmlAnalysis();
+                Map<String, String> sourceMap = adlGradeHtmlAnalysis.analysis(content, recTitle, recTypeId);
+                if (MapUtils.isNotEmpty(sourceMap)) {
+                    structureMap.putAll(sourceMap);
+                }
+            }
+            if (MapUtils.isNotEmpty(structureMap)) {
+                              ModelDocGenerate.beHospitalizedDocGen(structureMap);
+                adlGradeDoc = ModelDocGenerate.adlGradeDocGen(structureMap);
+                adlGradeDoc.setPageData((Map) structureMap);
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return adlGradeDoc;
+    }
+}

+ 38 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/AnesthesiaRecordDocTrans.java

@@ -0,0 +1,38 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.AnesthesiaRecordDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.trans.ModelDocTrans;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+
+/**
+ * @ClassName: AnesthesiaRecordDocTrans
+ * @Description: 手麻记录解析
+ * @Author songxl
+ * @Date 2021/3/19
+ * @Version 1.0
+ */
+@Slf4j
+public class AnesthesiaRecordDocTrans extends ModelDocTrans {
+    @Override
+    public List<AnesthesiaRecordDoc> extract(MedrecVo medrecVo) {
+        List<AnesthesiaRecordDoc> anesList = Lists.newArrayList();
+        try {
+            //1.获取mrqc medrecVo content数据
+            List<String> anesthesiaList = (List<String>)medrecVo.getContent().get("content");
+            //2.装载到AnesthesiaRecordDoc
+            anesthesiaList.forEach(anesthesiaStr->{
+                AnesthesiaRecordDoc anesthesiaTemp =JSONObject.parseObject
+                        (anesthesiaStr, AnesthesiaRecordDoc.class);
+                anesList.add(anesthesiaTemp);
+            });
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return anesList;
+    }
+}

+ 74 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/BeHospitalizedDocTrans.java

@@ -0,0 +1,74 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.BeHospitalizedDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.BeHospitalizedHtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 入院记录文档生成
+ * @author: rengb
+ * @time: 2020/3/5 15:47
+ */
+@Slf4j
+public class BeHospitalizedDocTrans extends ModelDocTrans {
+
+    @Override
+    public BeHospitalizedDoc extract(MedrecVo medrecVo) {
+        BeHospitalizedDoc beHospitalizedDoc = null;
+        try {
+            Map<String, Object> contentMap = ((List<Map>) medrecVo.getContent().get("content")).get(0);
+            String content = contentMap.get("htmlText").toString();
+            Map<String, String> structureMap = null;
+            if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+                structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+            } else {
+                String recTitle = contentMap.get("recTitle").toString();
+                String recTypeId = contentMap.get("recTypeId").toString();
+                HtmlAnalysis htmlAnalysis = new BeHospitalizedHtmlAnalysis();
+                Map<String, String> sourceMap = htmlAnalysis.analysis(content, recTitle, recTypeId);
+                if (MapUtils.isNotEmpty(sourceMap)) {
+                    structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                    structureMap.put("记录编号", contentMap.get("recId").toString());
+                    structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+                    //初步诊断特殊处理
+                    if (structureMap.containsKey("初步诊断")) {
+                        String initDiag = structureMap.get("初步诊断");
+                        if (initDiag.contains("<img")) {
+                            initDiag = initDiag.split("<img")[0];
+                            structureMap.put("初步诊断", initDiag);
+                        }
+                    }
+                }
+            }
+            if (MapUtils.isNotEmpty(structureMap)) {
+                beHospitalizedDoc = ModelDocGenerate.beHospitalizedDocGen(structureMap);
+                beHospitalizedDoc.setPageData((Map) structureMap);
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return beHospitalizedDoc;
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "家庭地址=住址",
+            "出生地=籍贯",
+            "疼痛评估=疼痛",
+            "代诉=主诉",
+            "入院日期=入院时间",
+            "记录日期=记录时间"
+//            "西医诊断"
+    );
+
+}

+ 73 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/ClinicBloodEffectDocTrans.java

@@ -0,0 +1,73 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.ClinicBloodEffectDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.ClinicBloodEffectHtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author 王宇
+ * @create 2020-04-30 12:39
+ * @desc 输血后效果评价
+ **/
+@Slf4j
+public class ClinicBloodEffectDocTrans extends ModelDocTrans {
+
+    @Override
+    public List<ClinicBloodEffectDoc> extract(MedrecVo medrecVo) {
+        List<ClinicBloodEffectDoc> retList = Lists.newArrayList();
+        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");
+        contentMaps.forEach(contentMap -> {
+            try {
+                ClinicBloodEffectDoc clinicBloodEffectDoc = getClinicalBloodDoc(contentMap);
+                if (clinicBloodEffectDoc != null) {
+                    retList.add(clinicBloodEffectDoc);
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        });
+        return retList;
+    }
+
+    private ClinicBloodEffectDoc getClinicalBloodDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis htmlAnalysis = new ClinicBloodEffectHtmlAnalysis();
+            Map<String, String> sourceMap = htmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        if (MapUtils.isNotEmpty(structureMap)) {
+            ClinicBloodEffectDoc clinicBloodEffectDoc = ModelDocGenerate.clinicBloodEffectDoc(structureMap);
+            clinicBloodEffectDoc.setPageData((Map) structureMap);
+            return clinicBloodEffectDoc;
+        } else {
+            return null;
+        }
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "病历标题=标题",
+            "病情记录=病历内容"
+    );
+
+}

+ 77 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/ClinicalBloodDocTrans.java

@@ -0,0 +1,77 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.ClinicalBloodDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.ClinicalBloodHtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 输血/血制品病程记录文档生成
+ * @author: rengb
+ * @time: 2020/3/17 13:21
+ */
+@Slf4j
+public class ClinicalBloodDocTrans extends ModelDocTrans {
+
+    @Override
+    public List<ClinicalBloodDoc> extract(MedrecVo medrecVo) {
+        List<ClinicalBloodDoc> retList = Lists.newArrayList();
+        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");
+        contentMaps.forEach(contentMap -> {
+            try {
+                ClinicalBloodDoc clinicalBloodDoc = getClinicalBloodDoc(contentMap);
+                if (clinicalBloodDoc != null) {
+                    retList.add(clinicalBloodDoc);
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        });
+        return retList;
+    }
+
+    private ClinicalBloodDoc getClinicalBloodDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis htmlAnalysis = new ClinicalBloodHtmlAnalysis();
+            Map<String, String> sourceMap = htmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        if (MapUtils.isNotEmpty(structureMap)) {
+            ClinicalBloodDoc clinicalBloodDoc = ModelDocGenerate.clinicalBloodDocGen(structureMap);
+            clinicalBloodDoc.setText(CommonAnalysisUtil.html2String(content));
+            clinicalBloodDoc.setPageData((Map) structureMap);
+            return clinicalBloodDoc;
+        } else {
+            return null;
+        }
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "病历标题=标题",
+            "输注成分=输注种类、血型、数量",
+            "输血过程=输注过程",
+            "病情记录=病历内容"
+    );
+
+}

+ 278 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/ConsultationDocTrans.java

@@ -0,0 +1,278 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.lantone.qc.pub.model.doc.consultation.ConsultationApplicationDoc;
+import com.lantone.qc.pub.model.doc.consultation.ConsultationDoc;
+import com.lantone.qc.pub.model.doc.consultation.ConsultationRecordDoc;
+import com.lantone.qc.pub.model.doc.consultation.ConsultationResultsDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.ConsultationHtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.ConsultationRecordHtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @Description: 会诊文档生成
+ * @author: rengb
+ * @time: 2020/3/17 13:22
+ */
+@Slf4j
+public class ConsultationDocTrans extends ModelDocTrans {
+
+    @Override
+    public List<ConsultationDoc> extract(MedrecVo medrecVo) {
+        List<ConsultationDoc> retList = Lists.newArrayList();
+
+        Map<String, List<Object>> contentMap = (Map) medrecVo.getContent().get("content");
+        if (contentMap == null) {
+            return retList;
+        }
+
+        Map<String, ConsultationRecordDoc> consultationRecordDocMap = getConsultationRecordDocMap((List) contentMap.get("会诊记录"));
+        Map<String, ConsultationResultsDoc> consultationResultsDocMap = getConsultationResultsDocMap((List) contentMap.get("会诊结果单"));
+        Map<String, ConsultationApplicationDoc> consultationApplicationDocMap = getConsultationApplicationDocMap((List) contentMap.get("会诊申请单"));
+
+        Set<String> consultationNameSet = Sets.newHashSet();
+        consultationNameSet.addAll(consultationRecordDocMap.keySet());
+        consultationNameSet.addAll(consultationResultsDocMap.keySet());
+        consultationNameSet.addAll(consultationApplicationDocMap.keySet());
+
+        consultationNameSet.forEach(consultationName -> {
+            ConsultationDoc consultationDoc = new ConsultationDoc();
+            consultationDoc.setConsultationName(consultationName);
+            consultationDoc.setConsultationRecordDoc(consultationRecordDocMap.get(consultationName));
+            consultationDoc.setConsultationResultsDoc(consultationResultsDocMap.get(consultationName));
+            consultationDoc.setConsultationApplicationDoc(consultationApplicationDocMap.get(consultationName));
+            retList.add(consultationDoc);
+        });
+
+        return retList;
+    }
+
+
+    /**************************************************会诊记录*********************************************************/
+    private Map<String, ConsultationRecordDoc> getConsultationRecordDocMap(List<Map<String, Object>> contentMaps) {
+        Map<String, ConsultationRecordDoc> retMap = Maps.newHashMap();
+        if (ListUtil.isEmpty(contentMaps)) {
+            return retMap;
+        }
+        int index = 1;
+        String consultationName = null;
+        for (Map<String, Object> contentMap : contentMaps) {
+            if (contentMap.get("htmlText") == null || StringUtil.isBlank(contentMap.get("htmlText").toString())) {
+                continue;
+            }
+            try {
+                ConsultationRecordDoc consultationRecordDoc = getConsultationRecordDoc(contentMap);
+                if (consultationRecordDoc != null) {
+                    consultationName = index + "";
+                    consultationRecordDoc.setConsultationName(consultationName);
+                    retMap.put(consultationName, consultationRecordDoc);
+                    index++;
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+        return retMap;
+    }
+
+    private ConsultationRecordDoc getConsultationRecordDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("htmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis ningBoZhongYiHtmlAnalysis = new ConsultationRecordHtmlAnalysis();
+            Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, consultationRecord_keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        if (MapUtils.isNotEmpty(structureMap)) {
+            ConsultationRecordDoc consultationRecordDoc = ModelDocGenerate.consultationRecordDocGen(structureMap);
+            consultationRecordDoc.setPageData((Map) structureMap);
+            return consultationRecordDoc;
+        } else {
+            return null;
+        }
+    }
+
+    private List<String> consultationRecord_keyContrasts = Lists.newArrayList(
+            "执行情况=会诊情况",
+            "记录日期=会诊申请日期",
+            "签名++++=签名",
+            "病情记录=简要病情",
+            "医师签名=签名"
+    );
+
+
+    /**************************************************会诊结果单*******************************************************/
+    private Map<String, ConsultationResultsDoc> getConsultationResultsDocMap(List<Map<String, Object>> contentMaps) {
+        Map<String, ConsultationResultsDoc> retMap = Maps.newHashMap();
+        if (ListUtil.isEmpty(contentMaps)) {
+            return retMap;
+        }
+        int index = 1;
+        String consultationName = null;
+        for (Map<String, Object> contentMap : contentMaps) {
+            if (contentMap.get("xmlText") == null || StringUtil.isBlank(contentMap.get("xmlText").toString())) {
+                continue;
+            }
+            try {
+                ConsultationResultsDoc consultationResultsDoc = getConsultationResultsDoc(contentMap);
+                if (consultationResultsDoc != null) {
+                    consultationName = index + "";
+                    consultationResultsDoc.setConsultationName(consultationName);
+                    retMap.put(consultationName, consultationResultsDoc);
+                    index++;
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+        return retMap;
+    }
+
+    private ConsultationResultsDoc getConsultationResultsDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis ningBoZhongYiHtmlAnalysis = new ConsultationHtmlAnalysis();
+            Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, consultationResults_pageDataTitles);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        if (StringUtil.isNotBlank(structureMap.get("会诊科室"))) {
+            structureMap.put("会诊科室", structureMap.get("会诊科室").replaceAll("XXXX", "").trim());
+        }
+        if (MapUtils.isNotEmpty(structureMap)) {
+            ConsultationResultsDoc consultationResultsDoc = ModelDocGenerate.consultationResultsDocGen(structureMap);
+            consultationResultsDoc.setPageData((Map) structureMap);
+            return consultationResultsDoc;
+        } else {
+            return null;
+        }
+    }
+
+    private List<String> consultationResults_pageDataTitles = Lists.newArrayList(
+            "科室=科别",
+            "专业=科别",
+            "申请会诊科别=申请科室",
+            "申请时间=申请日期",
+            "会诊日期=申请日期",
+            //"会诊诊断=当前诊断",
+            "患者病情及诊疗经过、申请会诊的理由及目的=会诊目的",
+            "病情摘要=会诊目的",
+            "出生年月=出生日期",
+            "床位=床号",
+            "外来专家意见=会诊意见",
+            "由受邀医生填写,本次会诊是否必要=由受邀医生填写本次会诊是否必要",
+            "单位=会诊医师所在医疗机构名称",
+            "记录医师"
+    );
+
+
+    /**************************************************会诊申请单*******************************************************/
+    private Map<String, ConsultationApplicationDoc> getConsultationApplicationDocMap(List<Map<String, Object>> contentMaps) {
+        Map<String, ConsultationApplicationDoc> retMap = Maps.newHashMap();
+        if (ListUtil.isEmpty(contentMaps)) {
+            return retMap;
+        }
+        int index = 1;
+        String consultationName = null;
+        for (Map<String, Object> contentMap : contentMaps) {
+            if (contentMap.get("xmlText") == null || StringUtil.isBlank(contentMap.get("xmlText").toString())) {
+                continue;
+            }
+            consultationName = index + "";
+            ConsultationApplicationDoc consultationApplicationDoc = getConsultationApplicationDoc(contentMap);
+            consultationApplicationDoc.setConsultationName(consultationName);
+            retMap.put(consultationName, consultationApplicationDoc);
+            index++;
+        }
+        return retMap;
+    }
+
+    private ConsultationApplicationDoc getConsultationApplicationDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis ningBoZhongYiHtmlAnalysis = new ConsultationHtmlAnalysis();
+            Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, consultationApplication_keyContrasts);
+            structureMap.put("记录编号", contentMap.get("recId").toString());
+            structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+        }
+
+        ConsultationApplicationDoc consultationApplicationDoc = ModelDocGenerate.consultationApplicationDocGen(structureMap);
+        consultationApplicationDoc.setText(content);
+        consultationApplicationDoc.setPageData((Map) structureMap);
+
+        return consultationApplicationDoc;
+    }
+
+    private List<String> consultationApplication_sourceTitles = Lists.newArrayList(
+            "姓名",
+            "性别",
+            "病区",
+            "床号",
+            "病案号",
+            "简要病情及诊疗",
+            "申请理由目的",
+            "受邀科室",
+            "会诊分类",
+            "会诊时间",
+            "会诊地点",
+            "签名"
+    );
+
+    private List<String> consultationApplication_keyContrasts = Lists.newArrayList(
+            "++++姓名=姓名",
+            "申请时间=申请日期",
+            "性别=性别",
+            "++++病区=病区",
+            "床号=",
+            "++++病案号=病案号",
+            "新会诊-简要病情及诊疗=简要病情及诊疗",
+            "新会诊-申请理由目的=会诊目的",
+            "新会诊-受邀科室=受邀科室",
+            "新会诊-会诊分类=会诊分类",
+            "新会诊-会诊时间=会诊时间",
+            "新会诊-会诊地点=会诊地点",
+            "新会诊-接待医生=会诊医师",
+            "新会诊-会诊意见=会诊意见",
+            "新会诊-会诊科室=会诊科室",
+            "签名++++=签名",
+            "++++会诊医师=会诊医师"
+    );
+
+}

+ 36 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/CrisisInfoDocTrans.java

@@ -0,0 +1,36 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.CrisisInfoDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 危急值结构化信息
+ * @author: rengb
+ * @time: 2020/3/19 19:41
+ */
+public class CrisisInfoDocTrans extends ModelDocTrans {
+
+    @Override
+    public List<CrisisInfoDoc> extract(MedrecVo medrecVo) {
+        List<CrisisInfoDoc> retList = Lists.newArrayList();
+        List<String> contents = (List) medrecVo.getContent().get("content");
+        contents.forEach(content -> {
+            retList.add(getCrisisInfoDoc((Map) FastJsonUtils.getJsonToMap(content)));
+        });
+        return retList;
+    }
+
+    private CrisisInfoDoc getCrisisInfoDoc(Map<String, String> content) {
+        CrisisInfoDoc crisisInfoDoc = new CrisisInfoDoc();
+        crisisInfoDoc.setStructureMap(content);
+        crisisInfoDoc.setPageData((Map) content);
+        return crisisInfoDoc;
+    }
+
+}

+ 72 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/CrisisValueReportDocTrans.java

@@ -0,0 +1,72 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.CrisisValueReportDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.CrisisValueReportHtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 危急值记录文档生成
+ * @author: rengb
+ * @time: 2020/3/19 19:41
+ */
+@Slf4j
+public class CrisisValueReportDocTrans extends ModelDocTrans {
+
+    @Override
+    public List<CrisisValueReportDoc> extract(MedrecVo medrecVo) {
+        List<CrisisValueReportDoc> retList = Lists.newArrayList();
+        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");
+        contentMaps.forEach(contentMap -> {
+            try {
+                CrisisValueReportDoc crisisValueReportDoc = getCrisisValueReportDoc(contentMap);
+                if (crisisValueReportDoc != null) {
+                    retList.add(crisisValueReportDoc);
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        });
+        return retList;
+    }
+
+    private CrisisValueReportDoc getCrisisValueReportDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("htmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis ningBoZhongYiHtmlAnalysis = new CrisisValueReportHtmlAnalysis();
+            Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        if (MapUtils.isNotEmpty(structureMap)) {
+            CrisisValueReportDoc crisisValueReportDoc = ModelDocGenerate.crisisValueReportDocGen(structureMap);
+            crisisValueReportDoc.setPageData((Map) structureMap);
+            return crisisValueReportDoc;
+        } else {
+            return null;
+        }
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "病情记录=病情分析及处理"
+    );
+
+}

+ 79 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/CriticallyIllNoticeDocTrans.java

@@ -0,0 +1,79 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.CriticallyIllNoticeDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.CriticallyIllNoticeHtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 病危通知书文档生成
+ * @author: rengb
+ * @time: 2020/3/19 19:41
+ */
+@Slf4j
+public class CriticallyIllNoticeDocTrans extends ModelDocTrans {
+
+    @Override
+    public List<CriticallyIllNoticeDoc> extract(MedrecVo medrecVo) {
+        List<CriticallyIllNoticeDoc> retList = Lists.newArrayList();
+        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");
+        contentMaps.forEach(contentMap -> {
+            try {
+                CriticallyIllNoticeDoc criticallyIllNoticeDoc = getCriticallyIllNoticeDoc(contentMap);
+                if (criticallyIllNoticeDoc != null) {
+                    retList.add(criticallyIllNoticeDoc);
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        });
+        return retList;
+    }
+
+    private CriticallyIllNoticeDoc getCriticallyIllNoticeDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis ningBoZhongYiHtmlAnalysis = new CriticallyIllNoticeHtmlAnalysis();
+            Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        if (MapUtils.isNotEmpty(structureMap)) {
+            CriticallyIllNoticeDoc criticallyIllNoticeDoc = ModelDocGenerate.criticallyIllNoticeDocGen(structureMap);
+            criticallyIllNoticeDoc.setText(CommonAnalysisUtil.html2String(content));
+            criticallyIllNoticeDoc.setPageData((Map) structureMap);
+            return criticallyIllNoticeDoc;
+        } else {
+            return null;
+        }
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "1.简要病情=简要病情",
+            "2.目前诊断=目前诊断",
+            "3.目前病情评估=目前病情评估",
+            "4.目前患者病情危重,随时出现以下一种或多种危及患者生命的并发症,且病情有进一步恶化可能=进一步恶化可能",
+            "5.注意事项=注意事项",
+            "6.患方知情选择=患方知情选择"
+    );
+
+}

+ 61 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DeathCaseDiscussDocTrans.java

@@ -0,0 +1,61 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.DeathCaseDiscussDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.DeathCaseDiscussHtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 死亡病例讨论记录文档生成
+ * @author: rengb
+ * @time: 2020/3/17 13:22
+ */
+@Slf4j
+public class DeathCaseDiscussDocTrans extends ModelDocTrans {
+
+    @Override
+    public DeathCaseDiscussDoc extract(MedrecVo medrecVo) {
+        DeathCaseDiscussDoc deathCaseDiscussDoc = null;
+        try {
+            Map<String, Object> contentMap = ((List<Map>) medrecVo.getContent().get("content")).get(0);
+            String content = contentMap.get("xmlText").toString();
+            Map<String, String> structureMap = null;
+            if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+                structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+            } else {
+                String recTitle = contentMap.get("recTitle").toString();
+                String recTypeId = contentMap.get("recTypeId").toString();
+                HtmlAnalysis ningBoZhongYiHtmlAnalysis = new DeathCaseDiscussHtmlAnalysis();
+                Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+                if (MapUtils.isNotEmpty(sourceMap)) {
+                    structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                    structureMap.put("记录编号", contentMap.get("recId").toString());
+                    structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+                }
+            }
+            if (MapUtils.isNotEmpty(structureMap)) {
+                deathCaseDiscussDoc = ModelDocGenerate.deathCaseDiscussDocGen(structureMap);
+                deathCaseDiscussDoc.setPageData((Map) structureMap);
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return deathCaseDiscussDoc;
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "讨论内容(包括病史摘要、治疗抢救过程、讨论目的、讨论意见及结论)=讨论内容",
+            "病史摘要(经管医师汇报病史)=病史摘要"
+    );
+
+}

+ 65 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DeathRecordDocTrans.java

@@ -0,0 +1,65 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.DeathRecordDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.DeathRecordHtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 死亡记录文档生成
+ * @author: rengb
+ * @time: 2020/3/17 13:23
+ */
+@Slf4j
+public class DeathRecordDocTrans extends ModelDocTrans {
+
+    @Override
+    public DeathRecordDoc extract(MedrecVo medrecVo) {
+        DeathRecordDoc deathRecordDoc = null;
+        try {
+            Map<String, Object> contentMap = ((List<Map>) medrecVo.getContent().get("content")).get(0);
+            String content = contentMap.get("xmlText").toString();
+            Map<String, String> structureMap = null;
+            if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+                structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+            } else {
+                String recTitle = contentMap.get("recTitle").toString();
+                String recTypeId = contentMap.get("recTypeId").toString();
+                HtmlAnalysis ningBoZhongYiHtmlAnalysis = new DeathRecordHtmlAnalysis();
+                Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+                if (MapUtils.isNotEmpty(sourceMap)) {
+                    structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                    structureMap.put("记录编号", contentMap.get("recId").toString());
+                    structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+                }
+            }
+            if (MapUtils.isNotEmpty(structureMap)) {
+                deathRecordDoc = ModelDocGenerate.deathRecordDocGen(structureMap);
+                deathRecordDoc.setText(CommonAnalysisUtil.html2String(content));
+                deathRecordDoc.setPageData((Map) structureMap);
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return deathRecordDoc;
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "签名时间=记录时间",
+            "科室=科别",
+            "死亡时间=死亡日期",
+            "医生签名=记录医生"
+    );
+
+}

+ 93 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DifficultCaseDiscussDocTrans.java

@@ -0,0 +1,93 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.DifficultCaseDiscussDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.DifficultCaseDiscussHtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 疑难病例讨论记录文档生成
+ * @author: rengb
+ * @time: 2020/3/17 13:23
+ */
+@Slf4j
+public class DifficultCaseDiscussDocTrans extends ModelDocTrans {
+
+    @Override
+    public List<DifficultCaseDiscussDoc> extract(MedrecVo medrecVo) {
+        List<DifficultCaseDiscussDoc> retList = Lists.newArrayList();
+        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");
+        contentMaps.forEach(contentMap -> {
+            try {
+                DifficultCaseDiscussDoc difficultCaseDiscussDoc = getDifficultCaseDiscussDoc(contentMap);
+                if (difficultCaseDiscussDoc != null) {
+                    retList.add(difficultCaseDiscussDoc);
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        });
+        return retList;
+    }
+
+    private DifficultCaseDiscussDoc getDifficultCaseDiscussDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("htmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis ningBoZhongYiHtmlAnalysis = new DifficultCaseDiscussHtmlAnalysis();
+            Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            /*if (!sourceMap.containsKey("具体讨论意见") && sourceMap.containsKey("参加人员")) {
+                String participant = sourceMap.get("参加人员");
+                if (participant.contains("医师汇报病史")) {
+                    String parCrew = "";
+                    //参加人员
+                    if (participant.indexOf("医师汇报病史") > 2) {
+                        parCrew = participant.substring(0, participant.indexOf("医师汇报病史") - 2);
+                    }
+                    //具体讨论意见
+                    String SpeDiscussion = participant.substring(Math.max(0, participant.indexOf("医师汇报病史") - 2));
+                    sourceMap.put("参加人员", parCrew);
+                    sourceMap.put("具体讨论意见", SpeDiscussion);
+                }
+            }*/
+
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        if (MapUtils.isNotEmpty(structureMap)) {
+            DifficultCaseDiscussDoc difficultCaseDiscussDoc = ModelDocGenerate.difficultCaseDiscussDocGen(structureMap);
+            difficultCaseDiscussDoc.setPageData((Map) structureMap);
+            return difficultCaseDiscussDoc;
+        } else {
+            return null;
+        }
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "床位=床号",
+            "讨论主持人=主持人姓名及专业技术职务",
+            "参加讨论人=参加人员的姓名及专业技术职务",
+            "病史简要=汇报病史",
+            "病史摘要=汇报病史",
+            "讨论意见=具体讨论意见",
+            "主持人小结=主持人总结"
+    );
+
+}

+ 36 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DoctorAdviceDocTrans.java

@@ -0,0 +1,36 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.DoctorAdviceDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 医嘱信息文档生成
+ * @author: rengb
+ * @time: 2020/3/19 19:41
+ */
+public class DoctorAdviceDocTrans extends ModelDocTrans {
+
+    @Override
+    public List<DoctorAdviceDoc> extract(MedrecVo medrecVo) {
+        List<DoctorAdviceDoc> retList = Lists.newArrayList();
+        List<String> contents = (List) medrecVo.getContent().get("content");
+        contents.forEach(content -> {
+            retList.add(getDoctorAdviceDoc((Map) FastJsonUtils.getJsonToMap(content)));
+        });
+        return retList;
+    }
+
+    private DoctorAdviceDoc getDoctorAdviceDoc(Map<String, String> content) {
+        DoctorAdviceDoc doctorAdviceDoc = new DoctorAdviceDoc();
+        doctorAdviceDoc.setStructureMap(content);
+        doctorAdviceDoc.setPageData((Map) content);
+        return doctorAdviceDoc;
+    }
+
+}

+ 72 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DutyShiftSystemDocTrans.java

@@ -0,0 +1,72 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.DutyShiftSystemDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.DutyShiftSystemHtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 值班交接制度文档生成
+ * @author: rengb
+ * @time: 2020/3/17 13:24
+ */
+@Slf4j
+public class DutyShiftSystemDocTrans extends ModelDocTrans {
+
+    @Override
+    public List<DutyShiftSystemDoc> extract(MedrecVo medrecVo) {
+        List<DutyShiftSystemDoc> retList = Lists.newArrayList();
+        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");
+        contentMaps.forEach(contentMap -> {
+            try {
+                DutyShiftSystemDoc dutyShiftSystemDoc = getDutyShiftSystemDoc(contentMap);
+                if (dutyShiftSystemDoc != null) {
+                    retList.add(dutyShiftSystemDoc);
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        });
+        return retList;
+    }
+
+    private DutyShiftSystemDoc getDutyShiftSystemDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("htmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis ningBoZhongYiHtmlAnalysis = new DutyShiftSystemHtmlAnalysis();
+            Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        if (MapUtils.isNotEmpty(structureMap)) {
+            DutyShiftSystemDoc dutyShiftSystemDoc = ModelDocGenerate.dutyShiftSystemDocGen(structureMap);
+            dutyShiftSystemDoc.setPageData((Map) structureMap);
+            return dutyShiftSystemDoc;
+        } else {
+            return null;
+        }
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+
+    );
+
+}

+ 83 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/FirstCourseRecordDocTrans.java

@@ -0,0 +1,83 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.model.doc.FirstCourseRecordDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.FirstCourseRecordHtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.HangzhoufubaoFirstCourseRecordHtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+import static com.lantone.qc.trans.comsis.ModelDocGenerate.structureMapJoin;
+
+/**
+ * @Description: 首次病程录文档生成
+ * @author: rengb
+ * @time: 2020/3/17 13:25
+ */
+@Slf4j
+public class FirstCourseRecordDocTrans extends ModelDocTrans {
+
+    @Override
+    public FirstCourseRecordDoc extract(MedrecVo medrecVo) {
+        FirstCourseRecordDoc firstCourseRecordDoc = null;
+        try {
+            Map<String, Object> contentMap = ((List<Map>) medrecVo.getContent().get("content")).get(0);
+            String content = contentMap.get("htmlText").toString();
+            Map<String, String> structureMap = null;
+            if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+                structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+            } else {
+                String recTitle = contentMap.get("recTitle").toString();
+                String recTypeId = contentMap.get("recTypeId").toString();
+                HtmlAnalysis hangzhoufubaoHtmlAnalysis = new HangzhoufubaoFirstCourseRecordHtmlAnalysis();
+                Map<String, String> sourceMap = hangzhoufubaoHtmlAnalysis.analysis(content, recTitle, recTypeId);
+                if (MapUtils.isNotEmpty(sourceMap)) {
+                    sourceMap = removeSerialNumber(sourceMap);
+                    structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                    structureMap.put("记录编号", contentMap.get("recId").toString());
+                    structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+                    structureMap.put("标题", recTitle);
+                }
+            }
+            if (StringUtil.isNotBlank(structureMap.get("医生签名"))) {
+                structureMap.put("医生签名", structureMap.get("医生签名").replaceAll("医生签名", ""));
+            }
+            if (MapUtils.isNotEmpty(structureMap)) {
+                firstCourseRecordDoc = ModelDocGenerate.firstCourseRecordDocGen(structureMap);
+                firstCourseRecordDoc.setText(CommonAnalysisUtil.html2String(content));
+                firstCourseRecordDoc.setPageData((Map) structureMap);
+                List<String> keys = Lists.newArrayList("需求评估", "预期目标", "诊疗计划", "治疗监测计划");
+                String treatPlanJoin = structureMapJoin(structureMap, keys);
+                firstCourseRecordDoc.getTreatPlanLabel().setAiText(treatPlanJoin);
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return firstCourseRecordDoc;
+    }
+
+    private Map<String, String> removeSerialNumber(Map<String, String> sourceMap) {
+        Map<String, String> structureMap = Maps.newLinkedHashMap();
+        sourceMap.forEach((key, value) -> structureMap.put(key.replaceAll("[一二三四五六()().123456]", ""), value));
+        return structureMap;
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "病历特点=病例特点",
+            "入院查体=查体",
+            "辅助检查=辅检"
+    );
+
+}

+ 54 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/FirstPageRecordDocTrans.java

@@ -0,0 +1,54 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Maps;
+import com.lantone.qc.dbanaly.util.ModuleMappingUtil;
+import com.lantone.qc.pub.Content;
+import com.lantone.qc.pub.model.doc.FirstPageRecordDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+
+import java.util.Map;
+
+/**
+ * @Description: 病案首页文档生成
+ * @author: 胡敬
+ * @time: 2020/3/16 17:47
+ */
+public class FirstPageRecordDocTrans extends ModelDocTrans {
+
+    @Override
+    public FirstPageRecordDoc extract(MedrecVo medrecVo) {
+        Map<String, String> content = (Map) medrecVo.getContent();
+        FirstPageRecordDoc firstPageRecordDoc = new FirstPageRecordDoc();
+        firstPageRecordDoc.setStructureMap(content);
+
+        Map<String, Object> structureExtMap = Maps.newHashMap();
+        structureExtMap.putAll(content);
+        structureExtMap.put(Content.diagnose_cts, FastJsonUtils.getJsonToBean(content.get(Content.diagnose_cts), Object.class));
+        //        structureExtMap.put(Content.outpatientEmergencyDiag, FastJsonUtils.getJsonToBean(content.get(Content.outpatientEmergencyDiag), Object.class));
+        structureExtMap.put(Content.operative_information, FastJsonUtils.getJsonToBean(content.get(Content.operative_information), Object.class));
+        structureExtMap.put(Content.dischargeDiag, FastJsonUtils.getJsonToBean(content.get(Content.dischargeDiag), Object.class));
+        //        structureExtMap.put(Content.pathologyDiagnose, FastJsonUtils.getJsonToBean(content.get(Content.pathologyDiagnose), Object.class));
+        firstPageRecordDoc.setStructureExtMap(structureExtMap);
+        //病案首页出院诊断页面信息只保留主要诊断和其他诊断
+        /*List<Map<String, String>> list = (List<Map<String, String>>) FastJsonUtils.getJsonToBean(content.get(Content.dischargeDiag), Object.class);
+        if (ListUtil.isNotEmpty(list)) {
+            Iterator<Map<String, String>> iterator = list.iterator();
+            Map<String, String> map = new HashMap<>();
+            while (iterator.hasNext()) {
+                map = new HashMap<>();
+                map = iterator.next();
+                if (!((map.get("诊断类别") != null && map.get("诊断类别").equals("主要诊断"))
+                        || (map.get("诊断类别") != null && map.get("诊断类别").equals("其他诊断")))) {
+                    iterator.remove();
+                }
+            }
+            medrecVo.getContent().put("出院诊断", list.toString());
+        }*/
+        medrecVo.getContent().put("mode_id", ModuleMappingUtil.getStandardModuleId("6"));
+        firstPageRecordDoc.setPageData(medrecVo.getContent());
+        return firstPageRecordDoc;
+    }
+
+}

+ 287 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/HangzhoufubaoDocTrans.java

@@ -0,0 +1,287 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.doc.InvasiveOperationDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.model.vo.QueryVo;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @ClassName : DocTrans
+ * @Description :
+ * @Author : 楼辉荣
+ * @Date: 2020-03-03 19:47
+ */
+@Slf4j
+public class HangzhoufubaoDocTrans extends com.lantone.qc.trans.DocTrans {
+
+    @Override
+    protected InputInfo extract(QueryVo queryVo) {
+        InputInfo inputInfo = new InputInfo();
+        for (MedrecVo i : queryVo.getMedrec()) {
+            if (i.getTitle() != null) {
+                if (i.getTitle().equals("会诊")) {
+                    ConsultationDocTrans consultationDocTrans = new ConsultationDocTrans();
+                    inputInfo.setConsultationDocs(consultationDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("手术")) {
+                    OperationDocTrans operationDocTrans = new OperationDocTrans();
+                    inputInfo.setOperationDocs(operationDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("转科")) {
+                    TransferRecordDocTrans transferRecordDocTrans = new TransferRecordDocTrans();
+                    inputInfo.setTransferRecordDocs(transferRecordDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("入院记录")) {
+                    BeHospitalizedDocTrans beHospitalizedDocTrans = new BeHospitalizedDocTrans();
+                    inputInfo.setBeHospitalizedDoc(beHospitalizedDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("输血/血制品病程记录")) {
+                    ClinicalBloodDocTrans clinicalBloodDocTrans = new ClinicalBloodDocTrans();
+                    inputInfo.setClinicalBloodDocs(clinicalBloodDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("输血后效果评价")) {
+                    ClinicBloodEffectDocTrans clinicBloodEffectDocTrans = new ClinicBloodEffectDocTrans();
+                    inputInfo.setClinicBloodEffectDocs(clinicBloodEffectDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("危急值记录")) {
+                    CrisisValueReportDocTrans crisisValueReportDocTrans = new CrisisValueReportDocTrans();
+                    inputInfo.setCrisisValueReportDocs(crisisValueReportDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("危急值")) {
+                    CrisisInfoDocTrans crisisInfoDocTrans = new CrisisInfoDocTrans();
+                    inputInfo.setCrisisInfoDocs(crisisInfoDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("病危通知书")) {
+                    CriticallyIllNoticeDocTrans criticallyIllNoticeDocTrans = new CriticallyIllNoticeDocTrans();
+                    inputInfo.setCriticallyIllNoticeDocs(criticallyIllNoticeDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("死亡病例讨论记录")) {
+                    DeathCaseDiscussDocTrans deathCaseDiscussDocTrans = new DeathCaseDiscussDocTrans();
+                    inputInfo.setDeathCaseDiscussDoc(deathCaseDiscussDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("死亡记录")) {
+                    DeathRecordDocTrans deathRecordDocTrans = new DeathRecordDocTrans();
+                    inputInfo.setDeathRecordDoc(deathRecordDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("疑难病例讨论记录")) {
+                    DifficultCaseDiscussDocTrans difficultCaseDiscussDocTrans = new DifficultCaseDiscussDocTrans();
+                    inputInfo.setDifficultCaseDiscussDocs(difficultCaseDiscussDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("医嘱信息")) {
+                    DoctorAdviceDocTrans doctorAdviceDocTrans = new DoctorAdviceDocTrans();
+                    inputInfo.setDoctorAdviceDocs(doctorAdviceDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("交接班记录")) {
+                    DutyShiftSystemDocTrans dutyShiftSystemDocTrans = new DutyShiftSystemDocTrans();
+                    inputInfo.setDutyShiftSystemDocs(dutyShiftSystemDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("首次病程录")) {
+                    FirstCourseRecordDocTrans firstCourseRecordDocTrans = new FirstCourseRecordDocTrans();
+                    inputInfo.setFirstCourseRecordDoc(firstCourseRecordDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("病案首页")) {
+                    FirstPageRecordDocTrans firstPageRecordDocTrans = new FirstPageRecordDocTrans();
+                    inputInfo.setFirstPageRecordDoc(firstPageRecordDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("出院小结")) {
+                    LeaveHospitalDocTrans leaveHospitalDocTrans = new LeaveHospitalDocTrans();
+                    inputInfo.setLeaveHospitalDoc(leaveHospitalDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("抢救记录")) {
+                    RescueDocTrans rescueDocTrans = new RescueDocTrans();
+                    inputInfo.setRescueDocs(rescueDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("阶段小结")) {
+                    StagesSummaryDocTrans stagesSummaryDocTrans = new StagesSummaryDocTrans();
+                    inputInfo.setStagesSummaryDocs(stagesSummaryDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("查房记录")) {
+                    ThreeLevelWardDocTrans threeLevelWardDocTrans = new ThreeLevelWardDocTrans();
+                    threeLevelWardDocTrans.setOperationDocs(inputInfo.getOperationDocs());
+                    inputInfo.setThreeLevelWardDocs(threeLevelWardDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("住院病历信息")) {
+                    MedicalRecordInfoDocTrans medicalRecordInfoDocTrans = new MedicalRecordInfoDocTrans();
+                    inputInfo.setMedicalRecordInfoDoc(medicalRecordInfoDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("化验")) {
+                    LisDocTrans lisDocTrans = new LisDocTrans();
+                    inputInfo.setLisDocs(lisDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("辅检")) {
+                    PacsDocTrans pacsDocTrans = new PacsDocTrans();
+                    inputInfo.setPacsDocs(pacsDocTrans.extract(i));
+                }
+                if (i.getTitle().equals("门诊")) {
+                    OutDepDocTrans outDepDocTrans = new OutDepDocTrans();
+                    inputInfo.setBeHospitalizedDoc(outDepDocTrans.extract(i));
+                }
+                /*******************************VTE评分 trans解析*****************************************/
+                if (i.getTitle().equals("VTE评分")) {
+                    VTEGradeDocTrans vteGradeDocTrans = new VTEGradeDocTrans();
+                    inputInfo.setVteGradeDoc(vteGradeDocTrans.extract(i));
+                }
+                /*******************************ADL评分 trans解析*****************************************/
+                if (i.getTitle().equals("ADL评分")) {
+                    ADLGradeDocTrans adlGradeDocTrans = new ADLGradeDocTrans();
+                    inputInfo.setAdlGradeDoc(adlGradeDocTrans.extract(i));
+                }
+                /*******************************手麻记录 trans解析*****************************************/
+                if (i.getTitle().equals("手麻记录")) {
+                    AnesthesiaRecordDocTrans anesthesiaRecordDocTrans= new AnesthesiaRecordDocTrans();
+                    inputInfo.setAnesthesiaRecordDocs(anesthesiaRecordDocTrans.extract(i));
+                }
+                /*******************************有创操作 trans解析*****************************************/
+                if (i.getTitle().equals("有创操作")) {
+                    InvasiveOperationDocTrans invasiveOperationDoc= new InvasiveOperationDocTrans();
+                    inputInfo.setInvasiveOperationDocs(invasiveOperationDoc.extract(i));
+                }
+            }
+        }
+        pageDataHandle(inputInfo);
+        return inputInfo;
+    }
+
+    private void pageDataHandle(InputInfo inputInfo) {
+        if (inputInfo.getBeHospitalizedDoc() != null) {
+            inputInfo.getPageData().put("入院记录", Lists.newArrayList(inputInfo.getBeHospitalizedDoc().getPageData()));
+        }
+        if (inputInfo.getDeathCaseDiscussDoc() != null) {
+            inputInfo.getPageData().put("死亡病例讨论记录", Lists.newArrayList(inputInfo.getDeathCaseDiscussDoc().getPageData()));
+        }
+        if (inputInfo.getDeathRecordDoc() != null) {
+            inputInfo.getPageData().put("死亡记录", Lists.newArrayList(inputInfo.getDeathRecordDoc().getPageData()));
+        }
+        if (inputInfo.getFirstCourseRecordDoc() != null) {
+            inputInfo.getPageData().put("首次病程录", Lists.newArrayList(inputInfo.getFirstCourseRecordDoc().getPageData()));
+        }
+        if (inputInfo.getLeaveHospitalDoc() != null) {
+            inputInfo.getPageData().put("出院小结", Lists.newArrayList(inputInfo.getLeaveHospitalDoc().getPageData()));
+        }
+        if (inputInfo.getFirstPageRecordDoc() != null) {
+            inputInfo.getPageData().put("病案首页", Lists.newArrayList(inputInfo.getFirstPageRecordDoc().getPageData()));
+        }
+
+        if (ListUtil.isNotEmpty(inputInfo.getClinicalBloodDocs())) {
+            inputInfo.getPageData().put("输血/血制品病程记录", inputInfo.getClinicalBloodDocs().stream().map(i -> i.getPageData()).collect(Collectors.toList()));
+//            inputInfo.setClinicalBloodDocs(inputInfo.getClinicalBloodDocs().stream().filter(i -> StringUtil.isNotBlank(i.getText()) && !i.getText().contains("输白蛋白")).collect(Collectors.toList()));
+        }
+        if (ListUtil.isNotEmpty(inputInfo.getClinicBloodEffectDocs())) {
+            inputInfo.getPageData().put(
+                    "输血后效果评价",
+                    inputInfo.getClinicBloodEffectDocs()
+                            .stream()
+                            .map(i -> i.getPageData())
+                            .sorted((map1, map2) -> OrdinaryAssistant.pageDataTimeSort(map1, map2, "记录时间", "yyyy-MM-dd HH:mm"))
+                            .collect(Collectors.toList()));
+        }
+        if (ListUtil.isNotEmpty(inputInfo.getCrisisValueReportDocs())) {
+            inputInfo.getPageData().put("危急值记录", inputInfo.getCrisisValueReportDocs().stream().map(i -> i.getPageData()).collect(Collectors.toList()));
+        }
+        if (ListUtil.isNotEmpty(inputInfo.getCriticallyIllNoticeDocs())) {
+            inputInfo.getPageData().put("病危通知书", inputInfo.getCriticallyIllNoticeDocs().stream().map(i -> i.getPageData()).collect(Collectors.toList()));
+        }
+        if (ListUtil.isNotEmpty(inputInfo.getDifficultCaseDiscussDocs())) {
+            inputInfo.getPageData().put("疑难病例讨论记录", inputInfo.getDifficultCaseDiscussDocs().stream().map(i -> i.getPageData()).collect(Collectors.toList()));
+        }
+        if (ListUtil.isNotEmpty(inputInfo.getDutyShiftSystemDocs())) {
+            inputInfo.getPageData().put("值班交接制度", inputInfo.getDutyShiftSystemDocs().stream().map(i -> i.getPageData()).collect(Collectors.toList()));
+        }
+        if (ListUtil.isNotEmpty(inputInfo.getRescueDocs())) {
+            inputInfo.getPageData().put("抢救记录", inputInfo.getRescueDocs().stream().map(i -> i.getPageData()).collect(Collectors.toList()));
+        }
+        if (ListUtil.isNotEmpty(inputInfo.getStagesSummaryDocs())) {
+            inputInfo.getPageData().put("阶段小结", inputInfo.getStagesSummaryDocs().stream().map(i -> i.getPageData()).collect(Collectors.toList()));
+        }
+        if (ListUtil.isNotEmpty(inputInfo.getThreeLevelWardDocs())) {
+            inputInfo.getPageData().put("查房记录", inputInfo.getThreeLevelWardDocs().get(0).getAllDoctorWradDocs().stream().map(i -> i.getPageData()).collect(Collectors.toList()));
+        }
+        if (ListUtil.isNotEmpty(inputInfo.getConsultationDocs())) {
+            List<Map<String, Object>> crPd = inputInfo.getConsultationDocs()
+                    .stream()
+                    .filter(consultationDoc -> consultationDoc != null && consultationDoc.getConsultationRecordDoc() != null)
+                    .map(consultationDoc -> consultationDoc.getConsultationRecordDoc().getPageData())
+                    .collect(Collectors.toList());
+            if (ListUtil.isNotEmpty(crPd)) {
+                inputInfo.getPageData().put("会诊记录", crPd);
+            }
+
+            List<Map<String, Object>> caPd = inputInfo.getConsultationDocs()
+                    .stream()
+                    .filter(consultationDoc -> consultationDoc != null && consultationDoc.getConsultationApplicationDoc() != null)
+                    .map(consultationDoc -> consultationDoc.getConsultationApplicationDoc().getPageData())
+                    .collect(Collectors.toList());
+            if (ListUtil.isNotEmpty(caPd)) {
+                inputInfo.getPageData().put("会诊申请单", caPd);
+            }
+
+            List<Map<String, Object>> ctPd = inputInfo.getConsultationDocs()
+                    .stream()
+                    .filter(consultationDoc -> consultationDoc != null && consultationDoc.getConsultationResultsDoc() != null)
+                    .map(consultationDoc -> consultationDoc.getConsultationResultsDoc().getPageData())
+                    .collect(Collectors.toList());
+            if (ListUtil.isNotEmpty(ctPd)) {
+                inputInfo.getPageData().put("会诊结果单", ctPd);
+            }
+        }
+        if (ListUtil.isNotEmpty(inputInfo.getOperationDocs())) {
+            List<Map<String, Object>> odPageDataList = inputInfo.getOperationDocs()
+                    .stream()
+                    .filter(operationDoc -> operationDoc != null && operationDoc.getOperationDiscussionDoc() != null)
+                    .map(operationDoc -> operationDoc.getOperationDiscussionDoc().getPageData())
+                    .collect(Collectors.toList());
+            if (ListUtil.isNotEmpty(odPageDataList)) {
+                inputInfo.getPageData().put("术后首次病程及谈话记录", odPageDataList);
+            }
+
+            List<Map<String, Object>> orPageDataList = inputInfo.getOperationDocs()
+                    .stream()
+                    .filter(operationDoc -> operationDoc != null && operationDoc.getOperationRecordDoc() != null)
+                    .map(operationDoc -> operationDoc.getOperationRecordDoc().getPageData())
+                    .collect(Collectors.toList());
+            if (ListUtil.isNotEmpty(orPageDataList)) {
+                inputInfo.getPageData().put("手术记录", orPageDataList);
+            }
+
+            List<Map<String, Object>> pdPageDataList = inputInfo.getOperationDocs()
+                    .stream()
+                    .filter(operationDoc -> operationDoc != null && operationDoc.getPreoperativeDiscussionDoc() != null)
+                    .map(operationDoc -> operationDoc.getPreoperativeDiscussionDoc().getPageData())
+                    .collect(Collectors.toList());
+            if (ListUtil.isNotEmpty(pdPageDataList)) {
+                inputInfo.getPageData().put("术前讨论、术前小结", pdPageDataList);
+            }
+        }
+        if (inputInfo.getTransferRecordDocs() != null) {
+            if (ListUtil.isNotEmpty(inputInfo.getTransferRecordDocs().getTransferIntoDocs())) {
+                inputInfo.getPageData().put(
+                        "转入记录",
+                        inputInfo.getTransferRecordDocs().getTransferIntoDocs()
+                                .stream()
+                                .filter(i -> i != null)
+                                .map(i -> i.getPageData())
+                                .collect(Collectors.toList())
+                );
+            }
+
+            if (ListUtil.isNotEmpty(inputInfo.getTransferRecordDocs().getTransferOutDocs())) {
+                inputInfo.getPageData().put(
+                        "转出记录",
+                        inputInfo.getTransferRecordDocs().getTransferOutDocs()
+                                .stream()
+                                .filter(i -> i != null)
+                                .map(i -> i.getPageData())
+                                .collect(Collectors.toList())
+                );
+            }
+        }
+    }
+}

+ 75 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/InvasiveOperationDocTrans.java

@@ -0,0 +1,75 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.InvasiveOperationDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.beilun.util.BeiLunHtmlAnalysis;
+import com.lantone.qc.trans.beilun.util.BeiLunInvasiveOperationHtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 有创操作
+ * @author: cy
+ * @time: 2021/8/27 16:12
+ */
+@Slf4j
+public class InvasiveOperationDocTrans extends ModelDocTrans {
+    @Override
+    public List<InvasiveOperationDoc> extract(MedrecVo medrecVo) {
+        List<InvasiveOperationDoc> retList = Lists.newArrayList();
+        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");
+        contentMaps.forEach(contentMap -> {
+            retList.add(getInvasiveOperationDoc(contentMap));
+        });
+        return retList;
+
+    }
+
+    private InvasiveOperationDoc getInvasiveOperationDoc(Map<String, Object> contentMap) {
+        InvasiveOperationDoc invasiveOperationDoc = new InvasiveOperationDoc();
+        if (MapUtils.isEmpty(contentMap)) {
+            return invasiveOperationDoc;
+        }
+        if(contentMap.get("htmlText") == null && contentMap.get("htmlText") != null){
+            contentMap.put("htmlText",contentMap.get("htmlText"));
+        }
+            if (contentMap.get("htmlText") == null || StringUtil.isBlank(contentMap.get("htmlText").toString())) {
+                return invasiveOperationDoc;
+            }
+            try {
+                String content = contentMap.get("htmlText").toString();
+                Map<String, String> structureMap = null;
+                if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+                    structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+                } else {
+                    String recTitle = contentMap.get("recTitle").toString();
+                    String recTypeId = contentMap.get("recTypeId").toString();
+                    BeiLunHtmlAnalysis beiLunHtmlAnalysis = new BeiLunInvasiveOperationHtmlAnalysis();
+                    Map<String, String> sourceMap = beiLunHtmlAnalysis.analysis(content, recTitle, recTypeId);
+                    if (MapUtils.isNotEmpty(sourceMap)) {
+                        structureMap.put("记录编号", contentMap.get("recId").toString());
+                        structureMap.put("标题", recTitle);
+                        structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+                    }
+                }
+                if (MapUtils.isNotEmpty(structureMap)) {
+                    invasiveOperationDoc.setStructureMap(structureMap);
+                    invasiveOperationDoc.setPageData((Map) structureMap);
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+
+        return invasiveOperationDoc;
+    }
+
+
+
+}

+ 69 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/LeaveHospitalDocTrans.java

@@ -0,0 +1,69 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.LeaveHospitalDoc;
+import com.lantone.qc.pub.model.label.LeaveHospitalDoctorAdviceLabel;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.LeaveHospitalHtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 出院小结文档生成
+ * @author: rengb
+ * @time: 2020/3/17 13:25
+ */
+@Slf4j
+public class LeaveHospitalDocTrans extends ModelDocTrans {
+
+    @Override
+    public LeaveHospitalDoc extract(MedrecVo medrecVo) {
+        LeaveHospitalDoc leaveHospitalDoc = null;
+        try {
+            Map<String, Object> contentMap = ((List<Map>) medrecVo.getContent().get("content")).get(0);
+            String content = contentMap.get("htmlText").toString();
+            Map<String, String> structureMap = null;
+            if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+                structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+            } else {
+                String recTitle = contentMap.get("recTitle").toString();
+                String recTypeId = contentMap.get("recTypeId").toString();
+                HtmlAnalysis hangzhoufubaoHtmlAnalysis = new LeaveHospitalHtmlAnalysis();
+                Map<String, String> sourceMap = hangzhoufubaoHtmlAnalysis.analysis(content, recTitle, recTypeId);
+                if (MapUtils.isNotEmpty(sourceMap)) {
+                    structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                    structureMap.put("记录编号", contentMap.get("recId").toString());
+                    structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+                }
+            }
+            if (MapUtils.isNotEmpty(structureMap)) {
+                leaveHospitalDoc = ModelDocGenerate.leaveHospitalDocGen(structureMap);
+                if (StringUtils.isNotEmpty(structureMap.get("出院医嘱"))) {
+                    LeaveHospitalDoctorAdviceLabel leaveHospitalDoctorAdviceLabel = new LeaveHospitalDoctorAdviceLabel();
+                    leaveHospitalDoctorAdviceLabel.setText(structureMap.get("出院医嘱"));
+                    leaveHospitalDoctorAdviceLabel.setAiText(structureMap.get("出院医嘱"));
+                    leaveHospitalDoc.setLeaveHospitalDoctorAdviceLabel(leaveHospitalDoctorAdviceLabel);
+                }
+                leaveHospitalDoc.setText(CommonAnalysisUtil.html2String(content));
+                leaveHospitalDoc.setPageData((Map) structureMap);
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return leaveHospitalDoc;
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+    );
+
+}

+ 36 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/LisDocTrans.java

@@ -0,0 +1,36 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.LisDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 化验信息文档生成
+ * @author: rengb
+ * @time: 2020/3/19 19:41
+ */
+public class LisDocTrans extends ModelDocTrans {
+
+    @Override
+    public List<LisDoc> extract(MedrecVo medrecVo) {
+        List<LisDoc> retList = Lists.newArrayList();
+        List<String> contents = (List) medrecVo.getContent().get("content");
+        contents.forEach(content -> {
+            retList.add(getDoctorAdviceDoc((Map) FastJsonUtils.getJsonToMap(content)));
+        });
+        return retList;
+    }
+
+    private LisDoc getDoctorAdviceDoc(Map<String, String> content) {
+        LisDoc doctorAdviceDoc = new LisDoc();
+        doctorAdviceDoc.setStructureMap(content);
+        doctorAdviceDoc.setPageData((Map) content);
+        return doctorAdviceDoc;
+    }
+
+}

+ 26 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/MedicalRecordInfoDocTrans.java

@@ -0,0 +1,26 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.lantone.qc.pub.model.doc.MedicalRecordInfoDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.trans.ModelDocTrans;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 住院病历信息
+ * @author: 胡敬
+ * @time: 2020/6/3 15:45
+ */
+public class MedicalRecordInfoDocTrans extends ModelDocTrans {
+
+    @Override
+    public MedicalRecordInfoDoc extract(MedrecVo medrecVo) {
+        Map<String, String> content = (Map) ((List) medrecVo.getContent().get("content")).get(0);
+        MedicalRecordInfoDoc medicalRecordInfoDoc = new MedicalRecordInfoDoc();
+        medicalRecordInfoDoc.setStructureMap(content);
+        medicalRecordInfoDoc.setPageData(medrecVo.getContent());
+        return medicalRecordInfoDoc;
+    }
+
+}

+ 396 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/OperationDocTrans.java

@@ -0,0 +1,396 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.lantone.qc.pub.model.doc.operation.*;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.*;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+import org.jsoup.Jsoup;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @Description: 手术文档生成
+ * @author: rengb
+ * @time: 2020/3/20 17:11
+ */
+@Slf4j
+public class OperationDocTrans extends ModelDocTrans {
+
+    @Override
+    public List<OperationDoc> extract(MedrecVo medrecVo) {
+        List<OperationDoc> retList = Lists.newArrayList();
+
+        Map<String, List<String>> contentMap = (Map) medrecVo.getContent().get("content");
+        if (contentMap == null) {
+            return retList;
+        }
+
+        Map<String, OperationDiscussionDoc> operationDiscussionDocMap = getOperationDiscussionDocMap((List) contentMap.get("术后首次病程及谈话记录"));
+        Map<String, OperationRecordDoc> operationRecordDocMap = getOperationRecordDocMap((List) contentMap.get("手术记录"));
+        Map<String, PreoperativeDiscussionDoc> preoperativeDiscussionDocMap = getPreoperativeDiscussionDocMap((List) contentMap.get("术前讨论、术前小结"));
+        Map<String, OperationInformedConsentDoc> operationInformedConsentDocMap = getOperationInformedConsentDocMap((List) contentMap.get("手术知情同意书"));
+        Map<String, OperationSafetyChecklistDoc> operationSafetyChecklistDocMap = getOperationSafetyChecklistDocMap((List) contentMap.get("手术安全核查表"));
+
+        Set<String> operationNameSet = Sets.newHashSet();
+        operationNameSet.addAll(operationDiscussionDocMap.keySet());
+        operationNameSet.addAll(operationRecordDocMap.keySet());
+        operationNameSet.addAll(preoperativeDiscussionDocMap.keySet());
+
+        operationNameSet.forEach(operationName -> {
+            OperationDoc operationDoc = new OperationDoc();
+            operationDoc.setOperationName(operationName);
+            operationDoc.setOperationDiscussionDoc(operationDiscussionDocMap.get(operationName));
+            operationDoc.setOperationRecordDoc(operationRecordDocMap.get(operationName));
+            operationDoc.setPreoperativeDiscussionDoc(preoperativeDiscussionDocMap.get(operationName));
+            operationDoc.setOperationInformedConsentDoc(operationInformedConsentDocMap.get(operationName));
+            operationDoc.setOperationSafetyChecklistDoc(operationSafetyChecklistDocMap.get(operationName));
+            retList.add(operationDoc);
+        });
+
+        return retList;
+    }
+
+
+    /*******************************************术后首次病程及谈话记录***************************************************/
+    private Map<String, OperationDiscussionDoc> getOperationDiscussionDocMap(List<Map<String, Object>> contentMaps) {
+        Map<String, OperationDiscussionDoc> retMap = Maps.newHashMap();
+        if (ListUtil.isEmpty(contentMaps)) {
+            return retMap;
+        }
+        int index = 1;
+        String operationName = null;
+        for (Map<String, Object> contentMap : contentMaps) {
+            if (contentMap.get("htmlText") == null || StringUtil.isBlank(contentMap.get("htmlText").toString())) {
+                continue;
+            }
+            try {
+                OperationDiscussionDoc operationDiscussionDoc = getOperationDiscussionDoc(contentMap);
+                if (operationDiscussionDoc != null) {
+                    operationName = index + "";
+                    operationDiscussionDoc.setOperationName(operationName);
+                    retMap.put(operationName, operationDiscussionDoc);
+                    index++;
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+        return retMap;
+    }
+
+    private OperationDiscussionDoc getOperationDiscussionDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("htmlText").toString();
+        Map<String, String> structureMap = null;
+        OperationDiscussionDoc operationDiscussionDoc = new OperationDiscussionDoc();
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+            if (MapUtils.isNotEmpty(structureMap)) {
+                operationDiscussionDoc = ModelDocGenerate.operationDiscussionDocGen(structureMap);
+                operationDiscussionDoc.setText(content);
+                operationDiscussionDoc.setPageData((Map) structureMap);
+                return operationDiscussionDoc;
+            } else {
+                return null;
+            }
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis ningBoZhongYiHtmlAnalysis = new OperationHtmlAnalysis();
+            Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, operationDiscussion_keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+            if (MapUtils.isNotEmpty(structureMap)) {
+                operationDiscussionDoc = ModelDocGenerate.operationDiscussionDocGen(structureMap);
+                String text = HtmlAnalysisUtil.blockDivToStr(Jsoup.parse(content).selectFirst("body").child(0), true);
+                operationDiscussionDoc.setText(text);
+                operationDiscussionDoc.setPageData((Map) structureMap);
+                return operationDiscussionDoc;
+            } else {
+                return null;
+            }
+        }
+    }
+
+    private List<String> operationDiscussion_keyContrasts = Lists.newArrayList(
+            "病历标题=标题",
+            "手术简要经过(包括“术中所见”)=手术简要经过"
+    );
+
+
+    /**********************************************手术记录*************************************************************/
+    private Map<String, OperationRecordDoc> getOperationRecordDocMap(List<Map<String, Object>> contentMaps) {
+        Map<String, OperationRecordDoc> retMap = Maps.newHashMap();
+        if (ListUtil.isEmpty(contentMaps)) {
+            return retMap;
+        }
+        int index = 1;
+        String operationName = null;
+        for (Map<String, Object> contentMap : contentMaps) {
+            if (contentMap.get("htmlText") == null || StringUtil.isBlank(contentMap.get("htmlText").toString())) {
+                continue;
+            }
+            try {
+                OperationRecordDoc operationRecordDoc = getOperationRecordDoc(contentMap);
+                if (operationRecordDoc != null) {
+                    operationName = index + "";
+                    operationRecordDoc.setOperationName(operationName);
+                    retMap.put(operationName, operationRecordDoc);
+                    index++;
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+        return retMap;
+    }
+
+    private OperationRecordDoc getOperationRecordDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("htmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis ningBoZhongYiHtmlAnalysis = new OperationRecordHtmlAnalysis();
+            Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, operationRecord_keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        if (MapUtils.isNotEmpty(structureMap)) {
+            OperationRecordDoc operationRecordDoc = ModelDocGenerate.operationRecordDocGen(structureMap);
+            operationRecordDoc.setPageData((Map) structureMap);
+            return operationRecordDoc;
+        } else {
+            return null;
+        }
+    }
+
+    private List<String> operationRecord_keyContrasts = Lists.newArrayList(
+            "手术风险评估(可选)=手术风险评估",
+            "手术类别(可选)=手术类别",
+            "麻醉医师=麻醉人员",
+            "手术经过及处理(包括患者的体位、切口处理、病灶所见及手术步骤等)=手术经过",
+            "术(中)后诊断=术中诊断",
+            "手术主刀医师=主刀医师",
+            "主刀医师签名=主刀签字"
+    );
+
+
+    /**********************************************术前讨论、术前小结****************************************************/
+    private Map<String, PreoperativeDiscussionDoc> getPreoperativeDiscussionDocMap(List<Map<String, Object>> contentMaps) {
+        Map<String, PreoperativeDiscussionDoc> retMap = Maps.newHashMap();
+        if (ListUtil.isEmpty(contentMaps)) {
+            return retMap;
+        }
+        int index = 1;
+        String operationName = null;
+        for (Map<String, Object> contentMap : contentMaps) {
+            if (contentMap.get("htmlText") == null || StringUtil.isBlank(contentMap.get("htmlText").toString())) {
+                continue;
+            }
+            try {
+                PreoperativeDiscussionDoc preoperativeDiscussionDoc = getPreoperativeDiscussionDoc(contentMap);
+                if (preoperativeDiscussionDoc != null) {
+                    operationName = index + "";
+                    preoperativeDiscussionDoc.setOperationName(operationName);
+                    retMap.put(operationName, preoperativeDiscussionDoc);
+                    index++;
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+        return retMap;
+    }
+
+    private PreoperativeDiscussionDoc getPreoperativeDiscussionDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("htmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis hangzhoufubaoHtmlAnalysis = new PreoperativeHtmlAnalysis();
+            Map<String, String> sourceMap = hangzhoufubaoHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, preoperativeDiscussion_keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        if (MapUtils.isNotEmpty(structureMap)) {
+            PreoperativeDiscussionDoc preoperativeDiscussionDoc = ModelDocGenerate.preoperativeDiscussionDocGen(structureMap);
+            preoperativeDiscussionDoc.setPageData((Map) structureMap);
+            return preoperativeDiscussionDoc;
+        } else {
+            return null;
+        }
+    }
+
+    private void eliminateDate(Map<String, String> structureMap, String text) {
+        if (structureMap.containsKey(text)) {
+            String value = structureMap.get(text).replaceAll(text, "");
+            structureMap.put(text, value);
+        }
+    }
+
+    private List<String> preoperativeDiscussion_keyContrasts = Lists.newArrayList(
+            "拟施手术方式、名称及可能的变更=拟施手术方式",
+            "主要术中、术后风险及防范措施=风险及防范措施",
+            "术中、术后注意事项(含护理事项)=术中术后注意事项"
+    );
+
+    /**********************************************手术知情同意书****************************************************/
+    private Map<String, OperationInformedConsentDoc> getOperationInformedConsentDocMap(List<Map<String, Object>> contentMaps) {
+        Map<String, OperationInformedConsentDoc> retMap = Maps.newHashMap();
+        if (ListUtil.isEmpty(contentMaps)) {
+            return retMap;
+        }
+        int index = 1;
+        String operationName = null;
+        for (Map<String, Object> contentMap : contentMaps) {
+            if (contentMap.get("xmlText") == null || StringUtil.isBlank(contentMap.get("xmlText").toString())) {
+                continue;
+            }
+            operationName = index + "";
+            OperationInformedConsentDoc operationInformedConsentDoc = getOperationInformedConsentDoc(contentMap);
+            operationInformedConsentDoc.setOperationName(operationName);
+            retMap.put(operationName, operationInformedConsentDoc);
+            index++;
+        }
+        return retMap;
+    }
+
+    private OperationInformedConsentDoc getOperationInformedConsentDoc(Map<String, Object> contentMap) {
+        String modeId = "16";
+//        String content = contentMap.get("xmlText").toString();
+//        Map<String, String> xmlNodeValueMap = CxXmlUtil.firstLevelNodeValue(content);
+//        xmlNodeValueMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
+//        xmlNodeValueMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
+//        Map<String, String> structureMap = OrdinaryAssistant.mapKeyContrast(xmlNodeValueMap, operationInformedConsent_keyContrasts, modeId);
+//
+//        String text = CxXmlUtil.getXmlText(content);
+//        Map<String, String> cutWordMap = Preproc.getCutWordMap(true, operationInformedConsent_sourceTitles, text);
+//        cutWordMap.putAll(structureMap);
+//
+//        OperationInformedConsentDoc operationInformedConsentDoc = ModelDocGenerate.operationInformedConsentDocGen(cutWordMap);
+        OperationInformedConsentDoc operationInformedConsentDoc = new OperationInformedConsentDoc();
+//        operationInformedConsentDoc.setText(text);
+//        operationInformedConsentDoc.setPageData((Map) cutWordMap);
+
+        return operationInformedConsentDoc;
+    }
+
+    private List<String> operationInformedConsent_sourceTitles = Lists.newArrayList(
+            "姓名",
+            "性别",
+            "病区",
+            "床号",
+            "病案号",
+            "手术医生",
+            "目前诊断",
+            "手术名称",
+            "手术指征",
+            "风险及并发症",
+            "保守治疗",
+            "其他手术",
+            "签名",
+            "签名时间"
+    );
+
+    private List<String> operationInformedConsent_keyContrasts = Lists.newArrayList(
+            "姓名++++患者姓名=姓名",
+            "性别=",
+            "病区++++病区名称=病区",
+            "床号=",
+            "病案号++++住院号=病案号",
+            "手术医生=",
+            "目前诊断=",
+            "手术名称=",
+            "手术指征=",
+            "风险及并发症=",
+            "++++保守治疗=保守治疗",
+            "++++其他手术=其他手术",
+            "签名++++=签名",
+            "签名时间=签名时间"
+    );
+
+    /**********************************************手术安全核查表****************************************************/
+    private Map<String, OperationSafetyChecklistDoc> getOperationSafetyChecklistDocMap(List<Map<String, Object>> contentMaps) {
+        Map<String, OperationSafetyChecklistDoc> retMap = Maps.newHashMap();
+        if (ListUtil.isEmpty(contentMaps)) {
+            return retMap;
+        }
+        int index = 1;
+        String operationName = null;
+        for (Map<String, Object> contentMap : contentMaps) {
+            if (contentMap.get("xmlText") == null || StringUtil.isBlank(contentMap.get("xmlText").toString())) {
+                continue;
+            }
+            operationName = index + "";
+            OperationSafetyChecklistDoc operationSafetyChecklistDoc = getOperationSafetyChecklistDoc(contentMap);
+            operationSafetyChecklistDoc.setOperationName(operationName);
+            retMap.put(operationName, operationSafetyChecklistDoc);
+            index++;
+        }
+        return retMap;
+    }
+
+    private OperationSafetyChecklistDoc getOperationSafetyChecklistDoc(Map<String, Object> contentMap) {
+        String modeId = "21";
+//        String content = contentMap.get("xmlText").toString();
+//        Map<String, String> xmlNodeValueMap = CxXmlUtil.firstLevelNodeValue(content);
+//        xmlNodeValueMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
+//        xmlNodeValueMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
+//        Map<String, String> structureMap = OrdinaryAssistant.mapKeyContrast(xmlNodeValueMap, operationSafetyChecklist_keyContrasts, modeId);
+//
+//        String text = CxXmlUtil.getXmlText(content);
+//        Map<String, String> cutWordMap = Preproc.getCutWordMap(true, operationSafetyChecklist_sourceTitles, text);
+//        cutWordMap.putAll(structureMap);
+
+//        OperationSafetyChecklistDoc operationSafetyChecklistDoc = ModelDocGenerate.operationSafetyChecklistDocGen(cutWordMap);
+        OperationSafetyChecklistDoc operationSafetyChecklistDoc = new OperationSafetyChecklistDoc();
+//        operationSafetyChecklistDoc.setText(text);
+//        operationSafetyChecklistDoc.setPageData((Map) cutWordMap);
+
+        return operationSafetyChecklistDoc;
+    }
+
+    private List<String> operationSafetyChecklist_sourceTitles = Lists.newArrayList(
+            "姓名",
+            "性别",
+            "病区",
+            "床号",
+            "病案号",
+            "签名"
+    );
+
+    private List<String> operationSafetyChecklist_keyContrasts = Lists.newArrayList(
+            "姓名++++患者姓名=姓名",
+            "性别",
+            "病区",
+            "床号",
+            "病案号++++住院号=病案号",
+            "签名++++=签名"
+    );
+}

+ 40 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/OutDepDocTrans.java

@@ -0,0 +1,40 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.lantone.qc.pub.model.doc.BeHospitalizedDoc;
+import com.lantone.qc.pub.model.label.ChiefLabel;
+import com.lantone.qc.pub.model.label.PastLabel;
+import com.lantone.qc.pub.model.label.PresentLabel;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.trans.ModelDocTrans;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 门诊入院记录文档生成
+ * @author: rengb
+ * @time: 2020/3/19 19:41
+ */
+public class OutDepDocTrans extends ModelDocTrans {
+
+    @Override
+    public BeHospitalizedDoc extract(MedrecVo medrecVo) {
+        BeHospitalizedDoc beHospitalizedDoc = new BeHospitalizedDoc();
+        Map<String, String> structureMap = ((List<Map>) medrecVo.getContent().get("content")).get(0);
+
+        ChiefLabel chiefLabel = new ChiefLabel();
+        chiefLabel.setText(structureMap.get("主诉"));
+        beHospitalizedDoc.setChiefLabel(chiefLabel);
+
+        PresentLabel presentLabel = new PresentLabel();
+        presentLabel.setText(structureMap.get("现病史"));
+        beHospitalizedDoc.setPresentLabel(presentLabel);
+
+        PastLabel pastLabel = new PastLabel();
+        pastLabel.setText(structureMap.get("既往史"));
+        beHospitalizedDoc.setPastLabel(pastLabel);
+
+        return beHospitalizedDoc;
+    }
+
+}

+ 36 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/PacsDocTrans.java

@@ -0,0 +1,36 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.PacsDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 辅检信息文档生成
+ * @author: zh
+ * @time: 2021/4/7 15:41
+ */
+public class PacsDocTrans extends ModelDocTrans {
+
+    @Override
+    public List<PacsDoc> extract(MedrecVo medrecVo) {
+        List<PacsDoc> retList = Lists.newArrayList();
+        List<String> contents = (List) medrecVo.getContent().get("content");
+        contents.forEach(content -> {
+            retList.add(getDoctorAdviceDoc((Map) FastJsonUtils.getJsonToMap(content)));
+        });
+        return retList;
+    }
+
+    private PacsDoc getDoctorAdviceDoc(Map<String, String> content) {
+        PacsDoc doctorAdviceDoc = new PacsDoc();
+        doctorAdviceDoc.setStructureMap(content);
+        doctorAdviceDoc.setPageData((Map) content);
+        return doctorAdviceDoc;
+    }
+
+}

+ 73 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/RescueDocTrans.java

@@ -0,0 +1,73 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.RescueDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.RescueHtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 抢救记录文档生成
+ * @author: rengb
+ * @time: 2020/3/17 17:34
+ */
+@Slf4j
+public class RescueDocTrans extends ModelDocTrans {
+
+    @Override
+    public List<RescueDoc> extract(MedrecVo medrecVo) {
+        List<RescueDoc> retList = Lists.newArrayList();
+        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");
+        contentMaps.forEach(contentMap -> {
+            try {
+                RescueDoc rescueDoc = getRescueDoc(contentMap);
+                if (rescueDoc != null) {
+                    retList.add(rescueDoc);
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        });
+        return retList;
+    }
+
+    private RescueDoc getRescueDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("htmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis ningBoZhongYiHtmlAnalysis = new RescueHtmlAnalysis();
+            Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        if (MapUtils.isNotEmpty(structureMap)) {
+            RescueDoc rescueDoc = ModelDocGenerate.rescueDocGen(structureMap);
+            rescueDoc.setPageData((Map) structureMap);
+            return rescueDoc;
+        } else {
+            return null;
+        }
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "病历标题=标题",
+            "病情记录=抢救内容"
+    );
+
+}

+ 73 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/StagesSummaryDocTrans.java

@@ -0,0 +1,73 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.model.doc.StagesSummaryDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.StagesSummaryHtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 阶段小结文档生成
+ * @author: rengb
+ * @time: 2020/3/19 19:41
+ */
+@Slf4j
+public class StagesSummaryDocTrans extends ModelDocTrans {
+
+    @Override
+    public List<StagesSummaryDoc> extract(MedrecVo medrecVo) {
+        List<StagesSummaryDoc> retList = Lists.newArrayList();
+        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");
+        contentMaps.forEach(contentMap -> {
+            try {
+                StagesSummaryDoc stagesSummaryDoc = getStagesSummaryDoc(contentMap);
+                if (stagesSummaryDoc != null) {
+                    retList.add(stagesSummaryDoc);
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        });
+        return retList;
+    }
+
+    private StagesSummaryDoc getStagesSummaryDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis ningBoZhongYiHtmlAnalysis = new StagesSummaryHtmlAnalysis();
+            Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        if (MapUtils.isNotEmpty(structureMap)) {
+            StagesSummaryDoc stagesSummaryDoc = ModelDocGenerate.stagesSummaryDocGen(structureMap);
+            stagesSummaryDoc.setPageData((Map) structureMap);
+            return stagesSummaryDoc;
+        } else {
+            return null;
+        }
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "病历标题=标题",
+            "病情记录=病历内容"
+    );
+
+}

+ 368 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/ThreeLevelWardDocTrans.java

@@ -0,0 +1,368 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.dbanaly.util.KernelConstants;
+import com.lantone.qc.dbanaly.util.SpecialStorageUtil;
+import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationRecordDoc;
+import com.lantone.qc.pub.model.doc.ward.AttendingDoctorWardDoc;
+import com.lantone.qc.pub.model.doc.ward.DirectorDoctorWardDoc;
+import com.lantone.qc.pub.model.doc.ward.GeneralDoctorWardDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.pub.util.SpringContextUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.ThreeLevelWardHtmlAnalysis;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 查房记录文档生成
+ * @author: rengb
+ * @time: 2020/3/17 13:27
+ */
+@Slf4j
+@Setter
+public class ThreeLevelWardDocTrans extends ModelDocTrans {
+
+    private List<OperationDoc> operationDocs;
+
+    @Override
+    public List<ThreeLevelWardDoc> extract(MedrecVo medrecVo) {
+        List<ThreeLevelWardDoc> retList = Lists.newArrayList();
+        ThreeLevelWardDoc threeLevelWardDoc = new ThreeLevelWardDoc();
+        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");
+        contentMaps.forEach(contentMap -> {
+            try {
+                classifyThreeLevelWardDoc(threeLevelWardDoc, contentMap);
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        });
+        retList.add(threeLevelWardDoc);
+        return retList;
+    }
+
+    private void classifyThreeLevelWardDoc(ThreeLevelWardDoc threeLevelWardDoc, Map<String, Object> contentMap) {
+        String content = contentMap.get("htmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = "";
+            String recTypeId = "";
+            if (contentMap.containsKey("recTitle") && StringUtil.isNotBlank(contentMap.get("recTitle").toString())) {
+                recTitle = contentMap.get("recTitle").toString();
+            }
+            if (contentMap.containsKey("recTypeId") && StringUtil.isNotBlank(contentMap.get("recTypeId").toString())) {
+                recTypeId = contentMap.get("recTypeId").toString();
+            }
+            HtmlAnalysis hangzhoufubaoHtmlAnalysis = new ThreeLevelWardHtmlAnalysis();
+            Map<String, String> sourceMap = hangzhoufubaoHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        if (MapUtils.isEmpty(structureMap)) {
+            return;
+        }
+
+        if (structureMap.containsKey("病情记录")) {
+            structureMap.put("病情记录", structureMap.get("病情记录").replace(" ", ""));
+        }
+        //structureMap.put("查房日期", structureMap.get("记录时间"));
+        /*Map<String, String> cutWordMap = Maps.newHashMap();
+        String text = CxXmlUtil.getXmlText(content);
+        if (StringUtil.isNotBlank(text)) {
+            if (StringUtil.isBlank(structureMap.get("病情记录"))) {
+                structureMap.put("病情记录", text);
+            }
+            cutWordMap = Preproc.getCutWordMap(true, sourceTitles, text);
+            if (StringUtil.isBlank(structureMap.get("记录医师"))) {
+                Pattern p = Pattern.compile("^[^\\u4e00-\\u9fa5]+$");//分词结果如果不包含中文为日期,则不覆盖
+                if (StringUtil.isNotEmpty(cutWordMap.get("医师签名"))) {
+                    Matcher m = p.matcher(cutWordMap.get("医师签名"));
+                    if (!m.matches()) {
+                        structureMap.put("记录医师", cutWordMap.get("医师签名"));
+                    }
+                }
+                if (StringUtil.isNotEmpty(cutWordMap.get("记录医生"))) {
+                    Matcher m = p.matcher(cutWordMap.get("记录医生"));
+                    if (!m.matches()) {
+                        structureMap.put("记录医师", cutWordMap.get("记录医生"));
+                    }
+                }
+            }
+        }
+         */
+
+        //总的查房记录 汇总
+        ThreeLevelWardDoc allDoctorWradDoc = new ThreeLevelWardDoc();
+        allDoctorWradDoc.setStructureMap(structureMap);
+        allDoctorWradDoc.setPageData((Map) structureMap);
+        threeLevelWardDoc.addAllDoctorWradDoc(allDoctorWradDoc);
+
+        //主任医师查房
+        DirectorDoctorWardDoc directorDoctorWardDoc = findDirectorDoctorWardDoc(structureMap);
+        if (directorDoctorWardDoc != null) {
+            threeLevelWardDoc.addDirectorDoctorWardDoc(findDirectorDoctorWardDoc(structureMap));
+        }
+        //主治医师查房
+        AttendingDoctorWardDoc attendingDoctorWardDoc = findAttendingDoctorWardDoc(structureMap);
+        if (attendingDoctorWardDoc != null) {
+            threeLevelWardDoc.addAttendingDoctorWardDoc(attendingDoctorWardDoc);
+        }
+        //普通医师查房
+        if (directorDoctorWardDoc == null && attendingDoctorWardDoc == null) {
+            GeneralDoctorWardDoc generalDoctorWardDoc = new GeneralDoctorWardDoc();
+            generalDoctorWardDoc.setStructureMap(structureMap);
+            generalDoctorWardDoc.setPageData((Map) structureMap);
+            threeLevelWardDoc.addGeneralDoctorWardDoc(generalDoctorWardDoc);
+        }
+
+    }
+
+    /**
+     * 主任医师查房
+     *
+     * @param structureMap
+     */
+    private DirectorDoctorWardDoc findDirectorDoctorWardDoc(Map<String, String> structureMap) {
+        String title = structureMap.get("查房标题");
+        String content = structureMap.get("病情记录");
+        String writTitle = structureMap.get("文书标题");
+        String recordDateStr = structureMap.get("查房日期");
+        Date recordDate = StringUtil.parseDateTime(recordDateStr);
+        //标题有代字
+        DirectorDoctorWardDoc directorDoctorWardDoc = null;
+        if (StringUtil.isNotBlank(title)) {
+            if (title.contains("主刀") || title.contains("术后第")) {
+                String doctorTitle = getDoctorTitle(operationDocs, recordDate, "主刀医师");
+                title = title.replace("主刀", doctorTitle).replace("术后第", doctorTitle);
+            } else if (title.contains("一助")) {
+                String doctorTitle = getDoctorTitle(operationDocs, recordDate, "一助");
+                title = title.replace("一助", doctorTitle);
+            }
+            if ((StringUtils.isNotEmpty(subTitle(title)) && subTitle(title).contains("主任")) || findDirector(content)
+                    || title.contains("三级") || endocrinologyTitle(title)) {
+                directorDoctorWardDoc = new DirectorDoctorWardDoc();
+                directorDoctorWardDoc.setStructureMap(structureMap);
+                directorDoctorWardDoc.setPageData((Map) structureMap);
+            }
+        }
+
+        if (StringUtil.isNotBlank(writTitle)) {
+            if (writTitle.contains("主刀") || writTitle.contains("术后第")) {
+                String doctorTitle = getDoctorTitle(operationDocs, recordDate, "主刀医师");
+                writTitle = writTitle.replace("主刀", doctorTitle).replace("术后第", doctorTitle);
+            } else if (writTitle.contains("一助")) {
+                String doctorTitle = getDoctorTitle(operationDocs, recordDate, "一助");
+                writTitle = writTitle.replace("一助", doctorTitle);
+            }
+            if ((StringUtils.isNotEmpty(subTitle(writTitle)) && subTitle(writTitle).contains("主任")) || findDirector(content)
+                    || writTitle.contains("三级") || endocrinologyTitle(writTitle)) {
+                directorDoctorWardDoc = new DirectorDoctorWardDoc();
+                directorDoctorWardDoc.setStructureMap(structureMap);
+                directorDoctorWardDoc.setPageData((Map) structureMap);
+            }
+        }
+        return directorDoctorWardDoc;
+    }
+
+    /**
+     * 主治医师查房
+     *
+     * @param structureMap
+     */
+    private AttendingDoctorWardDoc findAttendingDoctorWardDoc(Map<String, String> structureMap) {
+        String title = structureMap.get("查房标题");
+        String writTitle = structureMap.get("文书标题");
+        String content = structureMap.get("病情记录");
+        String recordDateStr = structureMap.get("查房日期");
+        Date recordDate = StringUtil.parseDateTime(recordDateStr);
+        AttendingDoctorWardDoc attendingDoctorWardDoc = null;
+        //标题有代字
+        if (StringUtil.isNotBlank(title)) {
+            if (title.contains("主刀") || title.contains("术后第")) {
+                String doctorTitle = getDoctorTitle(operationDocs, recordDate, "主刀医师");
+                title = title.replace("主刀", doctorTitle).replace("术后第", doctorTitle);
+            } else if (title.contains("一助")) {
+                String doctorTitle = getDoctorTitle(operationDocs, recordDate, "一助");
+                title = title.replace("一助", doctorTitle);
+            }
+            if ((StringUtils.isNotEmpty(subTitle(title)) && subTitle(title).contains("主治"))
+                    || findAttend(content) || title.contains("三级") || endocrinologyTitle(title)) {
+                attendingDoctorWardDoc = new AttendingDoctorWardDoc();
+                attendingDoctorWardDoc.setStructureMap(structureMap);
+                attendingDoctorWardDoc.setPageData((Map) structureMap);
+            }
+        }
+
+        //文书标题和模板标题不一致
+        if (StringUtil.isNotBlank(writTitle)) {
+            if (writTitle.contains("主刀") || writTitle.contains("术后第")) {
+                String doctorTitle = getDoctorTitle(operationDocs, recordDate, "主刀医师");
+                writTitle = writTitle.replace("主刀", doctorTitle).replace("术后第", doctorTitle);
+            } else if (writTitle.contains("一助")) {
+                String doctorTitle = getDoctorTitle(operationDocs, recordDate, "一助");
+                writTitle = writTitle.replace("一助", doctorTitle);
+            }
+            if ((StringUtils.isNotEmpty(subTitle(writTitle)) && subTitle(writTitle).contains("主治"))
+                    || findAttend(content) || writTitle.contains("三级") || endocrinologyTitle(writTitle)) {
+                attendingDoctorWardDoc = new AttendingDoctorWardDoc();
+                attendingDoctorWardDoc.setStructureMap(structureMap);
+                attendingDoctorWardDoc.setPageData((Map) structureMap);
+            }
+        }
+        return attendingDoctorWardDoc;
+    }
+
+    /**
+     * 北仑内分泌科主任主治处理
+     *
+     * @param title
+     * @return
+     */
+    private boolean endocrinologyTitle(String title) {
+        String regex = ".*主任.*主任.*主治.*";
+        return title.matches(regex);
+    }
+
+    /**
+     * 共同照护讨论记录中找主任查房
+     *
+     * @param content
+     * @return
+     */
+    private boolean findDirector(String content) {
+        String director = "";
+        if (content.indexOf(",") != -1) {
+            director = content.substring(0, content.indexOf(","));
+        }
+        return director.contains("主任");
+    }
+
+    /**
+     * 共同照护讨论记录中找主治查房
+     *
+     * @param content
+     * @return
+     */
+    private boolean findAttend(String content) {
+        String director = "";
+        if (content.indexOf(",") != -1) {
+            director = content.substring(0, content.indexOf(","));
+        }
+        return director.contains("主治");
+    }
+
+    private String subTitle(String srcText) {
+        if (StringUtil.isNotBlank(srcText) && srcText.contains("代") && srcText.indexOf("代") != srcText.length() - 1) {
+            srcText = srcText.substring(srcText.lastIndexOf("代") + 1);
+        }
+        return srcText;
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "病历日期=查房日期",
+            "病历标题=查房标题",
+            "科主任=三级医师",
+            "记录日期=记录时间"
+    );
+
+    /**
+     * 获取主刀医师/一助职称(取距离查房记录时间最近的一次手术记录)
+     *
+     * @param operationDocs
+     * @return
+     */
+    public static String getDoctorTitle(List<OperationDoc> operationDocs, Date recordDate, String findTitle) {
+        String title = "";
+        SpecialStorageUtil specialStorageUtil = SpringContextUtil.getBean("specialStorageUtil");
+        Map<String, Object> surgeon = specialStorageUtil.getJsonStringValue(KernelConstants.HOSPITAL_DOCTOR_MAP);
+        if (surgeon == null) {
+            return title;
+        }
+        /* 用于存放手术结束时间距离查房时间最近的一次时间差 */
+        long timeDiff = 0L;
+        for (OperationDoc operationDoc : operationDocs) {
+            OperationRecordDoc operationRecordDoc = operationDoc.getOperationRecordDoc();
+            if (operationRecordDoc == null) {
+                continue;
+            }
+            Map<String, String> structureMap = operationRecordDoc.getStructureMap();
+            String chiefSurgeon = structureMap.get(findTitle);
+            String operatorEndDateStr = structureMap.get("手术结束时间");
+            if (StringUtil.isBlank(chiefSurgeon)) {
+                chiefSurgeon = structureMap.get("手术者及助手名称");
+                if (StringUtil.isNotBlank(chiefSurgeon) && chiefSurgeon.contains("、")) {
+                    chiefSurgeon = chiefSurgeon.split("、")[0].replace("主刀:", "");
+                }
+            }
+            if (StringUtil.isBlank(chiefSurgeon) || StringUtil.isBlank(operatorEndDateStr)) {
+                continue;
+            }
+            Map<String, String> doctor = (Map) surgeon.get(chiefSurgeon);
+            if (doctor != null) {
+                String professor = doctor.get("professor");
+                Date operatorEndDate = StringUtil.parseDateTime(operatorEndDateStr);
+                if (operatorEndDate != null) {
+                    long timeDifference = timeDifference(operatorEndDate, recordDate);
+                    if (timeDifference == 0) {
+                        continue;
+                    }
+                    if (timeDiff == 0 || timeDiff > timeDifference) {
+                        /* 取距离此次主刀医师查房最近的一次手术时间 */
+                        timeDiff = timeDifference;
+                        title = professor;
+                    }
+                }
+            }
+        }
+        return title;
+    }
+
+    public static long timeDifference(Date firstDate, Date secondDate) {
+        long timeDifference = 0L;
+        if (firstDate == null || secondDate == null) {
+            return timeDifference;
+        }
+        boolean flag = false;
+        if (firstDate.before(secondDate)) {
+            flag = true;
+        }
+        Calendar calendarS = Calendar.getInstance();
+        Calendar calendarE = Calendar.getInstance();
+        long timeS, timeE;
+        try {
+            calendarS.setTime(firstDate);
+            calendarE.setTime(secondDate);
+
+            timeS = calendarS.getTimeInMillis();
+            timeE = calendarE.getTimeInMillis();
+
+            if (flag) {
+                timeDifference = (timeE - timeS) / (1000 * 60);
+            } else {
+                timeDifference = (timeS - timeE) / (1000 * 60);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return timeDifference;
+    }
+
+}

+ 305 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/TransferRecordDocTrans.java

@@ -0,0 +1,305 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.model.doc.transferrecord.TransferIntoDoc;
+import com.lantone.qc.pub.model.doc.transferrecord.TransferOutDoc;
+import com.lantone.qc.pub.model.doc.transferrecord.TransferRecordDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import com.lantone.qc.trans.hangzhoufubao.util.HtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.TransferIntoHtmlAnalysis;
+import com.lantone.qc.trans.hangzhoufubao.util.TransferOutHtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.*;
+
+/**
+ * @Description: 转科记录文档生成
+ * @author: rengb
+ * @time: 2020/3/20 16:10
+ */
+@Slf4j
+public class TransferRecordDocTrans extends ModelDocTrans {
+
+    @Override
+    public TransferRecordDoc extract(MedrecVo medrecVo) {
+        TransferRecordDoc transferRecordDoc = new TransferRecordDoc();
+
+        Map<String, List<String>> contentMap = (Map) medrecVo.getContent().get("content");
+        if (contentMap == null) {
+            return transferRecordDoc;
+        }
+        List<Map<String, Object>> into = (List) contentMap.get("转入记录");
+        List<Map<String, Object>> out = (List) contentMap.get("转出记录");
+        List<Map<String, Object>> all = new ArrayList<>();
+
+        Map<String, TransferIntoDoc> transferIntoDocMap = new HashMap<>();
+        Map<String, TransferOutDoc> transferOutDocMap = new HashMap<>();
+        if (into != null) {
+            all.addAll(into);
+            transferIntoDocMap = getTransferIntoDocMap(into);
+        }
+        if (out != null) {
+            all.addAll(out);
+            transferOutDocMap = getTransferOutDocMap(out);
+        }
+        Map<String, TransferRecordDoc> transferAllDocMap = getTransferAllDocMap(all);
+
+        //转入
+        Map<Date, TransferIntoDoc> dateRecordIn = new TreeMap<>(new Comparator<Date>() {
+            @Override
+            public int compare(Date o1, Date o2) {
+                // 升序排列
+                return o1.compareTo(o2);
+            }
+        });
+        for (TransferIntoDoc transferIntoDoc : transferIntoDocMap.values()) {
+            Map<String, String> structureMap = transferIntoDoc.getStructureMap();
+            String inDateStr = structureMap.get("转科日期");
+            if (StringUtil.isBlank(inDateStr)) {
+                inDateStr = structureMap.get("病历日期");
+            }
+            Date inDate = StringUtil.parseDateTime(inDateStr);
+            if (inDate == null) {
+                continue;
+            }
+            dateRecordIn.put(inDate, transferIntoDoc);
+        }
+        transferRecordDoc.setTransferIntoDocs(new ArrayList<>(dateRecordIn.values()));
+        //转出
+        Map<Date, TransferOutDoc> dateRecordOut = new TreeMap<>(new Comparator<Date>() {
+            @Override
+            public int compare(Date o1, Date o2) {
+                // 升序排列
+                return o1.compareTo(o2);
+            }
+        });
+        for (TransferOutDoc transferOutDoc : transferOutDocMap.values()) {
+            Map<String, String> structureMap = transferOutDoc.getStructureMap();
+            String outDateStr = structureMap.get("转科日期");
+            if (StringUtil.isBlank(outDateStr)) {
+                outDateStr = structureMap.get("病历日期");
+            }
+            Date outDate = StringUtil.parseDateTime(outDateStr);
+            if (outDate == null) {
+                continue;
+            }
+            dateRecordOut.put(outDate, transferOutDoc);
+        }
+        transferRecordDoc.setTransferOutDocs(new ArrayList<>(dateRecordOut.values()));
+
+        //全部转科记录
+        Map<Date, TransferRecordDoc> dateRecordAll = new TreeMap<>(new Comparator<Date>() {
+            @Override
+            public int compare(Date o1, Date o2) {
+                // 升序排列
+                return o1.compareTo(o2);
+            }
+        });
+        for (TransferRecordDoc transferRecordAllDoc : transferAllDocMap.values()) {
+            Map<String, String> structureMap = transferRecordAllDoc.getStructureMap();
+            String transferDateStr = structureMap.get("转科日期");
+            if (StringUtil.isBlank(transferDateStr)) {
+                transferDateStr = structureMap.get("病历日期");
+            }
+            Date transferDate = StringUtil.parseDateTime(transferDateStr);
+            if (transferDate == null) {
+                continue;
+            }
+            dateRecordAll.put(transferDate, transferRecordAllDoc);
+        }
+        transferRecordDoc.setAllTransferDocs(new ArrayList<>(dateRecordAll.values()));
+
+        return transferRecordDoc;
+    }
+
+
+    /**************************************************转入*******************************************************/
+    private Map<String, TransferIntoDoc> getTransferIntoDocMap(List<Map<String, Object>> contentMaps) {
+        Map<String, TransferIntoDoc> retMap = Maps.newHashMap();
+        if (ListUtil.isEmpty(contentMaps)) {
+            return retMap;
+        }
+        int index = 1;
+        String transferRecordName = null;
+        for (Map<String, Object> contentMap : contentMaps) {
+            if (contentMap.get("htmlText") == null || StringUtil.isBlank(contentMap.get("htmlText").toString())) {
+                continue;
+            }
+            try {
+                TransferIntoDoc transferIntoDoc = getTransferIntoDoc(contentMap);
+                if (transferIntoDoc != null) {
+                    transferRecordName = index + "";
+                    transferIntoDoc.setTransferRecordName(transferRecordName);
+                    retMap.put(transferRecordName, transferIntoDoc);
+                    index++;
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+        return retMap;
+    }
+
+    private TransferIntoDoc getTransferIntoDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("htmlText").toString();
+        Map<String, String> structureMap = new HashMap<>();
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis ningBoZhongYiHtmlAnalysis = new TransferIntoHtmlAnalysis();
+            Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        //存入转入时间
+        getTransDate(contentMap.get("transferInDate"), "转入时间", structureMap);
+        if (MapUtils.isNotEmpty(structureMap)) {
+            TransferIntoDoc transferIntoDoc = new TransferIntoDoc();
+            transferIntoDoc.setStructureMap(structureMap);
+            transferIntoDoc.setPageData((Map) structureMap);
+            return transferIntoDoc;
+        } else {
+            return null;
+        }
+    }
+
+    /**************************************************全部*******************************************************/
+    private Map<String, TransferRecordDoc> getTransferAllDocMap(List<Map<String, Object>> contentMaps) {
+        Map<String, TransferRecordDoc> retMap = Maps.newHashMap();
+        if (ListUtil.isEmpty(contentMaps)) {
+            return retMap;
+        }
+        int index = 1;
+        String transferRecordName = null;
+        for (Map<String, Object> contentMap : contentMaps) {
+            if (contentMap.get("xmlText") == null || StringUtil.isBlank(contentMap.get("xmlText").toString())) {
+                continue;
+            }
+            try {
+                TransferRecordDoc transferRecordDoc = getTransferAllDoc(contentMap);
+                if (transferRecordDoc != null) {
+                    transferRecordName = index + "";
+                    transferRecordDoc.setTransferRecordName(transferRecordName);
+                    retMap.put(transferRecordName, transferRecordDoc);
+                    index++;
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+        return retMap;
+    }
+
+    private TransferRecordDoc getTransferAllDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = new HashMap<>();
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis ningBoZhongYiHtmlAnalysis = new TransferOutHtmlAnalysis();
+            Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        //存入转入时间
+        getTransDate(contentMap.get("transferInDate"), "转入时间", structureMap);
+        //存入转出时间
+        getTransDate(contentMap.get("transferOutDate"), "转出时间", structureMap);
+        if (MapUtils.isNotEmpty(structureMap)) {
+            TransferRecordDoc transferAllDoc = new TransferRecordDoc();
+            transferAllDoc.setStructureMap(structureMap);
+            transferAllDoc.setPageData((Map) structureMap);
+            return transferAllDoc;
+        } else {
+            return null;
+        }
+    }
+
+
+    /**************************************************转出*******************************************************/
+    private Map<String, TransferOutDoc> getTransferOutDocMap(List<Map<String, Object>> contentMaps) {
+        Map<String, TransferOutDoc> retMap = Maps.newHashMap();
+        if (ListUtil.isEmpty(contentMaps)) {
+            return retMap;
+        }
+        int index = 1;
+        String transferRecordName = null;
+        for (Map<String, Object> contentMap : contentMaps) {
+            if (contentMap.get("htmlText") == null || StringUtil.isBlank(contentMap.get("htmlText").toString())) {
+                continue;
+            }
+            try {
+                TransferOutDoc transferOutDoc = getTransferOutDoc(contentMap);
+                if (transferOutDoc != null) {
+                    transferRecordName = index + "";
+                    transferOutDoc.setTransferRecordName(transferRecordName);
+                    retMap.put(transferRecordName, transferOutDoc);
+                    index++;
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+        return retMap;
+    }
+
+    private TransferOutDoc getTransferOutDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("htmlText").toString();
+        Map<String, String> structureMap = new HashMap<>();
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            String recTitle = contentMap.get("recTitle").toString();
+            String recTypeId = contentMap.get("recTypeId").toString();
+            HtmlAnalysis ningBoZhongYiHtmlAnalysis = new TransferOutHtmlAnalysis();
+            Map<String, String> sourceMap = ningBoZhongYiHtmlAnalysis.analysis(content, recTitle, recTypeId);
+            if (MapUtils.isNotEmpty(sourceMap)) {
+                structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts);
+                structureMap.put("记录编号", contentMap.get("recId").toString());
+                structureMap.put("病历号", contentMap.get("behospitalCode") == null ? null : contentMap.get("behospitalCode").toString());
+            }
+        }
+        //存入转出时间
+        getTransDate(contentMap.get("transferOutDate"), "转出时间", structureMap);
+        if (MapUtils.isNotEmpty(structureMap)) {
+            TransferOutDoc transferOutDoc = new TransferOutDoc();
+            transferOutDoc.setStructureMap(structureMap);
+            transferOutDoc.setPageData((Map) structureMap);
+            return transferOutDoc;
+        } else {
+            return null;
+        }
+    }
+
+    //存入转入转出时间
+    private void getTransDate(Object transferDates, String dateStr, Map<String, String> structureMap) {
+        if (transferDates != null) {
+            structureMap.put(dateStr, transferDates.toString());
+        }
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "医师签名=记录医生",
+            "病历标题=标题",
+            "病情记录=病历内容",
+            "签名时间=记录时间"
+    );
+
+}

+ 52 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/VTEGradeDocTrans.java

@@ -0,0 +1,52 @@
+package com.lantone.qc.trans.hangzhoufubao;
+
+import com.lantone.qc.pub.model.doc.VTEGradeDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.ModelDocGenerate;
+import com.lantone.qc.trans.hangzhoufubao.util.VTEGradeHtmlAnalysis;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName: VTEGradeDocTrans
+ * @Description: VTE评分
+ * @Author songxl
+ * @Date 2021/3/9
+ * @Version 1.0
+ */
+@Slf4j
+public class VTEGradeDocTrans extends ModelDocTrans {
+    @Override
+    public VTEGradeDoc extract(MedrecVo medrecVo) {
+        VTEGradeDoc vteGradeDoc = null;
+        try {
+            Map<String, Object> contentMap = ((List<Map>) medrecVo.getContent().get("content")).get(0);
+            String content = contentMap.get("xmlText").toString();
+            Map<String, String> structureMap = null;
+            if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+                structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+            } else {
+                String recTitle = contentMap.get("recTitle").toString();
+                String recTypeId = contentMap.get("recTypeId").toString();
+                VTEGradeHtmlAnalysis vteGradeHtmlAnalysis = new VTEGradeHtmlAnalysis();
+                Map<String, String> sourceMap = vteGradeHtmlAnalysis.analysis(content, recTitle, recTypeId);
+                if (MapUtils.isNotEmpty(sourceMap)) {
+                    structureMap.putAll(sourceMap);
+                }
+            }
+            if (MapUtils.isNotEmpty(structureMap)) {
+                              ModelDocGenerate.beHospitalizedDocGen(structureMap);
+                vteGradeDoc = ModelDocGenerate.vteGradeDocGen(structureMap);
+                vteGradeDoc.setPageData((Map) structureMap);
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return vteGradeDoc;
+    }
+}

+ 41 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ADLGradeHtmlAnalysis.java

@@ -0,0 +1,41 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.Content;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.select.Elements;
+
+import java.util.Map;
+
+/**
+ * @ClassName:
+ * @Description: ADL评分HTML解析
+ * @Author songxl
+ * @Date 2021/3/9
+ * @Version 1.0
+ */
+@Slf4j
+public class ADLGradeHtmlAnalysis implements HtmlAnalysis {
+    private String modeId = "0";//模块id待定
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+
+            Document doc = Jsoup.parse(html);
+            //评估日期
+            Elements spanES = doc.getElementById("table2").nextElementSiblings().get(1).getElementsByTag("span");
+            String time = spanES.text().split(Content.adl_grade_time)[1]
+                    .replaceAll(":","").trim();
+            map.put(Content.adl_grade_time,time);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+}

+ 142 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/BeHospitalizedHtmlAnalysis.java

@@ -0,0 +1,142 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import com.lantone.qc.trans.yuhangsy.util.comsis.YuhangsyCommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/15 16:28
+ */
+@Slf4j
+public class BeHospitalizedHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "1";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Document doc = Jsoup.parse(html);
+
+            if (recTitle.contains("24")) {
+                analysis24h(doc, map);
+            } else if (recTitle.contains("日间病历")) {
+                analysisDay(doc, map);
+            } else {
+                analysisGeneral(doc, recTitle, map);
+            }
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, map);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+
+    //一般模板
+    private void analysisGeneral(Document doc, String recTitle, Map<String, String> map) {
+
+        List<String> titles = Lists.newArrayList("姓  名", "性   别", "出生日期", "出 生 地", "职 业", "民 族", "宗教信仰", "婚 姻",
+                "联系地址", "联系电话", "入院日期", "记录日期", "身份证号码", "病史陈述者", "病史可靠程度", "产前检查", "丈夫姓名",
+                "主 诉", "现病史", "既往史", "个人史", "月经史", "婚姻史", "生育史", "家族史", "体格检查","一般体格检查一般情况","一般体格检查一般状况","辅助检查", "妇科检查","产科检查","实验室检查", "特殊检查",
+                "初步诊断", "康复需求","营养需求","医生签名", "医师签名", "签名时间", "记录时间", "补充诊断", "修正诊断","其    他");
+        //个人基础信息table解析
+        String htmlContent = HangzhoufubaoCommonAnalysisUtil.html2String(doc.toString());
+        if (StringUtil.isNotBlank(htmlContent)) {
+            HangzhoufubaoCommonAnalysisUtil.html2StructureMap(titles,htmlContent,map);
+        }
+        //去掉生育史里面的表格jj
+        String reproductiveHistory = map.get("生育史");
+        if (StringUtil.isNotBlank(reproductiveHistory)) {
+            int index = reproductiveHistory.indexOf("孕次生产年月流产早产足月产");
+            map.put("生育史", reproductiveHistory.substring(0, index));
+        }
+
+
+        //拆分产科检查里面的辅助检查
+        String obstetricExamination = map.get("产科检查");
+        if (StringUtil.isNotBlank(obstetricExamination)) {
+            String str = "辅助检查";
+            int i = obstetricExamination.indexOf(str);
+            if (i > 0) {
+                map.put("产科检查",obstetricExamination.substring(0,i));
+                String substring = obstetricExamination.substring(i, obstetricExamination.length() - 1);
+                String replace = substring.replace("辅助检查", "");
+                map.put(str, "时间:" + replace);
+            }
+        }
+
+
+
+
+    }
+
+    //24小时出入院记录、24小时出入院记录(全院)、24小时入出院记录(全院通用)、24小时内入院死亡记录(全院通用)
+    private void analysis24h(Document doc, Map<String, String> map) {
+        String text = HtmlAnalysisUtil.blockDivToStr(doc.selectFirst("body").child(0), false);
+        text = text.substring(text.lastIndexOf("24小时入出院记录姓    名")).replaceFirst("第1页", "");
+        List<String> titles = Lists.newArrayList("姓    名", "家庭住址", "性    别", "工作单位", "年    龄", "身份证号码", "民    族",
+                "联系人(关系)", "职    业", "入院时间", "婚    姻", "死亡时间", "记录时间", "出 生 地", "病史陈述者", "主    诉", "入院情况", "心理评估",
+                "疼痛评估", "营养评估", "功能评估", "入院诊断", "诊疗经过", "死亡原因", "死亡诊断", "出院情况", "出院诊断", "出院计划", "出院医嘱",
+                "出院去向", "医师签名", "书写时间");
+
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, map);
+        CommonAnalysisUtil.processType(map, "出院去向");
+    }
+
+    //原-日间病历入出院记录、日间病历-性早熟
+    private void analysisDay(Document doc, Map<String, String> map) {
+        //个人基础信息table解析
+        HtmlAnalysisUtil.tableStyle1InsertMap(doc.getElementById("table1"), map);
+        //主诉、入院情况等table解析
+        HtmlAnalysisUtil.tableStyle2InsertMap(doc.getElementById("table6"), map);
+        //医生签名、医生签名时间
+        Element docSignElement = null, docSignTimeElement = null;
+        for (Element table6ElementNt : doc.getElementById("table6").parent().nextElementSiblings()) {
+            docSignElement = table6ElementNt.selectFirst("image,img");
+            if (docSignElement != null) {
+                docSignTimeElement = table6ElementNt.nextElementSibling();
+                break;
+            }
+        }
+        if (docSignElement != null) {
+//            map.put("医生签名", docSignElement.outerHtml());
+            map.put("医生签名", "暂无");
+        }
+        if (docSignTimeElement != null) {
+            map.put("医生签名时间", HtmlAnalysisUtil.elementLayer1ToStr(docSignTimeElement, false).trim());
+        }
+    }
+
+    private void disHandleExt(Map<String, String> map) {
+        String[] keys = {"中医诊断", "西医诊断"};
+        String value = null;
+        int index = 0;
+        for (String key : keys) {
+            value = map.get(key);
+            if (StringUtil.isNotBlank(value)) {
+                for (String key_ : keys) {
+                    index = value.indexOf(key_);
+                    if (index > 0) {
+                        map.put(key_, value.substring(index + 5));
+                        map.put(key, value.substring(0, index));
+                    }
+                }
+            }
+        }
+    }
+
+}

+ 55 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ClinicBloodEffectHtmlAnalysis.java

@@ -0,0 +1,55 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Element;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/28 19:41
+ */
+@Slf4j
+public class ClinicBloodEffectHtmlAnalysis implements HtmlAnalysis {
+    private String modeId = "32";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Element bigDivElement = Jsoup.parse(html).selectFirst("body").child(0);
+            analysisGeneral(recTitle, bigDivElement, map);
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, map);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+
+    private void analysisGeneral(String recTitle, Element bigDivElement, Map<String, String> map) {
+        if (bigDivElement.childNodeSize() == 1) {
+            bigDivElement = bigDivElement.child(0);
+        }
+        if (bigDivElement.selectFirst("hr") != null) {
+            bigDivElement.selectFirst("hr").previousElementSiblings().remove();
+        }
+        String text = HtmlAnalysisUtil.blockDivToStr(bigDivElement, true);
+        CommonAnalysisUtil.extractWardInfo(recTitle, text, map);
+        String bqjlText = "病情记录" + map.get("病情记录");
+        List<String> titles = Lists.newArrayList(
+                "医生签名"
+        );
+        titles = CommonAnalysisUtil.sortTitles(titles, text);
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, map);
+    }
+
+}

+ 57 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ClinicalBloodHtmlAnalysis.java

@@ -0,0 +1,57 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Element;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/28 17:56
+ */
+@Slf4j
+public class ClinicalBloodHtmlAnalysis implements HtmlAnalysis {
+
+
+    private String modeId = "10";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Element bigDivElement = Jsoup.parse(html).selectFirst("body").child(0);
+            analysisGeneral(recTitle,bigDivElement, map);
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, map);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+
+    private void analysisGeneral(String recTitle, Element bigDivElement, Map<String, String> map) {
+        if (bigDivElement.childNodeSize() == 1) {
+            bigDivElement = bigDivElement.child(0);
+        }
+        if (bigDivElement.selectFirst("hr") != null) {
+            bigDivElement.selectFirst("hr").previousElementSiblings().remove();
+        }
+        String text = HtmlAnalysisUtil.blockDivToStr(bigDivElement, true);
+        CommonAnalysisUtil.extractWardInfo(recTitle,text, map);
+        String bqjlText = "病情记录" + map.get("病情记录");
+        List<String> titles = Lists.newArrayList(
+                "医生签名"
+        );
+        titles = CommonAnalysisUtil.sortTitlesNoColon(titles, text);
+        CommonAnalysisUtil.cutByTitlesNoColon(text, titles, 0, map);
+    }
+
+}

+ 120 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ConsultationHtmlAnalysis.java

@@ -0,0 +1,120 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/12 13:53
+ */
+@Slf4j
+public class ConsultationHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "31";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> structureMap = Maps.newLinkedHashMap();
+
+        try {
+            List<String> titles = Lists.newArrayList("姓名", "性别", "出生日期", "科别", "病区", "床号", "住院号",
+                    "会诊类型", "被邀医院", "被邀科室", "被邀医师", "申请时间", "患者病情及诊疗经过、申请会诊的理由及目的", "申请会诊科别",
+                    "被邀会诊科别", "申请会诊医师", "会诊意见", "会诊时间", "科主任", "会诊到达时间", "查体", "会诊建议",
+                    "会诊诊断", "由受邀医生填写,本次会诊是否必要","会诊科室", "会诊医师", "外院会诊医师所在医疗机构名称", "会诊医师所在医疗机构名称");
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            String htmlContent = null;
+            Document doc = Jsoup.parse(html);
+            if ("外院专家会诊申请单".equals(recTitle)) {
+                htmlContent = CommonAnalysisUtil.html2String(html);
+                if (StringUtil.isNotBlank(htmlContent)) {
+                    htmlContent = htmlContent.replaceAll("[   ]", " ").replace("第1页", "");
+                    CommonAnalysisUtil.html2StructureMap(titles, htmlContent, structureMap);
+                }
+            } else if ("协定方会诊".equals(recTitle)) {
+                htmlContent = HtmlAnalysisUtil.blockDivToStr(doc.selectFirst("body").child(0), true);
+                if (StringUtil.isNotBlank(htmlContent)) {
+                    htmlContent = htmlContent.replaceAll("[   ]", " ").replace("第1页", "");
+                    CommonAnalysisUtil.html2StructureMap(titles, htmlContent, structureMap);
+                }
+                if (StringUtil.isNotBlank(structureMap.get("会诊时间"))) {
+                    String[] strArr = structureMap.get("会诊时间").split(" ");
+                    structureMap.put("会诊意见", strArr[strArr.length - 1]);
+                    structureMap.put("会诊时间", strArr[0]);
+                }
+                CommonAnalysisUtil.extractDateByTitle(structureMap, "申请时间");
+            } else if ("MDT会诊申请表".equals(recTitle) || "新-MDT会诊三合一".equals(recTitle)) {
+                titles = Lists.newArrayList("姓名", "性别", "出生日期", "联系电话",
+                        "申请科室", "入院/首诊时间", "住院号", "病情概述(含主诉、病史、诊断、诊治过程等)", "拟申请MDT时间、地点",
+                        "拟请MDT参加科室", "MDT目的", "申请人签名", "申请递交时间", "科主任签字", "专家诊治建议", "专家科室", "签名",
+                        "填写时间", "主持科室小结(MDT的最终诊治决议)", "科主任(主持人)签名", "记录人(主管医师)签字", "日期");
+                htmlContent = CommonAnalysisUtil.html2String(html);
+                if (StringUtil.isNotBlank(htmlContent)) {
+                    htmlContent = htmlContent.replaceAll("[   ]", " ").replace("住院/门诊号", "").replace("第1页", "");
+                    StringBuffer sbf = new StringBuffer();
+                    List<String> distinctText = Lists.newArrayList(htmlContent.split(" ")).stream().distinct().collect(Collectors.toList());
+                    for (String text : distinctText) {
+                        sbf.append(text).append(" ");
+                    }
+                    CommonAnalysisUtil.html2StructureMapNoColon(titles, sbf.toString(), structureMap);
+                }
+                if (StringUtil.isNotBlank(structureMap.get("主持科室小结(MDT的最终诊治决议)"))) {
+                    String[] valueArray = structureMap.get("主持科室小结(MDT的最终诊治决议)").split(" ");
+                    structureMap.put("主持科室小结(MDT的最终诊治决议)", valueArray[1]);
+                    String v = valueArray[2];
+                    String[] vArr = v.split(":");
+                    if (vArr.length > 1) {
+                        structureMap.put(vArr[0], vArr[1]);
+                    }
+                }
+            } else if ("(外地专家)会诊邀请函".equals(recTitle)) {
+                titles = Lists.newArrayList("姓名", "出生年月", "病区", "床位", "住院号", "病情摘要", "会诊日期", "被邀医师", "专业",
+                        "职称", "单位", "会诊费用", "会诊科室", "医师签名", "医生签名", "科主任 签名", "患方意见", "签字", "外来专家 意见", "签字",
+                        "邀请医院(钉钉审批后盖章)");
+                htmlContent = CommonAnalysisUtil.html2String(html);
+                if (StringUtil.isNotBlank(htmlContent)) {
+                    htmlContent = htmlContent.replaceAll("[   ]", " ").replace("第1页", "").replace("年   月   日   时   分", "");
+                    CommonAnalysisUtil.html2StructureMapNoColon(titles, htmlContent, structureMap);
+                }
+                if (structureMap.containsKey("外来专家意见")) {
+                    structureMap.put("外来专家意见", structureMap.get("外来专家意见").replaceAll("签字:", ""));
+                }
+                if (structureMap.containsKey("被邀医师")) {
+                    structureMap.put("会诊医师", structureMap.get("被邀医师"));
+                }
+
+            } else {
+                htmlContent = HtmlAnalysisUtil.blockDivToStr(doc.selectFirst("body").child(0), true);
+                //htmlContent = CommonAnalysisUtil.html2String(html);
+                if (StringUtil.isNotBlank(htmlContent)) {
+                    htmlContent = htmlContent.replaceAll("[   ]", " ").replace("第1页", "");
+                    CommonAnalysisUtil.html2StructureMap(titles, htmlContent, structureMap);
+                }
+            }
+            if (structureMap.containsKey("会诊到达时间")) {
+                String arriveDateStr = CommonAnalysisUtil.extractDate(structureMap.get("会诊到达时间"));
+                if (StringUtil.isNotBlank(arriveDateStr)) {
+                    structureMap.put("会诊意见", structureMap.get("会诊到达时间").replace(arriveDateStr, "").trim());
+                    structureMap.put("会诊到达时间", arriveDateStr);
+                }
+            }
+            CommonAnalysisUtil.processType(structureMap, "会诊类型");
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, structureMap);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return structureMap;
+    }
+
+}

+ 56 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ConsultationRecordHtmlAnalysis.java

@@ -0,0 +1,56 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Element;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/28 20:12
+ */
+@Slf4j
+public class ConsultationRecordHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "7";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Element bigDivElement = Jsoup.parse(html).selectFirst("body").child(0);
+            analysisGeneral(recTitle,bigDivElement, map);
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, map);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+
+    private void analysisGeneral(String recTitle, Element bigDivElement, Map<String, String> map) {
+        if (bigDivElement.childNodeSize() == 1) {
+            bigDivElement = bigDivElement.child(0);
+        }
+        if (bigDivElement.selectFirst("hr") != null) {
+            bigDivElement.selectFirst("hr").previousElementSiblings().remove();
+        }
+        String text = HtmlAnalysisUtil.blockDivToStr(bigDivElement, true);
+        CommonAnalysisUtil.extractWardInfo(recTitle,text, map);
+    //    String bqjlText = "病情记录" + map.get("病情记录").replace("请在此填写会诊处理意见","").replace("会诊回复时间","");
+        List<String> titles = Lists.newArrayList(
+                "会诊意见","会诊意见执行情况","记录医师"
+        );
+        titles = CommonAnalysisUtil.sortTitlesNoColon(titles, text);
+        CommonAnalysisUtil.cutByTitlesNoColon(text, titles, 0, map);
+    }
+
+}

+ 51 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/CrisisValueReportHtmlAnalysis.java

@@ -0,0 +1,51 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Element;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/28 19:48
+ */
+@Slf4j
+public class CrisisValueReportHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "23";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Element bigDivElement = Jsoup.parse(html).selectFirst("body").child(0);
+            analysisGeneral(recTitle,bigDivElement, map);
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, map);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+
+    private void analysisGeneral(String recTitle, Element bigDivElement, Map<String, String> map) {
+        if (bigDivElement.childNodeSize() == 1) {
+            bigDivElement = bigDivElement.child(0);
+        }
+        if (bigDivElement.selectFirst("hr") != null) {
+            bigDivElement.selectFirst("hr").previousElementSiblings().remove();
+        }
+
+        String text = HtmlAnalysisUtil.blockDivToStr(bigDivElement, true);
+        ArrayList<String> strings = Lists.newArrayList("报告时间", "报告内容", "处理情况", "记录医师");
+        HangzhoufubaoTranUtils.getStructureMapSplitCommonCutByList(map, text, recTitle, strings);
+    }
+
+}

+ 70 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/CriticallyIllNoticeHtmlAnalysis.java

@@ -0,0 +1,70 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 病危(重)通知单html解析
+ * @author: HUJING
+ * @time: 2020/9/14 15:28
+ */
+@Slf4j
+public class CriticallyIllNoticeHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "25";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> structureMap = Maps.newLinkedHashMap();
+
+        try {
+            List<String> titles = Lists.newArrayList("姓名", "科别", "床号", "病案号",
+                    "1.简要病情", "2.目前诊断", "3.目前病情评估", "4.目前患者病情危重,随时出现以下一种或多种危及患者生命的并发症,且病情有进一步恶化\n" +
+                            "可能", "5.注意事项", "谈话医师签名", "签名日期", "时间", "6.患方知情选择",
+                    "患者签名", "指印", "患者签名时间", "若患者无法签署知情同意书或授权于亲属,请法定监护人或被授权人在此签名", "法定监护人/被授权人签名", "与患者关系", "法定监护人签名时间");
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Document doc = Jsoup.parse(html);
+            String htmlContent = HtmlAnalysisUtil.blockDivToStr(doc.selectFirst("body").child(0), true)
+                    .replace("患者签名", "患者签名:")
+                    .replace("法定监护人/被授权人签名", "法定监护人/被授权人签名:")
+                    .replace("与患者关系", "与患者关系:")
+                    .replace("指印", "指印:")
+                    .replace("第1页", "");
+
+            int index1 = htmlContent.indexOf("患者签名");
+            int index2 = htmlContent.lastIndexOf("法定监护人/被授权人签名");
+            if (index1 != -1 && index2 != -1) {
+                htmlContent = htmlContent.substring(0, index1)
+                        + htmlContent.substring(index1, index2).replace("签名时间", "患者签名时间").replace("年    月    日    时    分", "")
+                        + htmlContent.substring(index2).replace("签名时间", "法定监护人签名时间").replace("年    月    日    时    分", "");
+            }
+
+            if (StringUtil.isNotBlank(htmlContent)) {
+                htmlContent = htmlContent.replaceAll("[   ]", " ");
+                CommonAnalysisUtil.html2StructureMap(titles, htmlContent, structureMap);
+            }
+            structureMap.put("患者签名", structureMap.get("患者签名").replace("患者签名", ""));
+            if (StringUtil.isNotBlank(structureMap.get("法定监护人/被授权人签名"))) {
+                structureMap.put("法定监护人/被授权人签名", structureMap.get("法定监护人/被授权人签名").replace("患方签名", ""));
+            }
+            CommonAnalysisUtil.processTypeRight(structureMap, "3.目前病情评估");
+            CommonAnalysisUtil.processType(structureMap, "6.患方知情选择");
+            CommonAnalysisUtil.processType(structureMap, "指印");
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, structureMap);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return structureMap;
+    }
+
+}

+ 56 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/DeathCaseDiscussHtmlAnalysis.java

@@ -0,0 +1,56 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/17 14:27
+ */
+@Slf4j
+public class DeathCaseDiscussHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "3";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTypeId = args[2];
+            Document doc = Jsoup.parse(html);
+            Element bigDivElement = doc.selectFirst("body").child(0);
+            HtmlAnalysisUtil.tableStyle1InsertMap(doc.getElementById("table4_6"), map);
+            String text = HtmlAnalysisUtil.blockDivToStr(bigDivElement, false).replace("病情变化、诊治、抢救情况", "");
+
+            int index1 = text.lastIndexOf("记录者签名");
+            int index2 = text.lastIndexOf("主持人签名");
+            if (index1 != -1 && index2 != -1) {
+                text = text.substring(0, index1)
+                        + text.substring(index1, index2).replace("签字时间", "记录者签字时间:").replace("年月日时分", "")
+                        + text.substring(index2).replace("签字时间", "主持人签字时间:").replace("年月日时分", "");
+            }
+
+            List<String> titles = Lists.newArrayList("姓名", "性别", "年龄 ", "地址 ", "入院时间", "死亡时间", "讨论时间", "讨论地点",
+                    "讨论主持人", "参加人员", "讨论内容(包括病史摘要、治疗抢救过程、讨论目的、讨论意见及结论)", "病史摘要(经管医师汇报病史)", "讨论目的",
+                    "讨论意见", "主持人小结", "死亡原因", "死亡诊断", "记录者签名", "记录者签字时间", "主持人签名", "主持人签字时间");
+            titles = CommonAnalysisUtil.sortTitles(titles, text);
+            CommonAnalysisUtil.cutByTitlesNoColon(text, titles, 0, map);
+            HtmlAnalysisUtil.mapValueRemoveStartColon(map);
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, map);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+
+}

+ 51 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/DeathRecordHtmlAnalysis.java

@@ -0,0 +1,51 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 死亡记录html解析
+ * @author: HUJING
+ * @time: 2020/9/14 15:41
+ */
+@Slf4j
+public class DeathRecordHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "24";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> structureMap = Maps.newLinkedHashMap();
+        try {
+            List<String> titles = Lists.newArrayList("性别", "年龄", "婚姻", "入院日期", "死亡时间", "入院情况", "入院诊断",
+                    "诊疗经过(重点记录病情演变、抢救经过)", "诊疗经过", "死亡原因", "死亡诊断", "医师签字", "医生签名", "记录时间");
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Document doc = Jsoup.parse(html);
+            HtmlAnalysisUtil.tableStyle1InsertMap(doc.getElementById("table1"), structureMap);
+            String htmlContent = HtmlAnalysisUtil.blockDivToStr(doc.selectFirst("body").child(0), false);
+            if (StringUtil.isNotBlank(htmlContent)) {
+                htmlContent = htmlContent.replaceAll("[   ]", " ");
+                CommonAnalysisUtil.html2StructureMap(titles, htmlContent, structureMap);
+            }
+            if (CommonAnalysisUtil.extractDate(structureMap.get("医生签名")) != null) {
+                structureMap.put("记录时间", CommonAnalysisUtil.extractDate(structureMap.get("医生签名")));
+            }
+            structureMap.put("医生签名", structureMap.get("医生签名").replace("时间", ""));
+            CommonAnalysisUtil.extractDateByTitle(structureMap, "记录时间");
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, structureMap);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return structureMap;
+    }
+}

+ 87 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/DifficultCaseDiscussHtmlAnalysis.java

@@ -0,0 +1,87 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 疑难、危重病例讨论记录html解析
+ * @author: HUJING
+ * @time: 2020/9/14 15:41
+ */
+@Slf4j
+public class DifficultCaseDiscussHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "19";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> structureMap = Maps.newLinkedHashMap();
+        try {
+            List<String> titles = Lists.newArrayList("记录时间", "讨论时间", "讨论地点", "主持人", "参加人员", "病例介绍",
+                    "讨论目的", "讨论意见", "主持人小结", "记录医师");
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Document doc = Jsoup.parse(html);
+            String htmlContent = HtmlAnalysisUtil.blockDivToStr(doc.selectFirst("body").child(0), true);
+            if (StringUtil.isNotBlank(htmlContent)) {
+                htmlContent = htmlContent.replaceAll("[   ]", " ").replace("第一页", "");
+                CommonAnalysisUtil.html2StructureMap(titles, htmlContent, structureMap);
+            }
+            CommonAnalysisUtil.extractDateByTitle(structureMap, "告知时间");
+            removeLast(structureMap);
+            if (structureMap.containsKey("住院号")) {
+                String date = CommonAnalysisUtil.extractDate(structureMap.get("住院号"));
+                if (StringUtil.isNotBlank(date)) {
+                    structureMap.put("时间", date);
+                    CommonAnalysisUtil.repKey(structureMap, "住院号", "\n");
+                }
+            }
+            if (structureMap.containsKey("记录者(签名)")) {
+                structureMap.put("记录医生", structureMap.get("记录者(签名)").replace(" ", ""));
+            }
+            if (structureMap.containsKey("科主任(签名)")) {
+                String date1 = CommonAnalysisUtil.NBZYExtractDate(structureMap.get("科主任(签名)").replace(" ", ""));
+                if (StringUtil.isNotBlank(date1)) {
+                    structureMap.put("科主任签名", structureMap.get("科主任(签名)").replace(" ", "").replace(date1, ""));
+                } else {
+                    structureMap.put("科主任签名", structureMap.get("科主任(签名)").replace(" ", "").replace("年月日", ""));
+                }
+            }
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, structureMap);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e + "html=" + args[0]);
+        }
+        return structureMap;
+    }
+
+    /**
+     * 去除value中最后的逗号
+     *
+     * @param structureMap
+     */
+    private void removeLast(Map<String, String> structureMap) {
+        for (Map.Entry<String, String> entry : structureMap.entrySet()) {
+            structureMap.put(entry.getKey(), findLast(entry.getValue()));
+        }
+    }
+
+    private String findLast(String value) {
+        if (StringUtil.isNotBlank(value)) {
+            if (value.lastIndexOf(",") != value.length() - 1) {
+                return value;
+            }
+            value = value.substring(0, value.length() - 1);
+            findLast(value);
+        }
+        return value;
+    }
+}

+ 56 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/DutyShiftSystemHtmlAnalysis.java

@@ -0,0 +1,56 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Element;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/28 20:00
+ */
+@Slf4j
+public class DutyShiftSystemHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "9";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Element bigDivElement = Jsoup.parse(html).selectFirst("body").child(0);
+            analysisGeneral(recTitle,bigDivElement, map);
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, map);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+
+    private void analysisGeneral(String recTitle, Element bigDivElement, Map<String, String> map) {
+        if (bigDivElement.childNodeSize() == 1) {
+            bigDivElement = bigDivElement.child(0);
+        }
+        if (bigDivElement.selectFirst("hr") != null) {
+            bigDivElement.selectFirst("hr").previousElementSiblings().remove();
+        }
+        String text = HtmlAnalysisUtil.blockDivToStr(bigDivElement, true);
+        CommonAnalysisUtil.extractWardInfo(recTitle,text, map);
+        String bqjlText = "病情记录" + map.get("病情记录");
+        List<String> titles = Lists.newArrayList(
+                "病情记录","记录医师"
+        );
+        titles = CommonAnalysisUtil.sortTitlesNoColon(titles, bqjlText);
+        CommonAnalysisUtil.cutByTitlesNoColon(bqjlText, titles, 0, map);
+    }
+
+}

+ 78 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/FirstCourseRecordHtmlAnalysis.java

@@ -0,0 +1,78 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: HUJING
+ * @time: 2020/9/9 11:24
+ */
+@Slf4j
+public class FirstCourseRecordHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "2";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> structureMap = Maps.newLinkedHashMap();
+        try {
+            List<String> titles = Lists.newArrayList("病史特点", "初步诊断", "诊断依据", "鉴别诊断","治疗目标","诊疗计划","医生签名");
+            String html = args[0];
+            String recTitle = args[1];
+            Document doc = Jsoup.parse(html);
+            String htmlContent = HtmlAnalysisUtil.blockDivToStr(doc.selectFirst("body").child(0), true)
+                    .replace("第1页", "");
+            CommonAnalysisUtil.extractWardInfo(recTitle, htmlContent, structureMap);
+            if (StringUtil.isNotBlank(htmlContent)) {
+                titles = CommonAnalysisUtil.sortTitles(titles, htmlContent);
+                CommonAnalysisUtil.cutByTitles(htmlContent, titles, 0, structureMap);
+                if (!structureMap.containsKey("诊断依据")) {
+                    String zdyj = "";
+                    if (structureMap.containsKey("西医诊断依据")) {
+                        zdyj += "西医诊断依据:" + structureMap.get("西医诊断依据");
+                    }
+                    if (structureMap.containsKey("中医辨病辨证依据")) {
+                        zdyj += "  中医辨病辨证依据:" + structureMap.get("中医辨病辨证依据");
+                    }
+                    structureMap.put("诊断依据", zdyj);
+                }
+                if (!structureMap.containsKey("鉴别诊断")) {
+                    String jbzd = "";
+                    if (structureMap.containsKey("西医鉴别诊断")) {
+                        jbzd += "西医鉴别诊断:" + structureMap.get("西医鉴别诊断");
+                    }
+                    if (structureMap.containsKey("中医鉴别诊断")) {
+                        jbzd += "  中医鉴别诊断:" + structureMap.get("中医鉴别诊断");
+                    }
+                    structureMap.put("鉴别诊断", jbzd);
+                }
+
+                /*if (structureMap.containsKey("诊疗计划")) {
+                    if (structureMap.get("诊疗计划").indexOf("中医治则") != -1) {
+                        structureMap.put("诊疗计划", structureMap.get("诊疗计划").substring(0, structureMap.get("诊疗计划").indexOf("中医治则")));
+                    }
+                }*/
+                if (structureMap.containsKey("医生签名")) {
+                    if (structureMap.get("医生签名").indexOf("SignControl") != -1) {
+                        structureMap.put("医生签名", structureMap.get("医生签名").substring(0, structureMap.get("医生签名").indexOf("SignControl")));
+                    }
+                }
+            }
+
+            HtmlAnalysisUtil.insertModuleId(modeId, recTitle, structureMap);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return structureMap;
+    }
+
+}

+ 641 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/HangzhoufubaoCommonAnalysisUtil.java

@@ -0,0 +1,641 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.pub.util.StringUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+import org.jsoup.select.Elements;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description :余杭三院自定义
+ * @Author : HUJING
+ * @Date: 2020/9/10 13:48
+ */
+@Slf4j
+public class HangzhoufubaoCommonAnalysisUtil {
+
+    /**
+     * 取文书中全部文本
+     *
+     * @param html
+     * @return
+     */
+    public static String html2String(String html) {
+        try {
+            Document document = Jsoup.parse(html);
+            Element body = document.select("body").first();
+            List<Node> nodes = body.childNodes();
+            Node node = nodes.get(0);
+            if (" ".equals(node.toString())) {
+                node = nodes.get(1);
+            }
+            String htmlContent = null;
+            if (node instanceof Element) {
+                Element element = (Element) node;
+                htmlContent = element.text();
+            }
+            return htmlContent;
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            return "";
+        }
+    }
+
+    public static void html2StructureMap(List<String> titles, String htmlText, Map<String, String> structureMap) {
+        List<String> sortTitles = sortTitles(titles, htmlText);
+        cutByTitles(htmlText, sortTitles, 0, structureMap);
+    }
+
+    /**
+     * 将html内容以行为单位存进list,从<hr>之后开始处理
+     *
+     * @param html 原始html内容
+     * @return
+     */
+    public List<String> html2List(String html, boolean existHr) {
+        List<String> htmlText = Lists.newArrayList();
+        Document document = Jsoup.parse(html);
+        Element body = document.select("body").first();
+        List<Node> nodes = body.childNodes();
+        List<Node> subNodes = nodes.get(0).childNodes();
+        boolean findNode = false;
+        for (Node node : subNodes) {
+            if ("hr".equals(node.nodeName())) {
+                findNode = true;
+                continue;
+            }
+            if (findNode || !existHr) {
+                Element element = (Element) node;
+                Elements elements = element.select("div");
+                for (Element e : elements) {
+                    String text = e.text();
+                    if (text.length() > 150) {
+                        continue;
+                    }
+                    htmlText.add(text);
+                }
+            }
+        }
+        if (htmlText.get(0).length() > 200) {
+            htmlText.remove(0);
+        }
+        return htmlText;
+    }
+
+    /**
+     * 将html内容以table的格式存进list
+     *
+     * @param html 原始html内容
+     * @return
+     */
+    public void html2ListByTable(String html, List<String> htmlText) {
+        Elements trs = Jsoup.parse(html).select("table").select("tr");
+        for (int i = 0; i < trs.size(); i++) {
+            Elements tds = trs.get(i).select("td");
+            for (int j = 0; j < tds.size(); j++) {
+                String text = tds.get(j).text();
+                htmlText.add(text);
+            }
+        }
+    }
+
+    /**
+     * 将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})?)?");
+        Pattern pattern2 = 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);
+        Matcher matcher2 = pattern2.matcher(top);
+        if (matcher2.find()) {
+            return matcher2.group(0);
+        } else 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);
+            } else {
+                Pattern p2 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日 [0-9]+:[0-9]+ | [0-9]{4}年[0-9]+月[0-9]+日[0-9]+:[0-9]+ ");
+                Matcher m2 = p2.matcher(top);
+                if (m2.find()) {
+                    return m2.group(0);
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 宁波中医院抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String NBZYExtractDate(String top) {
+        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 WFYExtractDate(String top) {
+        Pattern p1 = Pattern.compile("[0-9]+月[0-9]+日[0-9]+时[0-9]+分");
+        Matcher m1 = p1.matcher(top);
+        if (m1.find()) {
+            return m1.group(0);
+        }
+        return null;
+    }
+
+    /**
+     * 宁海医院抽取文本中的第一个时间
+     *
+     * @param top
+     * @return
+     */
+    public static String NHExtractDate(String top) {
+        Pattern pattern = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日 [0-9]+:[0-9]+ | [0-9]{4}年[0-9]+月[0-9]+日[0-9]+:[0-9]+");
+        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);
+            } else {
+                Pattern p2 = 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 m2 = p2.matcher(top);
+                if (m2.find()) {
+                    return m2.group(0);
+                }
+            }
+            Pattern pattern3 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日 [0-9]+:[0-9]+|[0-9]{4}年[0-9]+月[0-9]+日[0-9]+:[0-9]+");
+            Matcher matcher3 = pattern3.matcher(top);
+            if (matcher3.find()) {
+                return matcher3.group(0);
+            }
+
+        }
+        return null;
+    }
+
+    /**
+     * 根据title重新存放时间
+     *
+     * @param structmap
+     * @param title
+     */
+    public static void extractDateByTitle(Map<String, String> structmap, String title) {
+        if (structmap.containsKey(title)) {
+            String date = extractDate(structmap.get(title));
+            if (StringUtil.isNotBlank(date)) {
+                structmap.put(title, date);
+            }
+        }
+    }
+
+    /**
+     * 若内容中是包含选择框(会诊类型:     急会诊       普通会诊         请院外会诊),特殊处理
+     *
+     * @param structureMap
+     */
+    public static void processType(Map<String, String> structureMap, String title) {
+        if (structureMap.containsKey(title)) {
+            String type = structureMap.get(title);
+            type = type.replace(" ", "").replace("\uF06F", " \uF06F")
+                    .replace("\uF0FE", " \uF0FE");
+            String[] types = type.split(" ");
+            String s = "";
+            for (String t : types) {
+                if (t.contains("\uF0FE")) {
+                    s += t;
+                }
+            }
+            s = s.replace("\uF0FE", "");
+            structureMap.put(title, s);
+        }
+    }
+
+    /**
+     * 若内容中是包含选择框(会诊类型:     急会诊       普通会诊         请院外会诊),特殊处理
+     *
+     * @param structureMap
+     */
+    public static void processTypeRight(Map<String, String> structureMap, String title) {
+        if (structureMap.containsKey(title)) {
+            String type = structureMap.get(title);
+            String[] types = type.split(" ");
+            String s = "";
+            for (String t : types) {
+                if (t.contains("\uF0FE")) {
+                    s += t;
+                }
+            }
+            s = s.replace("\uF0FE", "");
+            structureMap.put(title, s);
+        }
+    }
+
+    /**
+     * 若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);
+        }
+    }
+
+    /**
+     * 宁海用抽取自定义病程录信息
+     *
+     * @param htmlText
+     * @param structureMap
+     */
+    public static void NHExtractWardInfo(String recTitle, String htmlText, Map<String, String> structureMap) {
+        if (StringUtil.isNotBlank(htmlText)) {
+            htmlText = htmlText.replaceAll("[   \n]", " ").replace("第1页", "")
+                    .replace("\n", " ");
+            String date = NHExtractDate(htmlText);
+            if (date != null) {
+                structureMap.put("病历日期", date);
+                htmlText = htmlText.replace(date, "").trim();
+            }
+            List<String> titleContent = Lists.newArrayList(htmlText.split(" "));
+            String title = titleContent.get(0);
+            String jointTitle = titleContent.get(1);
+            if (StringUtil.isNotBlank(title) && StringUtil.isNotBlank(jointTitle) && jointTitle.contains("医师查房记录")) {
+                structureMap.put("病历标题", title + jointTitle);
+                titleContent.remove(0);
+                titleContent.remove(0);
+            } else {
+                structureMap.put("病历标题", recTitle);
+                titleContent.remove(0);
+            }
+            StringBuffer sb = new StringBuffer();
+            for (String text : titleContent) {
+                sb.append(text).append(" ");
+            }
+            String content = sb.toString();
+            if (content.contains("<img")) {
+                String[] contentDoctor = content.split("<img");
+                structureMap.put("病情记录", contentDoctor[0]);
+                structureMap.put("记录医生", "<img" + contentDoctor[1]);
+            } else {
+                structureMap.put("病情记录", content);
+            }
+//            if (structureMap.containsKey("病情记录")) {
+//                String info = structureMap.get("病情记录");
+//                if (info.contains("医生签名")) {
+//                    structureMap.put("病情记录", info.substring(0, info.lastIndexOf("医生签名")));
+//                    structureMap.put("记录医生", "");
+//                } else if (info.contains("医师签名")) {
+//                    structureMap.put("病情记录", info.substring(0, info.lastIndexOf("医师签名")));
+//                    structureMap.put("记录医生", "");
+//                }
+//            }
+        }
+    }
+
+    /**
+     * 抽取自定义病程录信息
+     *
+     * @param htmlText
+     * @param structureMap
+     */
+    public static void extractWardInfo(String recTitle, String htmlText, Map<String, String> structureMap) {
+        if (StringUtil.isNotBlank(htmlText)) {
+            htmlText = htmlText.replaceAll("[   \n]", " ").replace("第1页", "")
+                    .replace("\n", " ");
+            String date = extractDate(htmlText);
+            if (date != null) {
+                structureMap.put("病历日期", date);
+                htmlText = htmlText.replace(date, "").trim();
+            }
+            List<String> titleContent = Lists.newArrayList(htmlText.split(" "));
+            String title = titleContent.get(0);
+            if (StringUtil.isNotBlank(title) && title.equals(recTitle)) {
+                structureMap.put("病历标题", title);
+                titleContent.remove(0);
+            } else {
+                structureMap.put("病历标题", recTitle);
+                structureMap.put("文书标题", title);
+                if (titleContent.size() > 2) {
+                    titleContent.remove(0);
+                    titleContent.remove(0);
+                }
+            }
+            StringBuffer sb = new StringBuffer();
+            for (String text : titleContent) {
+                sb.append(text).append(" ");
+            }
+            String content = sb.toString();
+            if (content.contains("<img")) {
+                String[] contentDoctor = content.split("<img");
+                structureMap.put("病情记录", contentDoctor[0]);
+                structureMap.put("记录医生", "<img" + contentDoctor[1]);
+            } else {
+                structureMap.put("病情记录", content);
+            }
+            if (structureMap.containsKey("病情记录")) {
+                String info = structureMap.get("病情记录");
+                if (info.contains("医生签名")) {
+                    structureMap.put("病情记录", info.substring(0, info.lastIndexOf("医生签名")));
+                    structureMap.put("记录医生", "");
+                } else if (info.contains("医师签名")) {
+                    structureMap.put("病情记录", info.substring(0, info.lastIndexOf("医师签名")));
+                    structureMap.put("记录医生", "");
+                }
+            }
+        }
+    }
+
+    /**
+     * 抽取自定义病程录信息(余杭三院)
+     *
+     * @param htmlText
+     * @param structureMap
+     */
+    public static void extractWardInfo2(String recTitle, String htmlText, Map<String, String> structureMap) {
+        if (StringUtil.isNotBlank(htmlText)) {
+            htmlText = htmlText.replaceAll("[   \n]", " ").replace("第1页", "")
+                    .replace("\n", " ");
+            String date = extractDate(htmlText);
+            if (date != null) {
+                structureMap.put("病历日期", date);
+                htmlText = htmlText.replaceFirst(date, "").trim();
+            }
+            List<String> titleContent = Lists.newArrayList(htmlText.split(" "));
+            String title = titleContent.get(0);
+            if (StringUtil.isNotBlank(title) && title.equals(recTitle)) {
+                structureMap.put("病历标题", title);
+                titleContent.remove(0);
+            } else {
+                structureMap.put("病历标题", recTitle);
+                if (title.contains(recTitle)) {
+                    titleContent.set(0, title.substring(title.indexOf(recTitle) + recTitle.length()));
+                }
+            }
+            StringBuffer sb = new StringBuffer();
+            for (String text : titleContent) {
+                sb.append(text).append(" ");
+            }
+            structureMap.put("病情记录", sb.toString());
+            if (structureMap.containsKey("病情记录")) {
+                String info = structureMap.get("病情记录");
+                if (info.contains("记录医师")) {
+                    structureMap.put("病情记录", info.substring(0, info.lastIndexOf("记录医师")));
+                    structureMap.put("记录医师", info.substring(info.lastIndexOf("记录医师") + "记录医师:".length()));
+                } else if (info.contains("医师签名")) {
+                    structureMap.put("病情记录", info.substring(0, info.lastIndexOf("医师签名")));
+                    structureMap.put("医师签名", info.substring(info.lastIndexOf("医师签名") + "医师签名:".length()));
+                }
+            }
+        }
+    }
+
+    /**
+     * 替换值
+     *
+     * @param map
+     * @param key
+     * @param afterKey
+     */
+    public static void repKey(Map<String, String> map, String key, String afterKey) {
+        if (StringUtil.isNotBlank(map.get(key))) {
+            map.put(key, map.get(key).replaceAll(afterKey, ""));
+        }
+    }
+
+    public static void makeEmpty(Map<String, String> structureMap, String... key) {
+        for (String k : key) {
+            if (structureMap.containsKey(k)) {
+                structureMap.put(k, "");
+            }
+        }
+    }
+
+    /**
+     * 格式时间从yyyy年MM月dd日HH时mm分到yyyy-MM-dd HH:mm
+     *
+     * @param map
+     */
+    public static void signatureTime1(String changeCame, Map<String, String> map) {
+        String goCureDoctor = map.get(changeCame);
+        if (StringUtil.isNotBlank(goCureDoctor)) {
+            try {
+                Pattern pattern2 = Pattern.compile("[0-9]{4}[年][0-9]{1,2}[月][0-9]{1,2}[日][0-9]{1,2}[时][0-9]{1,2}[分]");
+                Matcher matcher2 = pattern2.matcher(goCureDoctor);
+                if (!matcher2.find()) {
+                    return;
+                }
+                Date parse = new SimpleDateFormat("yyyy年MM月dd日HH时mm分").parse(goCureDoctor);
+                String format = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(parse);
+                map.put(changeCame, format);
+            } catch (ParseException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}

+ 56 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/HangzhoufubaoFirstCourseRecordHtmlAnalysis.java

@@ -0,0 +1,56 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.yuhangsy.util.YuhangsyHtmlAnalysis;
+import com.lantone.qc.trans.yuhangsy.util.YuhangsyHtmlAnalysisUtil;
+import com.lantone.qc.trans.yuhangsy.util.comsis.YuhangsyCommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+
+import java.util.*;
+
+/**
+ * @Description:
+ * @author: HUJING
+ * @time: 2020/9/9 11:24
+ */
+@Slf4j
+public class HangzhoufubaoFirstCourseRecordHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "2";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        List<String> strings = Arrays.asList("一、", "二、", "三、", "四、", "五、", "六、", "七、", "八、");
+        Map<String, String> structureMap = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Document doc = Jsoup.parse(html);
+            List<String> titles = Lists.newArrayList("记录时间","一般情况","病史特点", "初步诊断", "诊断依据", "鉴别诊断","治疗目标","诊疗计划","医生签名");
+            String htmlContent = hangzhoufubaoHtmlAnalysisUtil.blockDivToStr2(doc.selectFirst("body").child(0), true);
+            if (StringUtil.isNotBlank(htmlContent)) {
+                HangzhoufubaoCommonAnalysisUtil.html2StructureMap(titles, htmlContent, structureMap);
+            }
+            for (Map.Entry<String, String> stringStringEntry : structureMap.entrySet()) {
+                for (String string : strings) {
+                    String value = stringStringEntry.getValue();
+                    if (value.endsWith(string)) {
+                        structureMap.put(stringStringEntry.getKey(),value.substring(0, value.length() - string.length()));
+                        break;
+                    }
+                }
+            }
+
+            YuhangsyHtmlAnalysisUtil.insertModuleId(modeId, recTypeId, structureMap);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return structureMap;
+    }
+
+}

+ 137 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/HangzhoufubaoTranUtils.java

@@ -0,0 +1,137 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author 10185
+ * @create 2022/4/15 11:51
+ */
+public class HangzhoufubaoTranUtils {
+    public static void extractedDate(Map<String, String> structureMap, String htmlText) {
+        Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日[0-9]+时[0-9]+分");
+        Matcher m1 = p1.matcher(htmlText);
+        if (m1.find()) {
+            String date = m1.group(0);
+            structureMap.put("病历日期", date);
+        }
+    }
+
+    public static void getStructureMap(Map<String, String> structureMap, String htmlText, String recTitle) {
+        extractedDate(structureMap, htmlText);
+        String[] split = htmlText.split("\n");
+        if (split.length > 1) {
+            if (structureMap.get("病历日期") != null) {
+                String date = structureMap.get("病历日期");
+                String title = split[0].replace(date, "");
+                structureMap.put("文书标题", title);
+            }
+            structureMap.put("病历标题", recTitle);
+            String content = htmlText.substring(split[0].length(), htmlText.length()).trim().replace("\n", "").replace(" ", "");
+            String str = "记录医师";
+            int index = content.indexOf(str + ":");
+            if (index == -1) {
+                index = content.indexOf(str + ":");
+            }
+            if (index > 0) {
+                structureMap.put("病情记录", content.substring(0, index));
+                structureMap.put("记录医师", content.substring(index + str.length() + 1, content.length()));
+            }
+        }
+    }
+    public static void getStructureMapSplitByLineCutByList(Map<String, String> structureMap, String htmlText, String recTitle, List<String> titles) {
+        extractedDate(structureMap, htmlText);
+        String[] split = htmlText.split("\n");
+        if (split.length > 1) {
+            if (structureMap.get("病历日期") != null) {
+                String date = structureMap.get("病历日期");
+                String title = split[0].replace(date, "");
+                structureMap.put("文书标题", title);
+            }
+            structureMap.put("病历标题", recTitle);
+            String content = htmlText.substring(split[0].length(), htmlText.length()).trim().replace("\n", "").replace(" ", "");
+            String str = "记录医师";
+            int index = content.indexOf(str + ":");
+            if (index == -1) {
+                index = content.indexOf(str + ":");
+            }
+            if (index > 0) {
+                structureMap.put("病情记录", content.substring(0, index));
+              //  structureMap.put("记录医师", content.substring(index + str.length() + 1, content.length()));
+            }
+            //同时记录别的内容
+
+            titles = CommonAnalysisUtil.sortTitlesNoColon(titles, content);
+            CommonAnalysisUtil.cutByTitlesNoColon(content, titles, 0, structureMap);
+        }
+    }
+    public static void getStructureMapSplitByBlankCutByList(Map<String, String> structureMap, String htmlText, String recTitle, List<String> titles) {
+        extractedDate(structureMap, htmlText);
+        String[] split = htmlText.split(" ");
+        if (split.length > 1) {
+            if (structureMap.get("病历日期") != null) {
+                String date = structureMap.get("病历日期");
+                String title = split[0].replace(date, "");
+                structureMap.put("文书标题", split[1]);
+            }
+            structureMap.put("病历标题", recTitle);
+            String content = htmlText.substring(split[0].length(), htmlText.length()).trim().replace("\n", "").replace(" ", "");
+            String str = "记录医师";
+            int index = content.indexOf(str + ":");
+            if (index == -1) {
+                index = content.indexOf(str + ":");
+            }
+            if (index > 0) {
+                structureMap.put("病情记录", content.substring(0, index));
+                //  structureMap.put("记录医师", content.substring(index + str.length() + 1, content.length()));
+            }
+            //同时记录别的内容
+
+            titles = CommonAnalysisUtil.sortTitlesNoColon(titles, content);
+            CommonAnalysisUtil.cutByTitlesNoColon(content, titles, 0, structureMap);
+        }
+    }
+
+    public static void getStructureMapSplitCommonCutByList(Map<String, String> structureMap, String htmlText, String recTitle, List<String> titles) {
+        boolean flag = false;
+        extractedDate(structureMap, htmlText);
+        String[] split = htmlText.split("\n");
+        if (split.length <= 1) {
+            split = htmlText.split(" ");
+            flag = true;
+        }
+        if (split.length > 1) {
+            if (structureMap.get("病历日期") != null) {
+                String date = structureMap.get("病历日期");
+                String title = split[0].replace(date, "");
+                structureMap.put("文书标题", flag ? split[1] : title);
+            }
+            structureMap.put("病历标题", recTitle);
+            String content = htmlText.substring(split[0].length(), htmlText.length()).trim().replace("\n", "").replace(" ", "");
+            String str = "记录医师";
+            int index = content.indexOf(str + ":");
+            if (index == -1) {
+                index = content.indexOf(str + ":");
+            }
+            if (index == -1) {
+                index = content.indexOf("医师签名" + ":");
+            }
+            if (index == -1) {
+                index = content.indexOf("操作医师签名" + ":");
+            }
+            if (index > 0) {
+                structureMap.put("病情记录", content.substring(0, index));
+                //  structureMap.put("记录医师", content.substring(index + str.length() + 1, content.length()));
+            }
+            //同时记录别的内容
+
+            titles = CommonAnalysisUtil.sortTitlesNoColon(titles, content);
+            CommonAnalysisUtil.cutByTitlesNoColon(content, titles, 0, structureMap);
+        }
+    }
+}

+ 14 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/HtmlAnalysis.java

@@ -0,0 +1,14 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import java.util.Map;
+
+/**
+ * @Description: 北仑html解析
+ * @author: rengb
+ * @time: 2020/9/9 11:26
+ */
+public interface HtmlAnalysis {
+
+    Map<String, String> analysis(String... args);
+
+}

+ 243 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/HtmlAnalysisUtil.java

@@ -0,0 +1,243 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.dbanaly.util.ModuleMappingUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/15 16:31
+ */
+public class HtmlAnalysisUtil {
+
+    /**
+     * table样式:key和value在同一个td中,以冒号分开;保留换行
+     *
+     * @param tableElement
+     * @param map
+     */
+    public static void tableStyle1InsertMap(Element tableElement, Map<String, String> map) {
+        if (tableElement == null || map == null) {
+            return;
+        }
+        List<Element> tdElements = Lists.newArrayList();
+        tableElement.selectFirst("tbody").children().forEach(trElement -> {
+            trElement.children().forEach(tdElement -> {
+                tdElements.add(tdElement);
+            });
+        });
+        String tdText = null;
+        int tdMhIndex = 0;
+        for (Element tdElement : tdElements) {
+            if (tdElement.childNodeSize() == 0) {
+                continue;
+            }
+            tdText = blockDivToStr(tdElement.child(0), true);
+            if (tdText.endsWith("\n")) {
+                tdText = tdText.substring(0, tdText.length() - 1);
+            }
+            if (StringUtil.isBlank(tdText)) {
+                continue;
+            }
+            tdMhIndex = tdText.indexOf(":");
+            if (tdMhIndex == -1) {
+                tdMhIndex = tdText.indexOf(":");
+            }
+            if (tdMhIndex < 1) {
+                continue;
+            }
+            if (tdText.contains("姓    名") && tdText.contains("年    龄")) {
+                multiColonResolve(tdMhIndex, tdText, "年    龄", map);
+            } else if (tdText.contains("姓    名") && tdText.contains("年   龄")) {
+                multiColonResolve(tdMhIndex, tdText, "年   龄", map);
+            } else if (tdText.contains("姓    名") && tdText.contains("年  龄")) {
+                multiColonResolve(tdMhIndex, tdText, "年  龄", map);
+            } else if (tdText.contains("姓    名") && tdText.contains("年 龄")) {
+                multiColonResolve(tdMhIndex, tdText, "年 龄", map);
+            } else if (tdText.contains("产前检查") && tdText.contains("孕/产次")) {
+                multiColonResolve(tdMhIndex, tdText, "孕/产次", map);
+            } else if (tdText.contains("末次月经") && tdText.contains("预产期")) {
+                multiColonResolve(tdMhIndex, tdText, "预产期", map);
+            } else if (tdText.contains("中医诊断:") && tdText.contains("西医诊断:")) {
+                List<String> titles = Lists.newArrayList("中医诊断", "西医诊断");
+                CommonAnalysisUtil.cutByTitles(tdText, titles, 0, map);
+                map.put("初步诊断", "中医诊断:" + map.get("中医诊断") + " 西医诊断:" + map.get("西医诊断"));
+            } else {
+                map.put(
+                        StringUtil.removeBlank(tdText.substring(0, tdMhIndex)),
+                        tdText.length() - 1 <= tdMhIndex ? "" : tdText.substring(tdMhIndex + 1)
+                );
+            }
+        }
+    }
+
+    /**
+     * 取得多个字段时,分别存储
+     *
+     * @param tdText
+     * @param text
+     */
+    public static void multiColonResolve(int tdMhIndex, String tdText, String text, Map<String, String> map) {
+        String firstText = tdText.split(text)[0];
+        map.put(
+                StringUtil.removeBlank(firstText.substring(0, tdMhIndex)),
+                firstText.length() - 1 <= tdMhIndex ? "" : firstText.substring(tdMhIndex + 1)
+        );
+        String secondText = tdText.split(text)[1];
+        secondText = secondText.replace(":", "");
+        secondText = secondText.replace(":", "");
+        map.put(StringUtil.removeBlank(text), secondText);
+    }
+
+    /**
+     * table样式:td两两配对,一个key,一个value;不保留换行
+     *
+     * @param tableElement
+     * @param map
+     */
+    public static void tableStyle2InsertMap(Element tableElement, Map<String, String> map) {
+        if (tableElement == null || map == null) {
+            return;
+        }
+        List<Element> tdElements = Lists.newArrayList();
+        tableElement.selectFirst("tbody").children().forEach(trElement -> {
+            if (trElement.childNodeSize() != 2) {
+                return;
+            }
+            trElement.children().forEach(tdElement -> {
+                tdElements.add(tdElement);
+            });
+        });
+        int index = 0;
+        String key = null, value = null, text = null;
+        for (Element tdElement : tdElements) {
+            if (tdElement.childNodeSize() == 0) {
+                text = "";
+            } else {
+                text = blockDivToStr(tdElement.child(0), false);
+            }
+            if (index % 2 == 0) {
+                key = text.replaceAll("[:: ]", "");
+            }
+            if (index % 2 == 1) {
+                value = text;
+                if (StringUtil.isNotBlank(key)) {
+                    map.put(key, value);
+                }
+            }
+            index++;
+        }
+    }
+
+    /**
+     * 一个大的块状div下包含很多行行状div
+     *
+     * @param divElement
+     * @param isLineBreak 是否保留换行
+     * @return
+     */
+    public static String blockDivToStr(Element divElement, boolean isLineBreak) {
+        if (divElement == null) {
+            return "";
+        }
+        StringBuffer sbf = new StringBuffer();
+        for (Element childElement : divElement.children()) {
+            if (isLineBreak) {
+                sbf.append(elementLayer1ToStr(childElement, false)).append("\n");
+            } else {
+                sbf.append(elementLayer1ToStr(childElement, false).trim());
+            }
+        }
+        return sbf.toString();
+    }
+
+    /**
+     * 标签仅遍历第一子层级后转字符串
+     *
+     * @param element
+     * @param isLineBreak 是否保留换行
+     * @return
+     */
+    public static String elementLayer1ToStr(Element element, boolean isLineBreak) {
+        if (element == null) {
+            return "";
+        }
+        StringBuffer sbf = new StringBuffer();
+        List<Element> elements = Lists.newArrayList();
+        Elements childElements = element.children();
+        if (childElements.size() == 0) {
+            elements.add(element);
+        }
+        for (Element childElement : childElements) {
+            elements.add(childElement);
+        }
+        for (Element childElement : elements) {
+            if (childElement.tagName().equals("img") || childElement.tagName().equals("image")) {
+                //                sbf.append(childElement.outerHtml());
+                sbf.append("—");
+            } else {
+                sbf.append(childElement.text());
+            }
+            if (isLineBreak) {
+                sbf.append("\n");
+            }
+        }
+        String sbfString = removeSex(sbf.toString().replaceAll(" ", " "));
+        return sbfString;
+    }
+
+    /**
+     * 查询并插入页面模板id
+     *
+     * @param modeId
+     * @param recTitle
+     * @param map
+     */
+    public static void insertModuleId(String modeId, String recTitle, Map<String, String> map) {
+        if ((StringUtil.isBlank(modeId) && StringUtil.isBlank(recTitle)) || map == null) {
+            return;
+        }
+        String moduleId = ModuleMappingUtil.getHtmlDataTypeModuleId(recTitle);
+        if (StringUtil.isBlank(moduleId)) {
+            moduleId = ModuleMappingUtil.getStandardModuleId(modeId);
+        }
+        map.put("mode_id", moduleId);
+    }
+
+    /**
+     * map中有的value以冒号开头,用此方法来去掉冒号
+     *
+     * @param map
+     */
+    public static void mapValueRemoveStartColon(Map<String, String> map) {
+        if (map == null) {
+            return;
+        }
+        map.keySet().forEach(key -> {
+            if (map.get(key).startsWith(":") || map.get(key).startsWith(":")) {
+                map.put(key, map.get(key).replaceFirst("[::]", ""));
+            }
+        });
+    }
+
+    /**
+     * 北仑:入院记录中性别取得去除"性"
+     * e.g.(性    别:男性 ->性    别:男)
+     *
+     * @param sbfString
+     */
+    public static String removeSex(String sbfString) {
+        if (sbfString.contains("性    别:")) {
+            sbfString = sbfString.substring(0, sbfString.length() - 1);
+        }
+        return sbfString;
+    }
+
+}

+ 60 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/LeaveHospitalHtmlAnalysis.java

@@ -0,0 +1,60 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: HUJING
+ * @time: 2020/9/9 11:24
+ */
+@Slf4j
+public class LeaveHospitalHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "5";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> structureMap = Maps.newLinkedHashMap();
+        try {
+            List<String> titles = Lists.newArrayList("姓名", "性别","出生年月","主诊医师",
+                    "入院日期", "出院日期", "入院诊断", "出院诊断","疗效评价", "住院天数","入院情况", "住院诊治经过(包括重要发现和结论、接受手术和操作、药物和其它治疗)","辅助检查"
+                    ,"出院情况","出院去向", "出院带药","出院指导","复诊", "健康宣教",
+                    "可能需要的紧急医疗", "出院交通需求", "监护人意见", "监护人签名",
+                    "健康指导");
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Document doc = Jsoup.parse(html);
+            //个人基础信息table解析
+            String htmlContent = HangzhoufubaoCommonAnalysisUtil.html2String(doc.toString());
+            if (StringUtil.isNotBlank(htmlContent)) {
+                HangzhoufubaoCommonAnalysisUtil.html2StructureMap(titles,htmlContent,structureMap);
+            }
+/*            if (StringUtil.isNotBlank(CommonAnalysisUtil.extractDate(structureMap.get("出院日期")))) {
+                structureMap.put("住院天数", structureMap.get("出院日期").replace(CommonAnalysisUtil.extractDate(structureMap.get("出院日期")), ""));
+                structureMap.put("出院日期", CommonAnalysisUtil.extractDate(structureMap.get("出院日期")));*/
+
+           /* if (structureMap.containsKey("医生签名")) {
+                if (structureMap.get("医生签名").indexOf("SignControl") != -1) {
+                    structureMap.put("医生签名", structureMap.get("医生签名").substring(0, structureMap.get("医生签名").indexOf("SignControl")));
+                }
+            }
+            if (structureMap.containsKey("日期")) {
+                structureMap.put("日期", CommonAnalysisUtil.extractDate(structureMap.get("日期")));
+            }*/
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, structureMap);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e + "html=" + args[0]);
+        }
+        return structureMap;
+    }
+}

+ 101 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/OperationHtmlAnalysis.java

@@ -0,0 +1,101 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Element;
+
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/28 14:56
+ */
+@Slf4j
+public class OperationHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "18";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> structureMap = Maps.newLinkedHashMap();
+        try {
+            String htmlText = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Element bigDivElement = Jsoup.parse(htmlText).selectFirst("body").child(0);
+            htmlText = HtmlAnalysisUtil.blockDivToStr(bigDivElement, true);
+          /*  analysisGeneral(recTitle, bigDivElement, map);
+            CommonAnalysisUtil.makeEmpty(map, "医生签名");*/
+
+            getStructureMap(structureMap, htmlText, recTitle);
+
+            //  structureMap.put("记录医生")
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, structureMap);
+
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return structureMap;
+    }
+
+    private void getStructureMap(Map<String, String> structureMap, String htmlText, String recTitle) {
+        extractedDate(structureMap, htmlText);
+        String[] split = htmlText.split("\n");
+        if (split.length > 1) {
+            if (structureMap.get("病历日期") != null) {
+                String date = structureMap.get("病历日期");
+                String title = split[0].replace(date, "");
+                structureMap.put("文书标题", title);
+            }
+            structureMap.put("病历标题", recTitle);
+            String content = htmlText.substring(split[0].length(), htmlText.length()).trim().replace("\n", "").replace(" ", "");
+            String str = "记录医师";
+            int index = content.indexOf(str + ":");
+            if (index == -1) {
+                index = content.indexOf(str + ":");
+            }
+            if (index > 0) {
+                structureMap.put("病情记录", content.substring(0, index));
+                structureMap.put("记录医师", content.substring(index + str.length() + 1, content.length()));
+            }
+        }
+    }
+
+    private void extractedDate(Map<String, String> structureMap, String htmlText) {
+        Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日[0-9]+时[0-9]+分");
+        Matcher m1 = p1.matcher(htmlText);
+        if (m1.find()) {
+            String date = m1.group(0);
+            structureMap.put("病历日期", date);
+        }
+    }
+
+    private void analysisGeneral(String recTitle, Element bigDivElement, Map<String, String> map) {
+        if (bigDivElement.childNodeSize() == 1) {
+            bigDivElement = bigDivElement.child(0);
+        }
+        if (bigDivElement.selectFirst("hr") != null) {
+            bigDivElement.selectFirst("hr").previousElementSiblings().remove();
+        }
+        String text = HtmlAnalysisUtil.blockDivToStr(bigDivElement, true);
+        CommonAnalysisUtil.extractWardInfo(recTitle, text, map);
+        String bqjlText = "病情记录" + map.get("病情记录")
+                .replace("提醒:有创诊疗操作记录内容包括操作名称、时间、步骤、结果及患者的一般情况,记录操作过", "")
+                .replace("程是否顺利,有无不良反应,术后注意事项,操作医师签名、记录时间等。", "")
+                .replace("手术室完成的、治疗性质的及全麻下完成的有创诊疗操作参照手术管理。(包括介入治疗、胃肠镜", "")
+                .replace("下肿瘤切除/粘膜下肿瘤剥除等)", "");
+        List<String> titles = Lists.newArrayList("手术日期", "术前诊断", "术中诊断", "麻醉方式", "手术方式",
+                "手术简要经过(包括“术中所见”)", "病人回病房时情况", "术后处理措施", "术后注意事项", "医生签名");
+        titles = CommonAnalysisUtil.sortTitles(titles, bqjlText);
+        map.remove("病情记录");
+        CommonAnalysisUtil.cutByTitles(bqjlText, titles, 0, map);
+    }
+
+}

+ 80 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/OperationRecordHtmlAnalysis.java

@@ -0,0 +1,80 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Element;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/28 16:36
+ */
+@Slf4j
+public class OperationRecordHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "17";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Element bigDivElement = Jsoup.parse(html).selectFirst("body").child(0);
+            analysisGeneral(bigDivElement, map);
+            HtmlAnalysisUtil.mapValueRemoveStartColon(map);
+            CommonAnalysisUtil.makeEmpty(map, "医生签名");
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, map);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+
+    private void analysisGeneral(Element bigDivElement, Map<String, String> map) {
+        String text = HtmlAnalysisUtil.blockDivToStr(bigDivElement, true);
+        text = text.replaceAll("第1页", "")
+                .replace("(包括体位、切口处理经过,病灶所见及手术步骤等):", "");
+        List<String> titles = Lists.newArrayList(
+                "手术开始时间", "手术结束时间", "手术全程时间", "术前诊断", "手术名称", "手术指征", "术后诊断", "主刀医师", "麻醉人员", "器械护士",
+                "儿科医生", "护婴人", "指导人", "麻醉方式", "麻醉体位", "麻醉效果", "手术经过", "术中并发症", "冰冻切片诊断", "送检手术标本",
+                "失血量", "输入血/血制品", "植入物", "手术医生签名", "日 期");
+        titles = CommonAnalysisUtil.sortTitles(titles, text);
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, map);
+/*        CommonAnalysisUtil.processTypeRight(map, "NNIS分级");
+        CommonAnalysisUtil.processTypeRight(map, "手术类别(可选)");
+        CommonAnalysisUtil.processType(map, "手术标本");
+        CommonAnalysisUtil.processType(map, "术中并发症");
+        if (StringUtil.isNotBlank(map.get("NNIS分级"))) {
+            map.put("NNIS分级", map.get("NNIS分级").replace("-", ""));
+        }*/
+       /* if (map.containsKey("记录日期") && StringUtil.isNotBlank(map.get("记录日期"))) {
+            StringBuffer sb = new StringBuffer();
+            sb.append(map.get("记录日期"));
+            if (map.containsKey("时间") && StringUtil.isNotBlank(map.get("时间"))) {
+                sb.append(map.get("时间"));
+            }
+            map.put("日期", sb.toString());
+        }*/
+        /*if (map.containsKey("手术主刀医师") && StringUtil.isNotBlank(map.get("手术主刀医师"))) {
+            StringBuffer sb1 = new StringBuffer();
+            sb1.append("手术主刀医师:" + map.get("手术主刀医师"));
+            if (map.containsKey("一助") && StringUtil.isNotBlank(map.get("一助"))) {
+                sb1.append(" 一助:" + map.get("一助"));
+            }
+            if (map.containsKey("二助") && StringUtil.isNotBlank(map.get("二助"))) {
+                sb1.append(" 二助:" + map.get("二助"));
+            }
+            map.put("手术人员", sb1.toString());
+        }*/
+    }
+
+}

+ 87 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/PreoperativeHtmlAnalysis.java

@@ -0,0 +1,87 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Element;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/17 19:19
+ */
+@Slf4j
+public class PreoperativeHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "11";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Element bigDivElement = Jsoup.parse(html).selectFirst("body").child(0);
+            analysisGeneral(bigDivElement, map);
+
+            HtmlAnalysisUtil.mapValueRemoveStartColon(map);
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, map);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+
+    private void analysisGeneral(Element bigDivElement, Map<String, String> map) {
+        /*if (bigDivElement.selectFirst("hr") != null) {
+            bigDivElement.selectFirst("hr").previousElementSiblings().remove();
+        }*/
+        String text = HtmlAnalysisUtil.blockDivToStr(bigDivElement, true).replace("·", "");
+
+      /*  int index1 = text.lastIndexOf("经治医师签名");
+        int index2 = text.lastIndexOf("主刀医师签名");
+        if (index1 != -1 && index2 != -1) {
+            text = text.substring(0, index1)
+                    + text.substring(index1, index2).replace("签字时间", "经治医师签字时间:")
+                    + text.substring(index2).replace("签字时间", "主刀医师签字时间:");
+        }*/
+/*        text = text.replace("(", "(")
+                .replace(")", ")")
+                .replace("术前讨论及术前小结", "")
+                .replace("二、讨论结论:", "")
+                .replace("(如腹腔镜可能改开腹等)", "")
+                .replace("(如高血压病、冠心病、糖尿病、脑梗、心梗、心肺肝肾功能不全、口服抗凝药等)", "")
+                .replace("年月日时\n" + "分", "")
+                .replace("一、简要病情", "简要病情");*/
+        text = text.replace("参加人员(姓名及专业技术职务) ", "参加人员");
+        List<String> titles = Lists.newArrayList("记录时间", "术前讨论时间", "讨论方式", "参加人员", "简要病情", "术前诊断", "手术指征"
+                ,  "术前诊断", "手术指征", "术前准备", "手术禁忌证", "患者目前心理状态/文化需求", "拟行手术方案",
+                "拟施麻醉", "手术目标",
+                "手术中注意点", "术后注意点", "出院后潜在的医疗与康复需求", "主刀医师意见与手术安排","医生签名");
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, map);
+    }
+
+    /**
+     * 解决医生签名时间显示 年 月 日 时 分
+     *
+     * @param map
+     */
+    private void signatureTime(Map<String, String> map) {
+        String goCureDoctor = map.get("经治医生签字时间");
+        String operateDoctor = map.get("主刀医生签字时间");
+        if (StringUtil.isNotBlank(goCureDoctor) && goCureDoctor.contains("年 月 日 时 分")) {
+            map.put("经治医生签字时间", goCureDoctor.replace("年 月 日 时 分", ""));
+        }
+        if (StringUtil.isNotBlank(operateDoctor) && operateDoctor.contains("年 月 日 时 分")) {
+            map.put("主刀医生签字时间", operateDoctor.replace("年 月 日 时 分", ""));
+        }
+    }
+
+}

+ 54 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/RescueHtmlAnalysis.java

@@ -0,0 +1,54 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Element;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/28 20:12
+ */
+@Slf4j
+public class RescueHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "22";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Element bigDivElement = Jsoup.parse(html).selectFirst("body").child(0);
+            analysisGeneral(recTitle, bigDivElement, map);
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, map);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+
+    private void analysisGeneral(String recTitle, Element bigDivElement, Map<String, String> structureMap) {
+        if (bigDivElement.childNodeSize() == 1) {
+            bigDivElement = bigDivElement.child(0);
+        }
+        if (bigDivElement.selectFirst("hr") != null) {
+            bigDivElement.selectFirst("hr").previousElementSiblings().remove();
+        }
+        String htmlText = HtmlAnalysisUtil.blockDivToStr(bigDivElement, true);
+        List<String> titles = Lists.newArrayList(
+                "抢救时间", "抢救内容", "参加人员", "记录医师"
+        );
+        HangzhoufubaoTranUtils.getStructureMapSplitByLineCutByList(structureMap, htmlText, recTitle, titles);
+
+    }
+
+}
+

+ 56 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/StagesSummaryHtmlAnalysis.java

@@ -0,0 +1,56 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Element;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/28 20:16
+ */
+@Slf4j
+public class StagesSummaryHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "28";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Element bigDivElement = Jsoup.parse(html).selectFirst("body").child(0);
+            analysisGeneral(recTitle, bigDivElement, map);
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, map);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+
+    private void analysisGeneral(String recTitle, Element bigDivElement, Map<String, String> map) {
+        if (bigDivElement.childNodeSize() == 1) {
+            bigDivElement = bigDivElement.child(0);
+        }
+        if (bigDivElement.selectFirst("hr") != null) {
+            bigDivElement.selectFirst("hr").previousElementSiblings().remove();
+        }
+        String text = HtmlAnalysisUtil.blockDivToStr(bigDivElement, true);
+        CommonAnalysisUtil.extractWardInfo(recTitle, text, map);
+        String bqjlText = "病情记录" + map.get("病情记录");
+        List<String> titles = Lists.newArrayList(
+                "病情记录"
+        );
+        titles = CommonAnalysisUtil.sortTitlesNoColon(titles, bqjlText);
+        CommonAnalysisUtil.cutByTitlesNoColon(bqjlText, titles, 0, map);
+    }
+
+}

+ 133 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ThreeLevelWardHtmlAnalysis.java

@@ -0,0 +1,133 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+import org.jsoup.select.Elements;
+
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description: 自定义病程记录html解析
+ * @author: HUJING
+ * @time: 2020/9/15 10:28
+ */
+@Slf4j
+public class ThreeLevelWardHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "4";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> structureMap = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Document doc = Jsoup.parse(html);
+            String htmlText;
+            if (doc.selectFirst("body").childNodeSize() > 0) {
+                Element bigDivElement = doc.selectFirst("body").child(0);
+                if (bigDivElement.childNodeSize() == 1) {
+                    bigDivElement = bigDivElement.child(0);
+                }
+                htmlText = HtmlAnalysisUtil.blockDivToStr(bigDivElement, true);
+            }else{
+                htmlText = doc.text();
+            }
+
+            /*if (bigDivElement.selectFirst("hr") != null) {
+                bigDivElement.selectFirst("hr").previousElementSiblings().remove();
+            }*/
+
+            /*htmlText = htmlText.replace("注意:上级医师查房主要记 录:患者病情、诊断、鉴别诊断、当前治疗措施和疗效的分析及下一步诊疗意见等,能反应上级医 师的水平。", "")
+                    .replace("提醒:有创诊疗操作记录内容包括操作名称、时间、步骤、结果及患者的一般情况,记录操作过 程是否顺利,有无不良反应,术后注意事项,操作医师签名、记录时间等。 手术室完成的、治疗性质的及全麻下完成的有创诊疗操作参照手术管理。(包括介入治疗、胃肠镜 下肿瘤切除/粘膜下肿瘤剥除等)", "");*/
+           //CommonAnalysisUtil.extractWardInfo(recTitle, htmlText, structureMap);
+            //提取文本中的时间
+            //提取文本中的记录医师
+            extractedDate(structureMap, htmlText);
+            String[] split = htmlText.split("\n");
+            if (split.length > 1) {
+                if (structureMap.get("病历日期") != null) {
+                    String date = structureMap.get("病历日期");
+                   String  title = split[0].replace(date, "");
+                    structureMap.put("文书标题", title);}
+                    structureMap.put("病历标题", recTitle);
+                String content = htmlText.substring(split[0].length(), htmlText.length()).trim().replace("\n","").replace(" ","");
+                String str = "记录医师";
+                int index = content.indexOf(str+":");
+                if (index == -1) {
+                    index = content.indexOf(str+":");
+                }
+                if (index > 0) {
+                    structureMap.put("病情记录", content.substring(0, index));
+                    structureMap.put("记录医师", content.substring(index + str.length() + 1, content.length()));
+                }
+            }
+
+            //  structureMap.put("记录医生")
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, structureMap);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return structureMap;
+    }
+
+    private void extractedDate(Map<String, String> structureMap, String htmlText) {
+        Pattern p1 = Pattern.compile("[0-9]{4}年[0-9]+月[0-9]+日[0-9]+时[0-9]+分");
+        Matcher m1 = p1.matcher(htmlText);
+        if (m1.find()) {
+           String  date = m1.group(0);
+            structureMap.put("病历日期", date);
+        }
+    }
+
+    /**
+     * 将html内容以行为单位存进list,从<hr>之后开始处理
+     *
+     * @param html 原始html内容
+     * @return
+     */
+    public static List<String> html2List(String html, boolean existHr) {
+        List<String> htmlText = Lists.newArrayList();
+        Document document = Jsoup.parse(html);
+        Element body = document.select("body").first();
+        List<Node> nodes = body.childNodes();
+        List<Node> subNodes = nodes.get(0).childNodes();
+        boolean findNode = false;
+        for (Node node : subNodes) {
+            if ("hr".equals(node.nodeName())) {
+                findNode = true;
+                continue;
+            }
+            if (findNode || !existHr) {
+                String title = node.attr("title");
+                if ("main".equals(title)) {
+                    Element element = (Element) node;
+                    Elements elements = element.select("div");
+                    for (Element e : elements) {
+                        String text = e.text();
+                        if (text.length() > 150) {
+                            continue;
+                        }
+                        htmlText.add(text);
+                    }
+                }
+            }
+        }
+        if (htmlText.get(0).length() > 200) {
+            htmlText.remove(0);
+        }
+        return htmlText;
+    }
+
+}

+ 53 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/TransferIntoHtmlAnalysis.java

@@ -0,0 +1,53 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Element;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/28 20:20
+ */
+@Slf4j
+public class TransferIntoHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "26";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Element bigDivElement = Jsoup.parse(html).selectFirst("body").child(0);
+            analysisGeneral(recTitle, bigDivElement, map);
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, map);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+
+    private void analysisGeneral(String recTitle, Element bigDivElement, Map<String, String> map) {
+        if (bigDivElement.childNodeSize() == 1) {
+            bigDivElement = bigDivElement.child(0);
+        }
+        if (bigDivElement.selectFirst("hr") != null) {
+            bigDivElement.selectFirst("hr").previousElementSiblings().remove();
+        }
+        String text = HtmlAnalysisUtil.blockDivToStr(bigDivElement, true);
+        List<String> titles = Lists.newArrayList(
+                "入院情况", "入院诊断", "诊疗经过", "目前情况", "目前诊断", "转科目的", "诊疗计划", "医师签名", "时间"
+        );
+        HangzhoufubaoTranUtils.getStructureMapSplitCommonCutByList(map, text, recTitle, titles);
+    }
+
+}

+ 61 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/TransferOutHtmlAnalysis.java

@@ -0,0 +1,61 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Element;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/28 20:22
+ */
+@Slf4j
+public class TransferOutHtmlAnalysis implements HtmlAnalysis {
+
+    private String modeId = "27";
+
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+            Element bigDivElement = Jsoup.parse(html).selectFirst("body").child(0);
+            analysisGeneral(recTitle, bigDivElement, map);
+            HtmlAnalysisUtil.insertModuleId(modeId, recTypeId, map);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+
+    private void analysisGeneral(String recTitle, Element bigDivElement, Map<String, String> map) {
+        if (bigDivElement.childNodeSize() == 1) {
+            bigDivElement = bigDivElement.child(0);
+        }
+        if (bigDivElement.selectFirst("hr") != null) {
+            bigDivElement.selectFirst("hr").previousElementSiblings().remove();
+        }
+        String text = HtmlAnalysisUtil.blockDivToStr(bigDivElement, true);
+        List<String> titles = Lists.newArrayList(
+                "入院情况",
+                "入院诊断",
+                "诊疗经过",
+                "目前情况",
+                "目前诊断",
+                "转科目的",
+                "注意事项",
+                "医师签名",
+                "时间"
+        );
+        HangzhoufubaoTranUtils.getStructureMapSplitCommonCutByList(map, text, recTitle, titles);
+
+    }
+}

+ 41 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/VTEGradeHtmlAnalysis.java

@@ -0,0 +1,41 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Maps;
+import lombok.extern.slf4j.Slf4j;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+
+import java.util.Map;
+
+/**
+ * @ClassName: VTEGradeHtmlAnalysis
+ * @Description: VTE评分HTML解析
+ * @Author songxl
+ * @Date 2021/3/9
+ * @Version 1.0
+ */
+@Slf4j
+public class VTEGradeHtmlAnalysis implements HtmlAnalysis {
+    private String modeId = "0";//模块id待定
+    @Override
+    public Map<String, String> analysis(String... args) {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            String html = args[0];
+            String recTitle = args[1];
+            String recTypeId = args[2];
+
+            Document doc = Jsoup.parse(html);
+            //评估日期
+            Element valuationName = doc.getElementById("table4").getElementsByTag("tr").get(2)
+                    .getElementsByTag("span").get(0);
+            Element valuationTime = doc.getElementById("table4").getElementsByTag("tr").get(2)
+                    .getElementsByTag("span").get(1);
+            map.put(valuationName.text().replaceAll(":",""),valuationTime.text());
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return map;
+    }
+}

+ 12 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ez/EzAnalysis.java

@@ -0,0 +1,12 @@
+package com.lantone.qc.trans.hangzhoufubao.util.ez;
+
+import java.util.Map;
+
+/**
+ * @Description:
+ * @Author: HUJING
+ * @Date: 2021/1/6 14:24
+ */
+public interface EzAnalysis {
+    Map<String, String> analysis(String xml) throws Exception;
+}

+ 41 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ez/EzClinicalBloodAnalysis.java

@@ -0,0 +1,41 @@
+package com.lantone.qc.trans.hangzhoufubao.util.ez;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.trans.hangzhoufubao.util.ez.util.EzXmlUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 输血记录解析
+ * @author: HUJING
+ * @time: 2021/1/7 11:20
+ */
+@Slf4j
+public class EzClinicalBloodAnalysis implements EzAnalysis {
+
+    @Override
+    public Map<String, String> analysis(String xml) throws Exception {
+        Map<String, String> map = EzXmlUtil.analysis(xml);
+        Map<String, String> structureMap = EzXmlUtil.mapKeyContrast(map, keyContrasts);
+        return map;
+    }
+
+    /**
+     * 目前能解析字段:
+     * 全文本
+     * 诊断
+     * 检验结果
+     * 血型
+     * 输注量
+     * 输血开始时间
+     * 输血日期end
+     * 输血结束时间
+     * 输血指征
+     */
+    private static List<String> keyContrasts = Lists.newArrayList(
+            "输注量=输血量(mL)",
+            "血型=ABO血型代码"
+    );
+}

+ 21 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ez/EzDeathCaseDiscussAnalysis.java

@@ -0,0 +1,21 @@
+package com.lantone.qc.trans.hangzhoufubao.util.ez;
+
+import com.lantone.qc.trans.hangzhoufubao.util.ez.util.EzXmlUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Map;
+
+/**
+ * @Description: 死亡病例讨论记录文档生成
+ * @author: HUJING
+ * @time: 2021/1/4 17:25
+ */
+@Slf4j
+public class EzDeathCaseDiscussAnalysis implements EzAnalysis {
+
+    @Override
+    public Map<String, String> analysis(String xml) throws Exception {
+        Map<String, String> map = EzXmlUtil.analysis(xml);
+        return map;
+    }
+}

+ 40 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ez/EzOperationRecordAnalysis.java

@@ -0,0 +1,40 @@
+package com.lantone.qc.trans.hangzhoufubao.util.ez;
+
+import com.lantone.qc.trans.hangzhoufubao.util.ez.util.EzXmlUtil;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Map;
+
+/**
+ * @Description: 手术记录解析
+ * @author: HUJING
+ * @time: 2021/1/7 11:20
+ */
+@Slf4j
+public class EzOperationRecordAnalysis implements EzAnalysis {
+
+    @Override
+    public Map<String, String> analysis(String xml) throws Exception {
+        Map<String, String> map = EzXmlUtil.analysis(xml);
+        if (map.containsKey("手术结束时间")) {
+            map.put("手术结束时间", map.get("手术结束时间").split(" ")[0]);
+        }
+        return map;
+    }
+    /**
+     * 目前能解析字段:
+     *  手术开始时间
+     *  手术结束时间
+     *  术前诊断
+     *  手术名称
+     *  术中诊断
+     *  手 术 者
+     *  麻醉方法
+     *  麻 醉 者
+     *  术中并发症
+     *  存在问题
+     *  术中失血量
+     *  手术经过
+     *  日期
+     */
+}

+ 337 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ez/EzXmlAnalysis.java

@@ -0,0 +1,337 @@
+package com.lantone.qc.trans.hangzhoufubao.util.ez;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.dom4j.Node;
+
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/24 11:28
+ */
+public class EzXmlAnalysis {
+
+    public static Map<String, String> analysis(String deptName, String xml) throws Exception {
+        if (deptName.equals("小儿外科")) {
+            return analysisEk(deptName, xml);
+        }
+        return null;
+    }
+
+    public static Map<String, String> analysisEk(String deptName, String xml) throws Exception {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        Document doc = DocumentHelper.parseText(xml);
+        Element rootElement = doc.getRootElement();
+        jbxxInsertMap(rootElement, map);
+        tgjcInsertMap(rootElement, map);
+        fzjcInsertMap(rootElement, map);
+        zkjcInsertMap(rootElement, map);
+        disInsertMap(rootElement, map);
+        otherInsertMap(rootElement, map);
+        return map;
+    }
+
+    //其他信息
+    public static void otherInsertMap(Element rootElement, Map<String, String> map) {
+        List<String> titles = Lists.newArrayList(
+                "主诉", "现病史", "既往史", "手术史", "输血史", "过敏史", "个人史", "预防接种史", "家族史", "婚育史", "月经史"
+        );
+        String rootText = elementTxt(rootElement);
+        String signTimeStr = findTimeStr(rootText.substring(rootText.length() - 18));
+        if (StringUtil.isNotBlank(signTimeStr)) {
+            rootText = rootText.substring(0, rootText.lastIndexOf(signTimeStr));
+        }
+        titles = CommonAnalysisUtil.sortTitlesNoColon(titles, rootText);
+        CommonAnalysisUtil.cutByTitlesNoColon(rootText, titles, 0, map);
+    }
+
+    public static void disInsertMap(Element rootElement, Map<String, String> map) {
+        Node cbzdNode = rootElement.selectSingleNode("section[@name='初步诊断']");
+        if (cbzdNode != null) {
+            rootElement.remove(cbzdNode);
+        }
+        Node disNode = rootElement.selectSingleNode("section[@name='诊断']");
+        if (disNode != null) {
+            String disText = elementTxt(disNode);
+            List<String> titles = CommonAnalysisUtil.sortTitlesNoColon(Lists.newArrayList("初步诊断", "补充诊断", "再次补充诊断", "修正诊断", "出院诊断"), disText);
+            CommonAnalysisUtil.cutByTitlesNoColon(disText, titles, 0, map);
+            titles.forEach(title -> {
+                disExt(map, title);
+            });
+            rootElement.remove(disNode);
+        }
+    }
+
+    //诊断特殊处理
+    public static void disExt(Map<String, String> map, String key) {
+        String disMessage = map.get(key);
+        String sign = null;
+        String signTime = null;
+        int signIndex = 0;
+        if (StringUtil.isNotBlank(disMessage)) {
+            Pattern pattern = Pattern.compile("[0-9]+[年/-][0-9]+[月/-][0-9]+[日]{0,}");
+            Matcher matcher = pattern.matcher(disMessage);
+            if (matcher.find()) {
+                signTime = matcher.group();
+                disMessage = disMessage.substring(0, matcher.start());
+            }
+
+            signIndex = disMessage.indexOf("医师签名");
+            if (signIndex > -1) {
+                sign = disMessage.substring(signIndex).replace("医师签名", "").replaceAll("[::]", "");
+                disMessage = disMessage.substring(0, signIndex);
+            }
+            map.put(key, disMessage);
+            if (StringUtil.isNotBlank(sign)) {
+                map.put(key + "签名", sign.replaceAll("日期", ""));
+            }
+            if (StringUtil.isNotBlank(signTime)) {
+                map.put(key + "签名日期", signTime);
+            }
+        }
+    }
+
+    //辅助检查
+    public static void fzjcInsertMap(Element rootElement, Map<String, String> map) {
+        Node fzjcNode = rootElement.selectSingleNode("section[@name='辅助检查']");
+        if (fzjcNode != null) {
+            map.put("辅助检查", elementTxt(fzjcNode).replaceFirst("辅助检查", ""));
+            rootElement.remove(fzjcNode);
+        }
+    }
+
+    // 专科检查
+    public static void zkjcInsertMap(Element rootElement, Map<String, String> map) {
+        Node zkjcNode = rootElement.selectSingleNode("section[@name='专科检查']");
+        if (zkjcNode != null) {
+            map.put("专科检查", elementTxt(zkjcNode).replaceFirst("专科检查", ""));
+            rootElement.remove(zkjcNode);
+        }
+    }
+
+    //基本信息
+    public static void jbxxInsertMap(Element rootElement, Map<String, String> map) {
+        Node jbxxNode = rootElement.selectSingleNode("section[@name='基本信息']");
+        if (jbxxNode != null) {
+            ((List<Element>) jbxxNode.selectNodes("fieldelem")).forEach(i -> {
+                elementInsertMap(i, map);
+            });
+            String age = map.get("年龄");
+            String ageYear = "";
+            String ageMon = "";
+            if (StringUtil.isNotBlank(age)) {
+                ageYear = age;
+                if (age.indexOf("岁") > -1) {
+                    ageYear = age;
+                } else if (age.indexOf("月") > -1) {
+                    ageYear = "";
+                    ageMon = age;
+                }
+            }
+            map.put("年龄岁", ageYear);
+            map.put("年龄月", ageMon);
+            rootElement.remove(jbxxNode);
+        }
+    }
+
+    //身高体重
+    public static void sgtzInsertMap(Element rootElement, Map<String, String> map) {
+        Map<String, String> map2 = Maps.newHashMap();
+        Node tgjcNode = rootElement.selectSingleNode("section[@name='体格检查']");
+        if (tgjcNode != null) {
+            Node ybqkNode = tgjcNode.selectSingleNode("section[@name='一般情况']");
+            if (ybqkNode != null) {
+                if (StringUtil.isBlank(map.get("身高"))) {
+                    elementInsertMap((Element) ybqkNode.selectSingleNode("fieldelem[@name='身高']"), map);
+                }
+                if (StringUtil.isBlank(map.get("体重"))) {
+                    elementInsertMap((Element) ybqkNode.selectSingleNode("fieldelem[@name='体重']"), map);
+                }
+
+                String ybqkText = elementTxt(ybqkNode);
+                List<String> titles = Lists.newArrayList("身高", "体重");
+                titles = CommonAnalysisUtil.sortTitlesNoColon(titles, ybqkText);
+                CommonAnalysisUtil.cutByTitlesNoColon(ybqkText, titles, 0, map2);
+                sgtzxyInsertMap(map2);
+            }
+        }
+
+        smtzSgtzInsertMap(rootElement, map2);
+        if (!map.containsKey("身高")) {
+            map.put("身高", map2.get("身高"));
+
+        }
+        if (!map.containsKey("体重")) {
+            map.put("体重", map2.get("体重"));
+        }
+        if (!map.containsKey("收缩压")) {
+            map.put("收缩压", map2.get("收缩压"));
+        }
+        if (!map.containsKey("舒张压")) {
+            map.put("舒张压", map2.get("舒张压"));
+        }
+    }
+
+    //生命体征中提取身高体重
+    public static void smtzSgtzInsertMap(Element rootElement, Map<String, String> map) {
+        Node tgjcNode = rootElement.selectSingleNode("section[@name='体格检查']");
+        if (tgjcNode != null) {
+            Node smtzNode = tgjcNode.selectSingleNode("section[@name='生命体征']");
+            if (smtzNode != null) {
+                Map<String, String> map2 = Maps.newHashMap();
+                String smtzText = elementTxt(smtzNode);
+                List<String> titles = Lists.newArrayList("身高", "体重", "血压", "BP");
+                titles = CommonAnalysisUtil.sortTitlesNoColon(titles, smtzText);
+                CommonAnalysisUtil.cutByTitlesNoColon(smtzText, titles, 0, map2);
+                sgtzxyInsertMap(map2);
+
+                map.put("收缩压", map2.get("收缩压"));
+                map.put("舒张压", map2.get("舒张压"));
+                if (StringUtil.isBlank(map.get("身高"))) {
+                    map.put("身高", map2.get("身高"));
+                }
+                if (StringUtil.isBlank(map.get("体重"))) {
+                    map.put("体重", map2.get("体重"));
+                }
+            }
+        }
+    }
+
+    //身高、体重、血压公共处理方法
+    private static void sgtzxyInsertMap(Map<String, String> map) {
+        Pattern pattern = Pattern.compile("[0-9]+[.]{0,1}[0-9]*");
+        if (map.containsKey("身高")) {
+            String value = map.get("身高");
+            if (StringUtil.isNotBlank(value)) {
+                value = StringUtil.removeBlank(value);
+                Matcher matcher = pattern.matcher(value);
+                if (matcher.find()) {
+                    map.put("身高", matcher.group());
+                } else {
+                    map.put("身高", "");
+                }
+            }
+        }
+        if (map.containsKey("体重")) {
+            String value = map.get("体重");
+            if (StringUtil.isNotBlank(value)) {
+                value = StringUtil.removeBlank(value);
+                Matcher matcher = pattern.matcher(value);
+                if (matcher.find()) {
+                    map.put("体重", matcher.group());
+                } else {
+                    map.put("体重", "");
+                }
+            }
+        }
+        pattern = Pattern.compile("[0-9]+[.]{0,1}[0-9]*/[0-9]+[.]{0,1}[0-9]*");
+        if (map.containsKey("血压") || map.containsKey("BP")) {
+            String value = map.get("血压");
+            if (StringUtil.isBlank(value)) {
+                value = map.get("BP");
+            }
+            if (StringUtil.isNotBlank(value)) {
+                value = StringUtil.removeBlank(value);
+                Matcher matcher = pattern.matcher(value);
+                if (matcher.find()) {
+                    value = matcher.group();
+                    String[] arry = value.split("/");
+                    if (arry.length == 2) {
+                        map.put("收缩压", arry[0]);
+                        map.put("舒张压", arry[1]);
+                    }
+                }
+            }
+        }
+    }
+
+    //体格检查
+    public static void tgjcInsertMap(Element rootElement, Map<String, String> map) {
+        Node tgjcNode = rootElement.selectSingleNode("section[@name='体格检查']");
+        if (tgjcNode != null) {
+            Node smtzNode = tgjcNode.selectSingleNode("section[@name='生命体征']");
+            if (smtzNode != null) {
+                ((List<Element>) smtzNode.selectNodes("fieldelem")).forEach(i -> {
+                    elementInsertMap(i, map);
+                });
+            }
+            ((List<Element>) tgjcNode.selectNodes("section[@name!='生命体征']")).forEach(i -> {
+                elementInsertMap(i, map);
+            });
+
+            String jzsz = map.get("脊柱四肢");
+            String jz = "";
+            String sz = "";
+            if (StringUtil.isNotBlank(jzsz)) {
+                if (jzsz.indexOf("四肢") > -1) {
+                    jz = jzsz.substring(0, jzsz.indexOf("四肢"));
+                    sz = jzsz.substring(jzsz.indexOf("四肢"));
+                } else {
+                    jz = jzsz;
+                }
+            }
+            map.put("脊柱", jz);
+            map.put("四肢", sz);
+            sgtzInsertMap(rootElement, map);
+            rootElement.remove(tgjcNode);
+        }
+    }
+
+    public static String elementTxt(Node node) {
+        if (node != null) {
+            return StringUtil.removeBlank(node.getStringValue());
+        } else {
+            return "";
+        }
+    }
+
+    public static void elementInsertMap(Element element, Map<String, String> map) {
+        if (element == null || map == null) {
+            return;
+        }
+        String key = null;
+        List<Element> elements = element.elements();
+        if (elements.size() > 0 && (key = isKey(elementTxt(elements.get(0)))) != null) {
+            element.remove(elements.get(0));
+        } else {
+            key = element.attributeValue("name");
+        }
+        if (StringUtil.isNotBlank(key)) {
+            map.put(key, elementTxt(element));
+        }
+    }
+
+    public static String isKey(String key) {
+        if (StringUtil.isBlank(key)) {
+            return null;
+        }
+        key = StringUtil.removeBlank(key);
+        Pattern pattern = Pattern.compile("[\\u4e00-\\u9fa5]+[::]");
+        if (pattern.matcher(key).matches()) {
+            return key.substring(0, key.length() - 1);
+        } else {
+            return null;
+        }
+    }
+
+    public static String findTimeStr(String text) {
+        String ret = "";
+        Pattern pattern = Pattern.compile("[0-9]+[年/-][0-9]+[月/-][0-9]+[日]{0,}");
+        Matcher matcher = pattern.matcher(text);
+        if (matcher.find()) {
+            ret = matcher.group();
+        }
+        return ret;
+    }
+
+}

+ 143 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/ez/util/EzXmlUtil.java

@@ -0,0 +1,143 @@
+package com.lantone.qc.trans.hangzhoufubao.util.ez.util;
+
+import com.google.common.collect.Maps;
+import com.lantone.qc.dbanaly.facade.yiwu.util.MapUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.dom4j.*;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @Description:
+ * @author: HUJING
+ * @time: 2021/1/4 14:30
+ */
+@Slf4j
+public class EzXmlUtil {
+
+    public static Map<String, String> analysis(String xml) throws Exception {
+        Map<String, String> map = Maps.newLinkedHashMap();
+        try {
+            Document doc = DocumentHelper.parseText(bom(xml));
+            Element rootElement = doc.getRootElement();
+            findAllNodes(rootElement, map);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            throw new Exception("xml解析错误:" + e.getMessage());
+        }
+        return map;
+    }
+
+    /**
+     * 从指定节点开始,向下寻找所有节点 ,包括其子节点<br/>
+     *
+     * @param node 所指定的节点
+     */
+    public static void findAllNodes(Element node, Map<String, String> map) {
+
+        putNode(node, map);
+
+        // 递归遍历当前节点所有的子节点
+        List<Element> listElement = node.elements();
+
+        // 遍历所有一级子节点
+        for (Element e : listElement) {
+            findAllNodes(e, map);// 递归
+        }
+    }
+
+    /**
+     * 存放节点,不包括其子节点
+     *
+     * @param node 所指定的节点
+     */
+    public static void putNode(Element node, Map<String, String> map) {
+        String labelName = node.getName();
+        List<Attribute> listAttr = node.attributes();// 所有属性
+        for (Attribute attr : listAttr) {// 遍历所有属性
+            //String name = attr.getName();// 属性名称
+            if (("fieldelem".equals(labelName)) && StringUtil.isNotBlank(attr.getValue())) {
+                String fieldelemKey = attr.getValue();// 属性的值
+                String text = node.getStringValue();
+                map.put(fieldelemKey, text);
+            }
+            if ("section".equals(labelName)) {
+                List<Element> content = node.content();
+                if (content.size() > 0) {
+                    Element firstEle = content.get(0);
+                    String key = firstEle.getStringValue();
+                    if (key.endsWith(":")) {
+                        key = key.substring(0, key.length() - 1);
+                    }
+                    String value = "";
+                    for (int i = 1; i < content.size(); i++) {
+                        String v = content.get(i).getStringValue();
+                        value += v + " ";
+                    }
+                    map.put(key, value);
+                }
+            }
+        }
+    }
+
+    public static String bom(String result) {
+        if (null != result && !"".equals(result)) {
+            if (result.contains("<") && result.lastIndexOf(">") != -1 && result.lastIndexOf(">") > result.indexOf("<")) {
+                result = result.substring(result.indexOf("<"), result.lastIndexOf(">") + 1);
+            }
+        }
+        return result;
+    }
+
+    public static String elementTxt(Node node) {
+        if (node != null) {
+            return StringUtil.removeBlank(node.getStringValue());
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * 根据给定key映射
+     *
+     * @param sourceMap
+     * @param keyContrasts
+     * @return
+     */
+    public static Map<String, String> mapKeyContrast(Map<String, String> sourceMap, List<String> keyContrasts) {
+        Map<String, String> retMap = Maps.newHashMap();
+        mapKeyContrastCommon(sourceMap, keyContrasts, retMap);
+        return retMap;
+    }
+
+    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));
+            }
+        }
+    }
+}

+ 292 - 0
trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/util/hangzhoufubaoHtmlAnalysisUtil.java

@@ -0,0 +1,292 @@
+package com.lantone.qc.trans.hangzhoufubao.util;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.dbanaly.util.ModuleMappingUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: rengb
+ * @time: 2020/9/15 16:31
+ */
+public class hangzhoufubaoHtmlAnalysisUtil {
+
+    /**
+     * table样式:key和value在同一个td中,以冒号分开;保留换行
+     *
+     * @param tableElement
+     * @param map
+     */
+    public static void tableStyle1InsertMap(Element tableElement, Map<String, String> map) {
+        if (tableElement == null || map == null) {
+            return;
+        }
+        List<Element> tdElements = Lists.newArrayList();
+        tableElement.selectFirst("tbody").children().forEach(trElement -> {
+            trElement.children().forEach(tdElement -> {
+                tdElements.add(tdElement);
+            });
+        });
+        String tdText = null;
+        int tdMhIndex = 0;
+        for (Element tdElement : tdElements) {
+            if (tdElement.childNodeSize() == 0) {
+                continue;
+            }
+            tdText = blockDivToStr(tdElement.child(0), true);
+            if (tdText.endsWith("\n")) {
+                tdText = tdText.substring(0, tdText.length() - 1);
+            }
+            if (StringUtil.isBlank(tdText)) {
+                continue;
+            }
+            tdMhIndex = tdText.indexOf(":");
+            if (tdMhIndex == -1) {
+                tdMhIndex = tdText.indexOf(":");
+            }
+            if (tdMhIndex < 1) {
+                continue;
+            }
+            if (tdText.contains("姓    名") && tdText.contains("年    龄")) {
+                multiColonResolve(tdMhIndex, tdText, "年    龄", map);
+            } else if (tdText.contains("姓    名") && tdText.contains("年   龄")) {
+                multiColonResolve(tdMhIndex, tdText, "年   龄", map);
+            } else if (tdText.contains("姓    名") && tdText.contains("年  龄")) {
+                multiColonResolve(tdMhIndex, tdText, "年  龄", map);
+            } else if (tdText.contains("姓    名") && tdText.contains("年 龄")) {
+                multiColonResolve(tdMhIndex, tdText, "年 龄", map);
+            } else if (tdText.contains("产前检查") && tdText.contains("孕/产次")) {
+                multiColonResolve(tdMhIndex, tdText, "孕/产次", map);
+            } else if (tdText.contains("末次月经") && tdText.contains("预产期")) {
+                multiColonResolve(tdMhIndex, tdText, "预产期", map);
+            } else {
+                map.put(
+                        StringUtil.removeBlank(tdText.substring(0, tdMhIndex)),
+                        tdText.length() - 1 <= tdMhIndex ? "" : tdText.substring(tdMhIndex + 1)
+                );
+            }
+        }
+    }
+
+    /**
+     * 取得多个字段时,分别存储
+     *
+     * @param tdText
+     * @param text
+     */
+    public static void multiColonResolve(int tdMhIndex, String tdText, String text, Map<String, String> map) {
+        String firstText = tdText.split(text)[0];
+        map.put(
+                StringUtil.removeBlank(firstText.substring(0, tdMhIndex)),
+                firstText.length() - 1 <= tdMhIndex ? "" : firstText.substring(tdMhIndex + 1)
+        );
+        String secondText = tdText.split(text)[1];
+        secondText = secondText.replace(":", "");
+        secondText = secondText.replace(":", "");
+        map.put(StringUtil.removeBlank(text), secondText);
+    }
+
+    /**
+     * table样式:td两两配对,一个key,一个value;不保留换行
+     *
+     * @param tableElement
+     * @param map
+     */
+    public static void tableStyle2InsertMap(Element tableElement, Map<String, String> map) {
+        if (tableElement == null || map == null) {
+            return;
+        }
+        List<Element> tdElements = Lists.newArrayList();
+        tableElement.selectFirst("tbody").children().forEach(trElement -> {
+            if (trElement.childNodeSize() != 2) {
+                return;
+            }
+            trElement.children().forEach(tdElement -> {
+                tdElements.add(tdElement);
+            });
+        });
+        int index = 0;
+        String key = null, value = null, text = null;
+        for (Element tdElement : tdElements) {
+            if (tdElement.childNodeSize() == 0) {
+                text = "";
+            } else {
+                text = blockDivToStr(tdElement.child(0), false);
+            }
+            if (index % 2 == 0) {
+                key = text.replaceAll("[:: ]", "");
+            }
+            if (index % 2 == 1) {
+                value = text;
+                if (StringUtil.isNotBlank(key)) {
+                    map.put(key, value);
+                }
+            }
+            index++;
+        }
+    }
+
+    /**
+     * 一个大的块状div下包含很多行行状div
+     *
+     * @param divElement
+     * @param isLineBreak 是否保留换行
+     * @return
+     */
+    public static String blockDivToStr(Element divElement, boolean isLineBreak) {
+        if (divElement == null) {
+            return "";
+        }
+        StringBuffer sbf = new StringBuffer();
+        for (Element childElement : divElement.children()) {
+            if (isLineBreak) {
+                sbf.append(elementLayer1ToStr(childElement, false)).append("\n");
+            } else {
+                sbf.append(elementLayer1ToStr(childElement, false).trim());
+            }
+        }
+        return sbf.toString();
+    }
+
+    /**
+     * 标签仅遍历第一子层级后转字符串
+     *
+     * @param element
+     * @param isLineBreak 是否保留换行
+     * @return
+     */
+    public static String elementLayer1ToStr(Element element, boolean isLineBreak) {
+        if (element == null) {
+            return "";
+        }
+        StringBuffer sbf = new StringBuffer();
+        List<Element> elements = Lists.newArrayList();
+        Elements childElements = element.children();
+        if (childElements.size() == 0) {
+            elements.add(element);
+        }
+        for (Element childElement : childElements) {
+            elements.add(childElement);
+        }
+        for (Element childElement : elements) {
+            if (childElement.tagName().equals("img") || childElement.tagName().equals("image")) {
+                //                sbf.append(childElement.outerHtml());
+                sbf.append("—");
+            } else {
+                sbf.append(childElement.text());
+            }
+            if (isLineBreak) {
+                sbf.append("\n");
+            }
+        }
+        String sbfString = removeSex(sbf.toString().replaceAll(" ", " "));
+        return sbfString;
+    }
+
+    /**
+     * 查询并插入页面模板id
+     *
+     * @param modeId
+     * @param recTitle
+     * @param map
+     */
+    public static void insertModuleId(String modeId, String recTitle, Map<String, String> map) {
+        if ((StringUtil.isBlank(modeId) && StringUtil.isBlank(recTitle)) || map == null) {
+            return;
+        }
+        String moduleId = ModuleMappingUtil.getHtmlDataTypeModuleId(recTitle);
+        if (StringUtil.isBlank(moduleId)) {
+            moduleId = ModuleMappingUtil.getStandardModuleId(modeId);
+        }
+        map.put("mode_id", moduleId);
+    }
+
+    /**
+     * map中有的value以冒号开头,用此方法来去掉冒号
+     *
+     * @param map
+     */
+    public static void mapValueRemoveStartColon(Map<String, String> map) {
+        if (map == null) {
+            return;
+        }
+        map.keySet().forEach(key -> {
+            if (map.get(key).startsWith(":") || map.get(key).startsWith(":")) {
+                map.put(key, map.get(key).replaceFirst("[::]", ""));
+            }
+        });
+    }
+
+    /**
+     * 北仑:入院记录中性别取得去除"性"
+     * e.g.(性    别:男性 ->性    别:男)
+     *
+     * @param sbfString
+     */
+    public static String removeSex(String sbfString) {
+        if (sbfString.contains("性    别:")) {
+            sbfString = sbfString.substring(0, sbfString.length() - 1);
+        }
+        return sbfString;
+    }
+
+    /**
+     * 杭州妇保自定义xml解析模板(入院记录)
+     * @param divElement
+     * @param isLineBreak 是否保留换行
+     * @return
+     */
+    public static String blockDivToStr2(Element divElement, boolean isLineBreak) {
+        if (divElement == null) {
+            return "";
+        }
+        StringBuffer sbf = new StringBuffer();
+        for (Element childElement : divElement.children()) {
+            if (isLineBreak) {
+                sbf.append(elementLayer1ToStr2(childElement, false)).append("\n");
+            } else {
+                sbf.append(elementLayer1ToStr2(childElement, false).trim());
+            }
+        }
+        return sbf.toString();
+    }
+
+    /**
+     * 余杭三院自定义xml解析模板(入院记录)
+     * @param element
+     * @param isLineBreak 是否保留换行
+     * @return
+     */
+    public static String elementLayer1ToStr2(Element element, boolean isLineBreak) {
+        if (element == null) {
+            return "";
+        }
+        StringBuffer sbf = new StringBuffer();
+        List<Element> elements = Lists.newArrayList();
+        Elements childElements = element.children();
+        if (childElements.size() == 0) {
+            elements.add(element);
+        }
+        for (Element childElement : childElements) {
+            elements.add(childElement);
+        }
+        for (Element childElement : elements) {
+            if (childElement.tagName().equals("img") || childElement.tagName().equals("image")) {
+                //                sbf.append(childElement.outerHtml());
+                sbf.append("—");
+            } else {
+                sbf.append(childElement.text());
+            }
+            if (isLineBreak) {
+                sbf.append("\n");
+            }
+        }
+        String sbfString = removeSex(sbf.toString().replaceAll(" ", " "));
+        return sbfString;
+    }
+}

+ 420 - 0
trans/src/main/java/com/lantone/qc/trans/qdnzyy/BeHospitalizedDocTrans.java

@@ -0,0 +1,420 @@
+package com.lantone.qc.trans.qdnzyy;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.lantone.qc.dbanaly.facade.shengzhouzz.ShengzhouyyXmlUtil;
+import com.lantone.qc.dbanaly.util.ModuleMappingUtil;
+import com.lantone.qc.dbanaly.util.SpecialStorageUtil;
+import com.lantone.qc.pub.model.doc.BeHospitalizedDoc;
+import com.lantone.qc.pub.model.label.*;
+import com.lantone.qc.pub.model.vo.BehospitalInfoVO;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.pub.util.SpringContextUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:入院记录文档生成
+ * @Author:liuqq
+ * @time: ${DATE} ${TIME}
+ **/
+@Slf4j
+public class BeHospitalizedDocTrans extends ModelDocTrans {
+
+    private String modeId = "1";
+
+    @Override
+    public BeHospitalizedDoc extract(MedrecVo medrecVo) {
+        Map<String, Object> contentMap = ((List<Map>) medrecVo.getContent().get("content")).get(0);
+        String content = contentMap.get("xmlText").toString();
+        SpecialStorageUtil specialStorageUtil = SpringContextUtil.getBean("specialStorageUtil");
+        BehospitalInfoVO behospitalInfoVO = specialStorageUtil.getBehospitalInfoThreadLocal().get();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            Map<String, String> sourceMap = ShengzhouyyXmlUtil.xmlToMap(content);
+            sourceMap.put("mode_id", ModuleMappingUtil.getDeptModuleId(modeId));
+            String text = sourceMap.get("原始文本").replace(":", ":").replaceAll("■", "");
+            List<String> titles = Lists.newArrayList(
+                    "其    它", "一般情况", "关系", "可靠程度", "可 靠 度",
+                    "住    址", "电    话", "出 生 地", "生    于", "入 院 于",
+                    "既往史", "主    诉", "陈 述 者", "籍    贯", "记录日期",
+                    "民    族", "入院时间", "年    龄", "联系电话", "医师签名", "记录时间",
+                    "产科检查");//"供 史 者",
+            List<String> sortTitles = CommonAnalysisUtil.sortTitles(titles, text);
+            CommonAnalysisUtil.cutByTitles(text, sortTitles, 0, sourceMap);
+            sourceMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
+//            sourceMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
+            String rec_title = contentMap.get("recTitle").toString();
+            if ("产科住院病历(互联互通)".equals(rec_title)) sourceMap.put("病人性别", "女");
+            sourceMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
+            String docker_signatures = sourceMap.get("医师签名");
+            if (StringUtils.isNotBlank(docker_signatures)) {
+                String[] docker_signature = docker_signatures.split(" ");
+                if (docker_signature.length > 1) sourceMap.put("医师签名", docker_signature[0]);
+            }
+            if (StringUtils.isNotBlank(sourceMap.get("记录时间"))) {
+                String[] split = sourceMap.get("记录时间").split(" ");
+                if (split.length >= 2) {
+                    String rec_time = split[0] + " " + split[1];
+                    sourceMap.put("记录时间", rec_time);
+                }
+            }
+
+            String date_of_birth = sourceMap.get("出生日期");
+            String age = sourceMap.get("年龄");
+            if (StringUtils.isBlank(age) && StringUtils.isNotBlank(date_of_birth)) {
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
+                try {
+                    Date date_birth = sdf.parse(date_of_birth);
+                    long time = date_birth.getTime();
+                    long currentTimeMillis = System.currentTimeMillis();
+                    long abs = Math.abs(currentTimeMillis - time);
+                    long age1 = abs / 1000 / 60 / 60 / 24 / 365;
+                    sourceMap.put("年龄", age1 + "");
+                } catch (ParseException e) {
+                    e.printStackTrace();
+                }
+            }
+
+            structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts, modeId);
+            OrdinaryAssistant.removeBlank(structureMap);
+        }
+        BeHospitalizedDoc beHospitalizedDoc = beHospitalizedDocGen(structureMap); // 不走共用
+        beHospitalizedDoc.setPageData((Map) structureMap);
+        return beHospitalizedDoc;
+    }
+
+    private void mapJoin(Map<String, String> sourceMap, Map<String, String> dailyTrans) {
+        dailyTrans.forEach((k, v) -> {
+            if (!sourceMap.containsKey(k)) {
+                sourceMap.put(k, v);
+            }
+        });
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "患者姓名=姓名", "病人姓名=姓名", "生于=出生日期", "电话=联系电话",
+            "国籍=籍贯",
+            "病人性别=性别",
+            "患者现住址=住址",
+            "工作单位名称=工作单位",
+            "婚姻状况=婚姻", "婚姻=婚姻",
+            "供史者=病史陈述者", "陈述者=病史陈述者",
+            "入院诊断=初步诊断", "初步诊断西医诊断名称=初步诊断",
+            "医师签名=记录医生",
+            "现病史1=现病史",
+            "入院情况=现病史",
+            "工作单位名称=职业",
+            "产科检查=专科检查",
+            "签名时间=记录时间"
+    );
+    /*
+     "初步诊断医师=初步诊断医师签名",
+            "修正诊断医师=修正诊断医师签名",
+            "补充诊断医师=补充诊断医师签名",
+            "初步诊断时间=初步诊断日期",
+            "补充诊断时间=补充诊断日期",
+            "补充诊断时间=补充诊断日期",
+            "本人姓名=姓名",
+            "病人姓名=姓名",
+            "性别=性别",
+            "病人性别=性别",
+            "年龄=年龄",
+            "民族=民族",
+            "职业=职业",
+            "出生地址=出生地",
+            "出生、生长史=出生生长史",
+            "地址=联系地址",
+            "患者现住址=住址",
+            "工作场所=工作单位",
+            "患者工作单位名称=工作单位",
+            "信息来源=病史陈述者",
+            "病史陈述者=病史陈述者",
+            "陈述者=病史陈述者",
+            "生日=出生日期",
+            "出生时间=出生日期",
+            "病人出生日期=出生日期",
+            "新生儿出生日期=出生日期",
+            //            "出生地址=户口地址",
+            "本人电话=联系电话电话",
+            "入病房时间=入院日期",
+            "入院日期时间=入院日期",
+            "病历日期=记录日期",
+            "主诉=主诉",
+            "现病史=现病史",
+            "内科疾病史(其它)=内科疾病史其它",
+            "一般健康状况=既往健康状况",
+            "婚姻家庭关系和睦=夫妻关系",
+            "体格检查=体格检查",
+            "初步诊断=初步诊断",
+            "修正诊断=修正诊断",
+            "医生=医师签名",
+            "补充诊断=补充诊断",
+            //            "户口地址=联系地址",
+            "家属提供的信息可信吗=病史可靠性",
+            "入院诊断(中医疾病)=中医诊断",
+            "长期用药情况(包括可能成瘾的药物)=长期用药",
+            "体温(口)=体温",
+            "性别代码=性别",
+            "家庭住址=户口地址",
+            "联系人电话号码=联系电话",
+            "家长姓名=联系人",
+            "联系人姓名=联系人",
+            "患者出生地址=出生地",
+
+            "现住址=户口地址",
+            //            "_{K4}=性别",
+            "联系住址=户口地址",
+            "联系地址=户口地址",
+            "患者工作单位名称=户口地址",
+            "出生日期时间=出生日期",
+            //            "医生签名=初步诊断医师签名",
+            "签字日期=初步诊断日期",
+            "供史者=病史陈述者",
+            "无痛人流主诉=主诉",
+            "联系人电话=联系电话",
+            "医师签字时间=初步诊断日期",
+            "医师签名时间=初步诊断日期",
+            "入院诊断编码=初步诊断",
+            "婚姻=婚姻状况",
+            "病史提供者=病史陈述者",
+            "家庭地址=户口地址",
+            "患者手机号码=联系电话",
+            "孕 产次=孕产次",
+            "有/无=产前检查",
+            "末次月经日期=末次月经",
+            "入院诊断1=入院诊断",
+            //            "记录医师=初步诊断医师签名",
+            "修正诊断签名日期=修正诊断日期",
+            "修正诊断一医师签名=修正诊断医师签名",
+            "患者姓名=姓名",
+            "年月日=初步诊断日期",
+            "年月日时分=初步诊断日期",
+            "诊疗经过=诊疗情况",
+            "随访安排=随访计划",
+            "活动能力与生活自理情况=出院医嘱",
+            "患者籍贯新=籍贯",
+            "现住址邮编=邮政编码",
+            "患者签名时间=初步诊断日期",
+            "日期=初步诊断日期",
+            "骨盆外测量=专科检查",
+            "婚姻=婚姻状况",
+            "住址=户口地址",
+            "患者籍贯=出生地",
+            "他=其他",
+            "入院诊断1=初步诊断",
+            "出院诊断1=出院诊断",
+            "主刀医师签名=记录医师",
+            "签名医师=记录医师",
+            "时间=记录时间",
+            "记录时间=记录时间",
+            "诊断和诊断修正=修正诊断"
+     */
+
+
+    /**
+     * 入院记录
+     *
+     * @param structureMap
+     * @return
+     */
+    public static BeHospitalizedDoc beHospitalizedDocGen(Map<String, String> structureMap) {
+        BeHospitalizedDoc beHospitalizedDoc = new BeHospitalizedDoc();
+
+        // 走模型
+        ChiefLabel chiefLabel = new ChiefLabel();
+        chiefLabel.setText(structureMap.get("主诉"));
+        beHospitalizedDoc.setChiefLabel(chiefLabel);
+        if (StringUtil.isBlank(structureMap.get("主诉"))) {
+            beHospitalizedDoc.setChiefLabel(null);
+        }
+
+        // 走模型
+        PresentLabel presentLabel = new PresentLabel();
+        if (StringUtil.isNotBlank(structureMap.get("现病史"))) {
+            presentLabel.setText(structureMap.get("现病史"));
+        } else if (StringUtil.isNotBlank(structureMap.get("入院情况"))) {
+            presentLabel.setText(structureMap.get("入院情况"));
+        }
+        beHospitalizedDoc.setPresentLabel(presentLabel);
+
+        PastLabel pastLabel = new PastLabel();
+        pastLabel.setCrfLabel(false);
+        if (StringUtil.isNotBlank(structureMap.get("既往史"))) {
+            pastLabel.setText(structureMap.get("既往史"));
+        } else if (StringUtil.isNotBlank(structureMap.get("入院情况"))) {
+            pastLabel.setText(structureMap.get("入院情况"));
+        }
+        beHospitalizedDoc.setPastLabel(pastLabel);
+
+        PersonalLabel personalLabel = new PersonalLabel();
+        //        personalLabel.setCrfLabel(false);
+        personalLabel.setText(structureMap.get("个人史"));
+        beHospitalizedDoc.setPersonalLabel(personalLabel);
+        if (StringUtil.isBlank(structureMap.get("个人史"))) {
+            beHospitalizedDoc.setPersonalLabel(null);
+        }
+
+        MaritalLabel maritalLabel = new MaritalLabel();
+        //        maritalLabel.setCrfLabel(false);
+        maritalLabel.setText("婚育史: " + structureMap.get("婚育史"));
+        beHospitalizedDoc.setMaritalLabel(maritalLabel);
+        if (StringUtil.isBlank(structureMap.get("婚育史"))) {
+            beHospitalizedDoc.setMaritalLabel(null);
+        }
+
+        MenstrualLabel menstrualLabel = new MenstrualLabel();
+        //        menstrualLabel.setCrfLabel(false);
+        menstrualLabel.setText("月经史:" + structureMap.get("月经史"));
+        beHospitalizedDoc.setMenstrualLabel(menstrualLabel);
+        if (StringUtil.isBlank(structureMap.get("月经史"))) {
+            beHospitalizedDoc.setMenstrualLabel(null);
+        }
+
+        FamilyLabel familyLabel = new FamilyLabel();
+        //        familyLabel.setCrfLabel(false);
+        familyLabel.setText(structureMap.get("家族史"));
+        beHospitalizedDoc.setFamilyLabel(familyLabel);
+        if (StringUtil.isBlank(structureMap.get("家族史"))) {
+            beHospitalizedDoc.setFamilyLabel(null);
+        }
+
+        VitalLabel vitalLabel = new VitalLabel();
+        //        vitalLabel.setCrfLabel(false);
+        vitalLabel.setText(structureMap.get("体格检查"));
+        beHospitalizedDoc.setVitalLabel(vitalLabel);
+        if (StringUtil.isBlank(structureMap.get("体格检查"))) {
+            beHospitalizedDoc.setVitalLabel(null);
+        }
+
+        VitalLabelSpecial vitalLabelSpecial = new VitalLabelSpecial();
+        //        vitalLabelSpecial.setCrfLabel(false);
+        vitalLabelSpecial.setText(structureMap.get("专科体格检查"));
+        beHospitalizedDoc.setVitalLabelSpecial(vitalLabelSpecial);
+        if (StringUtil.isBlank(structureMap.get("专科体格检查"))) {
+            beHospitalizedDoc.setVitalLabelSpecial(null);
+        }
+
+        // 走模型
+        PacsLabel pacsLabel = new PacsLabel();
+        //        pacsLabel.setCrfLabel(false);
+        pacsLabel.setText(structureMap.get("辅助检查"));
+        beHospitalizedDoc.setPacsLabel(pacsLabel);
+        if (StringUtil.isBlank(structureMap.get("辅助检查"))) {
+            beHospitalizedDoc.setPacsLabel(null);
+        }
+
+        // 走模型
+        DiagLabel initialDiagLabel = new DiagLabel();
+        initialDiagLabel.setText(structureMap.get("初步诊断"));
+        beHospitalizedDoc.setInitialDiagLabel(initialDiagLabel);
+        if (StringUtil.isBlank(structureMap.get("初步诊断"))) {
+            beHospitalizedDoc.setInitialDiagLabel(null);
+        }
+
+        // 走模型
+        DiagLabel revisedDiagLabel = new DiagLabel();
+        revisedDiagLabel.setText(structureMap.get("修正诊断"));
+        beHospitalizedDoc.setRevisedDiagLabel(revisedDiagLabel);
+        if (StringUtil.isBlank(structureMap.get("修正诊断"))) {
+            beHospitalizedDoc.setRevisedDiagLabel(null);
+        }
+
+        // 走模型
+        DiagLabel suppleDiagLabel = new DiagLabel();
+        suppleDiagLabel.setText(structureMap.get("补充诊断"));
+        beHospitalizedDoc.setSuppleDiagLabel(suppleDiagLabel);
+        if (StringUtil.isBlank(structureMap.get("补充诊断"))) {
+            beHospitalizedDoc.setSuppleDiagLabel(null);
+        }
+
+        beHospitalizedDoc.setStructureMap(structureMap);
+
+        return beHospitalizedDoc;
+    }
+
+    /**
+     * 给structureMap添加一个key(映射)
+     *
+     * @param structureMap
+     * @param target       需要用到的key
+     * @param source       structureMap中含有的key
+     */
+    protected void addKeyMapping(Map<String, String> structureMap, String target, String source) {
+        if (StringUtils.isEmpty(structureMap.get(target)) && StringUtils.isNotEmpty(structureMap.get(source))) {
+            structureMap.put(target, structureMap.get(source));
+        }
+    }
+
+    /**
+     * 日间病历解析全用切词方式
+     *
+     * @param text
+     * @param behDeptId
+     */
+    private Map<String, String> dailyTrans(String text, String behDeptId) {
+        Map<String, String> parseMap = Maps.newHashMap();
+        List<String> titles = Lists.newArrayList();
+        switch (behDeptId) {
+            case "51923":
+                titles = Lists.newArrayList("姓名", "出生日期", "出生地", "其他", "辅助检查", "与患者关系", "性别",
+                        "年龄", "职业", "入院时间", "婚姻", "出院时间", "民族", "身份证号", "联系电话", "邮政编码",
+                        "工作单位", "联系地址", "病史提供者", "病史陈述者", "主诉", "入院情况", "月 经 史", "婚 育 史", "体格检查", "妇科检查", "入院诊断", "诊疗情况",
+                        "诊疗经过", "出院情况", "出院诊断", "出院医嘱", "医师签名", "记录医师", "主刀医师签名",
+                        "记录时间", "时间");
+                break;
+            case "52883":
+                titles = Lists.newArrayList("姓名", "出生日期", "出生地", "其他", "辅助检查", "与患者关系", "性别",
+                        "年龄", "职业", "入院时间", "婚姻", "出院时间", "民族", "身份证号", "联系电话", "邮政编码",
+                        "工作单位", "联系地址", "病史提供者", "病史陈述者", "主诉", "入院情况", "入院诊断", "诊疗情况",
+                        "诊疗经过", "出院情况", "出院诊断", "出院医嘱", "注意事项", "出院带药", "随访计划", "医师签名",
+                        "记录医师", "记录时间", "时间");
+                break;
+            case "52903":
+                titles = Lists.newArrayList("姓名", "出生日期", "出生地", "其他", "辅助检查", "与患者关系", "性别",
+                        "年龄", "职业", "入院时间", "婚姻", "出院时间", "民族", "身份证号", "联系电话", "邮政编码",
+                        "工作单位", "联系地址", "病史提供者", "病史陈述者", "主诉", "入院情况", "入院诊断", "诊疗情况",
+                        "诊疗经过", "出院情况", "出院诊断", "出院医嘱", "注意事项", "出院带药", "随访计划", "医师签名",
+                        "记录医师", "记录时间", "时间");
+                break;
+            case "52923":
+                titles = Lists.newArrayList("姓名", "出生日期", "出生地", "其他", "辅助检查", "与患者关系", "性别",
+                        "年龄", "职业", "入院时间", "婚姻", "出院时间", "民族", "身份证号", "联系电话", "邮政编码",
+                        "工作单位", "联系地址", "病史提供者", "病史陈述者", "主诉", "入院情况", "入院诊断", "诊疗情况",
+                        "诊疗经过", "出院情况", "出院诊断", "出院医嘱", "注意事项", "出院带药", "随访计划", "医师签名",
+                        "记录医师", "记录时间", "时间");
+                break;
+            case "53523":
+                titles = Lists.newArrayList("姓名", "出生日期", "出生地", "其他", "辅助检查", "与患者关系", "性别",
+                        "年龄", "职业", "入院时间", "婚姻", "出院时间", "民族", "身份证号", "联系电话", "邮政编码",
+                        "工作单位", "联系地址", "病史提供者", "病史陈述者", "主诉", "入院情况", "入院诊断", "诊疗情况",
+                        "诊疗经过", "出院情况", "出院诊断", "出院医嘱", "注意事项", "出院带药", "随访计划", "医师签名",
+                        "记录医师", "记录时间", "时间");
+                break;
+        }
+        titles = CommonAnalysisUtil.sortTitles(titles, text);
+        CommonAnalysisUtil.cutByTitles(text, titles, 0, parseMap);
+        return parseMap;
+    }
+
+    private String modifyDiagKey(String text, String key) {
+        if (text.contains(key + ":")) {
+            text = text.replaceFirst("医师签名", key + "医师");
+            text = text.replaceFirst("日期", key + "时间");
+        }
+        return text;
+    }
+}

+ 58 - 0
trans/src/main/java/com/lantone/qc/trans/qdnzyy/ClinicBloodEffectDocTrans.java

@@ -0,0 +1,58 @@
+package com.lantone.qc.trans.qdnzyy;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.dbanaly.facade.yiwu.YiWuXmlUtil;
+import com.lantone.qc.dbanaly.util.ModuleMappingUtil;
+import com.lantone.qc.pub.model.doc.ClinicBloodEffectDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @desc 输血后效果评价
+ **/
+
+public class ClinicBloodEffectDocTrans extends ModelDocTrans {
+    private String modeId = "32";
+
+    @Override
+    public List<ClinicBloodEffectDoc> extract(MedrecVo medrecVo) {
+        List<ClinicBloodEffectDoc> retList = Lists.newArrayList();
+        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");
+        contentMaps.forEach(contentMap -> {
+            retList.add(getClinicBloodEffectDoc(contentMap));
+        });
+        return retList;
+    }
+
+    private ClinicBloodEffectDoc getClinicBloodEffectDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            Map<String, String> sourceMap = YiWuXmlUtil.xmlToMap(content);
+            sourceMap.put("mode_id", ModuleMappingUtil.getDeptModuleId(modeId));
+            sourceMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
+            sourceMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
+            structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts, modeId);
+        }
+
+        ClinicBloodEffectDoc clinicBloodEffectDoc = new ClinicBloodEffectDoc();
+        clinicBloodEffectDoc.setStructureMap(structureMap);
+        clinicBloodEffectDoc.setPageData((Map) structureMap);
+
+        return clinicBloodEffectDoc;
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "病程时间=病历日期",
+            "病程标题=病程标题",//提示:页面暂时缺少对应的展示列
+            "病程内容=评估结论",
+            "记录医师签名=评估医师"
+    );
+}

+ 76 - 0
trans/src/main/java/com/lantone/qc/trans/qdnzyy/ClinicalBloodDocTrans.java

@@ -0,0 +1,76 @@
+package com.lantone.qc.trans.qdnzyy;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.dbanaly.facade.yiwu.YiWuXmlUtil;
+import com.lantone.qc.dbanaly.util.ModuleMappingUtil;
+import com.lantone.qc.pub.model.doc.ClinicalBloodDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import org.apache.commons.collections.MapUtils;
+
+import java.util.List;
+import java.util.Map;
+
+public class ClinicalBloodDocTrans extends ModelDocTrans {
+    private String modeId = "10";
+
+    @Override
+    public List<ClinicalBloodDoc> extract(MedrecVo medrecVo) {
+        List<ClinicalBloodDoc> retList = Lists.newArrayList();
+        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");
+        contentMaps.forEach(contentMap -> {
+            retList.add(getClinicalBloodDoc(contentMap));
+        });
+        return retList;
+    }
+
+    private ClinicalBloodDoc getClinicalBloodDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            Map<String, String> sourceMap = YiWuXmlUtil.xmlToMap(content);
+            sourceMap.put("mode_id", ModuleMappingUtil.getDeptModuleId(modeId));
+            sourceMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
+            sourceMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
+            structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts, modeId);
+        }
+        if (MapUtils.isNotEmpty(structureMap)) {
+            String CliBDateStr = structureMap.get("输血日期");
+            if (StringUtil.isNotBlank(CliBDateStr) && CliBDateStr.length() == 39) {
+                structureMap.put("输注开始", CliBDateStr.substring(0, 19));
+                structureMap.put("输注结束", CliBDateStr.substring(20));
+            }
+        }
+
+        ClinicalBloodDoc clinicalBloodDoc = new ClinicalBloodDoc();
+        clinicalBloodDoc.setText(structureMap.get("原始文本"));
+        clinicalBloodDoc.setStructureMap(structureMap);
+        clinicalBloodDoc.setPageData((Map) structureMap);
+        return clinicalBloodDoc;
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            /*"开始时间=输注开始",
+            "医生=记录医生",
+            "记录医师=记录医生",
+            "结束时间=输注结束",
+            "内容=输注后效果评价",
+            "输血原因(可多选)=输注原因",
+            "ABO=血型",
+            "医师签名=记录医生",
+            "记录医师签名=记录医生",
+            "病程时间=记录时间",
+            "病情内容=病历内容",
+            "病程内容=病历内容"*/
+            "病程时间=病历日期",
+            "病程标题=标题",
+            "病程内容=病历内容",
+            "记录医师签名=记录医生",
+            "病程时间=记录时间"
+    );
+}

+ 242 - 0
trans/src/main/java/com/lantone/qc/trans/qdnzyy/ConsultationDocTrans.java

@@ -0,0 +1,242 @@
+package com.lantone.qc.trans.qdnzyy;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.lantone.qc.dbanaly.facade.shengzhouzz.ShengzhouyyXmlUtil;
+import com.lantone.qc.dbanaly.util.ModuleMappingUtil;
+import com.lantone.qc.pub.model.doc.consultation.ConsultationApplicationDoc;
+import com.lantone.qc.pub.model.doc.consultation.ConsultationDoc;
+import com.lantone.qc.pub.model.doc.consultation.ConsultationRecordDoc;
+import com.lantone.qc.pub.model.doc.consultation.ConsultationResultsDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @Description: 会诊文档生成
+ */
+public class ConsultationDocTrans extends ModelDocTrans {
+    /**
+     * 会诊记录包含3个模块:会诊申请单,会诊结果单,会诊记录
+     * 配套放置,华卓需要注意顺序问题,没有字段可以关联,我们做不到check
+     *
+     * @param medrecVo
+     * @return
+     */
+    @Override
+    public List<ConsultationDoc> extract(MedrecVo medrecVo) {
+        List<ConsultationDoc> retList = Lists.newArrayList();
+
+        Map<String, List<String>> contentMap = (Map) medrecVo.getContent().get("content");
+        if (contentMap == null) {
+            return retList;
+        }
+
+        Map<String, ConsultationRecordDoc> consultationRecordDocMap = getConsultationRecordDocMap((List) contentMap.get("会诊记录"));
+        Map<String, ConsultationResultsDoc> consultationResultsDocMap = getConsultationResultsDocMap((List) contentMap.get("会诊结果单"));
+        Map<String, ConsultationApplicationDoc> consultationApplicationDocMap = getConsultationApplicationDocMap((List) contentMap.get("会诊申请单"));
+
+        Set<String> consultationNameSet = Sets.newHashSet();
+        consultationNameSet.addAll(consultationRecordDocMap.keySet());
+        consultationNameSet.addAll(consultationResultsDocMap.keySet());
+        consultationNameSet.addAll(consultationApplicationDocMap.keySet());
+
+        consultationNameSet.forEach(consultationName -> {
+            ConsultationDoc consultationDoc = new ConsultationDoc();
+            consultationDoc.setConsultationName(consultationName);
+            consultationDoc.setConsultationRecordDoc(consultationRecordDocMap.get(consultationName));
+            consultationDoc.setConsultationResultsDoc(consultationResultsDocMap.get(consultationName));
+            consultationDoc.setConsultationApplicationDoc(consultationApplicationDocMap.get(consultationName));
+            retList.add(consultationDoc);
+        });
+
+        return retList;
+    }
+
+
+    /**************************************************会诊记录*********************************************************/
+    private Map<String, ConsultationRecordDoc> getConsultationRecordDocMap(List<Map<String, Object>> contentMaps) {
+        Map<String, ConsultationRecordDoc> retMap = Maps.newHashMap();
+        if (ListUtil.isEmpty(contentMaps)) {
+            return retMap;
+        }
+        int index = 1;
+        String consultationName = null;
+        for (Map<String, Object> contentMap : contentMaps) {
+            if (contentMap.get("xmlText") == null || StringUtil.isBlank(contentMap.get("xmlText").toString())) {
+                continue;
+            }
+            consultationName = index + "";
+            ConsultationRecordDoc consultationRecordDoc = getConsultationRecordDoc(contentMap);
+            consultationRecordDoc.setConsultationName(consultationName);
+            retMap.put(consultationName, consultationRecordDoc);
+            index++;
+        }
+        return retMap;
+    }
+
+    private ConsultationRecordDoc getConsultationRecordDoc(Map<String, Object> contentMap) {
+        String modeId = "7";
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            Map<String, String> sourceMap = ShengzhouyyXmlUtil.xmlToMap(content);
+            sourceMap.put("mode_id", ModuleMappingUtil.getDeptModuleId(modeId));
+
+            //按指定标题切词
+            List<String> titles = Lists.newArrayList("记录医师", "会诊意见的执行情况", "会诊医师",
+                    "会诊科室", "会诊时间", "会诊意见","会诊原因");
+            String text = sourceMap.get("原始文本");
+            List<String> sortTitles = CommonAnalysisUtil.sortTitles(titles, text);
+            CommonAnalysisUtil.cutByTitles(text, sortTitles, 0, sourceMap);
+
+            sourceMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
+            sourceMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
+            structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, consultationRecord_keyContrasts, modeId);
+        }
+
+        ConsultationRecordDoc consultationRecordDoc = new ConsultationRecordDoc();
+        consultationRecordDoc.setStructureMap(structureMap);
+        consultationRecordDoc.setPageData((Map) structureMap);
+        return consultationRecordDoc;
+    }
+
+    // 会诊记录映射字段
+    private List<String> consultationRecord_keyContrasts = Lists.newArrayList(
+            "会诊意见的执行情况=会诊情况",
+            "记录医师=记录医生",
+            "病程时间=记录时间"
+            /*"事件日期=记录时间",
+            "医生=记录医师",
+            "会诊意见的执行情况=会诊情况",
+            "记录医师签名=记录医生",
+            "记录医师=记录医生"*/
+    );
+
+
+    /**************************************************会诊结果单*******************************************************/
+    private Map<String, ConsultationResultsDoc> getConsultationResultsDocMap(List<Map<String, Object>> contentMaps) {
+        Map<String, ConsultationResultsDoc> retMap = Maps.newHashMap();
+        if (ListUtil.isEmpty(contentMaps)) {
+            return retMap;
+        }
+        int index = 1;
+        String consultationName = null;
+        for (Map<String, Object> contentMap : contentMaps) {
+            if (contentMap.get("xmlText") == null || StringUtil.isBlank(contentMap.get("xmlText").toString())) {
+                continue;
+            }
+            consultationName = index + "";
+            ConsultationResultsDoc consultationResultsDoc = getConsultationResultsDoc(contentMap);
+            consultationResultsDoc.setConsultationName(consultationName);
+            retMap.put(consultationName, consultationResultsDoc);
+            index++;
+        }
+        return retMap;
+    }
+
+    private ConsultationResultsDoc getConsultationResultsDoc(Map<String, Object> contentMap) {
+        String modeId = "31";
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            Map<String, String> sourceMap = ShengzhouyyXmlUtil.xmlToMap(content);
+            List<String> titles = Lists.newArrayList("会诊记录", "会诊科室", "会诊医师", "会诊意见",
+                    "会诊后采取措施", "记录医师", "会诊原因","会诊时间","记录时间","会诊意见的执行情况");
+            String text = sourceMap.get("原始文本");
+            List<String> sortTitles = CommonAnalysisUtil.sortTitles(titles, text);
+            CommonAnalysisUtil.cutByTitles(text, sortTitles, 0, sourceMap);
+            sourceMap.put("mode_id", ModuleMappingUtil.getDeptModuleId(modeId));
+            sourceMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
+            sourceMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
+            structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, consultationResults_keyContrasts, modeId);
+        }
+
+        ConsultationResultsDoc consultationResultsDoc = new ConsultationResultsDoc();
+        consultationResultsDoc.setStructureMap(structureMap);
+        consultationResultsDoc.setPageData((Map) structureMap);
+        return consultationResultsDoc;
+    }
+
+    // 会诊结果映射字段
+    private List<String> consultationResults_keyContrasts = Lists.newArrayList(
+         /*   "会诊诊断=当前诊断",
+            "事件日期1(会诊申请日期)=申请日期",
+            "医生=医师签名",
+            "本人姓名=姓名",
+            "病史描述=病史回顾描述",
+            "病历日期=会诊日期及时间",
+            "记录及建议=会诊意见",
+            "临床科室1=申请科室",
+            "申请医生1=申请医生"*/
+//            "会诊记录","会诊科室","会诊医师","会诊意见","会诊后采取措施","记录医师"
+            "会诊后采取措施=会诊意见的执行情况"
+    );
+
+
+    /**************************************************会诊申请单*******************************************************/
+    private Map<String, ConsultationApplicationDoc> getConsultationApplicationDocMap(List<Map<String, Object>> contentMaps) {
+        Map<String, ConsultationApplicationDoc> retMap = Maps.newHashMap();
+        if (ListUtil.isEmpty(contentMaps)) {
+            return retMap;
+        }
+        int index = 1;
+        String consultationName = null;
+        for (Map<String, Object> contentMap : contentMaps) {
+            if (contentMap.get("xmlText") == null || StringUtil.isBlank(contentMap.get("xmlText").toString())) {
+                continue;
+            }
+            consultationName = index + "";
+            ConsultationApplicationDoc consultationApplicationDoc = getConsultationApplicationDoc(contentMap);
+            consultationApplicationDoc.setConsultationName(consultationName);
+            retMap.put(consultationName, consultationApplicationDoc);
+            index++;
+        }
+        return retMap;
+    }
+
+    private ConsultationApplicationDoc getConsultationApplicationDoc(Map<String, Object> contentMap) {
+        String modeId = "30";
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            Map<String, String> sourceMap = ShengzhouyyXmlUtil.xmlToMap(content);
+            sourceMap.put("mode_id", ModuleMappingUtil.getDeptModuleId(modeId));
+            sourceMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
+            sourceMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
+            structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, consultationApplication_keyContrasts, modeId);
+        }
+
+        ConsultationApplicationDoc consultationApplicationDoc = new ConsultationApplicationDoc();
+        consultationApplicationDoc.setStructureMap(structureMap);
+        consultationApplicationDoc.setPageData((Map) structureMap);
+
+        return consultationApplicationDoc;
+    }
+
+    // 会诊申请单映射字段
+    private List<String> consultationApplication_keyContrasts = Lists.newArrayList(
+            "事件日期=申请日期",
+            "会诊类别=会诊分类",
+            "会诊理由和目的=申请理由目的",
+            "病历日期=会诊日期及时间",
+            "本人姓名=姓名",
+            "病历号=病案号",
+            "临床科室=申请科室"
+    );
+}

+ 54 - 0
trans/src/main/java/com/lantone/qc/trans/qdnzyy/CrisisValueReportDocTrans.java

@@ -0,0 +1,54 @@
+package com.lantone.qc.trans.qdnzyy;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.dbanaly.facade.yiwu.YiWuXmlUtil;
+import com.lantone.qc.dbanaly.util.ModuleMappingUtil;
+import com.lantone.qc.pub.model.doc.CrisisValueReportDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 危急值记录文档生成
+ */
+public class CrisisValueReportDocTrans extends ModelDocTrans {
+    private String modeId = "23";
+
+    @Override
+    public List<CrisisValueReportDoc> extract(MedrecVo medrecVo) {
+        List<CrisisValueReportDoc> retList = Lists.newArrayList();
+        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");
+        contentMaps.forEach(contentMap -> {
+            retList.add(getCrisisValueReportDoc(contentMap));
+        });
+        return retList;
+    }
+
+    private CrisisValueReportDoc getCrisisValueReportDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            Map<String, String> sourceMap = YiWuXmlUtil.xmlToMap(content);
+            sourceMap.put("mode_id", ModuleMappingUtil.getDeptModuleId(modeId));
+            sourceMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
+            sourceMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
+            structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts, modeId);
+        }
+
+        CrisisValueReportDoc crisisValueReportDoc = new CrisisValueReportDoc();
+        crisisValueReportDoc.setStructureMap(structureMap);
+        crisisValueReportDoc.setPageData((Map) structureMap);
+
+        return crisisValueReportDoc;
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "病历日期=记录时间"
+    );
+}

+ 58 - 0
trans/src/main/java/com/lantone/qc/trans/qdnzyy/CriticallyIllNoticeDocTrans.java

@@ -0,0 +1,58 @@
+package com.lantone.qc.trans.qdnzyy;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.dbanaly.facade.shengzhouzz.ShengzhouyyXmlUtil;
+import com.lantone.qc.dbanaly.util.ModuleMappingUtil;
+import com.lantone.qc.pub.model.doc.CriticallyIllNoticeDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.CommonAnalysisUtil;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 病危通知书文档生成
+ */
+public class CriticallyIllNoticeDocTrans extends ModelDocTrans {
+    private String modeId = "25";
+
+    @Override
+    public List<CriticallyIllNoticeDoc> extract(MedrecVo medrecVo) {
+        List<CriticallyIllNoticeDoc> retList = Lists.newArrayList();
+        List<Map<String, Object>> contentMaps = (List) medrecVo.getContent().get("content");
+        contentMaps.forEach(contentMap -> {
+            retList.add(getCriticallyIllNoticeDoc(contentMap));
+        });
+        return retList;
+    }
+
+    private CriticallyIllNoticeDoc getCriticallyIllNoticeDoc(Map<String, Object> contentMap) {
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            Map<String, String> sourceMap = ShengzhouyyXmlUtil.xmlToMap(content);
+            sourceMap.put("mode_id", ModuleMappingUtil.getDeptModuleId(modeId));
+            List<String> titles = Lists.newArrayList("防范措施","","目前病情");
+            String text = sourceMap.get("原始文本");
+            titles = CommonAnalysisUtil.sortTitles(titles, text);
+            CommonAnalysisUtil.cutByTitles(text, titles, 0, sourceMap);
+
+            sourceMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
+            sourceMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
+            structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts, modeId);
+        }
+
+        CriticallyIllNoticeDoc criticallyIllNoticeDoc = new CriticallyIllNoticeDoc();
+        criticallyIllNoticeDoc.setStructureMap(structureMap);
+        criticallyIllNoticeDoc.setPageData((Map) structureMap);
+
+        return criticallyIllNoticeDoc;
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList();
+}

+ 59 - 0
trans/src/main/java/com/lantone/qc/trans/qdnzyy/DeathCaseDiscussDocTrans.java

@@ -0,0 +1,59 @@
+package com.lantone.qc.trans.qdnzyy;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.dbanaly.facade.shengzhouzz.ShengzhouyyXmlUtil;
+import com.lantone.qc.dbanaly.util.ModuleMappingUtil;
+import com.lantone.qc.pub.model.doc.DeathCaseDiscussDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.pub.util.MapUtil;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 死亡病例讨论记录文档生成
+ */
+public class DeathCaseDiscussDocTrans extends ModelDocTrans {
+    private String modeId = "3";
+
+    @Override
+    public DeathCaseDiscussDoc extract(MedrecVo medrecVo) {
+        Map<String, Object> contentMap = ((List<Map>) medrecVo.getContent().get("content")).get(0);
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            Map<String, String> sourceMap = ShengzhouyyXmlUtil.xmlToMap(content);
+            sourceMap.put("mode_id", ModuleMappingUtil.getDeptModuleId(modeId));
+            sourceMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
+            sourceMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
+            String moderator_summary_opinions = sourceMap.get("主持人总结意见");
+            if (StringUtils.isNotBlank(moderator_summary_opinions)){
+                String[] split = moderator_summary_opinions.split("死亡原因:");
+                sourceMap.put("主持人小结",split[0]);
+                sourceMap.put("死亡诊断",split[1]);
+            }
+            structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts, modeId);
+        }
+
+        MapUtil.keyAssig(structureMap, "参加讨论人员", "参加人员及职称医生", "参加人员及职称");
+        DeathCaseDiscussDoc deathCaseDiscussDoc = new DeathCaseDiscussDoc();
+        deathCaseDiscussDoc.setStructureMap(structureMap);
+        deathCaseDiscussDoc.setPageData((Map) structureMap);
+
+        return deathCaseDiscussDoc;
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "病程时间=讨论时间",
+            "主持人姓名=主持人",
+            "参加讨论人员名单=参加人员",
+            "讨论结论=讨论内容",
+            "记录人签名=记录医生"
+    );
+}

+ 54 - 0
trans/src/main/java/com/lantone/qc/trans/qdnzyy/DeathRecordDocTrans.java

@@ -0,0 +1,54 @@
+package com.lantone.qc.trans.qdnzyy;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.dbanaly.facade.yiwu.YiWuXmlUtil;
+import com.lantone.qc.dbanaly.util.ModuleMappingUtil;
+import com.lantone.qc.pub.model.doc.DeathRecordDoc;
+import com.lantone.qc.pub.model.vo.MedrecVo;
+import com.lantone.qc.pub.util.FastJsonUtils;
+import com.lantone.qc.trans.ModelDocTrans;
+import com.lantone.qc.trans.comsis.OrdinaryAssistant;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 死亡记录文档生成
+ */
+public class DeathRecordDocTrans extends ModelDocTrans {
+    private String modeId = "24";
+
+    @Override
+    public DeathRecordDoc extract(MedrecVo medrecVo) {
+        Map<String, Object> contentMap = ((List<Map>) medrecVo.getContent().get("content")).get(0);
+        String content = contentMap.get("xmlText").toString();
+        Map<String, String> structureMap = null;
+        if (contentMap.get("isParsed") != null && "1".equals(contentMap.get("isParsed").toString())) {
+            structureMap = (Map) FastJsonUtils.getJsonToMap(content);
+        } else {
+            Map<String, String> sourceMap = YiWuXmlUtil.xmlToMap(content);
+            sourceMap.put("mode_id", ModuleMappingUtil.getDeptModuleId(modeId));
+            sourceMap.put("mode_id=" + contentMap.get("modeId").toString(), "");
+            sourceMap.put("rec_title=" + contentMap.get("recTitle").toString(), "");
+            structureMap = OrdinaryAssistant.mapKeyContrast(sourceMap, keyContrasts, modeId);
+        }
+
+        DeathRecordDoc deathRecordDoc = new DeathRecordDoc();
+        deathRecordDoc.setStructureMap(structureMap);
+        deathRecordDoc.setPageData((Map) structureMap);
+
+        return deathRecordDoc;
+    }
+
+    private List<String> keyContrasts = Lists.newArrayList(
+            "当前诊断=死亡诊断",
+            "死亡日期=死亡时间",
+            "初步诊断=入院诊断",
+            "诊治经过=诊疗经过",
+            "本人姓名=姓名",
+            "现病史- 发病情况=发病情况",
+            "病历日期=记录时间",
+            "医生=记录医师",
+            "死亡时间=死亡日期"
+    );
+}

+ 0 - 0
trans/src/main/java/com/lantone/qc/trans/qdnzyy/DifficultCaseDiscussDocTrans.java


Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels