Browse Source

2021版新增规则编写

zhanghang 3 years ago
parent
commit
faaff9f4d0

+ 47 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/difficultcasediscuss/DIF03148.java

@@ -0,0 +1,47 @@
+package com.lantone.qc.kernel.catalogue.difficultcasediscuss;
+
+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.DifficultCaseDiscussDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : DIF03148
+ * @Description : 	疑难病例讨论未由科主任组织讨论
+ * @Author : 楼辉荣
+ * @Date: 2020-03-06 17:2
+ */
+@Component
+public class DIF03148 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        /**
+         * 疑难病例讨论主任人为科主任姓名      【疑难病例讨论记录】主持人填写处是科主任姓名
+         */
+        status.set("0");
+        List<DifficultCaseDiscussDoc> difficultCaseDiscussDocs = inputInfo.getDifficultCaseDiscussDocs();
+        if(ListUtil.isEmpty(difficultCaseDiscussDocs)){
+            return;
+        }
+        if(difficultCaseDiscussDocs != null && difficultCaseDiscussDocs.size()>0){
+            for (DifficultCaseDiscussDoc dcdd:difficultCaseDiscussDocs) {
+                Map<String, String> dcddStructureMap = dcdd.getStructureMap();
+                String diisDate = dcddStructureMap.get("主持人");
+                if(CatalogueUtil.isEmpty(diisDate)){
+                  return;
+                }
+                String professor = CatalogueUtil.getProfessor(diisDate);
+                if(!professor.contains("主任")){
+                    status.set("-1");
+                    return;
+                }
+
+            }
+        }
+    }
+}

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

@@ -1,11 +1,14 @@
 package com.lantone.qc.kernel.catalogue.difficultcasediscuss;
 
+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.model.InputInfo;
 import com.lantone.qc.pub.model.OutputInfo;
 import com.lantone.qc.pub.model.doc.DifficultCaseDiscussDoc;
 import com.lantone.qc.pub.util.ListUtil;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.List;
@@ -19,12 +22,15 @@ import java.util.Map;
  */
 @Component
 public class DIF0554 extends QCCatalogue {
+    @Autowired
+    private SpecialStorageUtil specialStorageUtil;
     public void start(InputInfo inputInfo, OutputInfo outputInfo) {
         status.set("0");
         List<DifficultCaseDiscussDoc> difficultCaseDiscussDocs = inputInfo.getDifficultCaseDiscussDocs();
         if(ListUtil.isEmpty(difficultCaseDiscussDocs)){
             return;
         }
+        Map<String, Map<String, Object>> hospitalDoctorMap = specialStorageUtil.getJsonStringValue(KernelConstants.HOSPITAL_DOCTOR_MAP);
         if(difficultCaseDiscussDocs != null && difficultCaseDiscussDocs.size()>0){
             for (DifficultCaseDiscussDoc dcdd:difficultCaseDiscussDocs) {
                 Map<String, String> dcddStructureMap = dcdd.getStructureMap();

+ 95 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/preoperativediscussion/PRE0580.java

@@ -0,0 +1,95 @@
+package com.lantone.qc.kernel.catalogue.preoperativediscussion;
+
+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.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.PreoperativeDiscussionDoc;
+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.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @Description: 术前讨论记录未记录讨论者的姓名及职称
+ * @author: rengb
+ * @time: 2020/3/23 15:09
+ */
+@Component
+public class PRE0580 extends QCCatalogue {
+    @Autowired
+    private SpecialStorageUtil specialStorageUtil;
+
+    @Override
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo){
+        /**
+         * 术前讨论、术前小结存在的前提       【参加人员】判断是否为空,并【姓名】加职称:【主治/助理/主任/副主任/规培/实习/住院/院长】
+         */
+        status.set("0");
+        List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+        if(ListUtil.isEmpty(operationDocs)){
+            return;
+        }
+        for (OperationDoc operationDoc : operationDocs) {
+            PreoperativeDiscussionDoc preoperativeDiscussionDoc = operationDoc.getPreoperativeDiscussionDoc();
+            if (preoperativeDiscussionDoc != null) {
+                Map<String, String> structureMap = preoperativeDiscussionDoc.getStructureMap();
+                if (structureMap == null) {
+                    continue;
+                }
+                String participants = structureMap.get("参加人员");
+                if (StringUtil.isBlank(participants)) {
+                    if(!participantsSplit(participants)) {
+                        status.set("-1");
+                        return;
+                    }
+                }
+
+            }
+        }
+    }
+
+    //对参加人员进行切割并判断
+    private boolean participantsSplit( String participants ) {
+        List<String> punctuationList = Content.punctuationList;
+        for (String punctuation : punctuationList) {
+            if(participants.contains(punctuation)){
+                String[] strings = punctuation.split(punctuation);
+                for (String string : strings) {
+                    if(!findDirectorDoctor(string)){
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    private boolean findDirectorDoctor(String string) {
+        Map<String, Map<String, Object>> hospitalDoctorMap = specialStorageUtil.getJsonStringValue(KernelConstants.HOSPITAL_DOCTOR_MAP);
+        if (hospitalDoctorMap == null) {
+            return true;
+        }
+        for (String keyStr : hospitalDoctorMap.keySet()) {
+            if (string.contains(keyStr)) {
+                Object professor = hospitalDoctorMap.get(keyStr).get("professor");
+                if (professor != null) {
+                    if (!string.contains(professor.toString())) {
+                        return false;
+                    }
+
+                }
+            }
+        }
+        return true;
+    }
+
+}

+ 1 - 2
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03137.java

@@ -32,7 +32,6 @@ public class THR03137 extends QCCatalogue {
         if(ListUtil.isEmpty(doctorAdviceDocs)){
             return;
         }
-        doc:
         for (DoctorAdviceDoc doctorAdviceDoc : doctorAdviceDocs) {
             //取长期临时医嘱,不为作废医嘱
             if(doctorAdviceDoc.getStructureMap()!=null){
@@ -49,7 +48,7 @@ public class THR03137 extends QCCatalogue {
                                 String rex2="[\\s\\S]*(?=科)[\\s\\S]{0,6}(?=转)[\\s\\S]*";
                                 if(medicalOrderName.matches(rex1)||medicalOrderName.matches(rex2)) {
                                     flag = true;
-                                    break doc;
+                                    break ;
                                 }
                             }
                         }

+ 157 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03147.java

@@ -0,0 +1,157 @@
+package com.lantone.qc.kernel.catalogue.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.ThreeLevelWardDoc;
+import com.lantone.qc.pub.util.DateUtil;
+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.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : THR03147
+ * @Description : 患者出院前48小时内无上级医师(主治及以上)同意出院的病程记录
+ * @Author : 胡敬
+ * @Date: 2020-03-19 13:51
+ */
+@Component
+public class THR03147 extends QCCatalogue {
+    @Autowired
+    private SpecialStorageUtil specialStorageUtil;
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        /**
+         * 出院时间前48小时,48小时内找上级医师同意出院的病程记录
+         *
+         * 以患者病案首页【出院时间】找前48小时内【查房记录】,查房记录标题或查房记录内容或医生签字包含【上级/主任/主治/主治及以上医师姓名】和查房记录内容包含【出院】同时存在
+         */
+        status.set("0");
+        if(inputInfo.getFirstPageRecordDoc()==null || inputInfo.getFirstPageRecordDoc().getStructureMap()==null){
+            return;
+        }
+        //获取病案首页出院时间
+        String dischargeTime = inputInfo.getFirstPageRecordDoc().getStructureMap().get("出院时间");
+        if (CatalogueUtil.isEmpty(dischargeTime)) {
+            return;
+        }
+        Date dischargeDate = StringUtil.parseDateTime(dischargeTime);
+        List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
+        if(ListUtil.isEmpty(threeLevelWardDocs)){
+            return;
+        }
+        List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDocs.get(0).getAllDoctorWradDocs();
+        if(ListUtil.isEmpty(allDoctorWradDocs)){
+            return;
+        }
+        if(!getAllPatientRounds(allDoctorWradDocs,dischargeDate)){
+            status.set("-1");
+            return;
+        }
+
+    }
+
+
+    //获取患者出院前48小时内所有的查房记录并判断
+    public  boolean getAllPatientRounds(List<ThreeLevelWardDoc> allDoctorWradDocs ,Date dischargeDate){
+        boolean flag=true;
+        List<String> superiorList = Content.superiorList;
+        for (ThreeLevelWardDoc allDoctorWradDoc : allDoctorWradDocs) {
+            Map<String, String> structureMap = allDoctorWradDoc.getStructureMap();
+            if(structureMap==null){
+                continue;
+            }
+            String checkTheTime = structureMap.get("查房日期");
+            if (CatalogueUtil.isEmpty(checkTheTime)) {
+                continue;
+            }
+            Date checkTheDate = StringUtil.parseDateTime(checkTheTime);
+            if(!CatalogueUtil.compareTime(
+                    checkTheDate,
+                    dischargeDate,
+                    Long.valueOf(48 * 60))){
+                flag=false;
+                //出院前48小时的查房记录
+                String illnessRecords = structureMap.get("病情记录");
+                //包含出院
+                if(StringUtil.isNotEmpty(illnessRecords)){
+                if(illnessRecords.contains("出院")) {
+                    // 查房记录标题或查房记录内容或医生签字包含【上级/主任/主治/主治及以上医师姓名】
+                    String roundTitle = structureMap.get("查房标题");
+                    //标题判断
+                    if (StringUtil.isNotEmpty(roundTitle)) {
+                        for (String superior : superiorList) {
+                            if (roundTitle.contains(superior)) {
+                                flag=true;
+                                break;
+                            }
+                        }
+                       if(judgeContainsDoctor(roundTitle)){
+                            flag=true;
+                            break;
+                        }
+                    }
+                    //查房记录判断
+                        for (String superior : superiorList) {
+                            if (illnessRecords.contains(superior)) {
+                                flag=true;
+                                break;
+                            }
+                        }
+                    if(judgeContainsDoctor(illnessRecords)){
+                        flag=true;
+                        break;
+                    }
+                    //审核人判断
+                    String reviewer = structureMap.get("审核人");
+                    if (StringUtil.isNotEmpty(reviewer)) {
+                        for (String superior : superiorList) {
+                            if (reviewer.contains(superior)) {
+                                flag=true;
+                                break;
+                            }
+                        }
+                        if(judgeContainsDoctor(reviewer)){
+                            flag=true;
+                            break;
+                        }
+                    }
+                }
+                }
+            }
+        }
+        return flag;
+    }
+
+    //判断是否含有主治及以上医师姓名
+    private boolean judgeContainsDoctor(String string) {
+        List<String> indicationsAboveList = Content.indicationsAboveList;
+        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) {
+                    for (String indicationsAbove : indicationsAboveList) {
+                        if (professor.toString().contains(indicationsAbove)) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+}

+ 145 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03149.java

@@ -0,0 +1,145 @@
+package com.lantone.qc.kernel.catalogue.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.DoctorAdviceDoc;
+import com.lantone.qc.pub.model.doc.FirstCourseRecordDoc;
+import com.lantone.qc.pub.model.doc.RescueDoc;
+import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.SpringContextUtil;
+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.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : THR03149
+ * @Description :  抢救患者上级医师(副高及以上)查房记录不及时
+ * @Author : Mark
+ * @Date: 2020-04-07 17:06
+ */
+@Component
+public class THR03149 extends QCCatalogue {
+    @Autowired
+    private SpecialStorageUtil specialStorageUtil;
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        /**
+         * 【抢救开始时间】时间延后6小时内,找标题为【主任*查房】或【主任级别的姓名查房】,若无报出
+         *
+         * 1.先判断是否是抢救患者p6,并无【死亡记录】,是则找2.【抢救记录】内【抢救开始时间】标题或抢救过程中抢救开始时间延后6小时内,
+         * 找标题为【主任*查房】或【主任级别的姓名查房】,若有不报,若无 3.去【首次病程记录/抢救记录】内找是否有包含【请示*上级医生/请示*上级医师】,若无,报出
+         *
+         * 判断该病人是否属于抢救病人  1.【临时医嘱/长期医嘱】包含【抢救】医嘱或2.【抢救记录】文书
+         */
+        boolean flag = false;
+        List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
+        List<RescueDoc> rescueDocs = inputInfo.getRescueDocs();
+        if(ListUtil.isNotEmpty(rescueDocs)){
+            flag=true;
+        }
+        //为一个抢救患者
+        if(ListUtil.isNotEmpty(rescueDocs)){
+            //获取抢救时间
+            for (RescueDoc rescueDoc : rescueDocs) {
+                String saveTime = rescueDoc.getStructureMap().get("抢救开始时间");
+                if(StringUtil.isBlank(saveTime)){
+                    continue;
+                }
+                Date saveDate = StringUtil.parseDateTime(saveTime);
+                if(!getAllSaveDoctor(inputInfo,outputInfo,saveDate)){
+                    //去【首次病程记录/抢救记录】内找是否有包含【请示*上级医生/请示*上级医师】
+                }
+            }
+        }
+
+        if(ListUtil.isNotEmpty(doctorAdviceDocs)){
+            for (DoctorAdviceDoc doctorAdviceDoc : doctorAdviceDocs) {
+                //取长期临时医嘱,不为作废医嘱
+                if(doctorAdviceDoc.getStructureMap()!=null) {
+                    Map<String, String> doctorAdviceDocStructureMap = doctorAdviceDoc.getStructureMap();
+                    String adviceType = doctorAdviceDocStructureMap.get(Content.doctorAdviceType);
+                    if (StringUtil.isNotEmpty(adviceType)) {
+                        if (adviceType.equals(Content.standingOrder) || adviceType.equals(Content.statOrder)) {
+                            String adviceState = doctorAdviceDocStructureMap.get(Content.doctorAdviceState);
+                            if (StringUtil.isNotEmpty(adviceState)) {
+                                if (!Content.cancellationOrderList.contains(adviceState)) {
+                                    //医嘱若是包含  转*科/科*转则为一个转科患者
+                                    String medicalOrderName = doctorAdviceDoc.getStructureMap().get(Content.medicalOrderName);
+                                    if (medicalOrderName.contains("抢救")) {
+                                        flag = true;
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    //抢救6小时内 找标题为【主任*查房】或【主任级别的姓名查房】
+    public  boolean getAllSaveDoctor(InputInfo inputInfo, OutputInfo outputInfo,Date saveDate ) {
+        List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
+        if (ListUtil.isEmpty(threeLevelWardDocs)) {
+            return false;
+        }
+        List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDocs.get(0).getAllDoctorWradDocs();
+        if (ListUtil.isEmpty(allDoctorWradDocs)) {
+            return false;
+        }
+        for (ThreeLevelWardDoc allDoctorWradDoc : allDoctorWradDocs) {
+            Map<String, String> structureMap = allDoctorWradDoc.getStructureMap();
+            String checkTime = structureMap.get("查房日期");
+            if(StringUtil.isBlank(checkTime)){
+                continue;
+            }
+            if (!CatalogueUtil.compareTime(
+                    saveDate,
+                    StringUtil.parseDateTime(checkTime),
+                    Long.valueOf(6 * 60))) {
+                //不大于抢救开始时间6小时内,取查房标题
+                String wardRoundTitle = structureMap.get("查房标题");
+                //【主任*查房】或【主任级别的姓名查房】
+                if(StringUtil.isBlank(wardRoundTitle)){
+                    continue;
+                }
+                if(wardRoundTitle.contains("主任")){
+                    return true;
+                }
+                if(judgeContainsDoctor(wardRoundTitle)){
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    //判断是否含有主任医师姓名
+    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;
+    }
+}

+ 12 - 0
public/src/main/java/com/lantone/qc/pub/Content.java

@@ -406,6 +406,18 @@ public class Content {
     public static List<String>  bleedingRecordList= Arrays.asList(
             "失血","出血"
     );
+    //术前讨论记录未记录讨论者的姓名及职称中对标点符号切割
+    public static List<String>  punctuationList= Arrays.asList(
+            ",",";",",",";"
+    );
+    //查房记录标题或查房记录内容或医生签字包含【上级/主任/主治】所用
+    public static List<String>  superiorList= Arrays.asList(
+            "主任","主治"
+    );
+    //主治及以上
+    public static List<String>  indicationsAboveList= Arrays.asList(
+            "主任","主治","副主任"
+    );
     //抗菌药物目录
     public static List<String> antimicrobialDrugList = Arrays.asList(
             "多西环素","二维四环素甲氧苄啶","复方四环素","复方四环素泼尼松","胍甲环素","美他环素","米诺环素","四环素","替加环素","土霉素","琥珀氯霉素","甲砜霉素","甲砜霉素甘氨酸酯","氯霉素",