Kaynağa Gözat

Merge remote-tracking branch 'origin/master'

rengb 5 yıl önce
ebeveyn
işleme
5ed27cb7bb

+ 43 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/operationdiscussion/OPE0350.java

@@ -0,0 +1,43 @@
+package com.lantone.qc.kernel.catalogue.operationdiscussion;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+
+import java.text.ParseException;
+import java.util.List;
+
+/**
+ * @Description: 术后首次病程记录未记录术中所见
+ * @author: 胡敬
+ * @time: 2020/3/24 13:28
+ */
+public class OPE0350 extends QCCatalogue {
+    @Override
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status = "0";
+        boolean isOperativePatient = true;//是手术患者(暂时默认是)
+        if (isOperativePatient) {
+            List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+            if (ListUtil.isNotEmpty(operationDocs)) {
+                long count = operationDocs.stream().filter(operationDoc -> {
+                    boolean flag = false;
+                    if (operationDoc.getOperationDiscussionDoc() != null
+                            && operationDoc.getOperationDiscussionDoc().getOperationDiscussionLabel() != null
+                            && (StringUtil.isBlank(operationDoc.getOperationDiscussionDoc().getOperationDiscussionLabel().getOperativeFindings())
+                            || operationDoc.getOperationDiscussionDoc().getOperationDiscussionLabel().getOperativeFindings().length() < 30)) {
+                        flag = true;
+                    }
+                    return true;
+                }).count();
+                if (count > 0) {
+                    status = "-1";
+                }
+            }
+        }
+    }
+
+}

+ 41 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/operationdiscussion/OPE0351.java

@@ -0,0 +1,41 @@
+package com.lantone.qc.kernel.catalogue.operationdiscussion;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+
+import java.util.List;
+
+/**
+ * @Description: 术后首次病程记录未记录患者生命体征
+ * @author: 胡敬
+ * @time: 2020/3/24 13:28
+ */
+public class OPE0351 extends QCCatalogue {
+    @Override
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status = "0";
+        boolean isOperativePatient = true;//是手术患者(暂时默认是)
+        if (isOperativePatient) {
+            List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+            if (ListUtil.isNotEmpty(operationDocs)) {
+                long count = operationDocs.stream().filter(operationDoc -> {
+                    boolean flag = false;
+                    if (operationDoc.getOperationDiscussionDoc() != null
+                            && operationDoc.getOperationDiscussionDoc().getOperationDiscussionLabel() != null
+                            && operationDoc.getOperationDiscussionDoc().getOperationDiscussionLabel().getVitals().size() == 0) {
+                        flag = true;
+                    }
+                    return true;
+                }).count();
+                if (count > 0) {
+                    status = "-1";
+                }
+            }
+        }
+    }
+
+}

+ 42 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/operationdiscussion/OPE0352.java

@@ -0,0 +1,42 @@
+package com.lantone.qc.kernel.catalogue.operationdiscussion;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+
+import java.util.List;
+
+/**
+ * @Description: 术后首次病程记录未记录术后风险
+ * @author: 胡敬
+ * @time: 2020/3/24 13:28
+ */
+public class OPE0352 extends QCCatalogue {
+    @Override
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status = "0";
+        boolean isOperativePatient = true;//是手术患者(暂时默认是)
+        if (isOperativePatient) {
+            List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+            if (ListUtil.isNotEmpty(operationDocs)) {
+                long count = operationDocs.stream().filter(operationDoc -> {
+                    boolean flag = false;
+                    if (operationDoc.getOperationDiscussionDoc() != null
+                            && operationDoc.getOperationDiscussionDoc().getOperationDiscussionLabel() != null
+                            && (StringUtil.isBlank(operationDoc.getOperationDiscussionDoc().getOperationDiscussionLabel().getRiskAfterOp())
+                            || operationDoc.getOperationDiscussionDoc().getOperationDiscussionLabel().getRiskAfterOp().length() < 10)) {
+                        flag = true;
+                    }
+                    return true;
+                }).count();
+                if (count > 0) {
+                    status = "-1";
+                }
+            }
+        }
+    }
+
+}

+ 44 - 0
kernel/src/main/java/com/lantone/qc/kernel/catalogue/operationdiscussion/OPE0353.java

@@ -0,0 +1,44 @@
+package com.lantone.qc.kernel.catalogue.operationdiscussion;
+
+import com.lantone.qc.kernel.catalogue.QCCatalogue;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.util.ListUtil;
+import com.lantone.qc.pub.util.StringUtil;
+
+import java.util.List;
+
+/**
+ * @Description: 术后首次病程记录未记录处理及注意事项
+ * @author: 胡敬
+ * @time: 2020/3/24 13:28
+ */
+public class OPE0353 extends QCCatalogue {
+    @Override
+    protected void start(InputInfo inputInfo, OutputInfo outputInfo) {
+        status = "0";
+        boolean isOperativePatient = true;//是手术患者(暂时默认是)
+        if (isOperativePatient) {
+            List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+            if (ListUtil.isNotEmpty(operationDocs)) {
+                long count = operationDocs.stream().filter(operationDoc -> {
+                    boolean flag = false;
+                    if (operationDoc.getOperationDiscussionDoc() != null
+                            && operationDoc.getOperationDiscussionDoc().getOperationDiscussionLabel() != null
+                            && (StringUtil.isBlank(operationDoc.getOperationDiscussionDoc().getOperationDiscussionLabel().getMeasuresAfterOp())
+                            || operationDoc.getOperationDiscussionDoc().getOperationDiscussionLabel().getMeasuresAfterOp().length() < 10)
+                            || StringUtil.isBlank(operationDoc.getOperationDiscussionDoc().getOperationDiscussionLabel().getAttentionAfterOp())
+                            || operationDoc.getOperationDiscussionDoc().getOperationDiscussionLabel().getAttentionAfterOp().length() < 10) {
+                        flag = true;
+                    }
+                    return true;
+                }).count();
+                if (count > 0) {
+                    status = "-1";
+                }
+            }
+        }
+    }
+
+}

+ 2 - 0
kernel/src/main/java/com/lantone/qc/kernel/structure/ai/AIAnalyze.java

@@ -15,6 +15,7 @@ public class AIAnalyze {
     FirstCourseRecordAI firstCourseRecordAI = new FirstCourseRecordAI();
     LeaveHospitalAI leaveHospitalAI = new LeaveHospitalAI();
     ThreeLevelWardAI threeLevelWardAI = new ThreeLevelWardAI();
+    OperationAI operationAI = new OperationAI();
 
     public AIAnalyze(CRFServiceClient crfService) {
         this.crfServiceClient = crfService;
@@ -25,6 +26,7 @@ public class AIAnalyze {
         firstCourseRecordAI.medrec(inputInfo, crfServiceClient);
         leaveHospitalAI.medrec(inputInfo, crfServiceClient);
         threeLevelWardAI.medrec(inputInfo, crfServiceClient);
+        operationAI.medrec(inputInfo, crfServiceClient);
     }
 
 

+ 73 - 0
kernel/src/main/java/com/lantone/qc/kernel/structure/ai/OperationAI.java

@@ -0,0 +1,73 @@
+package com.lantone.qc.kernel.structure.ai;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.lantone.qc.kernel.client.CRFServiceClient;
+import com.lantone.qc.kernel.structure.ai.process.EntityProcessOperationDiscussion;
+import com.lantone.qc.kernel.structure.ai.process.EntityProcessThreeLevelWard;
+import com.lantone.qc.pub.Content;
+import com.lantone.qc.pub.model.InputInfo;
+import com.lantone.qc.pub.model.doc.ThreeLevelWardDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationDiscussionDoc;
+import com.lantone.qc.pub.model.doc.operation.OperationDoc;
+import com.lantone.qc.pub.model.label.OperationDiscussionLabel;
+import com.lantone.qc.pub.model.label.ThreeLevelWardLabel;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @ClassName : OperationAI
+ * @Description :
+ * @Author : 胡敬
+ * @Date: 2020-03-24 09:52
+ */
+public class OperationAI extends ModelAI {
+    /**
+     *
+     */
+    public static List<String> medicalTextType = Arrays.asList("CourseAfterOperation");
+    public static String entityRelationObject = "entity_relation_object";
+    public static String outputs = "outputs";
+    public static String content = "content";
+
+    public void medrec(InputInfo inputInfo, CRFServiceClient crfServiceClient) {
+        JSONArray crfContent = new JSONArray();
+        List<OperationDoc> operationDocs = inputInfo.getOperationDocs();
+        for (int i = 0; i < operationDocs.size(); i++) {
+            if (operationDocs.get(i).getOperationDiscussionDoc() == null) {
+                continue;
+            }
+            OperationDiscussionDoc operationDiscussionDoc = operationDocs.get(i).getOperationDiscussionDoc();
+            putContent(crfContent, medicalTextType.get(0), operationDiscussionDoc.getText(), Content.operation_Discussion + i);
+        }
+
+        JSONObject midData = loadAI(crfContent, crfServiceClient);//crf返回数据
+
+        for (int i = 0; i < operationDocs.size(); i++) {
+            if (midData.get(Content.operation_Discussion + i) == null){
+                continue;
+            }
+            putOperationDiscussionCrfData(midData.getJSONObject(Content.operation_Discussion + i), inputInfo);
+        }
+    }
+
+    /**
+     * 处理查房记录
+     *
+     * @param jsonObject
+     * @param inputInfo
+     */
+    public void putOperationDiscussionCrfData(JSONObject jsonObject, InputInfo inputInfo) {
+        JSONObject aiOut = loadEntity(jsonObject, entityRelationObject, outputs, content);
+        //使用现病史结构来处理病历特点
+        EntityProcessOperationDiscussion entityProcessOperationDiscussion = new EntityProcessOperationDiscussion();
+        OperationDiscussionLabel operationDiscussionLabel = entityProcessOperationDiscussion.extractEntity(aiOut);
+        OperationDiscussionDoc operationDiscussionDoc = new OperationDiscussionDoc();
+        operationDiscussionDoc.setOperationDiscussionLabel(operationDiscussionLabel);
+        OperationDoc operationDoc = new OperationDoc();
+        operationDoc.setOperationDiscussionDoc(operationDiscussionDoc);
+        //临床表现
+        inputInfo.getOperationDocs().add(operationDoc);
+    }
+}

+ 3 - 1
kernel/src/main/java/com/lantone/qc/kernel/structure/ai/model/EntityEnum.java

@@ -24,7 +24,9 @@ public enum EntityEnum {
     CURE_AIM("治疗目的"), OTHER("其他"), OUTERCOURTYARD("外院"), NURSINGLEVEL("护理级别"), CHIEF("主诉"), NOTES("注意事项"),
     KEY_WORD_FOR_DOCTOR_ADVICES("出院医嘱标题"), DOCTORADVICE("医嘱"), KEY_WORD_FOR_PART("大标题"), OUTCOME("转归情况"),
     PHYSICAL_EXAMINATION("查体"),TITLE_FOR_SIGN("查体标题"),TITLE_FOR_DIAG("诊断标题"),TITLE_FOR_DIAG_BASIS("诊断依据标题"),
-    TITLE_FOR_DIFF("鉴别诊断标题"),TITLE_FOR_TREAT("诊疗计划标题"),TITLE("其他标题"), TREATMENT_PLAN("诊疗计划");
+    TITLE_FOR_DIFF("鉴别诊断标题"),TITLE_FOR_TREAT("诊疗计划标题"),TITLE("标题"), TREATMENT_PLAN("诊疗计划"),
+    TITLE_OF_OPERATIVE_FINDINGS("手术经过标题"),TITLE_OF_MEASURES_AFTER_OP("术后处理措施标题"),
+    TITLE_OF_RISK_AFTER_OP("术后风险标题"),TITLE_OF_ATTENTION_AFTER_OP("术后注意事项标题"),VITAL("生命体征");
 
     private String value;
 

+ 137 - 0
kernel/src/main/java/com/lantone/qc/kernel/structure/ai/process/EntityProcessOperationDiscussion.java

@@ -0,0 +1,137 @@
+package com.lantone.qc.kernel.structure.ai.process;
+
+import com.alibaba.fastjson.JSONObject;
+import com.lantone.qc.kernel.structure.ai.model.EntityEnum;
+import com.lantone.qc.kernel.structure.ai.model.Lemma;
+import com.lantone.qc.pub.model.entity.Clinical;
+import com.lantone.qc.pub.model.entity.Diag;
+import com.lantone.qc.pub.model.entity.Vital;
+import com.lantone.qc.pub.model.label.OperationDiscussionLabel;
+import com.lantone.qc.pub.model.label.ThreeLevelWardLabel;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName : EntityProcessOperationDiscussion
+ * @Description : 术后首次病程及谈话记录
+ * @Author : 胡敬
+ * @Date: 2020-03-24 10:48
+ */
+public class EntityProcessOperationDiscussion extends EntityProcess {
+    private List<String> titleList = Arrays.asList(
+            EntityEnum.TITLE.toString(),
+            EntityEnum.TITLE_OF_OPERATIVE_FINDINGS.toString(),
+            EntityEnum.TITLE_OF_MEASURES_AFTER_OP.toString(),
+            EntityEnum.TITLE_OF_RISK_AFTER_OP.toString(),
+            EntityEnum.TITLE_OF_ATTENTION_AFTER_OP.toString());
+
+    public OperationDiscussionLabel extractEntity(JSONObject aiOut) {
+        OperationDiscussionLabel operationDiscussionLabel = new OperationDiscussionLabel();
+        String content = aiOut.getString("content");
+
+        Map<String, List<String>> titleText = subWithTitle(aiOut);
+        //手术经过文本(术中所见)
+        if (titleText.get(EntityEnum.TITLE_OF_OPERATIVE_FINDINGS.toString()) != null) {
+            List<String> operativeFindingsList = titleText.get(EntityEnum.TITLE_OF_OPERATIVE_FINDINGS.toString());
+            String text = textJoin(content, operativeFindingsList);
+            operationDiscussionLabel.setOperativeFindings(text);
+        }
+
+        //术后风险文本
+        if (titleText.get(EntityEnum.TITLE_OF_RISK_AFTER_OP.toString()) != null) {
+            List<String> riskAfterOpList = titleText.get(EntityEnum.TITLE_OF_RISK_AFTER_OP.toString());
+            String text = textJoin(content, riskAfterOpList);
+            operationDiscussionLabel.setRiskAfterOp(text);
+        }
+
+        //术后注意事项文本(处理及注意事项)
+        if (titleText.get(EntityEnum.TITLE_OF_ATTENTION_AFTER_OP.toString()) != null) {
+            List<String> attentionAfterOpList = titleText.get(EntityEnum.TITLE_OF_ATTENTION_AFTER_OP.toString());
+            String text = textJoin(content, attentionAfterOpList);
+            operationDiscussionLabel.setAttentionAfterOp(text);
+        }
+
+        //术后处理措施文本(处理及注意事项)
+        if (titleText.get(EntityEnum.TITLE_OF_MEASURES_AFTER_OP.toString()) != null) {
+            List<String> measuresAfterOpList = titleText.get(EntityEnum.TITLE_OF_MEASURES_AFTER_OP.toString());
+            String text = textJoin(content, measuresAfterOpList);
+            operationDiscussionLabel.setMeasuresAfterOp(text);
+        }
+
+        //生命体征
+        List<Lemma> vitalLemmas = createEntityTree(aiOut, EntityEnum.VITAL.toString());
+        List<Vital> vitals = new ArrayList<>();
+        for (Lemma lemma : vitalLemmas) {
+            Vital vital = new Vital();
+            vital.setValue(lemma.getText());
+            vitals.add(vital);
+        }
+        operationDiscussionLabel.setVitals(vitals);
+        return operationDiscussionLabel;
+    }
+
+    private String textJoin(String content, List<String> operativeFindingsList) {
+        StringBuffer text = new StringBuffer();
+        for (String titleTextIndex : operativeFindingsList) {
+            String[] titleTextIndexSplit = titleTextIndex.split(",");
+            text.append(content.substring(Integer.parseInt(titleTextIndexSplit[0]),
+                    Integer.parseInt(titleTextIndexSplit[1])));
+        }
+        return text.toString();
+    }
+
+    /**
+     * 根据各标题截取文本index
+     *
+     * @param aiOut
+     * @return
+     */
+    private Map<String, List<String>> subWithTitle(JSONObject aiOut) {
+        Map<String, List<String>> titleText = new LinkedHashMap<>();
+        String content = aiOut.getString("content");
+        List<Lemma> lemmaList = loadAllLemmaList(aiOut.getJSONObject("annotation").getJSONArray("T"));
+        Lemma lemma;
+        int start = 0;
+        String subContentIndex = "", title = "";
+        for (int i = 0; i < lemmaList.size(); i++) {
+            lemma = lemmaList.get(i);
+            if (!titleList.contains(lemma.getProperty()) && i != lemmaList.size() - 1) {
+                continue;
+            }
+            if (i != lemmaList.size() - 1) {
+                if (start == 0) {
+                    start = Integer.parseInt(lemma.getPosition());
+                    title = lemma.getText();//截取的这一段文本的标题
+                } else {
+                    //subContent = content.substring(start + title.length(), Integer.parseInt(lemma.getPosition()));
+                    subContentIndex = start + title.length() + "," + Integer.parseInt(lemma.getPosition());
+                    putSubContent(titleText, title, subContentIndex);
+                    start = Integer.parseInt(lemma.getPosition());
+                    title = lemma.getText();//截取的这一段文本的标题
+                }
+            } else {
+                //如果是最后一个Lemma,文本就从start开始取,取到结束
+                //subContent = content.substring((start + lemma.getText().length()));
+                int lastIndex = content.length() - 1;
+                subContentIndex = start + title.length() + "," + lastIndex;
+                putSubContent(titleText, title, subContentIndex);
+            }
+        }
+        return titleText;
+    }
+
+    private void putSubContent(Map<String, List<String>> titleText, String text, String subContent) {
+        List<String> textList;
+        if (titleText.containsKey(text)) {
+            titleText.get(text).add(subContent);
+        } else {
+            textList = new ArrayList<>();
+            textList.add(subContent);
+            titleText.put(text, textList);
+        }
+    }
+}

+ 24 - 22
kernel/src/main/java/com/lantone/qc/kernel/structure/ai/process/EntityProcessThreeLevelWard.java

@@ -41,12 +41,10 @@ public class EntityProcessThreeLevelWard extends EntityProcess {
         //诊断依据
         if (titleText.get(EntityEnum.TITLE_FOR_DIAG_BASIS.toString()) != null) {
             List<String> diagBasisList = titleText.get(EntityEnum.TITLE_FOR_DIAG_BASIS.toString());
-            String diagBasis = String.join(",", diagBasisList);
-            String[] diagBasisSplit = diagBasis.split(",");
+            String text = textJoin(content, diagBasisList);
+            String[] diagBasisSplit = String.join(",", diagBasisList).split(",");
             //诊断依据文本
-            threeLevelWardLabel.setDiagBasisText(content.substring(
-                    Integer.parseInt(diagBasisSplit[0]),
-                    Integer.parseInt(diagBasisSplit[diagBasisSplit.length - 1])));
+            threeLevelWardLabel.setDiagBasisText(text);
             //病史(在 诊断依据 以外的片段中出现 任一 临床表现)
             addClinical(threeLevelWardLabel, diagBasisSplit, clinicalLemmas);
             //补充诊断/初步诊断/修正诊断
@@ -62,23 +60,7 @@ public class EntityProcessThreeLevelWard extends EntityProcess {
             addClinical(threeLevelWardLabel, diffDiagSplit, clinicalLemmas);
             //补充诊断/初步诊断/修正诊断
             addDiag(threeLevelWardLabel, diffDiagSplit, diagLemmas);
-        }
-
-        //查体
-        List<Lemma> signLemmas = createEntityTree(aiOut, EntityEnum.PHYSICAL_EXAMINATION.toString());
-        List<Sign> signs = new ArrayList<>();
-        for (Lemma lemma : signLemmas) {
-            Sign sign = new Sign();
-            sign.setName(lemma.getText());
-            signs.add(sign);
-        }
-        threeLevelWardLabel.setSigns(signs);
-
-        //鉴别诊断
-        if (titleText.get(EntityEnum.TITLE_FOR_DIFF.toString()) != null) {
-            List<String> diffDiagList = titleText.get(EntityEnum.TITLE_FOR_DIFF.toString());
-            String diagBasis = String.join(",", diffDiagList);
-            String[] diffDiagSplit = diagBasis.split(",");
+            //添加鉴别诊断
             List<Lemma> dieaseLemmas = createEntityTree(aiOut, EntityEnum.DIEASE.toString());
             List<Diag> diags = new ArrayList<>();
             for (Lemma dieaseLemma : dieaseLemmas) {
@@ -100,6 +82,16 @@ public class EntityProcessThreeLevelWard extends EntityProcess {
             }
         }
 
+        //查体
+        List<Lemma> signLemmas = createEntityTree(aiOut, EntityEnum.PHYSICAL_EXAMINATION.toString());
+        List<Sign> signs = new ArrayList<>();
+        for (Lemma lemma : signLemmas) {
+            Sign sign = new Sign();
+            sign.setName(lemma.getText());
+            signs.add(sign);
+        }
+        threeLevelWardLabel.setSigns(signs);
+
         //诊疗计划
         List<Lemma> treatmentPlanLemmas = createEntityTree(aiOut, EntityEnum.TREATMENT_PLAN.toString());
         List<TreatmentPlan> treatmentPlans = new ArrayList<>();
@@ -112,6 +104,16 @@ public class EntityProcessThreeLevelWard extends EntityProcess {
         return threeLevelWardLabel;
     }
 
+    private String textJoin(String content, List<String> operativeFindingsList) {
+        StringBuffer text = new StringBuffer();
+        for (String titleTextIndex : operativeFindingsList) {
+            String[] titleTextIndexSplit = titleTextIndex.split(",");
+            text.append(content.substring(Integer.parseInt(titleTextIndexSplit[0]),
+                    Integer.parseInt(titleTextIndexSplit[1])));
+        }
+        return text.toString();
+    }
+
     /**
      * 根据各标题截取文本index
      *

+ 195 - 0
kernel/src/main/java/com/lantone/qc/kernel/web/controller/QCTestController.java

@@ -6,6 +6,7 @@ import com.lantone.qc.kernel.util.CacheFileManager;
 import com.lantone.qc.kernel.util.KernelConstants;
 import com.lantone.qc.pub.jdbc.MysqlJdbc;
 import com.lantone.qc.pub.model.OutputInfo;
+import com.lantone.qc.pub.model.keys.ModelStandardKeys;
 import com.lantone.qc.pub.model.vo.MedrecVo;
 import com.lantone.qc.pub.model.vo.QueryVo;
 import com.lantone.qc.pub.res.Response;
@@ -38,6 +39,200 @@ public class QCTestController {
     @Autowired
     private QCAnalysis qCAnalysis;
 
+    private Map<String, List<String>> inputLabelMap = new HashMap<>();
+    {
+        inputLabelMap.put("入院记录", Lists.newArrayList("姓名", "性别", "年龄", "民族", "职业", "出生地", "婚姻", "联系地址", "病史陈述者", "出生日期", "户口地址", "电话", "入院日期", "记录日期", "主诉", "现病史", "既往史", "个人史", "婚育史", "月经史", "家族史", "体格检查(一)", "体格检查(二)", "辅助检查", "初步诊断", "修正诊断", "医师签名", "补充诊断"));
+    }
+
+    @ApiOperation(value = "质控测试接口,无需token信息", notes = "")
+    @PostMapping("qc_test")
+    public Response<OutputInfo> qc(String cid, String caseNumber, String hospitalId) {
+        Response response = new Response();
+        if (StringUtils.isEmpty(hospitalId)) {
+            response.setData("未填写医院流水号(hospitalId)......");
+        }
+        if (StringUtils.isEmpty(cid)) {
+            response.setData("未填写医院缩写(cid)......");
+        }
+        //key = 患者就诊号
+        Map<String, QueryVo> queryVoMap = createQueryVo(cid, hospitalId, caseNumber);
+        //key = 患者就诊号
+        Map<String, Map<String, String>> inputCaseMappingMap = createInputCaseMapping(hospitalId, caseNumber);
+
+        List<Map<String, Object>> updates = new ArrayList<>();
+        List<Map<String, Object>> wheres = new ArrayList<>();
+        for (Map.Entry<String, QueryVo> entry : queryVoMap.entrySet()) {
+            OutputInfo outputInfo = qCAnalysis.anlysis(entry.getValue());
+
+            Map<String, String> passMap = inputCaseMappingMap.get(entry.getKey());
+            for (Map.Entry<String, String> e : passMap.entrySet()) {
+                Map<String, Object> m = new HashMap<>();
+                Map<String, Object> w = new HashMap<>();
+                if (outputInfo.getResult().get(e.getKey()) == null) {
+                    m.put("check_label", "-2");
+                } else {
+                    m.put("check_label", outputInfo.getResult().get(e.getKey()).get("status"));
+                }
+                w.put("id", e.getValue());
+
+                updates.add(m);
+                wheres.add(w);
+            }
+        }
+        PropertiesUtil propertiesUtil = new PropertiesUtil("kernel.properties");
+        MysqlJdbc mysqlJdbc = new MysqlJdbc(propertiesUtil.getProperty("mysql.test.user"),
+                propertiesUtil.getProperty("mysql.test.password"),
+                propertiesUtil.getProperty("mysql.test.url"));
+        mysqlJdbc.update("qc_inputcases_mapping_all", updates, wheres);
+        return response;
+    }
+
+    public Map<String, QueryVo> createQueryVo(String cid, String hospitalId, String caseNumber) {
+        PropertiesUtil propertiesUtil = new PropertiesUtil("kernel.properties");
+        MysqlJdbc mysqlJdbc = new MysqlJdbc(propertiesUtil.getProperty("mysql.test.user"),
+                propertiesUtil.getProperty("mysql.test.password"),
+                propertiesUtil.getProperty("mysql.test.url"));
+        Connection conn = mysqlJdbc.connect();
+        Statement st = null;
+        ResultSet rs = null;
+        String r1, r2, r3, r4, r5;
+
+        Map<String, QueryVo> queryVoMap = new HashMap<>();
+        QueryVo queryVo = new QueryVo();
+        List<MedrecVo> medrec = new ArrayList<>();
+        try {
+            st = conn.createStatement();
+            String sql = "select case_number from qc_cases_number where hospital_id = " + hospitalId;   //查询医院所有病历号
+            rs = st.executeQuery(sql);
+            List<String> numbers = new ArrayList<>();
+            while (rs.next()) {
+                r1 = rs.getString(1);
+                numbers.add(r1);
+            }
+
+            sql = "select id from qc_mode";   //查询数据模块
+            rs = st.executeQuery(sql);
+            List<String> modeIds = new ArrayList<>();
+            while (rs.next()) {
+                r1 = rs.getString(1);
+                modeIds.add(r1);
+            }
+
+            sql = "select code, name from qc_cases_entry";   //查询所有条目
+            rs = st.executeQuery(sql);
+            Map<String, Map<String, String>> inputCatalogueMap = new HashMap<>();
+            while (rs.next()) {
+                r1 = rs.getString(1);
+                r2 = rs.getString(2);
+                Map<String, String> m = new HashMap<>();
+                m.put("precond","");
+                m.put("name", r2);
+                m.put("code", r1);
+                inputCatalogueMap.put(r1, m);
+            }
+
+            sql = "SELECT h.code, n.case_number, q.name, qmm.text " +
+                    "FROM qc_model_mapping qmm, qc_mode q, qc_cases_number n, qc_hospital_info h " +
+                    "where qmm.case_number_id = n.id and qmm.mode_id = q.id and n.hospital_id = h.id and n.is_deleted = 'N' ";
+            if (StringUtils.isNotEmpty(caseNumber)) {
+                sql = sql + " and n.case_number = " + caseNumber;
+            }
+            sql = sql + " order by n.id, q.id";
+            rs = st.executeQuery(sql);
+            String tempCaseNumber = "", label = "";
+            List<String> details = new ArrayList<>();
+            while (rs.next()) {
+                r1 = rs.getString(1);
+                r2 = rs.getString(2);
+                r3 = rs.getString(3);
+                r4 = rs.getString(4);
+                if (!tempCaseNumber.equals(String.valueOf(r2)) && StringUtils.isNotEmpty(tempCaseNumber)) {
+                    queryVo.setCid(cid);
+                    queryVo.setMedrec(medrec);
+                    queryVo.setInputCatalogueMap(inputCatalogueMap);
+                    queryVoMap.put(r1, queryVo);
+                    //新的一份病历记录
+                    medrec = new ArrayList<>();
+                    queryVo = new QueryVo();
+                }
+                if (r3.equals("入院记录") || r3.equals("首次病程录") || r3.equals("死亡病例讨论记录") || r3.equals("出院小结") || r3.equals("死亡记录")) {
+                    MedrecVo medrecVo = new MedrecVo();
+                    medrecVo.setTitle(r3);
+                    Map<String, Object> m = new HashMap<>();
+                    m.put("content", r4);
+                    medrecVo.setContent(m);
+                    medrec.add(medrecVo);
+                } else if (r3.equals("查房记录") || r3.equals("会诊记录") || r3.equals("医嘱信息") || r3.equals("值班交接制度") || r3.equals("输血/血制品病程记录")
+                        || r3.equals("抢救记录") || r3.equals("危急值记录") || r3.equals("病危通知书") || r3.equals("阶段小结") || r3.equals("疑难病例讨论记录") || r3.equals("病重通知书")
+                        || r3.equals("术前讨论、术前小结") || r3.equals("麻醉记录") || r3.equals("麻醉知情同意书") || r3.equals("麻醉术前访视记录")
+                        || r3.equals("麻醉术后访视记录") || r3.equals("手术知情同意书") || r3.equals("手术记录") || r3.equals("术后首次病程及谈话记录")
+                        || r3.equals("手术风险评估表") || r3.equals("手术安全核查表") || r3.equals("转科记录(转入)") || r3.equals("转科记录(转出)")) {
+                    if (!label.equals(String.valueOf(r3)) && StringUtils.isNotEmpty(label)) {
+                        MedrecVo medrecVo = new MedrecVo();
+                        medrecVo.setTitle(label);
+                        Map<String, Object> m = new HashMap<>();
+                        m.put("content", details);
+                        medrecVo.setContent(m);
+                        medrec.add(medrecVo);
+                        details = new ArrayList<>();
+                    }
+                    details.add(r4);
+                    label = r3;
+                }
+            }
+        } catch (SQLException sqle) {
+            sqle.printStackTrace();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            mysqlJdbc.close(rs, st, conn);
+        }
+        return queryVoMap;
+    }
+
+    public Map<String, Map<String, String>> createInputCaseMapping(String hospitalId, String caseNumber) {
+        Map<String, Map<String, String>> result = new HashMap<>();
+        PropertiesUtil propertiesUtil = new PropertiesUtil("kernel.properties");
+        MysqlJdbc mysqlJdbc = new MysqlJdbc(propertiesUtil.getProperty("mysql.test.user"),
+                propertiesUtil.getProperty("mysql.test.password"),
+                propertiesUtil.getProperty("mysql.test.url"));
+        Connection conn = mysqlJdbc.connect();
+        Statement st = null;
+        ResultSet rs = null;
+        String r1, r2, r3, r4, r5;
+        try {
+            st = conn.createStatement();
+            String sql = "SELECT qim.id, qim.case_number_id, qc.code  FROM qc_inputcases_mapping qim, qc_cases_number q, qc_cases_entry qc " +
+                    "where qim.case_number_id = q.id and qim.cases_entry_id = qc.id and q.is_deleted = 'N' " +
+                    "and q.hospital_id = " + hospitalId ;
+            if (StringUtils.isNotEmpty(caseNumber)) {
+                sql = sql + " and q.case_number = " + caseNumber;
+            }
+            sql = sql + " order by q.id, qim.cases_id ";
+            rs = st.executeQuery(sql);
+
+            String caseNumberId = "";
+            Map<String, String> m = new HashMap<>();
+            while (rs.next()) {
+                r1 = rs.getString(1);
+                r2 = rs.getString(2);
+                r3 = rs.getString(3);
+                if (!caseNumberId.equals(String.valueOf(r2)) && StringUtils.isNotEmpty(caseNumberId)) {
+                    result.put(r2, m);
+                    m = new HashMap<>();
+                }
+                m.put(r3, r1);
+            }
+        } catch (SQLException sqle) {
+            sqle.printStackTrace();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            mysqlJdbc.close(rs, st, conn);
+        }
+        return result;
+    }
+
     @ApiOperation(value = "质控测试接口,无需token信息", notes = "")
     @PostMapping("rec_test")
     public Response<OutputInfo> extract(String caseIds, int length, String cid, String txtId, String hospitalId) {

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

@@ -211,6 +211,8 @@ public class Content {
     public static final String healing_level="愈合等级";
     public static final String anesthesia_mode="麻醉方式";
     public static final String anesthesia_doctor="麻醉医师";
+    public static final String operation_Discussion="术后首次病程及谈话记录";
+
     public static final String outWay="离院方式";
     public static final String brainInjuryComaTime="颅脑损伤患者昏迷时间";
     public static final String daCode="医嘱转院机构名称";

+ 2 - 0
public/src/main/java/com/lantone/qc/pub/model/doc/operation/OperationDiscussionDoc.java

@@ -1,6 +1,7 @@
 package com.lantone.qc.pub.model.doc.operation;
 
 import com.lantone.qc.pub.model.doc.ModelDoc;
+import com.lantone.qc.pub.model.label.OperationDiscussionLabel;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -13,4 +14,5 @@ import lombok.Setter;
 @Getter
 @Setter
 public class OperationDiscussionDoc extends ModelDoc {
+    OperationDiscussionLabel operationDiscussionLabel = new OperationDiscussionLabel();
 }

+ 28 - 0
public/src/main/java/com/lantone/qc/pub/model/label/OperationDiscussionLabel.java

@@ -0,0 +1,28 @@
+package com.lantone.qc.pub.model.label;
+
+import com.lantone.qc.pub.model.entity.Clinical;
+import com.lantone.qc.pub.model.entity.Diag;
+import com.lantone.qc.pub.model.entity.Sign;
+import com.lantone.qc.pub.model.entity.TreatmentPlan;
+import com.lantone.qc.pub.model.entity.Vital;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ClassName : OperationDiscussionLabel
+ * @Description :
+ * @Author : 胡敬
+ * @Date: 2020-03-24 11:02
+ */
+@Getter
+@Setter
+public class OperationDiscussionLabel {
+    String operativeFindings;   //手术经过文本(术中所见)
+    String riskAfterOp;    //术后风险文本
+    String attentionAfterOp;    //术后注意事项文本(处理及注意事项)
+    String measuresAfterOp;    //术后处理措施文本(处理及注意事项)
+    List<Vital> vitals = new ArrayList<>();   //生命体征实体
+}