Explorar o código

宁波镇海规则新增

zhaops %!s(int64=3) %!d(string=hai) anos
pai
achega
2b3e408dfa

+ 238 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/clinicalblood/CLI0304.java

@@ -0,0 +1,238 @@
+package com.lantone.qc.kernel.catalogue.clinicalblood;
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.util.RegexUtil;
+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.DoctorAdviceDoc;
+import com.lantone.qc.pub.model.doc.FirstPageRecordDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * @Description :无输血前化验检查
+ * @Author : zhaops
+ * @Date 2022/7/8 10:19
+ */
+@Component
+public class CLI0304 extends QCCatalogue {
+    /**
+     * 1.病历包含【输血*记录】时,获取【临时医嘱】处方类型为(化验/检验/检查)是否存在:(输血前检查/术前三项/术前四项/感染四项/输血前四项)中任意一项,
+     * 1.1若不存在查(乙*肝、丙*肝、人类免疫缺陷病毒、梅毒)是否全部存在,仍不存在报出。
+     * 1.2存在后再查(血型/血型鉴定/血型血清学检查/血型鉴定与抗体筛查)是否存在任意一项,不存在则报出。
+     * 1.3都存在时判断化验医嘱开始日期是否都在“输血*记录”之前。多份输血记录时只走第一份时间,日期只对比到天数
+     * 2.【临时医嘱】包含【输*血/输*红细胞/输*血小板/输*血浆/输*冷沉淀因子】但排除带“预约”。出现时。获取【临时医嘱】处方类型为(化验/检验/检查)是否存在:
+     * 2.1(输血前检查/术前三项/术前四项/感染四项/输血前四项)中任意一项。若不存在查(乙*肝、丙*肝、人类免疫缺陷病毒、梅毒)是否全部存在,仍不存在报出,
+     * 2.2存在后再查(血型/血型鉴定/血型血清学检查/血型鉴定与抗体筛查)是否存在任意一项,不存在则报出。
+     * 2.3都存在时判断化验医嘱开始日期是否都在“输血医嘱”之前。多份输血医嘱只走最早时间,只对比到天数
+     * 3.【病案首页】(血费>0)出现时,获取【临时医嘱】处方类型为(化验/检验/检查)是否存在:(输血前检查/术前三项/术前四项/感染四项/输血前四项)中任意一项。
+     * 3.1若不存在查(乙*肝、丙*肝、人类免疫缺陷病毒、梅毒)是否全部存在,仍不存在报出,
+     * 3.2存在后再查(血型/血型鉴定/血型血清学检查/血型鉴定与抗体筛查)是否存在任意一项,不存在则报出。
+     */
+
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        List<ClinicalBloodDoc> clinicalBloodDocs = inputInfo.getClinicalBloodDocs();
+        List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
+        FirstPageRecordDoc firstPageRecordDoc = inputInfo.getFirstPageRecordDoc();
+
+        if (ListUtil.isEmpty(doctorAdviceDocs)) {
+            status.set("0");
+            return;
+        }
+
+        String[] dateFormats = new String[]{"yyyy年MM月dd日", "yyyy-MM-dd", "yyyy-MM-dd"};
+        String regex1 = "输血前检查|术前三项|术前四项|感染四项|输血前四项";
+        String regex2 = "乙[\\u4E00-\\u9FA5A-Za-z]{0,}肝";
+        String regex3 = "丙[\\u4E00-\\u9FA5A-Za-z]{0,}肝";
+        String regex4 = "血型|血型鉴定|血型血清学检查|血型鉴定与抗体筛查";
+        String regex5 = "输[\\u4E00-\\u9FA5A-Za-z]{0,}(血|红细胞|血小板|血浆|冷沉淀因子)";
+        List<String> strList = Lists.newArrayList("输血前检查", "术前三项", "术前四项", "感染四项", "输血前四项");
+
+        //医嘱类型判别:临时医嘱,医嘱处方类型:化验、检验、检查
+        List<DoctorAdviceDoc> filterDAList = doctorAdviceDocs.stream().filter(Objects::nonNull)
+                .filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱类型判别")) && i.getStructureMap().get("医嘱判别类型").equals("临时医嘱"))
+                .filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱处方类型"))
+                        && (i.getStructureMap().get("医嘱处方类型").contains("化验")
+                        || i.getStructureMap().get("医嘱处方类型").contains("检验")
+                        || i.getStructureMap().get("医嘱处方类型").contains("检查")))
+                .collect(Collectors.toList());
+        if (ListUtil.isEmpty(filterDAList)) {
+            status.set("0");
+            return;
+        }
+
+        //病历包含【输血*记录】时
+        if (ListUtil.isNotEmpty(clinicalBloodDocs)) {
+            List<DoctorAdviceDoc> itemDAList = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                            && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), regex1)))
+                    .collect(Collectors.toList());
+
+            if (ListUtil.isEmpty(itemDAList)) {
+                List<DoctorAdviceDoc> l1 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), regex2)))
+                        .collect(Collectors.toList());
+                List<DoctorAdviceDoc> l2 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), regex3)))
+                        .collect(Collectors.toList());
+                List<DoctorAdviceDoc> l3 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), "人类免疫缺陷病毒")))
+                        .collect(Collectors.toList());
+                List<DoctorAdviceDoc> l4 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), "梅毒")))
+                        .collect(Collectors.toList());
+                if (ListUtil.isNotEmpty(l1) && ListUtil.isNotEmpty(l2) && ListUtil.isNotEmpty(l3) && ListUtil.isNotEmpty(l4)) {
+                    status.set("-1");
+                    return;
+                }
+            } else {
+                List<DoctorAdviceDoc> l1 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), regex4)))
+                        .collect(Collectors.toList());
+                if (ListUtil.isEmpty(l1)) {
+                    status.set("-1");
+                    return;
+                }
+            }
+
+            if (filterDAList.stream().map(i -> i.getStructureMap().get("医嘱项目名称")).collect(Collectors.toList())
+                    .containsAll(strList)) {
+                //输血记录日期
+                List<Date> cBDateList = clinicalBloodDocs.stream()
+                        .filter(Objects::nonNull)
+                        .filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("病历日期")))
+                        .map(i -> StringUtil.parseDateTime(i.getStructureMap().get("病历日期"), dateFormats))
+                        .sorted((Comparator.comparing(i -> i)))
+                        .collect(Collectors.toList());
+
+                //医嘱日期
+                List<Date> daDateList = filterDAList.stream()
+                        .filter(Objects::nonNull)
+                        .filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱开始时间")))
+                        .map(i -> StringUtil.parseDateTime(i.getStructureMap().get("医嘱开始时间"), dateFormats))
+                        .sorted((Comparator.comparing(i -> i)))
+                        .collect(Collectors.toList());
+
+                if (ListUtil.isNotEmpty(cBDateList) && ListUtil.isNotEmpty(daDateList)
+                        && cBDateList.get(0).after(daDateList.get(daDateList.size() - 1))) {
+                    status.set("-1");
+                    return;
+                }
+            }
+        }
+
+        //输血临时医嘱
+        List<DoctorAdviceDoc> clinicalBloodDAList = doctorAdviceDocs.stream().filter(Objects::nonNull)
+                .filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱类型判别")) && i.getStructureMap().get("医嘱判别类型").equals("临时医嘱"))
+                .filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                        && (!i.getStructureMap().get("医嘱项目名称").contains("预约"))
+                        && RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), regex5))
+                .collect(Collectors.toList());
+        if (ListUtil.isNotEmpty(clinicalBloodDAList)) {
+            if (ListUtil.isNotEmpty(filterDAList)) {
+                List<DoctorAdviceDoc> itemDAList = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), regex1)))
+                        .collect(Collectors.toList());
+
+                if (ListUtil.isEmpty(itemDAList)) {
+                    List<DoctorAdviceDoc> l1 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                    && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), regex2)))
+                            .collect(Collectors.toList());
+                    List<DoctorAdviceDoc> l2 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                    && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), regex3)))
+                            .collect(Collectors.toList());
+                    List<DoctorAdviceDoc> l3 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                    && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), "人类免疫缺陷病毒")))
+                            .collect(Collectors.toList());
+                    List<DoctorAdviceDoc> l4 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                    && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), "梅毒")))
+                            .collect(Collectors.toList());
+                    if (ListUtil.isNotEmpty(l1) && ListUtil.isNotEmpty(l2) && ListUtil.isNotEmpty(l3) && ListUtil.isNotEmpty(l4)) {
+                        status.set("-1");
+                        return;
+                    }
+                } else {
+                    List<DoctorAdviceDoc> l1 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                    && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), regex4)))
+                            .collect(Collectors.toList());
+                    if (ListUtil.isEmpty(l1)) {
+                        status.set("-1");
+                        return;
+                    }
+                }
+
+                if (filterDAList.stream().map(i -> i.getStructureMap().get("医嘱项目名称")).collect(Collectors.toList())
+                        .containsAll(strList)) {
+                    //输血医嘱日期
+                    List<Date> cBDateList = clinicalBloodDAList.stream()
+                            .filter(Objects::nonNull)
+                            .filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱开始时间")))
+                            .map(i -> StringUtil.parseDateTime(i.getStructureMap().get("医嘱开始时间"), dateFormats))
+                            .sorted((Comparator.comparing(i -> i)))
+                            .collect(Collectors.toList());
+
+                    //医嘱日期
+                    List<Date> daDateList = filterDAList.stream()
+                            .filter(Objects::nonNull)
+                            .filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱开始时间")))
+                            .map(i -> StringUtil.parseDateTime(i.getStructureMap().get("医嘱开始时间"), dateFormats))
+                            .sorted((Comparator.comparing(i -> i)))
+                            .collect(Collectors.toList());
+
+                    if (ListUtil.isNotEmpty(cBDateList) && ListUtil.isNotEmpty(daDateList)
+                            && cBDateList.get(0).after(daDateList.get(daDateList.size() - 1))) {
+                        status.set("-1");
+                        return;
+                    }
+
+                }
+
+            }
+        }
+
+        //【病案首页】(血费>0)出现时
+        if (firstPageRecordDoc != null && firstPageRecordDoc.getStructureMap().containsKey("血费")) {
+            if (BigDecimal.valueOf(Double.valueOf(firstPageRecordDoc.getStructureMap().get("血费"))).compareTo(BigDecimal.ZERO) == 1) {
+                List<DoctorAdviceDoc> itemDAList = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), regex1)))
+                        .collect(Collectors.toList());
+
+                if (ListUtil.isEmpty(itemDAList)) {
+                    List<DoctorAdviceDoc> l1 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                    && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), regex2)))
+                            .collect(Collectors.toList());
+                    List<DoctorAdviceDoc> l2 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                    && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), regex3)))
+                            .collect(Collectors.toList());
+                    List<DoctorAdviceDoc> l3 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                    && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), "人类免疫缺陷病毒")))
+                            .collect(Collectors.toList());
+                    List<DoctorAdviceDoc> l4 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                    && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), "梅毒")))
+                            .collect(Collectors.toList());
+                    if (ListUtil.isNotEmpty(l1) && ListUtil.isNotEmpty(l2) && ListUtil.isNotEmpty(l3) && ListUtil.isNotEmpty(l4)) {
+                        status.set("-1");
+                        return;
+                    }
+                } else {
+                    List<DoctorAdviceDoc> l1 = filterDAList.stream().filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱项目名称"))
+                                    && (RegexUtil.getRegexRes(i.getStructureMap().get("医嘱项目名称"), regex4)))
+                            .collect(Collectors.toList());
+                    if (ListUtil.isEmpty(l1)) {
+                        status.set("-1");
+                        return;
+                    }
+                }
+            }
+        }
+    }
+}

+ 56 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/firstcourserecord/FIRC03230.java

@@ -0,0 +1,56 @@
+package com.lantone.qc.kernel.catalogue.firstcourserecord;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.util.RegexUtil;
+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.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Description : 未记录中医辩证分析
+ * @Author : zhaops
+ *
+ * @Date 2022/7/7 10:30
+ */
+@Component
+public class FIRC03230 extends QCCatalogue {
+
+    /**
+     * 首先找到首次病程录,未找到则通过。
+     * 首次病程录结构化数据或文本数据存在,然后获取"诊断依据"
+     * 1,文本形式是否包含有“辨证/辨病/论治/中医辨病辨证依据”。
+     * 或2.结构化“中医辨病辨证依据/辨[^。,;。,;]{0,5}证[^。,;。,;]{0,5}依据”后数据不为空,仅为标点符号或阿拉伯数字,或非文字则报出
+     */
+
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
+        if (firstCourseRecordDoc == null) {
+            status.set("0");
+            return;
+        }
+
+        String text = firstCourseRecordDoc.getText();
+        String diagnoseText = firstCourseRecordDoc.getStructureMap() != null
+                ? firstCourseRecordDoc.getStructureMap().get("诊断依据")
+                : "";
+
+        if (StringUtil.isBlank(text) && StringUtil.isBlank(diagnoseText)) {
+            status.set("0");
+            return;
+        }
+        String regex1 = "辨证|辨病|论治|中医辨病辨证依据";
+        String regex2 = "(中医辨病辨证依据|(辨[^。,;。,;]{0,5}证[^。,;。,;]{0,5}依据))[。,;:。,;:\\d]{0,}[\\u4E00-\\u9FA5A-Za-z]+";
+
+        if ((StringUtil.isNotBlank(text) && RegexUtil.getRegexRes(text, regex1))
+                || (StringUtil.isNotBlank(diagnoseText) && RegexUtil.getRegexRes(diagnoseText, regex2))) {
+            status.set("0");
+            return;
+        } else {
+            status.set("-1");
+            return;
+        }
+
+    }
+}

+ 56 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/firstcourserecord/FIRC03231.java

@@ -0,0 +1,56 @@
+package com.lantone.qc.kernel.catalogue.firstcourserecord;
+
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.util.RegexUtil;
+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.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Description : 无中医鉴别诊断
+ * @Author : zhaops
+ *
+ * @Date 2022/7/7 10:30
+ */
+@Component
+public class FIRC03231 extends QCCatalogue {
+    /**
+     * 首先找到首次病程录,未找到则通过。
+     * 首次病程录结构化数据或文本数据存在,然后获取"鉴别诊断"
+     * 1,文本形式是否包含有“中医鉴别诊断/中医[^。,;。,;]{0,5}鉴别”,无则报出
+     * 或2.结构化“中医鉴别诊断/中医[^。,;。,;]{0,5}鉴别”后数据不为空,仅为标点符号或阿拉伯数字,或非文字则报出
+     */
+
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
+        if (firstCourseRecordDoc == null) {
+            status.set("0");
+            return;
+        }
+
+        String text = firstCourseRecordDoc.getText();
+        String diagText = firstCourseRecordDoc.getStructureMap() != null
+                ? firstCourseRecordDoc.getStructureMap().get("鉴别诊断")
+                : "";
+
+        if (StringUtil.isBlank(text) && StringUtil.isBlank(diagText)) {
+            status.set("0");
+            return;
+        }
+        String regex1 = "中医鉴别诊断|(中医[^。,;。,;]{0,5}鉴别)";
+        String regex2 = "(中医鉴别诊断|(中医[^。,;。,;]{0,5}鉴别))[。,;:。,;:\\d]{0,}[\\u4E00-\\u9FA5A-Za-z]+";
+
+        if ((StringUtil.isNotBlank(text) && RegexUtil.getRegexRes(text, regex1))
+                || (StringUtil.isNotBlank(diagText) && RegexUtil.getRegexRes(diagText, regex2))) {
+            status.set("0");
+            return;
+        } else {
+            status.set("-1");
+            return;
+        }
+
+    }
+}

+ 76 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/firstcourserecord/FIRC03232.java

@@ -0,0 +1,76 @@
+package com.lantone.qc.kernel.catalogue.firstcourserecord;
+
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.util.RegexUtil;
+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.DiagnosisLabel;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Description :无中医四诊
+ * @Author : zhaops
+ *
+ * @Date 2022/7/7 10:30
+ */
+@Component
+public class FIRC03232 extends QCCatalogue {
+    /**
+     * 首先找到首次病程录,未找到则通过。
+     * 首次病程录结构化数据或文本数据存在,然后获取"病例特点/诊断依据"
+     * 查找"病例特点/诊断依据"文本形式内是否包含有
+     * “四诊/神色/神态/面色/面[^。,;。,;]{0,5}(黄|红|青|暗|紫|黑|白)/气血/形态/语声/语气/音色/声音[^。,;。,;]{0,5}弱/气息/舌象/舌/苔/脉/血虚/气血/",
+     * 其中任意两项则通过。
+     * 或(模型标注四诊),若存在则通过
+     */
+
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
+        if (firstCourseRecordDoc == null) {
+            status.set("0");
+            return;
+        }
+
+        String text = firstCourseRecordDoc.getText();
+        String diagnoseText = firstCourseRecordDoc.getStructureMap() != null
+                ? firstCourseRecordDoc.getStructureMap().get("诊断依据")
+                : "";
+        String caseCharacteristicText = firstCourseRecordDoc.getStructureMap() != null
+                ? firstCourseRecordDoc.getStructureMap().get("病例特点")
+                : "";
+
+        //病历特点
+        CaseCharacteristicLabel caseCharacteristicLabel = firstCourseRecordDoc.getCaseCharacteristicLabel();
+        //诊断依据
+        DiagnosisLabel diagnosisLabel = firstCourseRecordDoc.getDiagnosisLabel();
+
+        if (StringUtil.isBlank(text) && StringUtil.isBlank(diagnoseText) && StringUtil.isBlank(caseCharacteristicText)
+                && null == caseCharacteristicLabel
+                && null == diagnosisLabel) {
+            status.set("0");
+            return;
+        }
+
+        String diagnoseText_crf = diagnosisLabel.getText();
+        String caseCharacteristicText_crf = caseCharacteristicLabel.getText();
+
+        String regex = "四诊|神色|神态|面色|(面[^。,;。,;]{0,5}(黄|红|青|暗|紫|黑|白))|气血|形态|语声|语气|音色|(声音[^。,;。,;]{0,5}弱)|气息|舌象|舌|苔|脉|血虚|气血";
+
+        if ((StringUtil.isNotBlank(text) && RegexUtil.getRegexRes(text, regex, 2))
+                || (StringUtil.isNotBlank(diagnoseText) && RegexUtil.getRegexRes(diagnoseText, regex, 2))
+                || (StringUtil.isNotBlank(caseCharacteristicText) && RegexUtil.getRegexRes(caseCharacteristicText, regex, 2))
+                || (StringUtil.isNotBlank(diagnoseText_crf) && RegexUtil.getRegexRes(diagnoseText_crf, "四诊"))
+                || (StringUtil.isNotBlank(caseCharacteristicText_crf) && RegexUtil.getRegexRes(caseCharacteristicText_crf, "四诊"))) {
+            status.set("0");
+            return;
+        } else {
+            status.set("-1");
+            return;
+        }
+
+    }
+}

+ 182 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03233.java

@@ -0,0 +1,182 @@
+package com.lantone.qc.kernel.catalogue.threelevelward;
+
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.util.RegexUtil;
+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.LeaveHospitalDoc;
+import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Description :  使用中药饮片治疗未记录四诊
+ * @Author : zhaops
+ *
+ * @Date 2022/7/7 10:30
+ */
+@Component
+public class THR03233 extends QCCatalogue {
+    /**
+     * 1.首先判断医嘱是否存在。若不存在则返回,
+     * 2.然后获取医嘱类型名称含有"普药/中药"的医嘱,去医嘱内查找中药饮片(详见中药饮片列表),未存在则通过。
+     * 3.根据中药饮片医嘱的开始时间(同一天开的中药饮片只算一次),找往前一天往后2天的时间段内文书,
+     * 在“首程诊疗计划、查房记录、出院小结”等存在的情况下获取其中的信息,是否包含有“四诊/神色/神态/面色/形态/语声/气息/舌象/舌/苔/脉/血虚/气血",
+     * 其中任意两项则通过。或(模型标注四诊),若存在则通过,未找到符合四诊情况的则报出
+     */
+
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+
+        List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
+        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
+        LeaveHospitalDoc leaveHospitalDoc = inputInfo.getLeaveHospitalDoc();
+        List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
+
+        if (ListUtil.isEmpty(doctorAdviceDocs)) {
+            status.set("0");
+            return;
+        }
+
+        doctorAdviceDocs = doctorAdviceDocs.stream()
+                .filter(Objects::nonNull)
+                .filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱处方类型"))
+                        && (i.getStructureMap().get("医嘱处方类型").equals("药品")))
+                .filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("药品类型"))
+                        && (i.getStructureMap().get("药品类型").equals("普药") || i.getStructureMap().get("药品类型").equals("中药")))
+                .collect(Collectors.toList());
+        if (ListUtil.isEmpty(doctorAdviceDocs)) {
+            status.set("0");
+            return;
+        }
+
+        Boolean isRecord = false;
+        List<DoctorAdviceDoc> recordList = Lists.newLinkedList();
+        List<String> chinesemedicineyinpian = Content.CHINESEMEDICINEYINPIAN;
+        for (DoctorAdviceDoc item : doctorAdviceDocs) {
+            if (null != item.getStructureMap()) {
+                if (RegexUtil.getRegexListRes(item.getStructureMap().get("医嘱项目名称"), chinesemedicineyinpian)) {
+                    if (!recordList.contains(item)) {
+                        recordList.add(item);
+                    }
+                    isRecord = true;
+                }
+            }
+        }
+        if (!isRecord) {
+            status.set("0");
+            return;
+        }
+
+
+        List<String> date = Lists.newLinkedList();
+        for (DoctorAdviceDoc item : recordList) {
+            if (null != item.getStructureMap().get("医嘱开始时间")) {
+                date.add(item.getStructureMap().get("医嘱开始时间"));
+            }
+        }
+
+        if (ListUtil.isEmpty(date)) {
+            status.set("0");
+            return;
+        }
+
+        String[] dateFormats = new String[]{"yyyy年MM月dd日", "yyyy-MM-dd", "yyyy-MM-dd"};
+
+        /*List<Date> dateList = date.stream().map(i -> {
+                    try {
+                        return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse(i);
+                    } catch (ParseException e) {
+                        e.printStackTrace();
+                    }
+                    return null;
+                })
+                .filter(Objects::nonNull)
+                .sorted(Comparator.comparing(i -> i))
+                .collect(Collectors.toList());*/
+        List<Date> dateList = date.stream().map(i -> StringUtil.parseDateTime(i, dateFormats))
+                .filter(Objects::nonNull)
+                .sorted(Comparator.comparing(i -> i))
+                .collect(Collectors.toList());
+
+        Calendar c1 = Calendar.getInstance();
+        c1.setTime(dateList.get(0));
+        c1.add(Calendar.DAY_OF_MONTH, -1);
+        Calendar c2 = Calendar.getInstance();
+        c1.setTime(dateList.get(dateList.size() - 1));
+        c1.add(Calendar.DAY_OF_MONTH, 2);
+
+        Date startDate = c1.getTime();
+        Date endDate = c2.getTime();
+
+        String regex = "四诊|神色|神态|面色|形态|语声|气息|舌象|舌|苔|脉|血虚|气血";
+
+        //首次诊疗计划
+        if (null != firstCourseRecordDoc) {
+            String treatPlan = firstCourseRecordDoc.getStructureMap().get("诊疗计划");
+            Date treatPlanDate = StringUtil.parseDateTime(firstCourseRecordDoc.getStructureMap().get("病历日期"), dateFormats);
+            if (StringUtil.isNotBlank(treatPlan)
+                    && treatPlanDate.after(startDate)
+                    && treatPlanDate.before(endDate)
+                    && RegexUtil.getRegexRes(treatPlan, regex, 2)) {
+                status.set("0");
+                return;
+            }
+            if (null != firstCourseRecordDoc.getTreatPlanLabel()
+                    && firstCourseRecordDoc.getTreatPlanLabel().getText().contains("四诊")) {
+                status.set("0");
+                return;
+            }
+        }
+
+        //查房记录
+        if (ListUtil.isNotEmpty(threeLevelWardDocs)) {
+            threeLevelWardDocs = threeLevelWardDocs.stream()
+                    .filter(Objects::nonNull)
+                    .filter(i -> i.getStructureMap().containsKey("查房日期") && i.getStructureMap().containsKey("病情记录"))
+                    .filter(i -> StringUtil.parseDateTime(i.getStructureMap().get("查房日期"), dateFormats).after(startDate)
+                            && StringUtil.parseDateTime(i.getStructureMap().get("查房日期"), dateFormats).before(endDate))
+                    .collect(Collectors.toList());
+            if (ListUtil.isNotEmpty(threeLevelWardDocs)) {
+                for (ThreeLevelWardDoc item : threeLevelWardDocs) {
+                    if (RegexUtil.getRegexRes(item.getStructureMap().get("病情记录"), regex, 2)) {
+                        status.set("0");
+                        return;
+                    }
+
+                    //todo 模型记录四诊(暂不处理)
+                    //List<ThreeLevelWardLabel> threeLevelWardLabel = item.getThreeLevelWardLabel();
+                }
+            }
+        }
+
+        //出院小结
+        if (null != leaveHospitalDoc) {
+            String leaveHosText = leaveHospitalDoc.getStructureMap().get("出院医嘱");
+            Date leaveHospitalDate = StringUtil.parseDateTime(firstCourseRecordDoc.getStructureMap().get("出院日期"), dateFormats);
+            if (StringUtil.isNotBlank(leaveHosText)
+                    && leaveHospitalDate.after(startDate)
+                    && leaveHospitalDate.before(endDate)
+                    && RegexUtil.getRegexRes(leaveHosText, regex, 2)) {
+                status.set("0");
+                return;
+            }
+            if (null != leaveHospitalDoc.getLeaveHospitalDoctorAdviceLabel()
+                    && leaveHospitalDoc.getLeaveHospitalDoctorAdviceLabel().getText().contains("四诊")) {
+                status.set("0");
+                return;
+            }
+        }
+
+        status.set("-1");
+        return;
+    }
+}

+ 156 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03234.java

@@ -0,0 +1,156 @@
+package com.lantone.qc.kernel.catalogue.threelevelward;
+
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.util.RegexUtil;
+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.LeaveHospitalDoc;
+import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Description : 使用中药饮片治疗未记录辩证
+ * @Author : zhaops
+ *
+ * @Date 2022/7/7 10:30
+ */
+@Component
+public class THR03234 extends QCCatalogue {
+    /**
+     * 1.首先判断医嘱是否存在。若不存在则返回,
+     * 2.然后获取医嘱中药品类型为"普药/中药"的医嘱,
+     * 去医嘱内查找中药饮片(详见中药饮片列表),未存在则通过。
+     * 3.根据中药饮片医嘱的开始时间(同一天开的中药饮片只算一次),找往前一天往后2天的时间段内文书,
+     * 在“首程诊疗计划、查房记录、出院小结”等存在的情况下获取其中的信息,判断是否包含有“中医辨病辨证依据/中医辩证”,若存在则通过,未找到则报出
+     */
+
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
+        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
+        LeaveHospitalDoc leaveHospitalDoc = inputInfo.getLeaveHospitalDoc();
+        List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
+
+        if (ListUtil.isEmpty(doctorAdviceDocs)) {
+            status.set("0");
+            return;
+        }
+
+        doctorAdviceDocs=doctorAdviceDocs.stream()
+                .filter(Objects::nonNull)
+                .filter(i->StringUtil.isNotBlank(i.getStructureMap().get("医嘱处方类型"))
+                        &&(i.getStructureMap().get("医嘱处方类型").equals("药品")))
+                .filter(i->StringUtil.isNotBlank(i.getStructureMap().get("药品类型"))
+                        &&(i.getStructureMap().get("药品类型").equals("普药")||i.getStructureMap().get("药品类型").equals("中药")))
+                .collect(Collectors.toList());
+        if (ListUtil.isEmpty(doctorAdviceDocs)) {
+            status.set("0");
+            return;
+        }
+
+        Boolean isRecord = false;
+        List<DoctorAdviceDoc> recordList = Lists.newLinkedList();
+        List<String> chinesemedicineyinpian = Content.CHINESEMEDICINEYINPIAN;
+        for (DoctorAdviceDoc item : doctorAdviceDocs) {
+            if (null != item.getStructureMap()) {
+                if (RegexUtil.getRegexListRes(item.getStructureMap().get("医嘱项目名称"), chinesemedicineyinpian)) {
+                    if (!recordList.contains(item)) {
+                        recordList.add(item);
+                    }
+                    isRecord = true;
+                }
+            }
+        }
+        if (!isRecord) {
+            status.set("0");
+            return;
+        }
+
+        List<String> date = Lists.newLinkedList();
+        for (DoctorAdviceDoc item : recordList) {
+            if (null != item.getStructureMap().get("医嘱开始时间")) {
+                date.add(item.getStructureMap().get("医嘱开始时间"));
+            }
+        }
+
+        if (ListUtil.isEmpty(date)) {
+            status.set("0");
+            return;
+        }
+
+        String[] dateFormats = new String[]{"yyyy年MM月dd日", "yyyy-MM-dd", "yyyy-MM-dd"};
+
+        List<Date> dateList = date.stream().map(i -> StringUtil.parseDateTime(i, dateFormats))
+                .filter(Objects::nonNull)
+                .sorted(Comparator.comparing(i -> i))
+                .collect(Collectors.toList());
+
+        Calendar c1 = Calendar.getInstance();
+        c1.setTime(dateList.get(0));
+        c1.add(Calendar.DAY_OF_MONTH, -1);
+        Calendar c2 = Calendar.getInstance();
+        c1.setTime(dateList.get(dateList.size() - 1));
+        c1.add(Calendar.DAY_OF_MONTH, 2);
+
+        Date startDate = c1.getTime();
+        Date endDate = c2.getTime();
+
+        String regex = "中医辨病辨证依据|中医辩证";
+
+        //首次诊疗计划
+        if (null != firstCourseRecordDoc) {
+            String treatPlan = firstCourseRecordDoc.getStructureMap().get("诊疗计划");
+            Date treatPlanDate = StringUtil.parseDateTime(firstCourseRecordDoc.getStructureMap().get("病历日期"), dateFormats);
+            if (StringUtil.isNotBlank(treatPlan)
+                    && treatPlanDate.after(startDate)
+                    && treatPlanDate.before(endDate)
+                    && RegexUtil.getRegexRes(treatPlan, regex, 2)) {
+                status.set("0");
+                return;
+            }
+        }
+
+        //查房记录
+        if (ListUtil.isNotEmpty(threeLevelWardDocs)) {
+            threeLevelWardDocs = threeLevelWardDocs.stream()
+                    .filter(Objects::nonNull)
+                    .filter(i -> i.getStructureMap().containsKey("查房日期") && i.getStructureMap().containsKey("病情记录"))
+                    .filter(i -> StringUtil.parseDateTime(i.getStructureMap().get("查房日期"), dateFormats).after(startDate)
+                            && StringUtil.parseDateTime(i.getStructureMap().get("查房日期"), dateFormats).before(endDate))
+                    .collect(Collectors.toList());
+            if (ListUtil.isNotEmpty(threeLevelWardDocs)) {
+                for (ThreeLevelWardDoc item : threeLevelWardDocs) {
+                    if (RegexUtil.getRegexRes(item.getStructureMap().get("病情记录"), regex, 2)) {
+                        status.set("0");
+                        return;
+                    }
+                }
+            }
+        }
+
+        //出院小结
+        if (null != leaveHospitalDoc) {
+            String leaveHosText = leaveHospitalDoc.getStructureMap().get("出院医嘱");
+            Date leaveHospitalDate = StringUtil.parseDateTime(firstCourseRecordDoc.getStructureMap().get("出院日期"), dateFormats);
+            if (StringUtil.isNotBlank(leaveHosText)
+                    && leaveHospitalDate.after(startDate)
+                    && leaveHospitalDate.before(endDate)
+                    && RegexUtil.getRegexRes(leaveHosText, regex, 2)) {
+                status.set("0");
+                return;
+            }
+        }
+
+        status.set("-1");
+        return;
+    }
+}

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

@@ -0,0 +1,157 @@
+package com.lantone.qc.kernel.catalogue.threelevelward;
+
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.util.RegexUtil;
+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.LeaveHospitalDoc;
+import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Description :使用中药饮片治疗未记录治则或治法
+ * @Author : zhaops
+ *
+ * @Date 2022/7/7 10:30
+ */
+@Component
+public class THR03235 extends QCCatalogue {
+    /**
+     * 1.首先判断医嘱是否存在。若不存在则返回,
+     * 2.然后获取【医嘱处方类型】为"药品/中药"的医嘱,
+     * 去医嘱内查找中药饮片(详见),未存在则通过。
+     * 3.根据中药饮片医嘱的开始时间(同一天开的中药饮片只算一次),找往前一天往后2天的时间段内文书,
+     * 在“首程诊疗计划、查房记录、出院小结”等存在的情况下获取其中的信息,判断该份文书内是否包含有“治则/治为则/治法”,若存在则通过,未找到则报出
+     */
+
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
+        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
+        LeaveHospitalDoc leaveHospitalDoc = inputInfo.getLeaveHospitalDoc();
+        List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
+
+        if (ListUtil.isEmpty(doctorAdviceDocs)) {
+            status.set("0");
+            return;
+        }
+
+        doctorAdviceDocs=doctorAdviceDocs.stream()
+                .filter(Objects::nonNull)
+                .filter(i->StringUtil.isNotBlank(i.getStructureMap().get("医嘱处方类型"))
+                        &&(i.getStructureMap().get("医嘱处方类型").equals("药品")))
+                .filter(i->StringUtil.isNotBlank(i.getStructureMap().get("药品类型"))
+                        &&(i.getStructureMap().get("药品类型").equals("药品")||i.getStructureMap().get("药品类型").equals("中药")))
+                .collect(Collectors.toList());
+        if (ListUtil.isEmpty(doctorAdviceDocs)) {
+            status.set("0");
+            return;
+        }
+
+        List<String> chineseMedicineyinpian = Content.CHINESEMEDICINEYINPIAN;
+        Boolean isRecord = false;
+        List<DoctorAdviceDoc> recordList = Lists.newLinkedList();
+        for (DoctorAdviceDoc item : doctorAdviceDocs) {
+            if (null != item.getStructureMap()) {
+                if (RegexUtil.getRegexListRes(item.getStructureMap().get("医嘱项目名称"), chineseMedicineyinpian)) {
+                    if (!recordList.contains(item)) {
+                        recordList.add(item);
+                    }
+                    isRecord = true;
+                }
+            }
+        }
+        if (!isRecord) {
+            status.set("0");
+            return;
+        }
+
+        List<String> date = Lists.newLinkedList();
+        for (DoctorAdviceDoc item : recordList) {
+            if (null != item.getStructureMap().get("医嘱开始时间")) {
+                date.add(item.getStructureMap().get("医嘱开始时间"));
+            }
+        }
+
+        if (ListUtil.isEmpty(date)) {
+            status.set("0");
+            return;
+        }
+
+        String[] dateFormats = new String[]{"yyyy年MM月dd日", "yyyy-MM-dd", "yyyy-MM-dd"};
+
+        List<Date> dateList = date.stream().map(i -> StringUtil.parseDateTime(i, dateFormats))
+                .filter(Objects::nonNull)
+                .sorted(Comparator.comparing(i -> i))
+                .collect(Collectors.toList());
+
+        Calendar c1 = Calendar.getInstance();
+        c1.setTime(dateList.get(0));
+        c1.add(Calendar.DAY_OF_MONTH, -1);
+        Calendar c2 = Calendar.getInstance();
+        c1.setTime(dateList.get(dateList.size() - 1));
+        c1.add(Calendar.DAY_OF_MONTH, 2);
+
+        Date startDate = c1.getTime();
+        Date endDate = c2.getTime();
+
+        String regex = "治则|治为则|治法";
+
+        //首次诊疗计划
+        if (null != firstCourseRecordDoc) {
+            String treatPlan = firstCourseRecordDoc.getStructureMap().get("诊疗计划");
+            Date treatPlanDate = StringUtil.parseDateTime(firstCourseRecordDoc.getStructureMap().get("病历日期"), dateFormats);
+            if (StringUtil.isNotBlank(treatPlan)
+                    && treatPlanDate.after(startDate)
+                    && treatPlanDate.before(endDate)
+                    && RegexUtil.getRegexRes(treatPlan, regex, 2)) {
+                status.set("0");
+                return;
+            }
+        }
+
+        //查房记录
+        if (ListUtil.isNotEmpty(threeLevelWardDocs)) {
+            threeLevelWardDocs = threeLevelWardDocs.stream()
+                    .filter(Objects::nonNull)
+                    .filter(i -> i.getStructureMap().containsKey("查房日期") && i.getStructureMap().containsKey("病情记录"))
+                    .filter(i -> StringUtil.parseDateTime(i.getStructureMap().get("查房日期"), dateFormats).after(startDate)
+                            && StringUtil.parseDateTime(i.getStructureMap().get("查房日期"), dateFormats).before(endDate))
+                    .collect(Collectors.toList());
+            if (ListUtil.isNotEmpty(threeLevelWardDocs)) {
+                for (ThreeLevelWardDoc item : threeLevelWardDocs) {
+                    if (RegexUtil.getRegexRes(item.getStructureMap().get("病情记录"), regex, 2)) {
+                        status.set("0");
+                        return;
+                    }
+                }
+            }
+        }
+
+        //出院小结
+        if (null != leaveHospitalDoc) {
+            String leaveHosText = leaveHospitalDoc.getStructureMap().get("出院医嘱");
+            Date leaveHospitalDate = StringUtil.parseDateTime(firstCourseRecordDoc.getStructureMap().get("出院日期"), dateFormats);
+            if (StringUtil.isNotBlank(leaveHosText)
+                    && leaveHospitalDate.after(startDate)
+                    && leaveHospitalDate.before(endDate)
+                    && RegexUtil.getRegexRes(leaveHosText, regex, 2)) {
+                status.set("0");
+                return;
+            }
+        }
+
+        status.set("-1");
+        return;
+
+    }
+}

+ 159 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/threelevelward/THR03236.java

@@ -0,0 +1,159 @@
+package com.lantone.qc.kernel.catalogue.threelevelward;
+
+
+import com.google.common.collect.Lists;
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.util.RegexUtil;
+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.LeaveHospitalDoc;
+import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Description :使用中成药治疗未记录辩证
+ * @Author : zhaops
+ *
+ * @Date 2022/7/7 10:30
+ */
+@Component
+public class THR03236 extends QCCatalogue {
+    /**
+     * 1.首先判断医嘱是否存在。若不存在则返回,
+     * 2.然后获取【医嘱处方类型】为"药品"的医嘱,根据【给药方式】“口服/静滴/静推”筛选出“中成药”的医嘱(详见中成药列表),未存在则通过。
+     * 3.根据“中成药”医嘱的开始时间(同一“中成药”同一天内只算一次),找往前一天往后2天的时间段内文书,
+     * 在“首次病程录中的诊疗计划、查房记录、出院小结的出院医嘱”等存在的情况下其中的信息,然后根据信息文本匹配医嘱的药物,
+     * 找到相符合药物后判断该份文书内文本形式是否包含有“中医辨病辨证依据/中医辩证”,若存在则通过,未找到则报出
+     */
+
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        List<DoctorAdviceDoc> doctorAdviceDocs = inputInfo.getDoctorAdviceDocs();
+        FirstCourseRecordDoc firstCourseRecordDoc = inputInfo.getFirstCourseRecordDoc();
+        LeaveHospitalDoc leaveHospitalDoc = inputInfo.getLeaveHospitalDoc();
+        List<ThreeLevelWardDoc> threeLevelWardDocs = inputInfo.getThreeLevelWardDocs();
+
+        if (ListUtil.isEmpty(doctorAdviceDocs)) {
+            status.set("0");
+            return;
+        }
+
+        doctorAdviceDocs = doctorAdviceDocs.stream()
+                .filter(Objects::nonNull)
+                .filter(i -> StringUtil.isNotBlank(i.getStructureMap().get("医嘱处方类型"))
+                        && i.getStructureMap().get("医嘱处方类型").contains("药品"))
+                .collect(Collectors.toList());
+        if (ListUtil.isEmpty(doctorAdviceDocs)) {
+            status.set("0");
+            return;
+        }
+
+
+        String regex1 = "口服|静滴|静推";
+        List<String> chineseMedicine = Content.CHINESEMEDICINE;
+        Boolean isRecord = false;
+        List<DoctorAdviceDoc> recordList = Lists.newLinkedList();
+        for (DoctorAdviceDoc item : doctorAdviceDocs) {
+            if (null != item.getStructureMap()) {
+                if (item.getStructureMap().containsKey("给药方式") && RegexUtil.getRegexRes(item.getStructureMap().get("给药方式"), regex1)) {
+                    if (RegexUtil.getRegexListRes(item.getStructureMap().get("医嘱项目名称"), chineseMedicine)) {
+                        if (!recordList.contains(item)) {
+                            recordList.add(item);
+                        }
+                        isRecord = true;
+                    }
+                }
+            }
+        }
+        if (!isRecord) {
+            status.set("0");
+            return;
+        }
+
+
+        List<String> date = Lists.newLinkedList();
+        for (DoctorAdviceDoc item : recordList) {
+            if (null != item.getStructureMap().get("医嘱开始时间")) {
+                date.add(item.getStructureMap().get("医嘱开始时间"));
+            }
+        }
+
+        if (ListUtil.isEmpty(date)) {
+            status.set("0");
+            return;
+        }
+
+        String[] dateFormats = new String[]{"yyyy年MM月dd日", "yyyy-MM-dd", "yyyy-MM-dd"};
+
+        List<Date> dateList = date.stream().map(i -> StringUtil.parseDateTime(i, dateFormats))
+                .filter(Objects::nonNull)
+                .sorted(Comparator.comparing(i -> i))
+                .collect(Collectors.toList());
+
+        Calendar c1 = Calendar.getInstance();
+        c1.setTime(dateList.get(0));
+        c1.add(Calendar.DAY_OF_MONTH, -1);
+        Calendar c2 = Calendar.getInstance();
+        c1.setTime(dateList.get(dateList.size() - 1));
+        c1.add(Calendar.DAY_OF_MONTH, 2);
+
+        Date startDate = c1.getTime();
+        Date endDate = c2.getTime();
+
+        String regex = "中医辨病辨证依据|中医辩证";
+
+        //首次诊疗计划
+        if (null != firstCourseRecordDoc) {
+            String treatPlan = firstCourseRecordDoc.getStructureMap().get("诊疗计划");
+            Date treatPlanDate = StringUtil.parseDateTime(firstCourseRecordDoc.getStructureMap().get("病历日期"), dateFormats);
+            if (StringUtil.isNotBlank(treatPlan)
+                    && treatPlanDate.after(startDate)
+                    && treatPlanDate.before(endDate)
+                    && RegexUtil.getRegexRes(treatPlan, regex, 2)) {
+                status.set("0");
+                return;
+            }
+        }
+
+        //查房记录
+        if (ListUtil.isNotEmpty(threeLevelWardDocs)) {
+            threeLevelWardDocs = threeLevelWardDocs.stream()
+                    .filter(Objects::nonNull)
+                    .filter(i -> i.getStructureMap().containsKey("查房日期") && i.getStructureMap().containsKey("病情记录"))
+                    .filter(i -> StringUtil.parseDateTime(i.getStructureMap().get("查房日期"), dateFormats).after(startDate)
+                            && StringUtil.parseDateTime(i.getStructureMap().get("查房日期"), dateFormats).before(endDate))
+                    .collect(Collectors.toList());
+            if (ListUtil.isNotEmpty(threeLevelWardDocs)) {
+                for (ThreeLevelWardDoc item : threeLevelWardDocs) {
+                    if (RegexUtil.getRegexRes(item.getStructureMap().get("病情记录"), regex, 2)) {
+                        status.set("0");
+                        return;
+                    }
+                }
+            }
+        }
+
+        //出院小结
+        if (null != leaveHospitalDoc) {
+            String leaveHosText = leaveHospitalDoc.getStructureMap().get("出院医嘱");
+            Date leaveHospitalDate = StringUtil.parseDateTime(firstCourseRecordDoc.getStructureMap().get("出院日期"), dateFormats);
+            if (StringUtil.isNotBlank(leaveHosText)
+                    && leaveHospitalDate.after(startDate)
+                    && leaveHospitalDate.before(endDate)
+                    && RegexUtil.getRegexRes(leaveHosText, regex, 2)) {
+                status.set("0");
+                return;
+            }
+        }
+
+        status.set("-1");
+        return;
+    }
+}

+ 79 - 0
kernel/src/main/java/com/lantone/qc/kernel/util/RegexUtil.java

@@ -0,0 +1,79 @@
+package com.lantone.qc.kernel.util;
+
+import com.lantone.qc.pub.util.StringUtil;
+
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description :
+ * @Author : zhaops
+ * @Date 2022/7/7 10:57
+ */
+public class RegexUtil {
+    public static Boolean getRegexRes(String content, String regex) {
+        // 是否有符合的数据
+        try {
+            if (StringUtil.isBlank(content) || StringUtil.isBlank(regex)) {
+                return false;
+            }
+            Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
+            Matcher matcher = pattern.matcher(content);
+            if (matcher.find()) {
+                return true;
+            }
+        } catch (Exception e) {
+            return false;
+        }
+        return false;
+    }
+
+    /**
+     * 匹配指定个数条件
+     *
+     * @param content
+     * @param regex
+     * @param num
+     * @return
+     */
+    public static Boolean getRegexRes(String content, String regex, Integer num) {
+        // 是否有符合的数据
+        Integer count = 0;
+        try {
+            if (StringUtil.isBlank(content) || StringUtil.isBlank(regex)) {
+                return false;
+            }
+            Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
+            Matcher matcher = pattern.matcher(content);
+            if (matcher.find()) {
+                count++;
+            }
+            if (count >= num) {
+                return true;
+            }
+        } catch (Exception e) {
+            return false;
+        }
+        return false;
+    }
+
+    public static Boolean getRegexListRes(String content, List<String> regexList) {
+        // 是否有符合的数据
+        try {
+            for (String regex : regexList) {
+                if (StringUtil.isBlank(content) || StringUtil.isBlank(regex)) {
+                    return false;
+                }
+                Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
+                Matcher matcher = pattern.matcher(content);
+                if (matcher.find()) {
+                    return true;
+                }
+            }
+        } catch (Exception e) {
+            return false;
+        }
+        return false;
+    }
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 20 - 2
public/src/main/java/com/lantone/qc/pub/Content.java


+ 1 - 1
trans/src/main/java/com/lantone/qc/trans/shengzhouyy/FirstCourseRecordDocTrans.java

@@ -91,7 +91,7 @@ public class FirstCourseRecordDocTrans extends ModelDocTrans {
             "体温(口)=体温口",
             "病程时间=病历日期",
             "记录医师=记录医生",
-            "病例日期=病历日期",
+            "=病历日期",
             "一般情况=病历内容",
             "3.鉴别诊断=鉴别诊断",
             "1.初步诊断=初步诊断",