Sfoglia il codice sorgente

Merge branch 'dev-shaoyf' into dev

zhoutg 5 anni fa
parent
commit
f2d61e4d05

+ 121 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/preoperativediscussion/PRE03025.java

@@ -0,0 +1,121 @@
+package com.lantone.qc.kernel.catalogue.preoperativediscussion;
+
+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.ThreeLevelWardDoc;
+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.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 手术患者无术前讨论记录(邵逸夫)
+ * @author: zhoutg
+ * @time: 2020/3/23 15:09
+ */
+@Component
+public class PRE03025 extends QCCatalogue {
+
+    @Override
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo) throws ParseException {
+        /**
+         * 1:入院记录【现病史】包含".*急诊.*术.*|.*急症.*术.*"不报错。
+         * 2:如果术前讨论、术前小结次数条数为0 且( 首次病程录【诊疗计划】或查房记录【病情记录】包含".*急诊.*术.*|.*急症.*术.*"),则术前讨论、术前小结次数+1。
+         * 3:如果手术记录次数(同一日期天多次手术算1次) 大于 术前讨论、术前小结次数,则出错
+         */
+        status.set("0");
+        List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+        if (operationDocs == null || operationDocs.size() == 0) {
+            return;
+        }
+        if (inputInfo.getBeHospitalizedDoc() != null
+                && inputInfo.getBeHospitalizedDoc().getStructureMap().get("现病史") != null
+                && inputInfo.getBeHospitalizedDoc().getStructureMap().get("现病史").matches(".*急诊.*术.*|.*急症.*术.*")) {
+            return;
+        }
+        boolean emergencyOperation = findEmergencyOperation(inputInfo);
+        boolean emergencyOperationFromWardRecord = findEmergencyOperationFromWardRecord(inputInfo);
+
+        int i = getOperationSum(operationDocs); // 获取手术记录次数
+        int j = 0;  // 获取术前讨论、术前小结次数
+        for (OperationDoc operationDoc : operationDocs) {
+            if (operationDoc.getPreoperativeDiscussionDoc() != null) {
+                j++;
+            }
+        }
+        /* 如果首次病程录的诊疗计划里有急诊手术 或 查房记录的病情记录里有急诊手术,则术前小结的数量加1 */
+        if (emergencyOperation || emergencyOperationFromWardRecord) {
+            if (j == 0) {
+                j++;
+            }
+        }
+        if (i > 0 && i > j) {
+            status.set("-1");
+            info.set("手术记录不一致");
+        }
+    }
+
+    private boolean findEmergencyOperation(InputInfo inputInfo) {
+        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
+        if (firstCourseRecordDoc != null) {
+            String treatPlan = firstCourseRecordDoc.getStructureMap().get("诊疗计划");
+            // 根据医学部要求,加入“急症”和“术”
+            if (StringUtil.isNotBlank(treatPlan)) {
+                String regex = ".*急诊.*术.*|.*急症.*术.*";
+                return treatPlan.matches(regex);
+            }
+        }
+        return false;
+    }
+
+    private boolean findEmergencyOperationFromWardRecord(InputInfo inputInfo) {
+        List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
+        if (threeLevelWardDocs.size() == 0) {
+            return false;
+        }
+        List<ThreeLevelWardDoc> allDoctorWradDocs = threeLevelWardDocs.get(0).getAllDoctorWradDocs();
+        for (ThreeLevelWardDoc threeLevelWardDoc : allDoctorWradDocs) {
+            String content = threeLevelWardDoc.getStructureMap().get("病情记录");
+            // 根据医学部要求,加入“急症”和“术”
+            if (StringUtil.isNotBlank(content)) {
+                String regex = ".*急诊.*术.*|.*急症.*术.*";
+                if (content.matches(regex)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 获取手术记录次数,从【手术日期】中获取手术时间
+     * @param operationDocs
+     * @return
+     */
+    private int getOperationSum(List<OperationDoc> operationDocs) {
+        int num = 0;
+        for (OperationDoc operationDoc : operationDocs) {
+            OperationRecordDoc operationRecordDoc = operationDoc.getOperationRecordDoc();
+            if (operationRecordDoc == null) {
+                continue;
+            }
+            Map<String, String> structureMap = operationRecordDoc.getStructureMap();
+            String dateStr = structureMap.get("手术日期");
+            List<String> dateStrList = new ArrayList<>();
+            if (StringUtil.isNotBlank(dateStr)) {
+                if (!dateStrList.contains(dateStr)) {
+                    dateStrList.add(dateStr);
+                    num++;
+                }
+            }
+        }
+        return num;
+    }
+}

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

@@ -28,8 +28,8 @@ public class PRE0328 extends QCCatalogue {
     @Override
     protected void start(InputInfo inputInfo, OutputInfo outputInfo) throws ParseException {
         /**
-         * 1:入院记录【现病史】包含“急诊手术”不报错。
-         * 2:如果术前讨论、术前小结次数条数为0 且 首次病程录【诊疗计划】或查房记录【病情记录】包含急诊手术——".*急诊.*术.*|.*急症.*术.*",则术前讨论、术前小结次数+1。
+         * 1:入院记录【现病史】包含".*急诊.*术.*|.*急症.*术.*"不报错。
+         * 2:如果术前讨论、术前小结次数条数为0 且 (首次病程录【诊疗计划】或查房记录【病情记录】包含急诊手术——".*急诊.*术.*|.*急症.*术.*"),则术前讨论、术前小结次数+1。
          * 3:如果手术记录次数(第一次手术的开始至截止时间内有其他手术不算次数) 大于 术前讨论、术前小结次数,则出错
          */
         status.set("0");
@@ -39,7 +39,7 @@ public class PRE0328 extends QCCatalogue {
         }
         if (inputInfo.getBeHospitalizedDoc() != null
                 && inputInfo.getBeHospitalizedDoc().getStructureMap().get("现病史") != null
-                && inputInfo.getBeHospitalizedDoc().getStructureMap().get("现病史").contains("急诊手术")) {
+                && inputInfo.getBeHospitalizedDoc().getStructureMap().get("现病史").matches(".*急诊.*术.*|.*急症.*术.*")) {
             return;
         }
         boolean emergencyOperation = findEmergencyOperation(inputInfo);

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

@@ -0,0 +1,157 @@
+package com.lantone.qc.kernel.catalogue.threelevelward;
+
+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.StringUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : THR03014
+ * @Description : 每周无1次主任医师查房记录(Attending少于每周一次查房记录)
+ * @Author : 胡敬
+ * @Date: 2020-03-19 15:52
+ */
+@Component
+public class THR03014 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        if (inputInfo.getLeaveHospitalDoc() != null) {
+            Map<String, String> leaveHospitalStructureMap = inputInfo.getLeaveHospitalDoc().getStructureMap();
+            String admisTime = leaveHospitalStructureMap.get(Content.admisTime);
+            String dischargeTime = leaveHospitalStructureMap.get(Content.dischargeTime);
+            //如果住院天数小于7天则不判断该条规则
+            if (!CatalogueUtil.isEmpty(admisTime) && !CatalogueUtil.isEmpty(dischargeTime)) {
+                if (!CatalogueUtil.compareTime(StringUtil.parseDateTime(admisTime), StringUtil.parseDateTime(dischargeTime), (long) (7 * 24 * 60))) {
+                    return;
+                }
+            }
+        }
+
+        if (inputInfo.getBeHospitalizedDoc() != null && inputInfo.getThreeLevelWardDocs().size() > 0) {
+            Map<String, String> beHospitalStructureMap = inputInfo.getBeHospitalizedDoc().getStructureMap();
+            String admisTime = beHospitalStructureMap.get("入院日期");
+            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<>();
+            //每7天的病历记录
+            while (i >= 1) {
+                roundRecordThisWeek = extractWardRecord(inputInfo, allDoctorWradDocs, beginDate, hoursPerWeek, lastRecordDate);
+                if (CatalogueUtil.isEmpty(roundRecordThisWeek)) {
+                    break;
+                }
+                lastWardDateRange = DateUtil.formatDate(beginDate) + "    ->    " + DateUtil.formatDate(DateUtil.addDate(beginDate, 6));
+                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++) {
+                int attendNum = CatalogueUtil.appearNumber(roundRecordEveryWeek.get(j).split(","), Content.attend);
+                if (attendNum == 0) {
+                    //每7天无1次主治医师查房记录
+                    status.set("-1");
+                    resultInfos.add(lastWardDateRangeList.get(j));
+                }
+            }
+            if (resultInfos.size() > 0) {
+                info.set(StringUtils.join(resultInfos.toArray(), ";"));
+            }
+        }
+    }
+
+    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("主刀")) {
+                String doctorTitle = CatalogueUtil.getDoctorTitle(operationDocs, recordDate, "主刀医师");
+                title = title.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 "";
+    }
+
+}

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

@@ -0,0 +1,157 @@
+package com.lantone.qc.kernel.catalogue.threelevelward;
+
+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.StringUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : THR03016
+ * @Description : 每3天无1次主治医师查房记录(Fellow查房记录每3天1次)
+ * @Author : 胡敬
+ * @Date: 2020-03-19 15:52
+ */
+@Component
+public class THR03016 extends QCCatalogue {
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        if (inputInfo.getLeaveHospitalDoc() != null) {
+            Map<String, String> leaveHospitalStructureMap = inputInfo.getLeaveHospitalDoc().getStructureMap();
+            String admisTime = leaveHospitalStructureMap.get(Content.admisTime);
+            String dischargeTime = leaveHospitalStructureMap.get(Content.dischargeTime);
+            //如果住院天数小于3天则不判断该条规则
+            if (!CatalogueUtil.isEmpty(admisTime) && !CatalogueUtil.isEmpty(dischargeTime)) {
+                if (!CatalogueUtil.compareTime(StringUtil.parseDateTime(admisTime), StringUtil.parseDateTime(dischargeTime), (long) (3 * 24 * 60))) {
+                    return;
+                }
+            }
+        }
+
+        if (inputInfo.getBeHospitalizedDoc() != null && inputInfo.getThreeLevelWardDocs().size() > 0) {
+            Map<String, String> beHospitalStructureMap = inputInfo.getBeHospitalizedDoc().getStructureMap();
+            String admisTime = beHospitalStructureMap.get("入院日期");
+            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 = 3 * 24 * 60;
+            String roundRecordThisWeek = "";
+            List<String> roundRecordEveryWeek = new ArrayList<>();
+            beginDate = DateUtil.dateZeroClear(beginDate);//从入院记录当天0点开始算
+            int i = 1;
+            String lastWardDateRange = "";
+            List<String> lastWardDateRangeList = new ArrayList<>();
+            //每3天的病历记录
+            while (i >= 1) {
+                roundRecordThisWeek = extractWardRecord(inputInfo, allDoctorWradDocs, beginDate, hoursPerWeek, lastRecordDate);
+                if (CatalogueUtil.isEmpty(roundRecordThisWeek)) {
+                    break;
+                }
+                lastWardDateRange = DateUtil.formatDate(beginDate) + "    ->    " + DateUtil.formatDate(DateUtil.addDate(beginDate, 2));
+                lastWardDateRangeList.add(lastWardDateRange);
+                roundRecordEveryWeek.add(roundRecordThisWeek);
+                beginDate = DateUtil.addDate(beginDate, 3);
+                i++;
+            }
+            if (roundRecordEveryWeek.size() == 0) {
+                status.set("0");
+                return;
+            }
+            List<String> resultInfos = new ArrayList<>();
+            for (int j = 0; j < roundRecordEveryWeek.size(); j++) {
+                int attendNum = CatalogueUtil.appearNumber(roundRecordEveryWeek.get(j).split(","), Content.attend);
+                if (attendNum == 0) {
+                    //每3天无1次主治医师查房记录
+                    status.set("-1");
+                    resultInfos.add(lastWardDateRangeList.get(j));
+                }
+            }
+            if (resultInfos.size() > 0) {
+                info.set(StringUtils.join(resultInfos.toArray(), ";"));
+            }
+        }
+    }
+
+    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分钟内所有查房标题
+     * 抽取一周内所有查房标题,若一周内记录少于2天,则返回""
+     *
+     * @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("主刀")) {
+                String doctorTitle = CatalogueUtil.getDoctorTitle(operationDocs, recordDate, "主刀医师");
+                title = title.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(2 * 24 * 60))) {
+                return recordTitle;
+            }
+        }
+        return "";
+    }
+    
+}