Bläddra i källkod

Merge branch 'hb/beilun' into his/qdnzyy

# Conflicts:
#	dbanaly/src/main/resources/application-test.yml
#	kernel/src/main/resources/bootstrap.yml
xuejiafu 3 år sedan
förälder
incheckning
d48c9a3a10
100 ändrade filer med 58879 tillägg och 169 borttagningar
  1. 45 0
      dbanaly/src/main/resources/application-db.yml
  2. 2 2
      dbanaly/src/main/resources/application-debug.yml
  3. 3 4
      dbanaly/src/main/resources/application-dev.yml
  4. 7 7
      dbanaly/src/main/resources/application-local.yml
  5. 16 0
      dbanaly/src/main/resources/rebel.xml
  6. 1 1
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH0009.java
  7. 1 1
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH0010.java
  8. 1 1
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH0014.java
  9. 1 1
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH0030.java
  10. 62 22
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH0059.java
  11. 5 5
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH02966.java
  12. 2 2
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH0372.java
  13. 3 2
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/deathrecord/DEAR0342.java
  14. 1 1
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/deathrecord/DEAR0344.java
  15. 6 6
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/difficultcasediscuss/DIF0118.java
  16. 3 2
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/difficultcasediscuss/DIF0119.java
  17. 2 2
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/firstpagerecord/FIRP0162.java
  18. 12 3
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/firstpagerecord/FIRP0225.java
  19. 1 1
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/firstpagerecord/FIRP03213.java
  20. 50 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/firstpagerecord/FIRP03229.java
  21. 2 2
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/changshaxy/behospitalized/BEH02966.java
  22. 47 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/clinicalblood/CLI0306.java
  23. 54 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/clinicalblood/CLI0307.java
  24. 55 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/clinicalblood/CLI0308.java
  25. 44 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/clinicalblood/CLI0562.java
  26. 46 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/clinicalblood/CLI0564.java
  27. 72 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/clinicalblood/CLI0569.java
  28. 218 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/operationdiscussion/OPE03111.java
  29. 14 1
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/operationdiscussion/OPE0369.java
  30. 18 14
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/preoperativediscussion/PRE0328.java
  31. 8 5
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/threelevelward/THR02900.java
  32. 17 4
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/threelevelward/THR03090.java
  33. 4 4
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ninghaifuyou/behospitalized/BEH02966.java
  34. 64 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/shengzhouyy/deathcasediscuss/DEAC03232.java
  35. 64 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/shengzhouyy/deathrecord/DEAR03233.java
  36. 66 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/shengzhouyy/firstcourserecord/FIRC03086.java
  37. 62 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/shengzhouyy/firstcourserecord/FIRC03230.java
  38. 63 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/shengzhouyy/leavehospital/LEA03231.java
  39. 264 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/behospitalized/BEH02980.java
  40. 48 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/clinicalblood/CLI0308.java
  41. 42 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/clinicalblood/CLI0568.java
  42. 29 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/deathcasediscuss/DEAC0556.java
  43. 29 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/deathcasediscuss/DEAC0558.java
  44. 92 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/firstcourserecord/FIRC0087.java
  45. 132 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/firstpagerecord/FIRP0178.java
  46. 68 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/firstpagerecord/FIRP0190.java
  47. 45 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/firstpagerecord/FIRP0220.java
  48. 39 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/firstpagerecord/FIRP0516.java
  49. 74 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/operationdiscussion/OPE03142.java
  50. 68 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/operationdiscussion/OPE03143.java
  51. 68 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/operationdiscussion/OPE03144.java
  52. 66 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/operationdiscussion/OPE0323.java
  53. 45 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/operationdiscussion/OPE0636.java
  54. 45 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/operationdiscussion/OPE0640.java
  55. 250 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/threelevelward/THR0127.java
  56. 36 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/threelevelward/THR0685.java
  57. 2 2
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/leavehospital/LEA02968.java
  58. 31 30
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/operationdiscussion/OPE03107.java
  59. 7 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/operationdiscussion/OPE03111.java
  60. 33 16
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/operationdiscussion/OPE03143.java
  61. 3 3
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/preoperativediscussion/PRE0329.java
  62. 2 0
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/preoperativediscussion/PRE0330.java
  63. 4 4
      kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR02967.java
  64. 2 2
      kernel/src/main/resources/bootstrap.yml
  65. 84 0
      kernel/src/main/resources/cache/37/concept_clinic_bodypart_properties.dict
  66. 25358 0
      kernel/src/main/resources/cache/37/concept_diag_properties.dict
  67. 25358 0
      kernel/src/main/resources/cache/37/hospital_diag_info.dict
  68. 3123 0
      kernel/src/main/resources/cache/37/hospital_doctor_info.dict
  69. 16 0
      kernel/src/main/resources/rebel.xml
  70. 16 0
      nlp/src/main/java/rebel.xml
  71. 3 3
      public/src/main/java/com/lantone/qc/pub/util/DateUtil.java
  72. 16 0
      public/src/main/java/rebel.xml
  73. 16 0
      security/src/main/java/rebel.xml
  74. 7 16
      trans/src/main/java/com/lantone/qc/trans/beilun/util/BeiLunInvasiveOperationHtmlAnalysis.java
  75. 3 0
      trans/src/main/java/com/lantone/qc/trans/beilun/util/BeiLunThreeLevelWardHtmlAnalysis.java
  76. 52 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/ADLGradeDocTrans.java
  77. 38 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/AnesthesiaRecordDocTrans.java
  78. 79 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/BeHospitalizedDocTrans.java
  79. 73 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/ClinicBloodEffectDocTrans.java
  80. 77 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/ClinicalBloodDocTrans.java
  81. 278 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/ConsultationDocTrans.java
  82. 36 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/CrisisInfoDocTrans.java
  83. 72 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/CrisisValueReportDocTrans.java
  84. 79 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/CriticallyIllNoticeDocTrans.java
  85. 61 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DeathCaseDiscussDocTrans.java
  86. 65 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DeathRecordDocTrans.java
  87. 93 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DifficultCaseDiscussDocTrans.java
  88. 36 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DoctorAdviceDocTrans.java
  89. 72 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/DutyShiftSystemDocTrans.java
  90. 82 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/FirstCourseRecordDocTrans.java
  91. 54 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/FirstPageRecordDocTrans.java
  92. 288 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/HangzhoufubaoDocTrans.java
  93. 75 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/InvasiveOperationDocTrans.java
  94. 69 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/LeaveHospitalDocTrans.java
  95. 36 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/LisDocTrans.java
  96. 26 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/MedicalRecordInfoDocTrans.java
  97. 396 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/OperationDocTrans.java
  98. 40 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/OutDepDocTrans.java
  99. 36 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/PacsDocTrans.java
  100. 0 0
      trans/src/main/java/com/lantone/qc/trans/hangzhoufubao/RescueDocTrans.java

+ 45 - 0
dbanaly/src/main/resources/application-db.yml

@@ -0,0 +1,45 @@
+spring:
+  datasource:
+    name: druidDataSource
+    type: com.alibaba.druid.pool.DruidDataSource
+    druid:
+      lantone:
+        driver-class-name: com.mysql.jdbc.Driver
+        url: jdbc:mysql://192.168.2.122:3306/qc?useUnicode=true&characterEncoding=utf8
+        username: root
+        password: lantone
+        initial-size: 8
+        min-idle: 1
+        max-active: 20
+        max-wait: 60000
+        time-between-eviction-runsMillis: 60000
+        min-evictable-idle-timeMillis: 300000
+        validation-query: select 'x' FROM DUAL
+        test-while-idle: true
+        test-on-borrow: false
+        test-on-return: false
+        pool-prepared-statements: true
+        max-open-prepared-statements: 20
+        max-pool-prepared-statement-per-connection-size: 20
+        filters: stat
+        connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
+        use-global-data-source-stat: true
+  redis:
+    database: 10
+    host: 192.168.2.121
+    port: 6379
+    password: lantone
+    timeout: 2000
+    lettuce:
+      pool:
+        max-active: 8
+        min-idle: 0
+        max-wait: -1ms
+        max-idle: 8
+
+mybatis-plus:
+  type-aliases-package: com.lantone.qc.dbanaly.lt.entity
+  configuration:
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+
+xml-is-encryped: true

+ 2 - 2
dbanaly/src/main/resources/application-debug.yml

@@ -5,7 +5,7 @@ spring:
     druid:
       lantone:
         driver-class-name: com.mysql.jdbc.Driver
-        url: jdbc:mysql://192.168.2.237:3307/qc?useUnicode=true&characterEncoding=utf8&useSSL=false
+        url: jdbc:mysql://192.168.2.237:3307/qc_xszyy?useUnicode=true&characterEncoding=utf8&useSSL=false
         username: root
         password: lantone
         initial-size: 8
@@ -41,7 +41,7 @@ spring:
         min-idle: 0 # 连接池中的最小空闲连接
     timeout: 20000 # 连接超时时间(毫秒)
 
-xml-is-encryped: true
+xml-is-encryped: false
 
 CRF:
   url: http://192.168.2.234:3456/api/mr_info_ex/entity_predict

+ 3 - 4
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,12 +24,11 @@ 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服务器连接密码(默认为空)
     lettuce:

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

@@ -5,9 +5,9 @@ spring:
     druid:
       lantone:
         driver-class-name: com.mysql.jdbc.Driver
-        url: jdbc:mysql://10.68.24.21:3306/qc?useUnicode=true&characterEncoding=utf8&useSSL=false
+        url: jdbc:mysql://127.0.0.1:3306/qc?useUnicode=true&characterEncoding=utf8&useSSL=false
         username: root
-        password: lantone
+        password: langtong
         initial-size: 8
         min-idle: 1
         max-active: 20
@@ -42,16 +42,16 @@ spring:
 xml-is-encryped: true
 
 CRF:
-  url: http://10.68.24.42:13456/api/mr_info_ex/entity_predict
+  url: http://127.0.0.1:13456/api/mr_info_ex/entity_predict
 
 Similarity:
-  url: http://10.68.24.42:13456/api/mr_info_ex/similarity
+  url: http://127.0.0.1:13456/api/mr_info_ex/similarity
 
 NewSimilarity:
-  url: http://10.68.24.42:12323/api/similarity
+  url: http://127.0.0.1:12323/api/similarity
 
 NewBatchSimilarity:
-  url: http://10.68.24.42:12323/api/similarity_batch
+  url: http://127.0.0.1:12323/api/similarity_batch
 
 ChiefPresentSimilarity:
-  url: http://10.68.24.42:13456/api/mr_info_ex/chief_present_similarity
+  url: http://127.0.0.1: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) {

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

@@ -21,7 +21,7 @@ import java.util.List;
 @Component
 public class BEH0010 extends QCCatalogue {
     private List<String> containList = Arrays.asList("癌", "瘤", "复诊", "术后", "化疗后", "发现", "体检", "检查", "确诊"
-            , "诊断", "复查", "复发", "示", "超", "CT", "血透", "血液透析", "治疗后");
+            , "诊断", "复查", "复发", "示", "超", "CT", "血透", "血液透析", "治疗后", "痛");
 
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
         status.set("0");

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

@@ -28,7 +28,7 @@ import java.util.List;
 @Component
 public class BEH0014 extends QCCatalogue {
     private List<String> containList = Arrays.asList("体检", "发现", "检查", "因", "确诊", "诊断", "复查", "术后"
-            , "药物", "误服", "查", "撞", "伤", "跌", "月经", "暴力", "超", "术");
+            , "药物", "误服", "查", "撞", "伤", "跌", "月经", "暴力", "超", "术","不慎","出现");
 
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
         if (inputInfo.getBeHospitalizedDoc() == null) {

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

@@ -47,7 +47,7 @@ public class BEH0030 extends QCCatalogue {
             status.set("0");
         }
         String pastText = pastLabel.getText();
-        if (pastText.contains("肝炎") || pastText.contains("结核") || pastText.contains("详见原病历")
+        if (pastText.contains("肝炎") || pastText.contains("传染病") || pastText.contains("结核") || pastText.contains("详见原病历")
                 || pastText.contains("见旧病历") || pastText.contains("见既往病历") || pastText.contains("乙肝")) {
             status.set("0");
         }

+ 62 - 22
kernel/src/main/java/com/lantone/qc/kernel/catalogue/behospitalized/BEH0059.java

@@ -4,8 +4,10 @@ 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.MedicalRecordInfoDoc;
 import com.lantone.qc.pub.model.label.MenstrualLabel;
 import com.lantone.qc.pub.util.StringUtil;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 
 import java.util.Map;
@@ -17,44 +19,82 @@ import java.util.Map;
  * @Date: 2020-03-10 10:10
  */
 @Component
+@Slf4j
 public class BEH0059 extends QCCatalogue {
+    /**
+     * 1.判断住院信息表"科室"若为包含(儿科/新生儿)则通过
+     * 2..判断入院记录是否存在,若不存在则通过
+     * 3.获取性别(住院信息表/入院记录),若是性别不存在或性别为男则通过。然后获取年龄(住院信息表/入院记录),若是年龄小于10岁则通过。
+     * 4.获取入院记录结构化数据若是其中存在"月经"、"经期"、"绝经"且不为空则通过,
+     * 然后获取入院记录月经史,若不存在则报错返回,
+     * 若存在则去除符合规则‘[月经史|:|:|null]’的情况若是去除之后月经史为空则触发规则返回,若是不为空则判断其中是否包含中文字,若是包含则通过
+     */
     @Override
     protected void start(InputInfo inputInfo, OutputInfo outputInfo) {
-        if (inputInfo.getBeHospitalizedDoc() != null) {
-            if (inputInfo.getBeHospitalizedDoc().getStructureMap() == null
-                    || inputInfo.getBeHospitalizedDoc().getStructureMap().get("性别") == null
-                    || inputInfo.getBeHospitalizedDoc().getStructureMap().get("性别").contains("男")) {
-                status.set("0"); //如果性别是男,就不报错
-            } else {
-                String concatMenstrualText = concatMenstrualText(inputInfo);
-                if (StringUtil.isNotBlank(concatMenstrualText)) {
+        MedicalRecordInfoDoc medicalRecordInfoDoc = inputInfo.getMedicalRecordInfoDoc();
+        if (medicalRecordInfoDoc != null && medicalRecordInfoDoc.getStructureMap() != null) {
+            //科室
+            String behDeptName = medicalRecordInfoDoc.getStructureMap().get("behDeptName");
+            if (StringUtil.isNotBlank(behDeptName) && (behDeptName.contains("儿科") || behDeptName.contains("新生儿"))) {
+                status.set("0");
+                return;
+            }
+            //性别
+            String sex = medicalRecordInfoDoc.getStructureMap().get("sex");
+            if (StringUtil.isNotBlank(sex) && (sex.contains("男"))) {
+                status.set("0");
+                return;
+            }
+        }
+
+        if (inputInfo.getBeHospitalizedDoc() == null || inputInfo.getBeHospitalizedDoc().getStructureMap() == null) {
+            status.set("0");
+            return;
+        }
+        if (inputInfo.getBeHospitalizedDoc().getStructureMap().get("性别") != null &&
+                inputInfo.getBeHospitalizedDoc().getStructureMap().get("性别").contains("男")) {
+            status.set("0"); //如果性别是男,就不报错
+        }
+        //年龄
+        String age = inputInfo.getBeHospitalizedDoc().getStructureMap().get("年龄");
+        if (StringUtil.isNotBlank(age)) {
+            try {
+                age = age.replace("岁", "");
+                int ageNum = Integer.parseInt(age);
+                if (ageNum < 10) {
                     status.set("0");
                     return;
                 }
-                MenstrualLabel menstrualLabel = inputInfo.getBeHospitalizedDoc().getMenstrualLabel();
-                if (menstrualLabel == null) {
-                    return;
-                }
-                String menstrualText = StringUtil.removeBlank(menstrualLabel.getText()).replaceAll("[月经史|:|:|null]", "");
-                if (StringUtil.isBlank(menstrualText)) {
-                    return;
-                }
-                boolean containChinese = CatalogueUtil.isContainChinese(menstrualText);
-                if (containChinese) {
-                    status.set("0"); //如果性别是女,不为空就不报错
-                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e + "BEH0059 :  日期转换异常");
             }
-        }else {
+        }
+        String concatMenstrualText = concatMenstrualText(inputInfo);
+        if (StringUtil.isNotBlank(concatMenstrualText)) {
             status.set("0");
             return;
         }
+        MenstrualLabel menstrualLabel = inputInfo.getBeHospitalizedDoc().getMenstrualLabel();
+        if (menstrualLabel == null) {
+            return;
+        }
+        String menstrualText = StringUtil.removeBlank(menstrualLabel.getText()).replaceAll("[月经史|:|:|null]", "");
+        if (StringUtil.isBlank(menstrualText)) {
+            return;
+        }
+        boolean containChinese = CatalogueUtil.isContainChinese(menstrualText);
+        if (containChinese) {
+            status.set("0"); //如果性别是女,不为空就不报错
+        }
+
+
     }
 
     private String concatMenstrualText(InputInfo inputInfo) {
         Map<String, String> beHospitalizedStructureMap = inputInfo.getBeHospitalizedDoc().getStructureMap();
         StringBuilder sb = new StringBuilder();
         for (Map.Entry<String, String> bhMap : beHospitalizedStructureMap.entrySet()) {
-            if (bhMap.getKey().contains("月经") || bhMap.getKey().contains("经期") || bhMap.getKey().contains("绝经")) {
+            if (bhMap.getKey().contains("月经") || bhMap.getKey().contains("经期") || bhMap.getKey().contains("绝经") || bhMap.getKey().contains("月经史")) {
                 if (StringUtil.isNotBlank(bhMap.getValue())) {
                     sb.append(bhMap.getValue());
                 }

+ 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/behospitalized/BEH0372.java

@@ -29,7 +29,7 @@ public class BEH0372 extends QCCatalogue {
             bhbasicInfoStatus = inputInfo.getBeHospitalizedDoc().getStructureMap().get("婚姻");
         }
         if (StringUtil.isBlank(basicInfoStatus) || basicInfoStatus.contains("详见")
-                || basicInfoStatus.contains("见旧病历")|| basicInfoStatus.contains("见既往病历")|| StringUtil.isBlank(bhbasicInfoStatus)) {
+                || basicInfoStatus.contains("见旧病历") || basicInfoStatus.contains("见既往病历") || StringUtil.isBlank(bhbasicInfoStatus)) {
             status.set("0");
             return;
         }
@@ -58,7 +58,7 @@ public class BEH0372 extends QCCatalogue {
         }
 
         if (bhbasicInfoStatus.equals("已婚") && (basicInfoStatus.contains("结婚") || basicInfoStatus.contains("再婚")
-                || basicInfoStatus.contains("育有") || basicInfoStatus.contains("已婚"))) {
+                || basicInfoStatus.contains("育有") || basicInfoStatus.contains("已婚") || basicInfoStatus.contains("婚育"))) {
             status.set("0");
             return;
         }

+ 3 - 2
kernel/src/main/java/com/lantone/qc/kernel/catalogue/deathrecord/DEAR0342.java

@@ -27,13 +27,14 @@ public class DEAR0342 extends QCCatalogue {
             }
         }
     }
+
     private String getKeyByHospitalId() {
-        switch (Content.hospital_Id)
-        {
+        switch (Content.hospital_Id) {
             case "1":               //长兴
             case "2":
             case "5":
             case "35":
+            case "11":
                 return "诊疗经过";
             default:
                 return "诊疗经过(重点记录病情演变、抢救经过)";

+ 1 - 1
kernel/src/main/java/com/lantone/qc/kernel/catalogue/deathrecord/DEAR0344.java

@@ -24,7 +24,7 @@ public class DEAR0344 extends QCCatalogue {
             if (CatalogueUtil.isEmpty(diagnosisTreatmentProcess)) {
                 return;
             }
-            if (!diagnosisTreatmentProcess.contains("抢救")) {
+            if (!diagnosisTreatmentProcess.contains("抢救") && !diagnosisTreatmentProcess.contains("胸外按压") && !diagnosisTreatmentProcess.contains("心肺复苏")) {
                 status.set("-1");
             }
         }

+ 6 - 6
kernel/src/main/java/com/lantone/qc/kernel/catalogue/difficultcasediscuss/DIF0118.java

@@ -23,15 +23,15 @@ public class DIF0118 extends QCCatalogue {
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
         status.set("0");
         List<DifficultCaseDiscussDoc> difficultCaseDiscussDocs = inputInfo.getDifficultCaseDiscussDocs();
-        if(ListUtil.isEmpty(difficultCaseDiscussDocs)){
+        if (ListUtil.isEmpty(difficultCaseDiscussDocs)) {
             return;
         }
-        if(difficultCaseDiscussDocs != null && difficultCaseDiscussDocs.size()>0){
-            for (DifficultCaseDiscussDoc dcdd:difficultCaseDiscussDocs) {
+        if (difficultCaseDiscussDocs != null && difficultCaseDiscussDocs.size() > 0) {
+            for (DifficultCaseDiscussDoc dcdd : difficultCaseDiscussDocs) {
                 Map<String, String> dcddStructureMap = dcdd.getStructureMap();
                 String key = getKeyByHospitalId();
                 String diisDate = dcddStructureMap.get(key);
-                if(CatalogueUtil.isEmpty(diisDate)){
+                if (CatalogueUtil.isEmpty(diisDate)) {
                     status.set("-1");
                     break;
                 }
@@ -40,10 +40,10 @@ public class DIF0118 extends QCCatalogue {
     }
 
     private String getKeyByHospitalId() {
-        switch (Content.hospital_Id)
-        {
+        switch (Content.hospital_Id) {
             case "1":               //长兴
             case "2":
+            case "11":
                 return "主持人";
             default:
                 return "主持人姓名及专业技术职务";

+ 3 - 2
kernel/src/main/java/com/lantone/qc/kernel/catalogue/difficultcasediscuss/DIF0119.java

@@ -38,10 +38,11 @@ public class DIF0119 extends QCCatalogue {
             }
         }
     }
+
     private String getKeyByHospitalId() {
-        switch (Content.hospital_Id)
-        {
+        switch (Content.hospital_Id) {
             case "5":
+            case "11":
                 return "参加人员的姓名及专业技术职务";
             case "20":
                 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);

+ 12 - 3
kernel/src/main/java/com/lantone/qc/kernel/catalogue/firstpagerecord/FIRP0225.java

@@ -5,9 +5,12 @@ 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.util.DateUtil;
 import com.lantone.qc.pub.util.StringUtil;
 import org.springframework.stereotype.Component;
 
+import java.text.SimpleDateFormat;
+import java.util.Date;
 import java.util.Map;
 
 /**
@@ -22,14 +25,20 @@ public class FIRP0225 extends QCCatalogue {
         status.set("0");
         if (inputInfo.getFirstPageRecordDoc() != null && inputInfo.getFirstPageRecordDoc().getStructureMap() != null
                 && inputInfo.getLeaveHospitalDoc() != null && inputInfo.getLeaveHospitalDoc().getStructureMap() != null) {
-            Map<String, String> firstpageStructureMap = inputInfo.getFirstPageRecordDoc().getStructureMap();
+             Map<String, String> firstpageStructureMap = inputInfo.getFirstPageRecordDoc().getStructureMap();
             Map<String, String> leaveHospitalStructureMap = inputInfo.getLeaveHospitalDoc().getStructureMap();
             String firstDischargeTime = firstpageStructureMap.get(Content.dischargeTime);//病案首页出院时间
             String dischargeTime = leaveHospitalStructureMap.get(Content.dischargeTime);//出院小结出院时间
-            if (StringUtil.isBlank(firstDischargeTime) || StringUtil.isBlank(dischargeTime)){
+
+            Date firstDate = DateUtil.parseDate(firstDischargeTime,DateUtil.DATE_TIME_FORMAT); //将带字符串的YYYY-DD-MM HH:MM:SS 转成日期
+            Date dischargeDate = DateUtil.parseDateTime(dischargeTime,DateUtil.FORMAT_LONG_CN_MI);
+            String firstDatStr = DateUtil.format(firstDate, DateUtil.DATE_FORMAT);  //将对应的YYYY-MM-DD HH:MM:SS 日期转成对应的YYYY-MM-DD字符串
+            String dischargeDateStr = DateUtil.format(dischargeDate, DateUtil.DATE_FORMAT);
+
+            if (StringUtil.isBlank(firstDatStr) || StringUtil.isBlank(dischargeDateStr)){
                 return;
             }
-            if (!CatalogueUtil.equalsDate(firstDischargeTime, dischargeTime, "yyyy-MM-dd")) {
+            if (!CatalogueUtil.equalsDate(firstDatStr, dischargeDateStr, "yyyy-MM-dd")) {
                 status.set("-1");
             }
         }

+ 1 - 1
kernel/src/main/java/com/lantone/qc/kernel/catalogue/firstpagerecord/FIRP03213.java

@@ -70,7 +70,7 @@ public class FIRP03213 extends QCCatalogue {
         }
 
         for (String noMatchWord : noMatchWords) {
-            if (icdCode.contains(noMatchWord)) {
+            if (icdCode.equals(noMatchWord)) {
                 status.set("-1");
                 info.set(noMatchWord);
                 return;

+ 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;

+ 47 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/clinicalblood/CLI0306.java

@@ -0,0 +1,47 @@
+package com.lantone.qc.kernel.catalogue.hospital.ningbozhongyi.clinicalblood;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+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.ListUtil;
+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 : CLI0306
+ * @Description : 输血记录中无输血指征
+ * CRF缺少足够标注数据,使用规则判断输血原因是否有数字
+ * @Author : 楼辉荣
+ * @Date: 2020-03-06 17:28
+ */
+@Component
+public class CLI0306 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        List<ClinicalBloodDoc> clinicalBloodDocs = inputInfo.getClinicalBloodDocs();
+        if (ListUtil.isEmpty(clinicalBloodDocs)) {
+            status.set("0");
+            return;
+        }
+        if (clinicalBloodDocs != null && clinicalBloodDocs.size() > 0) {
+            for (ClinicalBloodDoc cliB : clinicalBloodDocs) {
+                Map<String, String> cliBStructureMap = cliB.getStructureMap();
+                if (cliBStructureMap.containsKey("病历内容")) {
+                    String bloodType = cliBStructureMap.get("病历内容");
+                    if (StringUtil.isNotBlank(bloodType)) {
+                        if (bloodType.contains("血常规")) {
+                            status.set("0");
+                            return;
+                        }
+                    }
+                }
+            }
+        } else {
+            status.set("0");
+        }
+    }
+}

+ 54 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/clinicalblood/CLI0307.java

@@ -0,0 +1,54 @@
+package com.lantone.qc.kernel.catalogue.hospital.ningbozhongyi.clinicalblood;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+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.ListUtil;
+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 : CLI0307
+ * @Description : 输血记录中无血液制品种类及量
+ * @Author : 楼辉荣
+ * @Date: 2020-03-06 17:28
+ */
+@Component
+public class CLI0307 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+
+        List<ClinicalBloodDoc> clinicalBloodDocs = inputInfo.getClinicalBloodDocs();
+        if (ListUtil.isEmpty(clinicalBloodDocs)) {
+            status.set("0");
+            return;
+        }
+        if (clinicalBloodDocs != null && clinicalBloodDocs.size() > 0) {
+            int matchSum = 0;
+            for (ClinicalBloodDoc cliB : clinicalBloodDocs) {
+                Map<String, String> cliBStructureMap = cliB.getStructureMap();
+                //台州
+                if (StringUtils.isNotEmpty(cliBStructureMap.get("输血计划"))) {
+                    matchSum++;
+                    continue;
+                }
+                if (cliBStructureMap.containsKey("病历内容")){
+                    String bloodType = cliBStructureMap.get("病历内容");
+                    if (StringUtil.isNotBlank(bloodType)) {
+                        if (bloodType.contains("今日予")) {
+                            matchSum++;
+                        }
+                    }
+                }
+            }
+            if (matchSum == clinicalBloodDocs.size()) {
+                status.set("0");
+            }
+        }
+
+    }
+}

+ 55 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/clinicalblood/CLI0308.java

@@ -0,0 +1,55 @@
+package com.lantone.qc.kernel.catalogue.hospital.ningbozhongyi.clinicalblood;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+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.ListUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : CLI0308
+ * @Description :  输血记录中未记录是否有不良反应
+ * @Author : 楼辉荣
+ * @Date: 2020-03-06 17:28
+ */
+@Component
+public class CLI0308 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        List<ClinicalBloodDoc> clinicalBloodDocs = inputInfo.getClinicalBloodDocs();
+        if (ListUtil.isEmpty(clinicalBloodDocs)) {
+            status.set("0");
+            return;
+        }
+
+        if (clinicalBloodDocs != null && clinicalBloodDocs.size() > 0) {
+            String regex = ".*(未.*|无.*|否.*).*(输血反应|不良反应).*";
+            for (ClinicalBloodDoc cliB : clinicalBloodDocs) {
+                Map<String, String> cliBStructureMap = cliB.getStructureMap();
+                if (StringUtils.isNotEmpty(cliBStructureMap.get("输注后效果评价")) && (cliBStructureMap.get("输注后效果评价").contains("不良反应")
+                        || cliBStructureMap.get("输注后效果评价").contains("不适") || cliBStructureMap.get("输注后效果评价").contains("未见"))) {
+                    status.set("0");
+                    break;
+                }
+
+                String infusion_process = cliBStructureMap.get("病历内容");
+                if (StringUtils.isNotEmpty(infusion_process)) {
+                    if (infusion_process.matches(regex) || infusion_process.contains("无") || infusion_process.contains("未见")
+                            || infusion_process.contains("未觉")) {
+                        status.set("0");
+                    } else {
+                        status.set("-1");
+                    }
+                }
+
+            }
+        } else {
+            status.set("0");
+        }
+    }
+}
+

+ 44 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/clinicalblood/CLI0562.java

@@ -0,0 +1,44 @@
+package com.lantone.qc.kernel.catalogue.hospital.ningbozhongyi.clinicalblood;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+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.ListUtil;
+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 : CLI0562
+ * @Description : 输血记录开始输血时间未填写
+ * @Author : 楼辉荣
+ * @Date: 2020-03-06 17:28
+ */
+@Component
+public class CLI0562 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        List<ClinicalBloodDoc> clinicalBloodDocs = inputInfo.getClinicalBloodDocs();
+        if(ListUtil.isEmpty(clinicalBloodDocs)){
+            return;
+        }
+
+        if (clinicalBloodDocs != null && clinicalBloodDocs.size() > 0) {
+            for (ClinicalBloodDoc cliB : clinicalBloodDocs) {
+                Map<String, String> cliBStructureMap = cliB.getStructureMap();
+                String start = cliBStructureMap.get("输注开始");
+                String record = cliBStructureMap.get("病历内容");
+                if(StringUtil.isNotBlank(start) || StringUtil.isNotBlank(cliBStructureMap.get("输血开始日期"))) break;
+                if (StringUtil.isBlank(start) && !record.contains("开始")) {
+                    status.set("-1");
+                    break;
+                }
+            }
+        }
+
+    }
+}

+ 46 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/clinicalblood/CLI0564.java

@@ -0,0 +1,46 @@
+package com.lantone.qc.kernel.catalogue.hospital.ningbozhongyi.clinicalblood;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+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.ListUtil;
+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 : CLI0564
+ * @Description : 输血记录输血结束时间未填写
+ * @Author : 楼辉荣
+ * @Date: 2020-03-06 17:28
+ */
+@Component
+public class CLI0564 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        List<ClinicalBloodDoc> clinicalBloodDocs = inputInfo.getClinicalBloodDocs();
+        if(ListUtil.isEmpty(clinicalBloodDocs)){
+            return;
+        }
+
+        if (clinicalBloodDocs != null && clinicalBloodDocs.size() > 0) {
+//            List<ClinicalBloodDoc> bloodDocs = clinicalBloodDocs.stream().filter(bloodDoc -> bloodDoc.getStructureMap().get("输血后效果评价") == null).collect(Collectors.toList());
+            for (ClinicalBloodDoc cliB : clinicalBloodDocs) {
+                Map<String, String> cliBStructureMap = cliB.getStructureMap();
+                String start = cliBStructureMap.get("输注结束");
+                String record = cliBStructureMap.get("病历内容");
+                if(StringUtil.isNotBlank(start) || StringUtil.isNotBlank(cliBStructureMap.get("输血结束日期"))) break;
+                if (StringUtil.isBlank(start) && !record.contains("输注结束")&& !record.contains("完毕")
+                        && !record.contains("输血结束")) {
+                    status.set("-1");
+                    break;
+                }
+            }
+        }
+
+    }
+}

+ 72 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/clinicalblood/CLI0569.java

@@ -0,0 +1,72 @@
+package com.lantone.qc.kernel.catalogue.hospital.ningbozhongyi.clinicalblood;
+
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+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.ListUtil;
+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;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @ClassName : CLI0569
+ * @Description :  输血记录血型未填写
+ * @Author : 楼辉荣
+ * @Date: 2020-03-06 17:28
+ */
+@Component
+public class CLI0569 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        List<ClinicalBloodDoc> clinicalBloodDocs = inputInfo.getClinicalBloodDocs();
+        if (ListUtil.isEmpty(clinicalBloodDocs)) {
+            return;
+        }
+        if (clinicalBloodDocs != null && clinicalBloodDocs.size() > 0) {
+            int matchSum = 0;
+            for (ClinicalBloodDoc cliB : clinicalBloodDocs) {
+                Map<String, String> cliBStructureMap = cliB.getStructureMap();
+                //台州
+                if (StringUtils.isNotEmpty(cliBStructureMap.get("血型"))) {
+                    matchSum++;
+                    continue;
+                }
+                String title = cliBStructureMap.get("标题");
+                if (StringUtil.isNotBlank(title) && title.contains("蛋白")){
+                    matchSum++;
+                    continue;
+                }
+                String record = cliBStructureMap.get("病历内容");
+                if (record.contains("A型") || record.contains("AB型") || record.contains("B型") || record.contains("O型")) {
+                    matchSum++;
+                    continue;
+                }
+                Pattern compile = Pattern.compile("[a-zA-Z]+型");
+                Matcher matcher = compile.matcher(StringUtil.removeBlank(cliBStructureMap.get("输注种类、血型、数量")));
+                if (matcher.find()) {
+                    matchSum++;
+                }
+                if (cliBStructureMap.containsKey("输注种类、血型、数量")) {
+                    String bloodType = cliBStructureMap.get("输注种类、血型、数量");
+                    if (StringUtils.isNotEmpty(bloodType) &&
+                            (bloodType.contains("白蛋白") || bloodType.contains("凝血酶原复合物")
+                                    || bloodType.contains("血浆"))) {
+                        matchSum++;
+                        continue;
+                    }
+                }
+            }
+            if (matchSum != clinicalBloodDocs.size()) {
+                status.set("-1");
+            }
+        }
+
+    }
+}

+ 218 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/operationdiscussion/OPE03111.java

@@ -0,0 +1,218 @@
+package com.lantone.qc.kernel.catalogue.hospital.ningbozhongyi.operationdiscussion;
+
+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.model.doc.DoctorAdviceDoc;
+import com.lantone.qc.pub.model.doc.FirstPageRecordDoc;
+import com.lantone.qc.pub.model.doc.PathologyShipDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationRecordDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @ClassName : OPE03111
+ * @Description: 手术病理检查存在手术记录中无病理相关记录
+ * @author: zh
+ * @time: 2021/04/06 11:22
+ */
+@Component
+public class OPE03111 extends QCCatalogue {
+
+    @Override
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo) throws ParseException {
+        status.set("0");
+        boolean blHz = false;
+        FirstPageRecordDoc firstPageRecordDoc = inputInfo.getFirstPageRecordDoc();
+        List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+        //是否包含手术记录
+        if(operationDocs==null || operationDocs.size()==0){
+            return;
+        }
+        if(operationDocs!=null) {
+            for (OperationDoc operationDoc : operationDocs) {
+                OperationRecordDoc operationRecordDoc = operationDoc.getOperationRecordDoc();
+                if (operationRecordDoc == null) {
+                    return;
+                }
+            }
+        }
+
+        //判断医嘱是否进行了病理检查
+        List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
+        if (ListUtil.isNotEmpty(doctorAdviceDocs)) {
+            for (DoctorAdviceDoc dad : doctorAdviceDocs) {
+                Map<String, String> dadStructureMap = dad.getStructureMap();
+                String daStatus = dadStructureMap.get(Content.doctorAdviceState);
+                String adviceType = dadStructureMap.get(Content.doctorAdviceType);
+                //取临时医嘱
+                if (StringUtil.isNotEmpty(adviceType) && adviceType.equals(Content.statOrder)) {
+                    if (StringUtil.isNotEmpty(daStatus)) {
+                        if (!Content.cancellationOrderList.contains(daStatus)) {
+                            String name = dadStructureMap.get(Content.medicalOrderName);
+                            if (bLStr(name)) {
+                                blHz = true;
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        //用首页或出院判断是否进行了病理检查
+        if(firstPageRecordDoc!=null){
+            String str = firstPageRecordDoc.getStructureMap().get("病理诊断费");
+            if ( !str.equals("0") && StringUtil.isNotEmpty(str)) {
+                double a = Double.parseDouble(str);
+                if ( a > Content.pathologicalFee) {
+                    blHz=true;
+                }
+            }
+        }
+        List<PathologyShipDoc> pathologyShipDocs = inputInfo.getPathologyShipDocs();
+        if(ListUtil.isNotEmpty(pathologyShipDocs)){
+            blHz=true;
+        }
+        //判断手术记录有无标本记录
+        if(blHz) {
+            status.set("-1");
+            if (operationDocs != null ) {
+                //有手术记录的情况下,手术记录中应该出现体现有标本
+                for (OperationDoc operationDoc : operationDocs) {
+                    String specimens = operationDoc.getOperationRecordDoc().getStructureMap().get("术中取病理标本");
+                    String pathological = operationDoc.getOperationRecordDoc().getStructureMap().get("病理检查");
+                    if(StringUtil.isNotEmpty(specimens)){
+                        if(specimens.equals("有")){
+                            status.set("0");
+                            return;
+                        }
+                        if(specimens.equals("无")){
+                            status.set("0");
+                            return;
+                        }
+                    }
+                    if (StringUtil.isNotEmpty(pathological)){
+                        if (pathological.equals("送")){
+                            status.set("0");
+                            continue;
+                        }
+                    }
+                    OperationRecordDoc operationRecordDoc = operationDoc.getOperationRecordDoc();
+                    if (operationRecordDoc != null) {
+                        String str = operationRecordDoc.getStructureMap().get("手术经过及处理");
+                        if (StringUtil.isNotEmpty(str)) {
+                            if (dateStr(str)) {
+                                status.set("0");
+                                return;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+    }
+
+    private boolean dateStr(String string){
+        if(StringUtil.isEmpty(string)){
+            return false;
+        }
+        boolean flag=false;
+        String str = Str(string);
+        String rex="[\\s\\S]*(?=流式)[\\s\\S]*";
+        String rex1="[\\s\\S]*(?=穿透)[^,;,;。]{0,7}(?=层)[\\s\\S]*";
+        String rex2="[\\s\\S]*(?=癌)[^,;,;。]{0,6}(?=浸润)[\\s\\S]*";
+        String rex3="[\\s\\S]*(?=分化)[\\s\\S]*";
+        String rex4="[\\s\\S]*(?=淋巴结)[^,;,;。]{0,8}(?=转移)[\\s\\S]*";
+        String rex5="[\\s\\S]*(?=浸润性)[^,;,;。]{0,8}(?=癌)[\\s\\S]*";
+        String rex6="[\\s\\S]*(?=突破)[^,;,;。]{0,7}(?=层)[\\s\\S]*";
+        List<String> surgeryPathologyList = Content.surgeryPathologyList;
+        for (String surgeryPathology : surgeryPathologyList) {
+            if(str.contains(surgeryPathology)){
+                flag=true;
+            }
+        }
+        if(flag || str.matches(rex1)|| str.matches(rex2)
+                ||str.matches(rex3)|| str.matches(rex4)||str.matches(rex5)|| str.matches(rex6)|| str.matches(rex)){
+            return true;
+        }
+        if(str.contains("冰冻")){
+            if(bdStr(str)){
+                return true;
+            }
+        }
+        return false;
+    }
+    private boolean bLStr(String string){
+        if(StringUtil.isEmpty(string)){
+            return false;
+        }
+        String str = Str(string);
+        List<String> doctorAdvicePathologyList = Content.doctorAdvicePathologyList;
+        for (String doctorAdvicePathology : doctorAdvicePathologyList) {
+            if(str.contains(doctorAdvicePathology)){
+                return true;
+            }
+        }
+        if(str.contains("冰冻")){
+            if(bdStr(str)){
+                return true;
+            }
+        }
+        return false;
+    }
+    //判断包含冰冻但不属于病理
+    private boolean bdStr(String str) {
+        ArrayList<String> blStrings = new ArrayList<>();
+        String rex1="[\\s\\S]{0,10}(?=冰冻)[\\s\\S]{0,10}";
+        Matcher matcher = Pattern.compile(rex1).matcher(str);
+        while (matcher.find()) {
+            String group = matcher.group();
+            blStrings.add(group);
+        }
+        List<String> notBLList = Content.notBDBLList;
+        if (ListUtil.isNotEmpty(blStrings)) {
+            for (String notBL : notBLList) {
+                for (int i = 0; i < blStrings.size(); i++) {
+                    String cfStr = blStrings.get(i);
+                    if (cfStr.contains(notBL)) {
+                        blStrings.remove(i);
+                        continue;
+                    }
+                }
+            }
+            if (blStrings.size() > 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private String Str(String str){
+        str = str.replaceAll("\\*", "\\\\*");
+        str = str.replaceAll("\\)", "\\\\)");
+        str = str.replaceAll("\\.", "\\\\.");
+        str = str.replaceAll("\\?", "\\\\?");
+        str = str.replaceAll("\\+", "\\\\+");
+        str = str.replaceAll("\\$", "\\\\$");
+        str = str.replaceAll("\\^", "\\\\^");
+        str = str.replaceAll("\\[", "\\\\[");
+        str = str.replaceAll("\\]", "\\\\]");
+        str = str.replaceAll("\\(", "\\\\(");
+        str = str.replaceAll("\\{", "\\\\{");
+        str = str.replaceAll("\\}", "\\\\}");
+        str = str.replaceAll("\\|", "\\\\|");
+        str = str.replaceAll("\\/", "\\\\/");
+        return str;
+    }
+}

+ 14 - 1
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/operationdiscussion/OPE0369.java

@@ -8,9 +8,11 @@ import com.lantone.qc.pub.model.doc.MedicalRecordInfoDoc;
 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.operation.PreoperativeDiscussionDoc;
 import com.lantone.qc.pub.util.DateUtil;
 import com.lantone.qc.pub.util.ListUtil;
 import com.lantone.qc.pub.util.StringUtil;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Component;
 
 import java.text.ParseException;
@@ -92,7 +94,18 @@ public class OPE0369 extends QCCatalogue {
                     }
                 }
             }
-
+            if (operationDocs!=null || operationDocs.size()>0){
+                PreoperativeDiscussionDoc preoperativeDiscussionDoc = operationDocs.get(0).getPreoperativeDiscussionDoc();
+                if(preoperativeDiscussionDoc != null){
+                    Map<String, String> structureMap = preoperativeDiscussionDoc.getStructureMap();
+                    String recTitle = structureMap.get("标题");
+                    if (StringUtils.isNotBlank(recTitle)){
+                        if (recTitle.contains("术前")) {
+                            return;
+                        }
+                    }
+                }
+            }
             ThreeLevelWardDoc threeLevelWardDoc = threeLevelWardDocs.get(0);
             List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDoc.getAllDoctorWradDocs();
             for (ThreeLevelWardDoc threeLevelWard : allDoctorWradDocs) {

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

@@ -34,7 +34,7 @@ public class PRE0328 extends QCCatalogue {
          * 3:如果手术记录次数(第一次手术的日期内有其他手术不算次数) 大于 术前讨论、术前小结次数,则出错
          */
         status.set("0");
-        List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
+       // List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
         List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
         if (operationDocs == null || operationDocs.size() == 0) {
             return;
@@ -48,9 +48,9 @@ public class PRE0328 extends QCCatalogue {
             String startTime = "";
             if (operationRecordDoc != null) {
                 startTime = operationRecordDoc.getStructureMap().get("手术开始时间");
-            }
-            if(StringUtil.isBlank(startTime)){
-                startTime = operationRecordDoc.getStructureMap().get("手术日期").replace(" 时","时");
+                if(StringUtil.isBlank(startTime)){
+                    startTime = operationRecordDoc.getStructureMap().get("手术日期").replace(" 时","时");
+                }
             }
             if (StringUtil.isNotBlank(startTime) && StringUtil.isNotBlank(admisTime) &&
                     StringUtil.parseDateTime(startTime) != null) {
@@ -77,18 +77,22 @@ public class PRE0328 extends QCCatalogue {
             }
         }
         //医嘱中包含“冠状动脉造影术”,且无术前讨论.则报规则
-        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("手术记录不一致");
-            }
-        }
+//        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) {
+//        if (i == 0 && i < j) {
+//            status.set("0");
+//            info.set("无手术记录");
+//        }
+        if (i != 0 && i > j){
             status.set("-1");
-            info.set("手术记录不一致");
+            info.set("手术次数和术前小结次数不一致");
         }
     }
 

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

@@ -51,7 +51,7 @@ 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("助手(一、二)");
@@ -80,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();
@@ -99,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)) {
@@ -122,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;

+ 17 - 4
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhongyi/threelevelward/THR03090.java

@@ -6,8 +6,10 @@ import com.lantone.qc.pub.model.OutputInfo;
 import com.lantone.qc.pub.model.doc.DoctorAdviceDoc;
 import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
 import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.model.doc.operation.PreoperativeDiscussionDoc;
 import com.lantone.qc.pub.util.DateUtil;
 import com.lantone.qc.pub.util.StringUtil;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Component;
 
 import java.util.List;
@@ -45,16 +47,27 @@ public class THR03090 extends QCCatalogue {
                 return;
             }
         }
-
+        if (operationDocs!=null || operationDocs.size()>0){
+            PreoperativeDiscussionDoc preoperativeDiscussionDoc = operationDocs.get(0).getPreoperativeDiscussionDoc();
+            if(preoperativeDiscussionDoc != null){
+                Map<String, String> structureMap = preoperativeDiscussionDoc.getStructureMap();
+                String recTitle = structureMap.get("标题");
+                if (StringUtils.isNotBlank(recTitle)){
+                    if (recTitle.contains("术前")) {
+                        return;
+                    }
+                }
+            }
+        }
         List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDocs.get(0).getAllDoctorWradDocs();
         for (ThreeLevelWardDoc threeLevelWard : allDoctorWradDocs) {
             Map<String, String> structureMap = threeLevelWard.getStructureMap();
             String makeTitle = structureMap.get("查房标题");
-            String writTitle = structureMap.get("文书标题");
+            String witeTitle = structureMap.get("文书标题");
             String makeDate = structureMap.get("查房日期");
             if (StringUtil.isNotBlank(makeDate) && StringUtil.parseDateTime(makeDate).before(StringUtil.parseDateTime(operationStartDate))) {
-                if (((StringUtil.isNotBlank(makeTitle) && makeTitle.contains("主刀")) || (StringUtil.isNotBlank(writTitle) && writTitle.contains("主刀"))
-                        || ((StringUtil.isNotBlank(makeTitle) && makeTitle.contains("术前")) || (StringUtil.isNotBlank(writTitle) && writTitle.contains("术前"))))) {
+                if (((StringUtil.isNotBlank(makeTitle) && makeTitle.contains("主刀")) || (StringUtil.isNotBlank(witeTitle) && witeTitle.contains("主刀"))
+                        || ((StringUtil.isNotBlank(makeTitle) && makeTitle.contains("术前")) || (StringUtil.isNotBlank(witeTitle) && witeTitle.contains("术前"))))) {
                     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;

+ 64 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/shengzhouyy/deathcasediscuss/DEAC03232.java

@@ -0,0 +1,64 @@
+package com.lantone.qc.kernel.catalogue.hospital.shengzhouyy.deathcasediscuss;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.DeathCaseDiscussDoc;
+import com.lantone.qc.pub.model.doc.LeaveHospitalDoc;
+import com.lantone.qc.pub.model.doc.MedicalRecordInfoDoc;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @ClassName : DEAC03232
+ * @Description: 死亡病例讨论记录内性别和基本信息不一致
+ * @author: wsy
+ * @time: 2022/5/18 15:15
+ */
+@Component
+public class DEAC03232 extends QCCatalogue {
+    /**
+     * 1.(死亡病例讨论记录)存在,查看文书结构化(性别)和文书内是否有包含(男性/女性/男/女/性别男/性别女),存在则统一提取出
+     * 2.获取住院信息表,查看性别和(死亡病例讨论记录)中提出的性别处理过同义词后是否一致,任一不一致则报出
+     * */
+    @Override
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        String gender = "";
+        MedicalRecordInfoDoc medicalRecordInfoDoc = inputInfo.getMedicalRecordInfoDoc();
+        DeathCaseDiscussDoc deathCaseDiscussDoc = inputInfo.getDeathCaseDiscussDoc();
+        if (medicalRecordInfoDoc == null || deathCaseDiscussDoc == null) {
+            return;
+        }
+        gender = medicalRecordInfoDoc.getStructureMap().get("sex");
+        if (StringUtil.isBlank(gender)) {
+            return;
+        }
+        Map<String, String> structureMap = deathCaseDiscussDoc.getStructureMap();
+        String firCGender = structureMap.get("性别");
+        String text = structureMap.get("原始文本");
+        if (gender.contains("男")) {
+            if (StringUtil.isNotBlank(firCGender) && firCGender.contains("女")) {
+                status.set("-1");
+                return;
+            }
+            if (StringUtil.isNotBlank(text) && text.contains("女")) {
+                status.set("-1");
+                return;
+            }
+        }
+
+        if (gender.contains("女")) {
+            if (StringUtil.isNotBlank(firCGender) && firCGender.contains("男")) {
+                status.set("-1");
+                return;
+            }
+            if (StringUtil.isNotBlank(text) && text.contains("男")) {
+                status.set("-1");
+                return;
+            }
+        }
+    }
+}

+ 64 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/shengzhouyy/deathrecord/DEAR03233.java

@@ -0,0 +1,64 @@
+package com.lantone.qc.kernel.catalogue.hospital.shengzhouyy.deathrecord;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.DeathCaseDiscussDoc;
+import com.lantone.qc.pub.model.doc.DeathRecordDoc;
+import com.lantone.qc.pub.model.doc.MedicalRecordInfoDoc;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @ClassName : DEAR03233
+ * @Description: 死亡记录内性别和基本信息不一致
+ * @author: wsy
+ * @time: 2022/5/18 15:15
+ */
+@Component
+public class DEAR03233 extends QCCatalogue {
+    /**
+     * 1.(死亡记录)存在,查看文书结构化(性别)和文书内是否有包含(男性/女性/男/女/性别男/性别女),存在则统一提取出
+     * 2.获取住院信息表,查看性别和(死亡记录)中提出的性别处理过同义词后是否一致,任一不一致则报出
+     * */
+    @Override
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        String gender = "";
+        MedicalRecordInfoDoc medicalRecordInfoDoc = inputInfo.getMedicalRecordInfoDoc();
+        DeathRecordDoc deathRecordDoc = inputInfo.getDeathRecordDoc();
+        if (medicalRecordInfoDoc == null || deathRecordDoc == null) {
+            return;
+        }
+        gender = medicalRecordInfoDoc.getStructureMap().get("sex");
+        if (StringUtil.isBlank(gender)) {
+            return;
+        }
+        Map<String, String> structureMap = deathRecordDoc.getStructureMap();
+        String firCGender = structureMap.get("性别");
+        String text = structureMap.get("原始文本");
+        if (gender.contains("男")) {
+            if (StringUtil.isNotBlank(firCGender) && firCGender.contains("女")) {
+                status.set("-1");
+                return;
+            }
+            if (StringUtil.isNotBlank(text) && text.contains("女")) {
+                status.set("-1");
+                return;
+            }
+        }
+
+        if (gender.contains("女")) {
+            if (StringUtil.isNotBlank(firCGender) && firCGender.contains("男")) {
+                status.set("-1");
+                return;
+            }
+            if (StringUtil.isNotBlank(text) && text.contains("男")) {
+                status.set("-1");
+                return;
+            }
+        }
+    }
+}

+ 66 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/shengzhouyy/firstcourserecord/FIRC03086.java

@@ -0,0 +1,66 @@
+package com.lantone.qc.kernel.catalogue.hospital.shengzhouyy.firstcourserecord;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.FirstCourseRecordDoc;
+import com.lantone.qc.pub.model.label.TreatPlanLabel;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @ClassName : FIRC03086
+ * @Description : 治疗措施不具体(缺护理级别)
+ * @Author : wsy
+ * @Date: 2021-01-07 15:21
+ */
+@Component
+public class FIRC03086 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
+        if (firstCourseRecordDoc == null) {
+            status.set("0");
+            return;
+        }
+        TreatPlanLabel treatPlanLabel = firstCourseRecordDoc.getTreatPlanLabel();
+        if (treatPlanLabel == null) {
+            status.set("0");
+            return;
+        }
+        String text = treatPlanLabel.getText();
+        boolean findText = false;
+        if (StringUtil.isNotBlank(text) && text.contains("护理")) {
+            findText = true;
+        }
+        Map<String, String> structureMap = firstCourseRecordDoc.getStructureMap();
+        String structureV = structureMap.get("诊疗计划");
+        if (StringUtil.isBlank(structureV) && StringUtil.isBlank(text)) {
+            status.set("0");
+            return;
+        }
+        //规则匹配增加
+        if (structureV.contains("一级") || structureV.contains("二级") || structureV.contains("三级") ||
+                structureV.contains("Ⅰ级") || structureV.contains("Ⅱ级") || structureV.contains("Ⅲ级") ||
+                structureV.contains("I级") || structureV.contains("II级") || structureV.contains("III级") ||
+                structureV.contains("I护") || structureV.contains("II护") || structureV.contains("III护") ||
+                structureV.contains("Ⅰ护") || structureV.contains("Ⅱ护") || structureV.contains("Ⅲ护")) {
+            status.set("0");
+            return;
+        }
+        if (StringUtil.isNotBlank(structureV) && structureV.contains("护理")) {
+            findText = true;
+        }
+        if (treatPlanLabel.getNursingLevel() != null) {
+            if (findText && !"护理常规".equals(treatPlanLabel.getNursingLevel().getName())) {
+                status.set("0");
+                return;
+            }
+        }
+        if (treatPlanLabel.getNursingLevel() == null || "护理常规".equals(treatPlanLabel.getNursingLevel().getName())) {
+            status.set("-1");
+            return;
+        }
+    }
+}

+ 62 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/shengzhouyy/firstcourserecord/FIRC03230.java

@@ -0,0 +1,62 @@
+package com.lantone.qc.kernel.catalogue.hospital.shengzhouyy.firstcourserecord;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.FirstCourseRecordDoc;
+import com.lantone.qc.pub.model.doc.MedicalRecordInfoDoc;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @ClassName : FIRC03230
+ * @Description : 首次病程录内性别和基本信息不一致
+ * @Author : wangsy
+ * @Date: 2022-05-18 17:28
+ */
+@Component
+public class FIRC03230 extends QCCatalogue {
+    /**
+     * 1.首次病程录存在,查看文书结构化(性别)和文书内是否有包含(男性/女性/男/女/性别男/性别女),存在则统一提取出
+     * 2.获取住院信息表,查看性别和首次病程录中提出的性别处理过同义词后是否一致,任一不一致则报出
+     */
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        String gender = "";
+        MedicalRecordInfoDoc medicalRecordInfoDoc = inputInfo.getMedicalRecordInfoDoc();
+        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
+        if (medicalRecordInfoDoc == null || firstCourseRecordDoc == null) {
+            return;
+        }
+        gender = medicalRecordInfoDoc.getStructureMap().get("sex");
+        if (StringUtil.isBlank(gender)) {
+            return;
+        }
+        Map<String, String> structureMap = firstCourseRecordDoc.getStructureMap();
+        String firCGender = structureMap.get("性别");
+        String text = structureMap.get("原始文本");
+        if (gender.contains("男")) {
+            if (StringUtil.isNotBlank(firCGender) && firCGender.contains("女")) {
+                status.set("-1");
+                return;
+            }
+            if (StringUtil.isNotBlank(text) && text.contains("女")) {
+                status.set("-1");
+                return;
+            }
+        }
+
+        if (gender.contains("女")) {
+            if (StringUtil.isNotBlank(firCGender) && firCGender.contains("男")) {
+                status.set("-1");
+                return;
+            }
+            if (StringUtil.isNotBlank(text) && text.contains("男")) {
+                status.set("-1");
+                return;
+            }
+        }
+    }
+}

+ 63 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/shengzhouyy/leavehospital/LEA03231.java

@@ -0,0 +1,63 @@
+package com.lantone.qc.kernel.catalogue.hospital.shengzhouyy.leavehospital;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.LeaveHospitalDoc;
+import com.lantone.qc.pub.model.doc.MedicalRecordInfoDoc;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @ClassName : LEA03231
+ * @Description: 出院记录内性别和基本信息不一致
+ * @author: wsy
+ * @time: 2022/5/18 15:15
+ */
+@Component
+public class LEA03231 extends QCCatalogue {
+    /**
+     * 1.(出院存小结/出院记录)存在,查看文书结构化(性别)和文书内是否有包含(男性/女性/男/女/性别男/性别女),存在则统一提取出
+     * 2.获取住院信息表,查看性别和(出院存小结/出院记录)中提出的性别处理过同义词后是否一致,任一不一致则报出
+     * */
+    @Override
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        String gender = "";
+        MedicalRecordInfoDoc medicalRecordInfoDoc = inputInfo.getMedicalRecordInfoDoc();
+        LeaveHospitalDoc leaveHospitalDoc = inputInfo.getLeaveHospitalDoc();
+        if (medicalRecordInfoDoc == null || leaveHospitalDoc == null) {
+            return;
+        }
+        gender = medicalRecordInfoDoc.getStructureMap().get("sex");
+        if (StringUtil.isBlank(gender)) {
+            return;
+        }
+        Map<String, String> structureMap = leaveHospitalDoc.getStructureMap();
+        String firCGender = structureMap.get("性别");
+        String text = structureMap.get("原始文本");
+        if (gender.contains("男")) {
+            if (StringUtil.isNotBlank(firCGender) && firCGender.contains("女")) {
+                status.set("-1");
+                return;
+            }
+            if (StringUtil.isNotBlank(text) && text.contains("女")) {
+                status.set("-1");
+                return;
+            }
+        }
+
+        if (gender.contains("女")) {
+            if (StringUtil.isNotBlank(firCGender) && firCGender.contains("男")) {
+                status.set("-1");
+                return;
+            }
+            if (StringUtil.isNotBlank(text) && text.contains("男")) {
+                status.set("-1");
+                return;
+            }
+        }
+    }
+}

+ 264 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/behospitalized/BEH02980.java

@@ -0,0 +1,264 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.behospitalized;
+
+import com.alibaba.fastjson.JSONArray;
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.client.ChiefPresentSimilarityServiceClient;
+import com.lantone.qc.kernel.structure.ai.ModelAI;
+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.entity.Allergy;
+import com.lantone.qc.pub.model.entity.Diag;
+import com.lantone.qc.pub.model.entity.GeneralDesc;
+import com.lantone.qc.pub.model.entity.Negative;
+import com.lantone.qc.pub.model.label.DiagLabel;
+import com.lantone.qc.pub.model.label.PastLabel;
+import com.lantone.qc.pub.model.label.PresentLabel;
+import com.lantone.qc.pub.util.StringUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * @ClassName : BEH02980
+ * @Description : 病历前后描述不一致
+ * @Author : Mark
+ * @Date: 2020-06-23 11:02
+ */
+@Component
+public class BEH02980 extends QCCatalogue {
+    @Autowired
+    ChiefPresentSimilarityServiceClient chiefPresentSimilarityServiceClient;
+
+    private List<String> containList = Arrays.asList("脑萎缩", "慢性", "纤颤", "高血压", "糖尿", "冠状", "冠心病", "支架", "起搏器", "房颤", "风湿");
+    private List<String> filterList = Arrays.asList("心脏病", "低血糖", "急性", ";");
+
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        if (inputInfo.getBeHospitalizedDoc() == null) {
+            return;
+        }
+        PresentLabel presentLabel = inputInfo.getBeHospitalizedDoc().getPresentLabel();
+        DiagLabel initialDiagLabel = inputInfo.getBeHospitalizedDoc().getInitialDiagLabel();
+        PastLabel pastLabel = inputInfo.getBeHospitalizedDoc().getPastLabel();
+
+        List<String> pos_diags = new ArrayList<>();
+        List<String> neg_diags = new ArrayList<>();
+        //现病史需要取一般情况之后疾病
+        if (presentLabel != null) {
+            List<GeneralDesc> generals = presentLabel.getGenerals();
+            if (generals.size() > 0) {
+                String presentText = presentLabel.getText();
+                List<Diag> presentDiags = presentLabel.getDiags();
+                /* 取现病史中一般情况之后的疾病名称 */
+                if (StringUtil.isNotBlank(presentText) && presentDiags.size() > 0) {
+                    String lastGeneral = generals.get(generals.size() - 1).getName();
+                    int lastGeneralIndex = presentText.indexOf(lastGeneral);
+                    for (Diag presentDiag : presentDiags) {
+                        if (presentDiag.getNegative() != null || presentDiag.getHospitalDiagName().contains("否认")) {
+                            continue;
+                        }
+                        /* 现病史中一般情况之后的疾病名称 */
+                        if (presentText.indexOf(presentDiag.getHospitalDiagName()) > lastGeneralIndex) {
+                            if (isContains(presentDiag.getHospitalDiagName()) && !isFilter(presentDiag.getHospitalDiagName())) {
+                                String dgname = presentDiag.getHospitalDiagName();
+                                if (presentDiag.getNegative() == null) {
+                                    if (!pos_diags.contains(dgname)) {
+                                        pos_diags.add(dgname);
+                                    }
+                                } else {
+                                    if (!neg_diags.contains(dgname)) {
+                                        neg_diags.add(dgname);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (pastLabel != null && StringUtils.isNotEmpty(pastLabel.getText())) {
+            extract_diags(pastLabel.getDiags(), pos_diags, neg_diags);
+            //否认其他的情况
+            String pasttext = pastLabel.getText();
+            //冠状动脉支架植入术特殊情况,只要出现,就从否认的史中去掉
+            if (neg_diags.contains("冠状动脉支架植入术")) {
+                neg_diags.remove("冠状动脉支架植入术");
+            }
+            String neg_diags_first[] = pasttext.split("否认");
+            for (String str1 : neg_diags_first) {
+                String neg_diags_second[] = str1.split("、");
+                for (String str2 : neg_diags_second) {
+                    for (String neg_diag : neg_diags) {
+                        if (str2.contains(neg_diag)) {
+                            String str3 = str2.substring(0, str2.indexOf(neg_diag));
+                            if (str3.contains("其它") || str3.contains("其他")) {
+                                int index = neg_diags.indexOf(neg_diag);
+                                neg_diags.set(index, "其它的");
+                            }
+                        }
+                    }
+                }
+            }
+//            //过敏史
+//            if(!"7".equals(Content.hospital_Id))
+//            {
+//                extract_Allergy(pastLabel.getAllergies(), pos_diags, neg_diags, pastLabel.getText());
+//            }
+        } else {
+            //例如邵逸夫 台州这种结构化数据,判断高血压 和 糖尿病是否有冲突
+            List<Diag> pastDiags = new ArrayList<>();
+            Map<String, String> structureMap = inputInfo.getBeHospitalizedDoc().getStructureMap();
+            String a1 = structureMap.get("高血压");
+            Diag diag = new Diag();
+            diag.setName("高血压");
+            diag.setHospitalDiagName("高血压");
+            if (StringUtils.isNotEmpty(a1) && "否认".equals(a1)) {
+                Negative negative = new Negative();
+                negative.setName("否认");
+                pastDiags.add(diag);
+            } else if (StringUtils.isNotEmpty(a1) && !"否认".equals(a1)) {
+                pastDiags.add(diag);
+            }
+
+            a1 = structureMap.get("糖尿病");
+            diag = new Diag();
+            diag.setName("糖尿病");
+            diag.setHospitalDiagName("糖尿病");
+            if (StringUtils.isNotEmpty(a1) && "否认".equals(a1)) {
+                Negative negative = new Negative();
+                negative.setName("否认");
+                pastDiags.add(diag);
+            } else if (StringUtils.isNotEmpty(a1) && !"否认".equals(a1)) {
+                pastDiags.add(diag);
+            }
+
+            extract_diags(pastDiags, pos_diags, neg_diags);
+        }
+        if (initialDiagLabel != null) {
+            extract_diags(initialDiagLabel.getDiags(), pos_diags, neg_diags);
+        }
+
+        String infoStr = "";
+        int matchSum = 0;
+        ModelAI modelAI = new ModelAI();
+        for (String negdiag : neg_diags) {
+            JSONArray jsonArray = modelAI.loadChiefPresentSimilarAI(negdiag, pos_diags, false
+                    , "diagnose", chiefPresentSimilarityServiceClient);
+            if (jsonArray.size() == 2) {
+                /* 相似度最高症状 */
+                String dgname = jsonArray.getString(0);
+                if ("糖尿病".equals(negdiag) && "妊娠期糖尿病".equals(dgname)) {
+                    continue;
+                }
+                if ("高血压史".equals(negdiag) && "高血压病".equals(dgname)) {
+                    matchSum++;
+                    if (StringUtils.isEmpty(infoStr)) {
+                        infoStr = negdiag;
+                    } else {
+                        infoStr = infoStr + "," + negdiag;
+                    }
+                    continue;
+                }
+                /* 相似度分数 */
+                double likeRate = jsonArray.getDoubleValue(1);
+                if (likeRate > 0.99) {
+                    matchSum++;
+                    if (StringUtils.isEmpty(infoStr)) {
+                        infoStr = negdiag;
+                    } else {
+                        infoStr = infoStr + "," + negdiag;
+                    }
+                    continue;
+                }
+            }
+        }
+        if (matchSum > 0) {
+            status.set("-1");
+            info.set(infoStr);
+        }
+
+    }
+
+    //疾病史
+    private List<String> extract_diags(List<Diag> diags, List<String> pos_diags, List<String> neg_diags) {
+        List<String> dgs = new ArrayList<>();
+        for (Diag dg : diags) {
+            String dgname = dg.getHospitalDiagName();
+            if (dg.getNegative() == null) {
+                if (!pos_diags.contains(dgname)) {
+                    pos_diags.add(dgname);
+                }
+            } else {
+                if (!neg_diags.contains(dgname)) {
+                    neg_diags.add(dgname);
+                    dgs.add(dgname);
+                }
+            }
+        }
+        return dgs;
+    }
+
+//    //过敏史
+//    private List<String> extract_Allergy(List<Allergy> allergys, List<String> pos_diags, List<String> neg_diags, String text) {
+//        List<String> dgs = new ArrayList<>();
+//        String content = text;
+//        int allergyNum = 0;
+//        for (Allergy dg : allergys) {
+//            String dgname = dg.getName();
+//            if (dg.getNegative() == null) {
+//                if (!pos_diags.contains(dgname)) {
+//                    pos_diags.add(dgname);
+//                }
+//                if (dg.getAllergyFood() != null) {
+//                    allergyNum = 1;
+//                }
+//                if (dg.getAllergyMedicine() != null) {
+//                    allergyNum = 2;
+//                }
+//            } else {
+//                int index = content.lastIndexOf(dgname);
+//                text = content.substring(Math.max(0, index - 10), index);
+//                if (allergyNum == 0 && !neg_diags.contains(dgname) && !text.contains("其他") && !text.contains("其它") && !text.contains("其余")) {
+//                    neg_diags.add(dgname);
+//                    dgs.add(dgname);
+//                }
+//                if (allergyNum == 1 && text.contains("食物") && !neg_diags.contains(dgname) && !text.contains("其他") && !text.contains("其它") && !text.contains("其余")) {
+//                    neg_diags.add(dgname);
+//                    dgs.add(dgname);
+//                }
+//                if (allergyNum == 2 && text.contains("药物") && !neg_diags.contains(dgname) && !text.contains("其他") && !text.contains("其它") && !text.contains("其余")) {
+//                    neg_diags.add(dgname);
+//                    dgs.add(dgname);
+//                }
+//            }
+//        }
+//        return dgs;
+//    }
+
+    private boolean isContains(String diagName) {
+        for (String c : containList) {
+            if (diagName.contains(c)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isFilter(String diagName) {
+        for (String c : filterList) {
+            if (diagName.contains(c)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}

+ 48 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/clinicalblood/CLI0308.java

@@ -0,0 +1,48 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.clinicalblood;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+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.ListUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : CLI0308
+ * @Description :  输血记录中未记录是否有不良反应
+ * @Author : 贺聪聪
+ * @Date: 2022-05-23 15:10
+ */
+@Component
+public class CLI0308 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        List<ClinicalBloodDoc> clinicalBloodDocs = inputInfo.getClinicalBloodDocs();//输血/血制品病程记录
+        if (ListUtil.isEmpty(clinicalBloodDocs)) {
+            status.set("0");
+            return;
+        }
+
+        if (clinicalBloodDocs != null && clinicalBloodDocs.size() > 0) {
+             String regex = ".*(未.*|无.*|否.*).*(输血反应|不良反应).*";
+            for (ClinicalBloodDoc cliB : clinicalBloodDocs) {
+                Map<String, String> cliBStructureMap = cliB.getStructureMap();
+                if(StringUtils.isNotEmpty(cliBStructureMap.get("病历内容")) && (cliBStructureMap.get("病历内容").contains("不良反应")
+                        || cliBStructureMap.get("病历内容").contains("不适") || cliBStructureMap.get("病历内容").contains("未见")
+                        || cliBStructureMap.get("病历内容").contains("未觉") || cliBStructureMap.get("病历内容").contains("不良")
+                        || cliBStructureMap.get("病历内容").contains(regex))){
+                    status.set("0");
+                    break;
+                }else {
+                    status.set("-1");
+                }
+            }
+        } else {
+            status.set("0");
+        }
+
+    }
+}

+ 42 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/clinicalblood/CLI0568.java

@@ -0,0 +1,42 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.clinicalblood;
+
+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.model.doc.ClinicalBloodDoc;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : CLI0568
+ * @Description :  输血记录输血记录时间未填写
+ * @Author : 贺聪聪
+ * @Date: 2022-05-20 13:28
+ */
+@Component
+public class CLI0568 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        List<ClinicalBloodDoc> clinicalBloodDocs = inputInfo.getClinicalBloodDocs();//输血/血制品病程记录
+
+        if(clinicalBloodDocs != null && clinicalBloodDocs.size()>0){
+            for (ClinicalBloodDoc cliB:clinicalBloodDocs) {
+                Map<String, String> cliBStructureMap = cliB.getStructureMap();
+                if(cliBStructureMap.containsKey("病历日期")){
+                    if(StringUtils.isEmpty(cliBStructureMap.get("病历日期"))){
+                        status.set("-1");
+                        break;
+                    }
+                }else {
+                    status.set("-1");
+                    break;
+                }
+            }
+        }
+
+    }
+}

+ 29 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/deathcasediscuss/DEAC0556.java

@@ -0,0 +1,29 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.deathcasediscuss;
+
+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 org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @ClassName : DEAC0556
+ * @Description :  死亡病例讨论参加人员姓名及职称未填写
+ * @Author :kwz
+ * @Date: 2020-03-18 18:38
+ */
+@Component
+public class DEAC0556 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        if (inputInfo.getDeathCaseDiscussDoc() != null) {
+            Map<String, String> deathCaseDiscussStructureMap = inputInfo.getDeathCaseDiscussDoc().getStructureMap();
+            String deathTime = deathCaseDiscussStructureMap.get("参加人员姓名及专业技术职称");
+            if (CatalogueUtil.isEmpty(deathTime)) {
+                status.set("-1");
+            }
+        }
+    }
+}

+ 29 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/deathcasediscuss/DEAC0558.java

@@ -0,0 +1,29 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.deathcasediscuss;
+
+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 org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @ClassName : DEAC0558
+ * @Description :  死亡病例讨论无主持人小结意见
+ * @Author :kwz
+ * @Date: 2020-03-18 18:38
+ */
+@Component
+public class DEAC0558 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        if (inputInfo.getDeathCaseDiscussDoc() != null) {
+            Map<String, String> deathCaseDiscussStructureMap = inputInfo.getDeathCaseDiscussDoc().getStructureMap();
+            String deathTime = deathCaseDiscussStructureMap.get("主持人小结意见");
+            if (CatalogueUtil.isEmpty(deathTime)) {
+                status.set("-1");
+            }
+        }
+    }
+}

+ 92 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/firstcourserecord/FIRC0087.java

@@ -0,0 +1,92 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.firstcourserecord;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.client.ChiefPresentSimilarityServiceClient;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.FirstCourseRecordDoc;
+import com.lantone.qc.pub.model.label.CaseCharacteristicLabel;
+import com.lantone.qc.pub.model.label.DiagLabel;
+import com.lantone.qc.pub.util.StringUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @ClassName : FIRC0087
+ * @Description : 无鉴别诊断
+ * @Author : 楼辉荣
+ * @Date: 2020-03-06 17:28
+ */
+@Component
+public class FIRC0087 extends QCCatalogue {
+    @Autowired
+    ChiefPresentSimilarityServiceClient chiefPresentSimilarityServiceClient;
+
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
+        if (firstCourseRecordDoc != null) {
+            DiagLabel differentialDiagLabel = firstCourseRecordDoc.getDifferentialDiagLabel();
+            CaseCharacteristicLabel casecharLabel = firstCourseRecordDoc.getCaseCharacteristicLabel();
+            DiagLabel initDiagLabel = firstCourseRecordDoc.getInitialDiagLabel();
+            Map<String, String> structureMap = firstCourseRecordDoc.getStructureMap();
+            //若拟诊讨论中记录鉴别诊断,则返回
+            String exToDiscuss = structureMap.get("拟诊讨论");
+            if (StringUtil.isNotBlank(exToDiscuss) && exToDiscuss.contains("鉴别诊断")) {
+                return;
+            }
+            if (differentialDiagLabel != null) {
+                String diffDiagStruct = structureMap.get("鉴别诊断");
+                if (StringUtils.isNotEmpty(diffDiagStruct)) {
+                    return;
+                }
+                /*if (StringUtil.isNotBlank(diffDiagStruct) && (diffDiagStruct.contains("诊断明确") || diffDiagStruct.contains("无需鉴别")
+                        || diffDiagStruct.contains("明确诊断"))) {
+                    return;
+                }*/
+
+                //List<Diag> diags = differentialDiagLabel.getDiags();
+                if (initDiagLabel.getDiags().size() > 0) {
+                    String diag = initDiagLabel.getDiags().get(0).getHospitalDiagName();
+                    String casechar = casecharLabel.getText();
+                    String chief = "";
+                    String present = "";
+                    if (casechar.contains("主诉") && casechar.contains("现病史")) {
+                        chief = casechar.substring(casechar.indexOf("主诉") + 2, casechar.indexOf("现病史"));
+                        present = casechar.substring(casechar.indexOf("现病史") + 3, casechar.indexOf("既往史"));
+                    }
+                    if (StringUtils.isNotEmpty(differentialDiagLabel.getText())) {
+                        if (differentialDiagLabel.getText().contains("诊断明确")
+                                || differentialDiagLabel.getText().contains("无需鉴别")) {
+                            if (chief.contains("术后") || chief.contains("孕") || chief.contains("化疗")
+                                    || chief.contains("肿瘤") || chief.contains("癌") || chief.contains("确诊")
+                                    || chief.contains("外伤") || chief.contains("摔伤")) {
+                                status.set("0");
+                            } else if (present.contains(diag)) {
+                                status.set("0");
+                            } else {
+                                status.set("-1");
+                            }
+                        }
+                    } else if (StringUtils.isEmpty(differentialDiagLabel.getText())) {
+                        status.set("-1");
+                    }
+                /*
+                if(diags == null || diags.size()<1){
+                    status.set("-1");
+                }
+
+                if (StringUtils.isNotEmpty(differentialDiagLabel.getText())
+                        && (differentialDiagLabel.getText().contains("暂缺")
+                            || differentialDiagLabel.getText().contains("无") || differentialDiagLabel.getText().contains("诊断"))) {
+                    status.set("0");
+                }
+                */
+                }
+            }
+        }
+    }
+}

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

@@ -0,0 +1,132 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.firstpagerecord;
+
+import com.alibaba.fastjson.JSONArray;
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.client.ChiefPresentSimilarityServiceClient;
+import com.lantone.qc.kernel.client.SimilarityServiceClient;
+import com.lantone.qc.kernel.structure.ai.ModelAI;
+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.entity.Lis;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : FIRP0178
+ * @Description :出院其他诊断不完全
+ * @Author : 贺聪聪
+ * @Date: 2022-05-12 9:44
+ */
+@Component
+public class FIRP0178 extends QCCatalogue {
+    @Autowired
+    SimilarityServiceClient similarityServiceClient;
+    @Autowired
+    ChiefPresentSimilarityServiceClient chiefPresentSimilarityServiceClient;
+
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        if (inputInfo.getFirstPageRecordDoc() != null && inputInfo.getLeaveHospitalDoc() != null) {
+            String mainDiagnosis = "";
+            Map<String, Object> firstpageStructureMap = inputInfo.getFirstPageRecordDoc().getStructureExtMap();
+            List<Map<String, String>> dischargeDiag = (List) firstpageStructureMap.get(Content.dischargeDiag);
+            if (ListUtil.isEmpty(dischargeDiag)) {
+                return;
+            }
+            if (dischargeDiag.get(0) != null) {
+                mainDiagnosis = dischargeDiag.get(0).get("诊断名称");
+            }
+
+            /* 病案首页出院小结诊断 除去主诊断*/
+            List<String> firstpageLeaveDiags = getFirstPageDiag(dischargeDiag);
+            if (ListUtil.isEmpty(firstpageLeaveDiags)) {
+                return;
+            }
+
+            //出院小结得出院诊断,模型提取出现问题,需要手动以1.2.3.为界限切开
+            Map<String, String> leavehospitalStructureMap = inputInfo.getLeaveHospitalDoc().getStructureMap();
+
+            String leaveStr = leavehospitalStructureMap.get("出院诊断");
+            //出院小结诊断 除去中医出院诊断
+            if (StringUtil.isNotBlank(leaveStr)) {
+                leaveStr = leaveStr.substring(Math.max(0, leaveStr.indexOf("西医诊断")));
+            }
+            List<String> leaveDiagsStr = cut(leaveStr, mainDiagnosis);
+
+            /* 修改为疾病相似度模型 */
+            ModelAI modelAI = new ModelAI();
+            String infoStr = "";
+            //最主要是给医生提醒,看是否有出院诊断漏写
+            for (int i = 1; i < leaveDiagsStr.size(); i++) {
+                JSONArray jsonArray = modelAI.loadChiefPresentSimilarAI(leaveDiagsStr.get(i), firstpageLeaveDiags, false
+                        , "diagnose", chiefPresentSimilarityServiceClient);
+                if (jsonArray.size() == 2) {
+                    /* 相似度分数 */
+                    double likeRate = jsonArray.getDoubleValue(1);
+                    if (likeRate < 0.9) {
+                        infoStr = CatalogueUtil.concatInfo(infoStr, leaveDiagsStr.get(i));
+                    }
+                } else if (jsonArray.size() == 0) {
+                    infoStr = CatalogueUtil.concatInfo(infoStr, leaveDiagsStr.get(i));
+                }
+            }
+            if (StringUtil.isNotBlank(infoStr)) {
+                status.set("-1");
+                info.set(infoStr);
+            }
+        }
+    }
+
+    //除去首页中的主诊断方法、中医出院诊断、去掉西医字段
+    private List<String> getFirstPageDiag(List<Map<String, String>> dischargeDiag) {
+        List<String> firstpageDiag = new ArrayList<>();
+        for (int i = 0; i < dischargeDiag.size(); i++) {
+            if ("主要诊断".equals(dischargeDiag.get(i).get("诊断类别")) || "主病".equals(dischargeDiag.get(i).get("诊断类别"))
+                    || "主症".equals(dischargeDiag.get(i).get("诊断类别"))) {
+                continue;
+            }
+            String diagnoseName = dischargeDiag.get(i).get(Content.diagnoseName);
+            if (StringUtil.isBlank(diagnoseName) || "-".equals(diagnoseName)) { // 诊断名称为空不算
+                continue;
+            }
+            //删除诊断名称中带有西医
+            diagnoseName = diagnoseName.replace("(西医)", "");
+            if (StringUtil.isNotBlank(diagnoseName)) {
+                firstpageDiag.add(diagnoseName);
+            }
+            // 去重
+            if (!firstpageDiag.contains(diagnoseName)) {
+                firstpageDiag.add(diagnoseName);
+            }
+        }
+        return firstpageDiag;
+    }
+
+    private List<String> cut(String leaveDiag, String mainDiagnosis) {
+        List<String> diags = new ArrayList<>();
+        if (leaveDiag != null) {
+            String[] leaveDiags = leaveDiag.split(",?,?[0-9]\\.");
+            for (String string : leaveDiags) {
+                if (!string.isEmpty()) {
+                    if (string.equals(mainDiagnosis)) {
+                        diags.add(0, string);
+                    } else {
+                        // 去重
+                        if (!diags.contains(string)) {
+                            diags.add(string);
+                        }
+                    }
+                }
+            }
+        }
+        return diags;
+    }
+}

+ 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");
+        }
+    }
+}

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

@@ -0,0 +1,45 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.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.Date;
+import java.util.Map;
+
+/**
+ * @ClassName : FIRP0220
+ * @Description : 入院时间与入院记录时间不一致
+ * @Author : 胡敬
+ * @Date: 2020-03-14 17:10
+ */
+@Component
+public class FIRP0220 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        if (inputInfo.getFirstPageRecordDoc() == null || inputInfo.getBeHospitalizedDoc() == null) {
+            status.set("0");
+            return;
+        }
+        Map<String, String> firstpageStructureMap = inputInfo.getFirstPageRecordDoc().getStructureMap();
+        Map<String, String> beHospitalStructureMap = inputInfo.getBeHospitalizedDoc().getStructureMap();
+        String firstAdmissionDate = firstpageStructureMap.get(Content.admisTime);
+        String admissionDate = beHospitalStructureMap.get(Content.admisDate);
+        if (StringUtil.isEmpty(firstAdmissionDate) || StringUtil.isEmpty(admissionDate)) {
+            status.set("0");
+            return;
+        }
+        String[] dateFormats = new String[]{"yyyy年MM月dd日HH时mm分ss", "yyyy年MM月dd日HH时mm分","yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm"};
+        Date firstDate = StringUtil.parseDateTime(firstAdmissionDate);
+        Date admisDate = StringUtil.parseDateTime(admissionDate, dateFormats);
+        if (firstDate != null && admisDate != null) {
+            if (firstDate.getYear() == admisDate.getYear() &&
+                    firstDate.getMonth() == admisDate.getMonth() &&
+                    firstDate.getDay() == admisDate.getDay()) {
+                status.set("0");
+            }
+        }
+    }
+}

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

@@ -0,0 +1,39 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.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.model.doc.BeHospitalizedDoc;
+import com.lantone.qc.pub.model.doc.FirstPageRecordDoc;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * @ClassName : FIRP0516
+ * @Description : 身份证号码与入院记录不一致
+ * @Author : 楼辉荣
+ * @Date: 2020-03-06 17:28
+ */
+@Component
+public class FIRP0516 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        BeHospitalizedDoc beHospitalizedDoc = inputInfo.getBeHospitalizedDoc();
+        FirstPageRecordDoc firstPageRecordDoc = inputInfo.getFirstPageRecordDoc();
+        if (beHospitalizedDoc != null && firstPageRecordDoc != null) {
+            Map<String, String> structureMap_bh = beHospitalizedDoc.getStructureMap();
+            Map<String, String> structureMap_fpr = firstPageRecordDoc.getStructureMap();
+            String bhIdNumber = structureMap_bh.get("身份证号码");
+            String fprIdNumber = structureMap_fpr.get(Content.idNumber);
+            if (StringUtil.isBlank(bhIdNumber) || StringUtil.isBlank(fprIdNumber)) {
+                return;
+            }
+            if (!bhIdNumber.equals(fprIdNumber)) {
+                status.set("-1");
+            }
+        }
+    }
+}

+ 74 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/operationdiscussion/OPE03142.java

@@ -0,0 +1,74 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.operationdiscussion;
+
+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.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationRecordDoc;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 手术记录出血情况未填写
+ * @author: kwz
+ * @time: 2020/06/29 11:22
+ */
+@Component
+public class OPE03142 extends QCCatalogue {
+    /**
+     * 1.手术记录中包含文本形式【失血/出血】
+     * 或2.标题形式包含【失血/出血】判断是否为空
+     *
+     * @param inputInfo
+     * @param outputInfo
+     */
+
+    @Override
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        int operationNum = 0;
+        int bleedingNum = 0;
+        //先判断有无手术记录
+        List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+        if (operationDocs != null && operationDocs.size() > 0) {
+            ss:
+            for (OperationDoc operationDoc : operationDocs) {
+                if (operationDoc == null) {
+                    continue;
+                }
+                OperationRecordDoc operationRecordDoc = operationDoc.getOperationRecordDoc();
+                if (operationRecordDoc != null) {
+                    operationNum++;
+                    Map<String, String> structureMap = operationRecordDoc.getStructureMap();
+                    if (structureMap == null) {
+                        continue;
+                    }
+                    String lossOfBlood = structureMap.get("失血");
+                    String bleeding = structureMap.get("出血");
+                    if (StringUtil.isNotBlank(lossOfBlood) || StringUtil.isNotBlank(bleeding)) {
+                        bleedingNum++;
+                        break ss;
+                    }
+                    String afterOperation = structureMap.get("手术经过及处理");
+                    List<String> bleedingRecordList = Content.bleedingRecordList;
+                    if (StringUtil.isNotBlank(afterOperation)) {
+                        for (String bleedingRecord : bleedingRecordList) {
+                            if (afterOperation.contains(bleedingRecord)) {
+                                bleedingNum++;
+                                break ss;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (operationNum != bleedingNum) {
+            status.set("-1");
+            return;
+        }
+    }
+}

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

@@ -0,0 +1,68 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.operationdiscussion;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+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.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationRecordDoc;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 手术记录输血情况未填写
+ * @author: kwz
+ * @time: 2020/06/29 11:22
+ */
+@Component
+public class OPE03143 extends QCCatalogue {
+    /**
+     * 标题形式包含【输血】判断是否为空
+     *
+     * @param inputInfo
+     * @param outputInfo
+     */
+    @Override
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        boolean flag = true;
+        //先判断有无手术记录
+        List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+        if (operationDocs == null || operationDocs.size() == 0) {
+            return;
+        }
+        for (OperationDoc operationDoc : operationDocs) {
+            if (operationDoc == null) {
+                continue;
+            }
+            OperationRecordDoc operationRecordDoc = operationDoc.getOperationRecordDoc();
+            if (operationRecordDoc != null) {
+                Map<String, String> structureMap = operationRecordDoc.getStructureMap();
+                if (structureMap == null) {
+                    continue;
+                }
+                String bloodTransfusion = structureMap.get("输血情况");
+                if (StringUtil.isNotBlank(bloodTransfusion)) {
+                    flag = false;
+                }
+
+                String afterOperation = structureMap.get("手术经过及处理");
+                if (StringUtil.isNotBlank(afterOperation)) {
+                    if (afterOperation.contains("输血")) {
+                        flag = false;
+                    }
+                }
+                //不存在手术记录返回
+            } else {
+                return;
+            }
+        }
+        if (flag) {
+            status.set("-1");
+            return;
+        }
+    }
+}

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

@@ -0,0 +1,68 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.operationdiscussion;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationRecordDoc;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 手术记录无主刀医师签字
+ * @author: kwz
+ * @time: 2020/06/29 11:22
+ */
+@Component
+public class OPE03144 extends QCCatalogue {
+    /**
+     * 手术记录【主刀医师签名/记录医师签名】判断是否为空,任意一处和【手术人员】相同既为符合
+     * @param inputInfo
+     * @param outputInfo
+     */
+    @Override
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo){
+        status.set("0");
+        //先判断有无手术记录
+        List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+        if(operationDocs != null && operationDocs.size()>0){
+            for (OperationDoc operationDoc : operationDocs) {
+                if(operationDoc==null){
+                    continue;
+                }
+                OperationRecordDoc operationRecordDoc = operationDoc.getOperationRecordDoc();
+                if(operationRecordDoc!=null){
+                    Map<String, String> structureMap = operationRecordDoc.getStructureMap();
+                    if(structureMap==null){
+                        continue;
+                    }
+                    //获取手术人员
+                    String surgeryName = structureMap.get("手术人员");
+                    //获取【主刀医师、记录医师】
+                    String physiciansName = structureMap.get("主刀医师");
+                    String reviewerName = structureMap.get("记录医师");
+                    if((StringUtil.isNotBlank(physiciansName)||StringUtil.isNotBlank(reviewerName)) && StringUtil.isNotBlank(surgeryName)){
+                        //主刀医师签名 与【手术人员】比较
+                        status.set("-1");
+                        if(StringUtil.isNotBlank(physiciansName)) {
+                            if (surgeryName.equals(physiciansName)) {
+                                status.set("0");
+                                return;
+                            }
+                        }
+                        //记录医师签名与【手术人员】比较
+                        if(StringUtil.isNotBlank(reviewerName)) {
+                            if (surgeryName.contains(reviewerName)) {
+                                status.set("0");
+                                return;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

+ 66 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/operationdiscussion/OPE0323.java

@@ -0,0 +1,66 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.operationdiscussion;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.text.ParseException;
+import java.util.List;
+
+/**
+ * @Description: 手术记录未由主刀或一助书写
+ * @author: Mark
+ * @time: 2020/04/04 11:22
+ */
+@Component
+public class OPE0323 extends QCCatalogue {
+
+    @Override
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo) throws ParseException {
+        status.set("0");
+        //医嘱
+        //        List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
+        //        if (ListUtil.isEmpty(doctorAdviceDocs)) {
+        //            return;
+        //        }
+        //        boolean isOperativePatient = CatalogueUtil.isOperativePatients(doctorAdviceDocs);
+        boolean isOperativePatient = true;//是手术患者(暂时默认是)
+//        if (isOperativePatient) {
+        List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+        if (operationDocs != null && operationDocs.size() > 0) {
+            if (ListUtil.isNotEmpty(operationDocs)) {
+                long count = operationDocs.stream().filter(operationDoc -> {
+                    boolean flag = false;
+                    if (operationDoc.getOperationRecordDoc() != null) {
+                        String surgeon = operationDoc.getOperationRecordDoc().getStructureMap().get("主刀医师");
+                        String assist1 = operationDoc.getOperationRecordDoc().getStructureMap().get("一助");
+                        String assist2 = operationDoc.getOperationRecordDoc().getStructureMap().get("二助");
+                        String assist3 = operationDoc.getOperationRecordDoc().getStructureMap().get("三助");
+                        String assist4 = operationDoc.getOperationRecordDoc().getStructureMap().get("手术人员");
+                        String signature = operationDoc.getOperationRecordDoc().getStructureMap().get("主刀医师签名");
+                        if (StringUtil.isBlank(signature)) {
+                            return flag;
+                        }
+                        if (StringUtil.isNotBlank(surgeon) || StringUtil.isNotBlank(assist1) || StringUtil.isNotBlank(assist2) || StringUtil.isNotBlank(assist3) || StringUtil.isNotBlank(assist4)) {
+                            String operator = surgeon + ", " + assist1 + "," + assist2 + "," + assist3 + "," + assist4;
+                            if (!operator.contains(signature)) {
+                                flag = true;
+                            }
+                        }
+                    }
+                    return flag;
+                }).count();
+                if (count > 0) {
+                    status.set("-1");
+                }
+            }
+        }
+
+//        }
+    }
+
+}

+ 45 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/operationdiscussion/OPE0636.java

@@ -0,0 +1,45 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.operationdiscussion;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.text.ParseException;
+import java.util.List;
+
+/**
+ * @Description: 手术医师未填写
+ * @author: 贺聪聪
+ * @time: 2022/5/11 15:00
+ */
+@Component
+public class OPE0636 extends QCCatalogue {
+
+    @Override
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo) throws ParseException {
+        status.set("0");
+        List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+        if(operationDocs == null || operationDocs.size() == 0){
+            status.set("0");
+            return;
+        }
+        if (ListUtil.isNotEmpty(operationDocs)) {
+            long count = operationDocs.stream().filter(operationDoc -> {
+                boolean flag = false;
+                if (operationDoc.getOperationRecordDoc() != null
+                        && StringUtil.isBlank(operationDoc.getOperationRecordDoc().getStructureMap().get("手术人员"))) {
+                    flag = true;
+                }
+                return flag;
+            }).count();
+            if (count > 0) {
+                status.set("-1");
+            }
+        }
+    }
+
+}

+ 45 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/operationdiscussion/OPE0640.java

@@ -0,0 +1,45 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.operationdiscussion;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.text.ParseException;
+import java.util.List;
+
+/**
+ * @Description: 麻醉医师未填写
+ * @author: 贺聪聪
+ * @time: 2022/5/11 15:14
+ */
+@Component
+public class OPE0640 extends QCCatalogue {
+
+    @Override
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo) throws ParseException {
+        status.set("0");
+        List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+        if(operationDocs == null || operationDocs.size() == 0){
+            status.set("0");
+            return;
+        }
+        if (ListUtil.isNotEmpty(operationDocs)) {
+            long count = operationDocs.stream().filter(operationDoc -> {
+                boolean flag = false;
+                if (operationDoc.getOperationRecordDoc() != null
+                        && StringUtil.isBlank(operationDoc.getOperationRecordDoc().getStructureMap().get("麻醉人员"))) {
+                    flag = true;
+                }
+                return flag;
+            }).count();
+            if (count > 0) {
+                status.set("-1");
+            }
+        }
+    }
+
+}

+ 250 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/threelevelward/THR0127.java

@@ -0,0 +1,250 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.threelevelward;
+
+import com.lantone.qc.dbanaly.util.KernelConstants;
+import com.lantone.qc.dbanaly.util.SpecialStorageUtil;
+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.MedicalRecordInfoDoc;
+import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.util.DateUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : THR0127
+ * @Description : 每周无2次副主任医师/主任医师查房记录
+ * @Author : 胡敬
+ * @Date: 2020-03-19 15:52
+ */
+@Component
+public class THR0127 extends QCCatalogue {
+    @Autowired
+    private SpecialStorageUtil specialStorageUtil;
+
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        MedicalRecordInfoDoc medicalRecordInfoDoc = inputInfo.getMedicalRecordInfoDoc();
+        if (medicalRecordInfoDoc != null && medicalRecordInfoDoc.getStructureMap() != null) {
+            //入院日期
+            String admisTime = medicalRecordInfoDoc.getStructureMap().get("behospitalDate");
+            //出院日期
+            String dischargeTime = medicalRecordInfoDoc.getStructureMap().get("leaveHospitalDate");
+            if (CatalogueUtil.isEmpty(admisTime)) {
+                return;
+            }
+            String presentTime = DateUtil.nowString();
+            //如果如果入院未超过7天则不判断该条规则
+            if (!CatalogueUtil.isEmpty(admisTime) && !CatalogueUtil.isEmpty(presentTime)) {
+                if (!CatalogueUtil.compareTime(StringUtil.parseDateTime(admisTime), StringUtil.parseDateTime(presentTime), (long) (7 * 24 * 60))) {
+                    return;
+                }
+            }
+            //如果住院天数小于7天则不判断该条规则
+            if (!CatalogueUtil.isEmpty(admisTime) && !CatalogueUtil.isEmpty(dischargeTime)) {
+                if (!CatalogueUtil.compareTime(StringUtil.parseDateTime(admisTime), StringUtil.parseDateTime(dischargeTime), (long) (7 * 24 * 60))) {
+                    return;
+                }
+            } else {
+                if (inputInfo.getThreeLevelWardDocs().size() == 0) {
+                    status.set("-1");
+                    return;
+                }
+            }
+
+            if (inputInfo.getBeHospitalizedDoc() != null && inputInfo.getThreeLevelWardDocs().size() > 0) {
+                if (CatalogueUtil.isEmpty(admisTime)) {
+                    return;
+                }
+                //开始时间(入院时间)
+                Date beginDate = StringUtil.parseDateTime(admisTime);
+                if (beginDate == null) {
+                    return;
+                }
+
+                ThreeLevelWardDoc threeLevelWardDoc = inputInfo.getThreeLevelWardDocs().get(0);
+                List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDoc.getAllDoctorWradDocs();
+                if (allDoctorWradDocs.size() == 0) {
+                    status.set("0");
+                    return;
+                }
+                Date lastRecordDate = getLastRecordDate(allDoctorWradDocs);
+                if (lastRecordDate == null) {
+                    return;
+                }
+                int hoursPerWeek = 7 * 24 * 60;
+                String roundRecordThisWeek = "";
+                List<String> roundRecordEveryWeek = new ArrayList<>();
+                beginDate = DateUtil.dateZeroClear(beginDate);//从入院记录当天0点开始算
+                int i = 1;
+                String lastWardDateRange = "";
+                List<String> lastWardDateRangeList = new ArrayList<>();
+                //每周的病历记录
+                while (i >= 1) {
+                    roundRecordThisWeek = extractWardRecord(inputInfo, allDoctorWradDocs, beginDate, hoursPerWeek, lastRecordDate);
+                    if (CatalogueUtil.isEmpty(roundRecordThisWeek)) {
+                        break;
+                    }
+                    //如果6天后日期大于出院日期,跳过
+                    if (StringUtil.isBlank(dischargeTime)) {
+                        dischargeTime = presentTime;
+                    }
+                    Date sixDate = DateUtil.addDate(beginDate, 7);
+                    if (StringUtil.parseDateTime(dischargeTime).before(sixDate)) {
+                        break;
+                    }
+                    lastWardDateRange = DateUtil.formatDate(beginDate) + "    ->    " + DateUtil.formatDate(DateUtil.addDay(sixDate, -1));
+                    lastWardDateRangeList.add(lastWardDateRange);
+                    roundRecordEveryWeek.add(roundRecordThisWeek);
+                    beginDate = DateUtil.addDate(beginDate, 7);
+                    i++;
+                }
+                if (roundRecordEveryWeek.size() == 0) {
+                    status.set("0");
+                    return;
+                }
+                List<String> resultInfos = new ArrayList<>();
+                for (int j = 0; j < roundRecordEveryWeek.size(); j++) {
+                    //获取标题中主任的名字
+                    String directorName = roundRecordEveryWeek.get(j);
+                    int directorNameNum = 0;
+                    if (judgeContainsDoctor(directorName)) {//判断标题中是否含有主任医师姓名
+                        directorNameNum++;
+                    }
+                    int directorNum = CatalogueUtil.appearNumber(roundRecordEveryWeek.get(j).split(","), Content.director);
+                    int dept_doctorNum = CatalogueUtil.appearNumber(roundRecordEveryWeek.get(j).split(","), Content.dept_doctor);
+                    //三级医师查房算一次主任查房
+                    String key = getKeyByHospitalId();
+                    int threeDoctorNum = CatalogueUtil.appearNumber(roundRecordEveryWeek.get(j).split(","), key);
+                    //北仑内分泌科(主任携主任代主治)
+                    int endocrinologyTitleNum = endocrinologyTitleNum(roundRecordEveryWeek.get(j).split(","));
+                    int num = 2;
+                    if ("7".equals(Content.hospital_Id)) {
+                        num = 1;
+                    }
+                    if (directorNum + dept_doctorNum + threeDoctorNum + endocrinologyTitleNum + directorNameNum < num) {
+                        //每周无2次主任医师查房记录/科主任查房记录
+                        status.set("-1");
+                        resultInfos.add(lastWardDateRangeList.get(j));
+                    }
+                }
+                if (resultInfos.size() > 0) {
+                    info.set(StringUtils.join(resultInfos.toArray(), ";"));
+                }
+            }
+        }
+    }
+
+    private String getKeyByHospitalId() {
+        switch (Content.hospital_Id) {
+            case "7":               //厦门
+                return "多学科联合";
+            case "35":               //长沙湘雅
+                return "上级";
+            default:
+                return "三级";
+        }
+    }
+
+    /**
+     * 北仑内分泌科主任主治处理
+     *
+     * @param srcText
+     * @return
+     */
+    private int endocrinologyTitleNum(String[] srcText) {
+        int count = 0;
+        for (String title : srcText) {
+            String regex = ".*主任.*主任.*主治.*";
+            if (title.matches(regex)) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    private Date getLastRecordDate(List<ThreeLevelWardDoc> allDoctorWradDocs) {
+        ThreeLevelWardDoc threeLevelWardDoc = allDoctorWradDocs.get(allDoctorWradDocs.size() - 1);
+        Map<String, String> lastWardDocStructureMap = threeLevelWardDoc.getStructureMap();
+        String wardDateStr = lastWardDocStructureMap.get("查房日期");
+        if (StringUtil.isNotBlank(wardDateStr)) {
+            return StringUtil.parseDateTime(wardDateStr);
+        }
+        return null;
+    }
+
+    /**
+     * 抽取duration分钟内所有查房标题
+     * 抽取一周内所有查房标题,若一周内记录少于6天,则返回""
+     *
+     * @param threeLevelWardDocs
+     * @param admisDate
+     * @param duration
+     * @return
+     */
+    private static String extractWardRecord(InputInfo inputInfo, List<ThreeLevelWardDoc> threeLevelWardDocs, Date admisDate, int duration, Date maxRecordDate) {
+        String recordTime = "", recordTitle = "", title = "";
+        List<Date> dateList = new ArrayList();
+        for (ThreeLevelWardDoc threeLevelWardDoc : threeLevelWardDocs) {
+            Map<String, String> threeLevelWardStructureMap = threeLevelWardDoc.getStructureMap();
+            recordTime = threeLevelWardStructureMap.get("查房日期");
+            title = threeLevelWardStructureMap.get("查房标题");
+            if (StringUtil.isBlank(recordTime) || StringUtil.isBlank(title)) {
+                continue;
+            }
+            Date recordDate = StringUtil.parseDateTime(recordTime);
+            if (recordDate == null) {
+                continue;
+            }
+            /* 替换查房标题中主刀/一助的职称 */
+            List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+            if (title.contains("主刀") || title.contains("术后第")) {
+                String doctorTitle = CatalogueUtil.getDoctorTitle(operationDocs, recordDate, "主刀医师");
+                title = title.replace("主刀", doctorTitle).replace("术后第", doctorTitle);
+            } else if (title.contains("一助")) {
+                String doctorTitle = CatalogueUtil.getDoctorTitle(operationDocs, recordDate, "一助");
+                title = title.replace("一助", doctorTitle);
+            }
+            if (admisDate.before(recordDate) && !CatalogueUtil.compareTime(admisDate, recordDate, Long.valueOf(duration))) {
+                recordTitle += title + ",";
+                dateList.add(recordDate);
+            }
+        }
+        if (dateList.size() > 0) {
+            //dateList.sort(Date::compareTo);
+            if (!maxRecordDate.equals(dateList.get(dateList.size() - 1)) || CatalogueUtil.compareTime(admisDate, dateList.get(dateList.size() - 1), Long.valueOf(6 * 24 * 60))) {
+                return recordTitle;
+            }
+        }
+        return "";
+    }
+
+    //判断是否含有主任医师姓名
+    private boolean judgeContainsDoctor(String string) {
+        Map<String, Map<String, Object>> hospitalDoctorMap = specialStorageUtil.getJsonStringValue(KernelConstants.HOSPITAL_DOCTOR_MAP);
+        if (hospitalDoctorMap == null) {
+            return false;
+        }
+        for (String keyStr : hospitalDoctorMap.keySet()) {
+            if (string.contains(keyStr)) {
+                Object professor = hospitalDoctorMap.get(keyStr).get("professor");
+                if (professor != null) {
+                    if (professor.toString().contains("主任")) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+}

+ 36 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/xszyy/threelevelward/THR0685.java

@@ -0,0 +1,36 @@
+package com.lantone.qc.kernel.catalogue.hospital.xszyy.threelevelward;
+
+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.RescueDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : THR0685
+ * @Description : 抢救记录未记录参加抢救医务人员姓名及职称
+ * @Author : 胡敬
+ * @Date: 2020-03-30 13:15
+ */
+@Component
+public class THR0685 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        List<RescueDoc> rescueDocs = inputInfo.getRescueDocs();
+        if (ListUtil.isEmpty(rescueDocs)) {
+            return;
+        }
+        for (RescueDoc rescueDoc : rescueDocs) {
+            Map<String, String> rescueStructureMap = rescueDoc.getStructureMap();
+            if (CatalogueUtil.isEmpty(rescueStructureMap.get("参加抢救的医务人员姓名及专业技术职称"))) {
+                status.set("-1");
+                return;
+            }
+        }
+    }
+}

+ 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) {

+ 31 - 30
kernel/src/main/java/com/lantone/qc/kernel/catalogue/operationdiscussion/OPE03107.java

@@ -1,6 +1,5 @@
 package com.lantone.qc.kernel.catalogue.operationdiscussion;
 
-import com.alibaba.fastjson.JSONArray;
 import com.lantone.qc.kernel.catalogue.QCCatalogue;
 import com.lantone.qc.pub.Content;
 import com.lantone.qc.pub.model.InputInfo;
@@ -10,9 +9,8 @@ import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
 import com.lantone.qc.pub.model.doc.operation.*;
 import com.lantone.qc.pub.util.ListUtil;
 import com.lantone.qc.pub.util.StringUtil;
-import org.apache.commons.collections.MapUtils;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Component;
+
 import java.text.ParseException;
 import java.util.*;
 import java.util.regex.Matcher;
@@ -26,45 +24,47 @@ import java.util.regex.Pattern;
 @Component
 public class OPE03107 extends QCCatalogue {
 
+    /**
+     * 首先病历中所有【手术记录】份数相加,无手术记录单则通过
+     * 然后查找手术次数,以下规则以数量多的一条为准:
+     * 1.【临时医嘱内(医嘱处方类型)为“手术”且医嘱状态不为“作废”、“删除”、“取消”任一】将所有出现的“手术”次数相加,再排除医嘱内相同时间行手术次数(如拟明日10点行*术)(台州市立)
+     * 2.或【术后*记录】次数相加
+     * 3.或【手术知情同意书】次数相加
+     * 最后判断查找到的手术次数跟手术记录的份数跟是否一致,手术记录仅有一份时,手术次数少于手术记录不报,手术记录有多份时,手术次数和手术记录不一致则报出
+     */
     @Override
     protected void start(InputInfo inputInfo, OutputInfo outputInfo) throws ParseException {
         status.set("0");
-        int opeCount=0;
-        int opePreCount=0;
-        int opeThrCount=0;
-        int opeRecordCount=0;
-        int opeDisCount=0;
-        int opeFormCount=0;
+        int opeCount = 0;
+        int opeThrCount = 0;
+        int opeRecordCount = 0;
+        int opeDisCount = 0;
+        int opeFormCount = 0;
         List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
         List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
         List<String> listTime = new ArrayList<>();
         //手术记录次数
-        if(ListUtil.isNotEmpty(operationDocs)){
+        if (ListUtil.isNotEmpty(operationDocs)) {
             for (OperationDoc operationDoc : operationDocs) {
                 OperationRecordDoc operationRecordDoc = operationDoc.getOperationRecordDoc();
                 //手术记录次数
-                if(operationRecordDoc!=null){
+                if (operationRecordDoc != null) {
                     opeRecordCount++;
-                }else {
+                } else {
                     return;
                 }
-                //术前讨论,小结次数
-                PreoperativeDiscussionDoc preoperativeDiscussionDoc = operationDoc.getPreoperativeDiscussionDoc();
-                if(preoperativeDiscussionDoc!=null){
-                    opePreCount++;
-                }
                 //术后首程次数
                 OperationDiscussionDoc operationDiscussionDoc = operationDoc.getOperationDiscussionDoc();
-                if(operationDiscussionDoc!=null){
+                if (operationDiscussionDoc != null) {
                     opeDisCount++;
                 }
                 //知情同意书次数
                 OperationInformedConsentDoc operationInformedConsentDoc = operationDoc.getOperationInformedConsentDoc();
-                if(operationInformedConsentDoc!=null){
+                if (operationInformedConsentDoc != null) {
                     opeFormCount++;
                 }
             }
-        }else {
+        } else {
             return;
         }
         //医嘱判断手术
@@ -99,15 +99,15 @@ public class OPE03107 extends QCCatalogue {
         }
         //查房
         List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
-        if(ListUtil.isNotEmpty(threeLevelWardDocs)){
+        if (ListUtil.isNotEmpty(threeLevelWardDocs)) {
             List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDocs.get(0).getAllDoctorWradDocs();
-            if(allDoctorWradDocs!=null){
+            if (allDoctorWradDocs != null) {
                 for (ThreeLevelWardDoc allDoctorWradDoc : allDoctorWradDocs) {
                     Map<String, String> structureMap = allDoctorWradDoc.getStructureMap();
                     String thrName = structureMap.get("查房标题");
                     if (StringUtil.isNotEmpty(thrName)) {
                         String substring = thrName.substring(0, 2);
-                        if (substring.equals("术前")){
+                        if (substring.equals("术前")) {
                             opeThrCount++;
                         }
                     }
@@ -116,14 +116,15 @@ public class OPE03107 extends QCCatalogue {
         }
 
         //获取手术最多的次数
-        opeCount=listTime.size();
-        int max = opeCount>opePreCount?opeCount: opePreCount;
-        max=max>opeThrCount?max:opeThrCount;
-        max=max>opeDisCount?max:opeDisCount;
-        max=max>opeFormCount?max:opeFormCount;
-        if(max==opeRecordCount){
+        opeCount = listTime.size();
+        int max = opeCount > opeThrCount ? opeCount : opeThrCount;
+        max = max > opeDisCount ? max : opeDisCount;
+        max = max > opeFormCount ? max : opeFormCount;
+
+        if (opeRecordCount == 1 && max < opeRecordCount) {
             return;
-        }else{
+        }
+        if (max != opeRecordCount) {
             status.set("-1");
             return;
         }

+ 7 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/operationdiscussion/OPE03111.java

@@ -43,6 +43,13 @@ public class OPE03111 extends QCCatalogue {
                 if (operationRecordDoc == null) {
                    return;
                 }
+                String pathological = operationRecordDoc.getStructureMap().get("病理检查");
+                if (StringUtil.isNotEmpty(pathological)){
+                    if (pathological.contains("送")){
+                        status.set("0");
+                        continue;
+                    }
+                }
             }
         }
 

+ 33 - 16
kernel/src/main/java/com/lantone/qc/kernel/catalogue/operationdiscussion/OPE03143.java

@@ -1,15 +1,14 @@
 package com.lantone.qc.kernel.catalogue.operationdiscussion;
 
 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.model.doc.ClinicalBloodDoc;
 import com.lantone.qc.pub.model.doc.operation.OperationDoc;
 import com.lantone.qc.pub.model.doc.operation.OperationRecordDoc;
 import com.lantone.qc.pub.util.StringUtil;
 import org.springframework.stereotype.Component;
 
-import java.text.ParseException;
 import java.util.List;
 import java.util.Map;
 
@@ -22,32 +21,50 @@ import java.util.Map;
 public class OPE03143 extends QCCatalogue {
     /**
      * 标题形式包含【输血】判断是否为空
+     *
      * @param inputInfo
      * @param outputInfo
      */
     @Override
-    protected void start(InputInfo inputInfo, OutputInfo outputInfo){
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo) {
         status.set("0");
+        boolean flag = true;
         //先判断有无手术记录
         List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
-        if(operationDocs != null && operationDocs.size()>0){
-           for (OperationDoc operationDoc : operationDocs) {
-                if(operationDoc==null){
+        if (operationDocs == null || operationDocs.size() == 0) {
+            return;
+        }
+        //先判断有无输血记录
+        List<ClinicalBloodDoc> clinicalBloodDocs = inputInfo.getClinicalBloodDocs();
+        if (clinicalBloodDocs == null) {
+            return;
+        }
+        for (OperationDoc operationDoc : operationDocs) {
+            if (operationDoc == null) {
+                continue;
+            }
+            OperationRecordDoc operationRecordDoc = operationDoc.getOperationRecordDoc();
+            if (operationRecordDoc != null) {
+                Map<String, String> structureMap = operationRecordDoc.getStructureMap();
+                if (structureMap == null) {
                     continue;
                 }
-                OperationRecordDoc operationRecordDoc = operationDoc.getOperationRecordDoc();
-                if(operationRecordDoc!=null){
-                    Map<String, String> structureMap = operationRecordDoc.getStructureMap();
-                    if(structureMap==null){
-                        continue;
-                    }
-                    String bloodTransfusion = structureMap.get("输血情况");
-                    if(StringUtil.isBlank(bloodTransfusion)){
-                        status.set("-1");
-                        return;
+                String bloodTransfusion = structureMap.get("输血情况");
+                if (StringUtil.isNotBlank(bloodTransfusion)) {
+                    flag = false;
+                }
+
+                String afterOperation = structureMap.get("手术经过");
+                if (StringUtil.isNotBlank(afterOperation)) {
+                    if (afterOperation.contains("输血")) {
+                        flag = false;
                     }
                 }
             }
         }
+        if (flag) {
+            status.set("-1");
+            return;
+        }
     }
 }

+ 3 - 3
kernel/src/main/java/com/lantone/qc/kernel/catalogue/preoperativediscussion/PRE0329.java

@@ -24,7 +24,7 @@ public class PRE0329 extends QCCatalogue {
         status.set("0");
         boolean isOperativePatient = true;//是手术患者(暂时默认是)
         List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
-        if(operationDocs == null || operationDocs.size()== 0){
+        if (operationDocs == null || operationDocs.size() == 0) {
             return;
         }
         String key = getKeyByHospitalId();
@@ -37,9 +37,9 @@ public class PRE0329 extends QCCatalogue {
     }
 
     private String getKeyByHospitalId() {
-        switch (Content.hospital_Id)
-        {
+        switch (Content.hospital_Id) {
             case "2":
+            case "11":
                 return "手术指征";
             default:
                 return "手术指征与禁忌";

+ 2 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/preoperativediscussion/PRE0330.java

@@ -47,6 +47,8 @@ public class PRE0330 extends QCCatalogue {
         {
             case "2":
                 return "拟施手术方式名称及可能的变更与禁忌症";
+            case "11":
+                return "拟施手术名称及方式";
             default:
                 return "拟施手术方式、名称及可能的变更与禁忌症";
         }

+ 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("蛋白")) {

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

@@ -18,10 +18,10 @@ spring:
   resources:
     static-locations: classpath:/
   profiles:
-    active: test
+    active: local
 
 qc:
-  hospital_id: 1,2,3,4,5,6,7,8,10,11,13,15,20,21,22,23,24,34,35,36,38
+  hospital_id: 1,2,3,4,5,6,7,8,10,11,13,15,20,34,35,36,37
 
 logging:          # 日志
   config: classpath:logback-spring.xml

+ 84 - 0
kernel/src/main/resources/cache/37/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==

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 25358 - 0
kernel/src/main/resources/cache/37/concept_diag_properties.dict


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 25358 - 0
kernel/src/main/resources/cache/37/hospital_diag_info.dict


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 3123 - 0
kernel/src/main/resources/cache/37/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>

+ 3 - 3
public/src/main/java/com/lantone/qc/pub/util/DateUtil.java

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

+ 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);

+ 3 - 0
trans/src/main/java/com/lantone/qc/trans/beilun/util/BeiLunThreeLevelWardHtmlAnalysis.java

@@ -41,6 +41,9 @@ public class BeiLunThreeLevelWardHtmlAnalysis implements BeiLunHtmlAnalysis {
             String htmlText = BeiLunHtmlAnalysisUtil.blockDivToStr(bigDivElement, true);
             htmlText = htmlText.replace("注意:上级医师查房主要记 录:患者病情、诊断、鉴别诊断、当前治疗措施和疗效的分析及下一步诊疗意见等,能反应上级医 师的水平。", "")
                     .replace("提醒:有创诊疗操作记录内容包括操作名称、时间、步骤、结果及患者的一般情况,记录操作过 程是否顺利,有无不良反应,术后注意事项,操作医师签名、记录时间等。 手术室完成的、治疗性质的及全麻下完成的有创诊疗操作参照手术管理。(包括介入治疗、胃肠镜 下肿瘤切除/粘膜下肿瘤剥除等)", "");
+            if (htmlText.contains("SignControl-")) {
+                htmlText = htmlText.substring(0, htmlText.indexOf("SignControl-"));
+            }
             CommonAnalysisUtil.extractWardInfo(recTitle, htmlText, structureMap);
             BeiLunHtmlAnalysisUtil.insertModuleId(modeId, recTypeId, structureMap);
         } catch (Exception 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;
+    }
+}

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

@@ -0,0 +1,79 @@
+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("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 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(
+
+    );
+
+}

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

@@ -0,0 +1,82 @@
+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.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 htmlAnalysis = new FirstCourseRecordHtmlAnalysis();
+                Map<String, String> sourceMap = htmlAnalysis.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;
+    }
+
+}

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

@@ -0,0 +1,288 @@
+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();
+            OperationHtmlAnalysis 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;
+    }
+
+}

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


Vissa filer visades inte eftersom för många filer har ändrats