瀏覽代碼

规则更新

zhaops 3 年之前
父節點
當前提交
0d53234b48

+ 216 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/hospital/ningbozhenhai/crisisvaluereport/CRI0382.java

@@ -0,0 +1,216 @@
+package com.lantone.qc.kernel.catalogue.hospital.ningbozhenhai.crisisvaluereport;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.kernel.client.SimilarityServiceClient;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.CrisisInfoDoc;
+import com.lantone.qc.pub.model.doc.CrisisValueReportDoc;
+import com.lantone.qc.pub.model.entity.Annotation;
+import com.lantone.qc.pub.model.vo.SimilarityVo;
+import com.lantone.qc.pub.util.DateUtil;
+import com.lantone.qc.pub.util.StringUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @Description : 危急值记录未在接到危急值报告后6小时内完成
+ * @Author : zhaops
+ * @Date 2022/8/2 13:36
+ */
+@Component
+public class CRI0382 extends QCCatalogue {
+    @Autowired
+    SimilarityServiceClient similarityServiceClient;
+
+    @Override
+    public void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status.set("0");
+        //无危急值结构化信息
+        List<CrisisInfoDoc> crisisInfoDocs = inputInfo.getCrisisInfoDocs();
+        if (crisisInfoDocs == null || crisisInfoDocs.size() == 0) {
+            return;
+        }
+        //有结构化信息但无危急值文书,如果报告时间都未超过6小时 允许无文书
+        boolean isOutTime = false;
+        Date currentDate = new Date();
+        int timeCha = 21600000;
+        String[] dateFormats = new String[]{"yyyy年MM月dd日HH时mm分", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm"};
+        for (CrisisInfoDoc crisisInfoDoc : crisisInfoDocs) {
+            String reptTime = crisisInfoDoc.getStructureMap().get("报告时间");
+            if (StringUtils.isNotEmpty(reptTime)) {
+                if (currentDate.getTime() - StringUtil.parseDateTime(reptTime, dateFormats).getTime() > timeCha) {
+                    isOutTime = true;
+                }
+            }
+        }
+        ;
+        if (isOutTime == false) {   //所有文书都未超过6小时,规则直接通过
+            return;
+        }
+
+        List<CrisisValueReportDoc> crisisValueReportDocs = inputInfo.getCrisisValueReportDocs();
+        //如果有危急值结构化数据 但无文书则直接提醒无危急值报告
+        if (crisisValueReportDocs == null || crisisValueReportDocs.size() == 0) {
+            status.set("-1");
+            return;
+        }
+        List<String> findCrisises = new ArrayList<>();
+        List<String> allCrisises = new ArrayList<>();
+        crisisInfoDocs.forEach(crisisInfoDoc -> {
+            String reptTime = crisisInfoDoc.getStructureMap().get("报告时间");
+            String crisisName = crisisInfoDoc.getStructureMap().get("危急结果值");
+            String crisisNm = "";
+            String companyNum = "";
+            if (crisisName.contains("项目为")) {
+                crisisName = crisisName.substring(crisisName.indexOf("项目为") + 3);
+            }
+            if (crisisName.contains(",结果:")) {
+                crisisNm = crisisName.split(",结果:")[0];
+                companyNum = crisisName.split(",结果:")[1];
+                if (StringUtil.isNotBlank(companyNum) && companyNum.contains("单位:")) {
+                    companyNum = companyNum.replaceAll("单位:", "");
+                }
+            }
+            if (crisisName.matches("[\\s\\S]*[(?==)][^,;,;。]{0,8}(?=秒)[\\s\\S]*")) {
+                crisisName = crisisName.split("=")[0];
+            }
+
+            //匹配文书检验结果书写格式
+            crisisName = StringUtil.removeBlank(crisisName)
+                    .replaceAll("(\\|(R|r)ange:\\d+(\\.\\d+)?(-|-)\\d+(\\.\\d+)?(;|;))", ",")
+                    .replaceAll("=", ":");
+            allCrisises.add(reptTime);
+            if (StringUtils.isNotEmpty(reptTime)) {
+                //当前时间和报告时间未超过6小时,规则通过
+                if (currentDate.getTime() - StringUtil.parseDateTime(reptTime, dateFormats).getTime() < timeCha) {
+                    findCrisises.add(reptTime);
+                } else {
+                    for (CrisisValueReportDoc crisisValueReportDoc : crisisValueReportDocs) {
+                        String recordTimeStr = crisisValueReportDoc.getStructureMap().get("病历日期");
+                        String docReptContent = crisisValueReportDoc.getStructureMap().get("病情分析及处理");
+                        String pattern = "\\d{4}年\\d{1,2}月\\d{1,2}日\\d{1,2}时\\d{1,2}分";
+                        Pattern r = Pattern.compile(pattern);
+                        Matcher m = r.matcher(docReptContent);
+                        Date reptDate = StringUtil.parseDateTime(reptTime, dateFormats);
+
+                        Boolean reptTimeMatch = false;
+                        while (m.find()) {
+                            if (DateUtil.getFirstTimeOfMinute(reptDate).getTime() == StringUtil.parseDateTime(m.group()).getTime()) {
+                                reptTimeMatch = true;
+                            }
+                        }
+                        //超声:添加文本相似度去比较病情分析及处理
+                        boolean flag = getLikeRate(submitContent(StringUtil.removeBlank(docReptContent))
+                                , StringUtil.removeBlank(crisisName));
+                        if ((StringUtil.parseDateTime(recordTimeStr, dateFormats).getTime() - StringUtil.parseDateTime(reptTime, dateFormats).getTime()) < timeCha
+                                && reptTimeMatch
+                                && (StringUtil.removeBlank(docReptContent).contains(StringUtil.removeBlank(crisisName)) ||
+                                (StringUtil.isNotBlank(crisisNm) && StringUtil.isNotBlank(companyNum)
+                                        && StringUtil.removeBlank(docReptContent).contains(StringUtil.removeBlank(crisisNm))
+                                        && StringUtil.removeBlank(docReptContent).contains(StringUtil.removeBlank(companyNum))
+                                ))
+                                || flag) {
+                            findCrisises.add(reptTime);
+                            break;
+                        }
+                    }
+                }
+            }
+        });
+
+        if (findCrisises.size() != allCrisises.size()) {
+            status.set("-1");
+            allCrisises.forEach(reptTime -> {
+                String criticalValueName = "";
+                if (!findCrisises.contains(reptTime) && !info.get().contains(reptTime)) {
+                    for (CrisisInfoDoc crisisInfoDoc : crisisInfoDocs) {
+                        if (reptTime.equals(crisisInfoDoc.getStructureMap().get("报告时间"))) {
+                            criticalValueName = crisisInfoDoc.getStructureMap().get("危急值名称");
+                        }
+                    }
+                    if (StringUtils.isEmpty(info.get())) {
+                        info.set(reptTime + " 危急值名称(" + criticalValueName + ")");
+                    } else {
+                        info.set(info.get() + "; " + reptTime + " 危急值名称(" + criticalValueName + ")");
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * @Author songxl
+     * @Description 内容截取
+     * @Date 2021/3/29
+     * @Param [content]
+     * @Return java.lang.String
+     * @MethodName submitContent
+     */
+    private String submitContent(String content) {
+        if (StringUtil.isNotBlank(content)) {
+            if (content.contains("具体为")) {
+                content = content.split("具体为")[1];
+            }
+            if (content.contains("处理意见")) {
+                content = content.split("处理意见")[0];
+            }
+        }
+        return content;
+
+    }
+
+    /**
+     * @Author songxl
+     * @Description 获取文本相似度
+     * @Date 2021/3/29
+     * @Param [text_1, text_2]
+     * @Return boolean
+     * @MethodName getFlag
+     */
+    private boolean getLikeRate(String text_1, String text_2) {
+        if (text_1.contains("超声")) {
+            JSONArray similarContent = new JSONArray();
+            JSONObject detailContent = new JSONObject();
+            detailContent.put("text_1", text_1);
+            detailContent.put("text_2", text_2);
+            similarContent.add(detailContent);
+            //存储CRF完整所需结构数据
+            SimilarityVo similarityVo = new SimilarityVo();
+            similarityVo.setData(similarContent);
+            //获取CRF模型返回数据
+            JSONArray data = getAnnotation(similarityServiceClient, similarityVo).getData();
+            double likeRate = 0d;
+            if (data.size() > 0) {
+                JSONObject dataContent = data.getJSONObject(0);
+                likeRate = dataContent.getDoubleValue("like_rate");
+            }
+            if (likeRate > 0.8) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private Annotation getAnnotation(SimilarityServiceClient similarityServiceClient, SimilarityVo similarityVo) {
+        Annotation annotation = new Annotation();
+        try {
+            String annotation_str = similarityServiceClient.getAnnotation(similarityVo);
+            annotation = JSON.parseObject(annotation_str, Annotation.class);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        } finally {
+            return annotation;
+        }
+    }
+}

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

@@ -485,6 +485,19 @@ public class DateUtil {
         return cal.getTime();
     }
 
+    /**
+     * 获取某一分钟的0秒的时间
+     *
+     * @param date 输入日期
+     * @return 返回加上0秒的时间
+     */
+    public static Date getFirstTimeOfMinute(Date date) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.set(Calendar.SECOND, 0);
+        return cal.getTime();
+    }
+
     /**
      * 获取某一天的23时59分59秒的时间
      *