瀏覽代碼

诊断依据导入初始化

zhoutg 4 年之前
父節點
當前提交
09ce5c802a

+ 104 - 0
src/main/java/com/diagbot/enums/LexiconExtEnum.java

@@ -0,0 +1,104 @@
+package com.diagbot.enums;
+
+import com.diagbot.core.KeyedNamed;
+import lombok.Setter;
+
+/**
+ * @Description:
+ * @Author:zhaops
+ * @time: 2021/2/24 10:46
+ */
+public enum LexiconExtEnum implements KeyedNamed {
+
+    Disease(100,"疾病"),
+    Medicine(101,"药品通用名"),
+    Form(102,"药品剂型"),
+    Symptom(103,"症状"),
+    Vital(104,"体格检查项目"),
+    VitalResult(105,"体格检查结果"),
+    Operation(106,"手术和操作"),
+    LisName(107,"实验室检查套餐"),
+    LisSubName(108,"实验室检查子项目"),
+    PacsName(109,"辅助检查项目"),
+    PacsSubName(110,"辅助检查子项目"),
+    PacsDescribe(111,"辅助检查描述"),
+    PacsResult(112,"辅助检查结果"),
+    Transfusion(113,"输血类型"),
+    Anesthesia(114,"麻醉"),
+    Dept(115,"科室"),
+    Gender(116,"性别"),
+    Group(117,"人群"),
+    Food(118,"食物"),
+    Allergen(119,"其他过敏原"),
+    Device(120,"医疗器械及物品"),
+    AdministrationRoute(121,"给药途径"),
+    Part(122,"部位"),
+    Nurse(123,"护理"),
+    Scale(124,"量表"),
+    Unit(125,"单位"),
+    ICD10Class(300,"ICD10疾病类别"),
+    MedChemClass(301,"药品化学物质类别"),
+    MedZhiLiaoClass(302,"药品治疗学类别"),
+    MedYaoLiClass(303,"药品药理学类别"),
+    MedJiePouClass(304,"药品解剖学类别"),
+    SymptomClass(305,"症状类别"),
+    OperationClass(306,"手术和操作类别"),
+    ICD10ClassNode(400,"ICD10疾病类别根节点"),
+    DeptDiseaseNode(401,"科室疾病类别根节点"),
+    MedChemClassNode(402,"药品化学物质类别根节点"),
+    MedZhiLiaoClassNode(403,"药品治疗学类别根节点"),
+    MedYaoLiClassNode(404,"药品药理学类别根节点"),
+    MedJiePouClassNode(405,"药品解剖学类别根节点"),
+    SymptomClassNode(406,"症状类别根节点"),
+    OperationClassNode(407,"手术和操作类别根节点"),
+    LisClassNode(408,"实验室检查类别根节点"),
+    PacsClassNode(409,"辅助检查类别根节点"),
+    Age(410,"年龄"),
+
+    zsxbszz(900, "主诉现病史正则"),
+    jwzz(901, "既往正则");
+
+    @Setter
+    private int key;
+
+    @Setter
+    private String name;
+
+    LexiconExtEnum(int key, String name) {
+        this.key = key;
+        this.name = name;
+    }
+
+    public static LexiconExtEnum getEnum(int key) {
+        for (LexiconExtEnum item : LexiconExtEnum.values()) {
+            if (item.key == key) {
+                return item;
+            }
+        }
+        return null;
+    }
+
+    public static LexiconExtEnum getEnum(String value) {
+        for (LexiconExtEnum item : LexiconExtEnum.values()) {
+            if (item.getName().equals(value)) {
+                return item;
+            }
+        }
+        return null;
+    }
+
+    public static String getName(int key) {
+        LexiconExtEnum item = getEnum(key);
+        return item != null ? item.name : null;
+    }
+
+    @Override
+    public int getKey() {
+        return key;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+}

+ 425 - 0
src/main/java/com/diagbot/facade/KlDiagnoseImportFacade.java

@@ -0,0 +1,425 @@
+package com.diagbot.facade;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.diagbot.entity.KlConcept;
+import com.diagbot.entity.KlDiagnose;
+import com.diagbot.enums.IsDeleteEnum;
+import com.diagbot.enums.LexiconEnum;
+import com.diagbot.enums.LexiconExtEnum;
+import com.diagbot.service.KlConceptService;
+import com.diagbot.util.EntityUtil;
+import com.diagbot.util.ExcelUtils;
+import com.diagbot.util.ListUtil;
+import com.diagbot.util.StringUtil;
+import com.diagbot.util.VerifyUtil;
+import com.diagbot.vo.DiagnoseImportVO;
+import com.diagbot.vo.ImportDiagnoseResVO;
+import com.diagbot.vo.ImportDiagnoseVO;
+import com.diagbot.vo.KlDiagnoseDetailVO;
+import com.diagbot.vo.KlDiagnoseGroupVO;
+import com.diagbot.vo.KlDiagnoseSaveVO;
+import com.diagbot.vo.KlDiagnoseTypeVO;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description:
+ * @author: zhoutg
+ * @time: 2021/3/15 11:42
+ */
+@Component
+public class KlDiagnoseImportFacade {
+
+    @Autowired
+    @Qualifier("klConceptServiceImpl")
+    private KlConceptService klConceptService;
+    @Autowired
+    KlDiagnoseFacade klDiagnoseFacade;
+
+    public Map<String, Object> importDiagnose(MultipartFile file, DiagnoseImportVO diagnoseImportVO) {
+        Map<String, Object> errMessage = new LinkedHashMap<>(); // 错误提示语
+        List<ImportDiagnoseResVO> allData = Lists.newArrayList();  // 最终需要保存的数据
+        // 校验数据
+        Boolean allFlag = verifyData(file, diagnoseImportVO, errMessage, allData);
+
+        // 保存数据
+        if (allFlag) {
+            saveData(allData);
+        }
+        return errMessage;
+    }
+
+    /**
+     * 校验数据
+     *
+     * @param file
+     * @param diagnoseImportVO
+     * @param diagMessage
+     * @param allData
+     * @return
+     */
+    public Boolean verifyData(MultipartFile file, DiagnoseImportVO diagnoseImportVO, Map<String, Object> diagMessage, List<ImportDiagnoseResVO> allData) {
+        Boolean allFlag = true;
+        List<String> diagtypes = Lists.newArrayList("拟诊", "确诊", "警惕");
+        // 获取标准词库Map
+        Map<String, KlConcept> concept_map = getConceptMap();
+
+        // 获取所有的sheet和序号的对应关系
+        Map<String, Integer> sheetNumNameMap = dealExcel(file);
+        List<String> diags = diagnoseImportVO.getDiags();
+        if (ListUtil.isNotEmpty(diags)) {
+            StringBuilder sb = new StringBuilder();
+            Map<String, Integer> inputNumNameMap = new HashMap<>();
+            for (String diag : diags) {
+                if (!sheetNumNameMap.containsKey(diag)) {
+                    sb.append(String.format("输入的诊断: %s不在下面的sheet中;  ", "【" + diag + "】"));
+                } else {
+                    inputNumNameMap.put(diag, sheetNumNameMap.get(diag));
+                }
+            }
+            if (StringUtil.isNotBlank(sb.toString())) {
+                diagMessage.put("输入校验", sb.toString());
+                allFlag = false;
+                return allFlag;
+            } else {
+                sheetNumNameMap = inputNumNameMap;
+            }
+        }
+        for (Map.Entry<String, Integer> sheet : sheetNumNameMap.entrySet()) {
+            StringBuilder sb = new StringBuilder();
+            String sheetName = sheet.getKey();
+            Integer sheetNum = sheet.getValue();
+            ImportDiagnoseResVO importDiagnoseResVO = new ImportDiagnoseResVO();
+
+            // 校验疾病名称【sheetName】
+            KlConcept klConcept = concept_map.get(sheetName + "_" + String.valueOf(LexiconEnum.Disease.getKey()));
+            if (klConcept != null) {
+                importDiagnoseResVO.setDiseaseName(sheetName);
+                importDiagnoseResVO.setDiseaseId(klConcept.getId());
+            } else {
+                sb.append(String.format("sheetName: %s不是标准词;  ", "【" + sheetName + "】"));
+            }
+            // 校验其他行数据、格式
+            List<ImportDiagnoseVO> data = ExcelUtils.importExcelMultiSheets(file, 0, 1, sheetNum.intValue(), ImportDiagnoseVO.class);
+            sb = dealVerify(sb, diagtypes, data, concept_map);
+
+            // 数据赋值
+            if (StringUtil.isBlank(sb.toString())) {
+                data = dealImportDiagnose(diagtypes, data, concept_map);
+                // 添加到正确数据列表
+                importDiagnoseResVO.setImportDiagnoseVOList(data);
+                allData.add(importDiagnoseResVO);
+            } else {
+                allFlag = false;
+                diagMessage.put(sheetName, sb.toString());
+            }
+        }
+        return allFlag;
+    }
+
+    /**
+     * 获取sheet名称和序号的对应关系
+     *
+     * @param file
+     * @return
+     */
+    private Map<String, Integer> dealExcel(MultipartFile file) {
+        Map<String, Integer> sheet_num_name = Maps.newLinkedHashMap();
+        Workbook workBook = null;
+        try {
+            workBook = ExcelUtils.getWorkBook(file);
+            int numberOfSheets = workBook.getNumberOfSheets();
+            for (int i = 0; i < numberOfSheets; i++) {
+                String sheetName = workBook.getSheetName(i);
+                sheet_num_name.put(sheetName, i);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return sheet_num_name;
+    }
+
+    /**
+     * 给标准词设置conceptId
+     *
+     * @param diagtypes
+     * @param importDiagnoseVOS
+     * @param concept_map
+     * @return
+     */
+    private List<ImportDiagnoseVO> dealImportDiagnose(List<String> diagtypes, List<ImportDiagnoseVO> importDiagnoseVOS, Map<String, KlConcept> concept_map) {
+        for (ImportDiagnoseVO idv : importDiagnoseVOS) {
+            String type = idv.getType().trim();
+            String rule = idv.getRule().trim();
+            if (!type.contains("正则") && !diagtypes.contains(type)) {
+                KlConcept klConcept = concept_map.get(rule + "_" + String.valueOf(LexiconExtEnum.getEnum(type).getKey()));
+                if (klConcept != null) {
+                    idv.setConceptId(klConcept.getId());
+                }
+            }
+        }
+        return importDiagnoseVOS;
+    }
+
+    //数据及格式校验
+    private StringBuilder dealVerify(StringBuilder sb, List<String> diagtypes, List<ImportDiagnoseVO> data, Map<String, KlConcept> concept_map) {
+
+        //所有序号
+        List<String> orderNums = Lists.newArrayList();
+        //所有公式
+        List<String> verifies = Lists.newArrayList();
+
+        if (ListUtil.isNotEmpty(data)) {
+            for (ImportDiagnoseVO imd : data) {
+                String type = imd.getType().trim();
+                String rule = imd.getRule().trim();
+                String orderNo = imd.getOrderNo().trim();
+                String maxSymbol = imd.getMaxSymbol();
+                String minSymbol = imd.getMinSymbol();
+
+                if (diagtypes.contains(type) && StringUtil.isNotBlank(orderNo)) {
+                    verifies.add(orderNo.trim());
+                }
+                if (StringUtil.isNotBlank(type) && StringUtil.isNotBlank(rule) && StringUtil.isNotBlank(orderNo)) {
+                    orderNums.add(orderNo);
+                    if (!type.contains("正则") &&
+                            !concept_map.containsKey(rule + "_" + String.valueOf(LexiconExtEnum.getEnum(type).getKey()))) {
+                        sb.append(String.format("%s不是标准词;  ", rule));
+                    }
+                }
+                if (StringUtil.isNotBlank(maxSymbol) &&
+                        !"<=".equals(maxSymbol) && !"<".equals(maxSymbol)) {
+                    sb.append(String.format("%s的最大符号%s不正确;  ", rule, maxSymbol));
+                }
+                if (StringUtil.isNotBlank(minSymbol) &&
+                        !">=".equals(minSymbol) && !">".equals(minSymbol)) {
+                    sb.append(String.format("%s的最小符号%s不正确;  ", rule, minSymbol));
+                }
+            }
+
+            //格式校验
+            if (ListUtil.isNotEmpty(verifies)) {
+                for (String vef : verifies) {
+                    String s = VerifyUtil.verifyFormula(orderNums, vef);
+                    sb.append(s);
+                }
+            }
+        }
+        return sb;
+    }
+
+    private Map<String, KlConcept> getConceptMap() {
+        List<KlConcept> klConcepts
+                = klConceptService.list(new QueryWrapper<KlConcept>()
+                .eq("is_deleted", IsDeleteEnum.N.getKey())
+        );
+        Map<String, KlConcept> map
+                = EntityUtil.makeEntityMapByKeys(klConcepts, "_", "libName", "libType");
+        return map;
+    }
+
+    /**
+     * 保存数据
+     *
+     * @param allData
+     */
+    public void saveData(List<ImportDiagnoseResVO> allData) {
+        for (ImportDiagnoseResVO importDiagnoseResVO : allData) {
+            Long diseaseId = importDiagnoseResVO.getDiseaseId();
+            String diseaseName = importDiagnoseResVO.getDiseaseName();
+            List<ImportDiagnoseVO> data = importDiagnoseResVO.getImportDiagnoseVOList();
+            // 获取序号对应的行数据
+            Map<String, List<ImportDiagnoseVO>> map = EntityUtil.makeEntityListMap(data, "orderNo");
+
+            if (ListUtil.isNotEmpty(data)) {
+                // 第一层
+                KlDiagnoseSaveVO klDiagnoseSaveVO = new KlDiagnoseSaveVO();
+                klDiagnoseSaveVO.setConceptId(diseaseId);
+                klDiagnoseSaveVO.setDescription(diseaseName);
+
+                // 第二层
+                List<KlDiagnoseTypeVO> klDiagnoseTypeVOList = Lists.newArrayList();
+
+                for (ImportDiagnoseVO importDiagnoseVO : data) {
+                    String type = importDiagnoseVO.getType();
+                    String getOrderNo = importDiagnoseVO.getOrderNo();
+                    if (StringUtil.isNotBlank(type) && StringUtil.isNotBlank(getOrderNo)) {
+                        if ("拟诊".equals(type) || "确诊".equals(type) || "警惕".equals(type)) {
+                            String[] splitGroup = getOrderNo.split("\\+");
+
+                            KlDiagnoseTypeVO klDiagnoseTypeVO = new KlDiagnoseTypeVO();
+                            if ("拟诊".equals(type)) {
+                                klDiagnoseTypeVO.setConditionType(2);
+                            } else if ("确诊".equals(type)) {
+                                klDiagnoseTypeVO.setConditionType(3);
+                            } else if ("警惕".equals(type)) {
+                                klDiagnoseTypeVO.setConditionType(4);
+                            }
+
+                            //  第三层
+                            List<KlDiagnoseGroupVO> groupVO = Lists.newArrayList();
+                            for (String group : splitGroup) {
+                                KlDiagnoseGroupVO klDiagnoseGroupVO = generateDiagnoseGroup(group, map);
+                                groupVO.add(klDiagnoseGroupVO);
+                            }
+
+                            klDiagnoseTypeVO.setGroupVO(groupVO);
+                            klDiagnoseTypeVOList.add(klDiagnoseTypeVO);
+                            klDiagnoseSaveVO.setKlDiagnoseTypeVO(klDiagnoseTypeVOList);
+                        }
+                    }
+                }
+
+                // 获取主表数据
+                KlDiagnose klDiagnose = klDiagnoseFacade.getOne(new QueryWrapper<KlDiagnose>().eq("concept_id", diseaseId), false);
+                if (klDiagnose != null) {
+                    klDiagnoseSaveVO.setId(klDiagnose.getId());
+                    klDiagnoseSaveVO.setModifier("0");
+                }
+                klDiagnoseFacade.saveDiagnoseAll(klDiagnoseSaveVO);
+            }
+        }
+    }
+
+
+    /**
+     * 生成KlDiagnoseGroupVO, 每一组+分隔后的内容
+     *
+     * @param map
+     * @param text
+     * @return
+     */
+    public KlDiagnoseGroupVO generateDiagnoseGroup(String text, Map<String, List<ImportDiagnoseVO>> map) {
+        KlDiagnoseGroupVO klDiagnoseGroupVO = new KlDiagnoseGroupVO();
+
+        //  list[0]:序号,list[1]:任几
+        List<String> list = Lists.newArrayList();
+        if (text.contains("[") || text.contains("]")) {
+            list.add(text.substring(text.indexOf("[") + 1, text.indexOf("]")));
+            String numStr = text.substring(text.indexOf("任") + 1);
+            String num = "1";
+            switch (numStr) {
+                case "一":
+                    num = "1";
+                    break;
+                case "二":
+                    num = "2";
+                    break;
+                case "三":
+                    num = "3";
+                    break;
+                case "四":
+                    num = "4";
+                    break;
+                case "五":
+                    num = "5";
+                    break;
+                case "六":
+                    num = "6";
+                    break;
+                case "七":
+                    num = "7";
+                    break;
+                case "八":
+                    num = "8";
+                    break;
+                case "九":
+                    num = "9";
+                    break;
+                case "十":
+                    num = "10";
+                    break;
+            }
+            list.add(num);
+        } else {
+            list.add(text);
+            list.add("1");
+        }
+        klDiagnoseGroupVO.setFitNo(Integer.valueOf(list.get(1))); // 任几
+
+        List<KlDiagnoseDetailVO> klDiagnoseDetail = Lists.newArrayList();
+        String[] orderArr = list.get(0).split("、");
+        for (String order : orderArr) {
+            KlDiagnoseDetailVO klDiagnoseDetailVO = new KlDiagnoseDetailVO();
+            ImportDiagnoseVO current = map.get(order).get(0);
+            LexiconExtEnum libTypeEnum = LexiconExtEnum.getEnum(current.getType());
+            if (libTypeEnum != null) {
+                klDiagnoseDetailVO.setBasLibName(current.getRule());
+                switch (libTypeEnum) {
+                    case Symptom: // 症状
+                    case VitalResult: // 体格检查结果
+                    case PacsResult: // 辅助检查结果
+                    case Group: // 人群
+                    case Disease: // 疾病
+                        klDiagnoseDetailVO.setBasConceptId(current.getConceptId());
+                        klDiagnoseDetailVO.setBasType(1);
+                        klDiagnoseDetailVO.setBasDescription(current.getRule());
+                        break;
+                    case zsxbszz: // 主诉现病史正则
+                        klDiagnoseDetailVO.setBasType(3);
+                        klDiagnoseDetailVO.setBasDescription(current.getRule());
+                        klDiagnoseDetailVO.setEqValue(current.getRule());
+                        break;
+                    case jwzz: // 既往正则
+                        klDiagnoseDetailVO.setBasType(4);
+                        klDiagnoseDetailVO.setBasDescription(current.getRule());
+                        klDiagnoseDetailVO.setEqValue(current.getRule());
+                        break;
+                    case Vital: // 体格检查项目
+                    case Age: // 年龄
+                        klDiagnoseDetailVO.setBasConceptId(current.getConceptId());
+                        if (StringUtil.isNotBlank(current.getMin())) {
+                            klDiagnoseDetailVO.setMinVal(current.getMin());
+                        }
+                        if (StringUtil.isNotBlank(current.getMinSymbol())) {
+                            klDiagnoseDetailVO.setMinOperator(current.getMinSymbol());
+                        }
+                        if (StringUtil.isNotBlank(current.getUnit())) {
+                            klDiagnoseDetailVO.setMinUnit(current.getUnit());
+                            klDiagnoseDetailVO.setMaxUnit(current.getUnit());
+                        }
+                        if (StringUtil.isNotBlank(current.getMax())) {
+                            klDiagnoseDetailVO.setMaxVal(current.getMax());
+                        }
+                        if (StringUtil.isNotBlank(current.getMaxSymbol())) {
+                            klDiagnoseDetailVO.setMaxOperator(String.valueOf(current.getMaxSymbol()));
+                        }
+                        klDiagnoseDetailVO.setBasDescription(current.getRule());
+                        klDiagnoseDetailVO.setBasType(2);
+                        break;
+                    case LisSubName: // 实验室检查子项目
+                        klDiagnoseDetailVO.setBasConceptId(current.getConceptId());
+                        klDiagnoseDetailVO.setEqValue(current.getEq());
+                        klDiagnoseDetailVO.setBasDescription(current.getRule() + current.getEq());
+                        klDiagnoseDetailVO.setBasType(2);
+                        break;
+                }
+            }
+            klDiagnoseDetail.add(klDiagnoseDetailVO);
+        }
+
+        klDiagnoseGroupVO.setKlDiagnoseDetail(klDiagnoseDetail);
+        return klDiagnoseGroupVO;
+    }
+
+    public static void main(String[] args) {
+        String text = "[1、2、3]任一";
+        List<String> list = Lists.newArrayList();
+        if (text.contains("[") || text.contains("]")) {
+            list.add(text.substring(text.indexOf("[") + 1, text.indexOf("]")));
+            list.add(text.substring(text.indexOf("]") + 1));
+        }
+        System.out.println(list);
+    }
+}

+ 38 - 5
src/main/java/com/diagbot/util/ExcelUtils.java

@@ -10,9 +10,17 @@ import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
 import com.diagbot.exception.CommonErrorCode;
 import com.diagbot.exception.CommonException;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.poi.hssf.usermodel.*;
-import org.apache.poi.ss.usermodel.*;
-import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.hssf.usermodel.HSSFCell;
+import org.apache.poi.hssf.usermodel.HSSFCellStyle;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
@@ -20,9 +28,14 @@ import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.lang.reflect.Method;
+import java.io.InputStream;
 import java.net.URLEncoder;
-import java.util.*;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
 
 /**
  * @Description: excel 导入导出工具类
@@ -30,6 +43,26 @@ import java.util.*;
  * @time: 2020/6/2 19:18
  */
 public class ExcelUtils {
+
+    /**
+     * 得到Workbook对象
+     * @param file
+     * @return
+     * @throws IOException
+     */
+    public static Workbook getWorkBook(MultipartFile file) throws IOException{
+        //这样写  excel 能兼容03和07
+        InputStream is = file.getInputStream();
+        Workbook hssfWorkbook = null;
+        try {
+            hssfWorkbook = new HSSFWorkbook(is);
+        } catch (Exception ex) {
+            is =file.getInputStream();
+            hssfWorkbook = new XSSFWorkbook(is);
+        }
+        return hssfWorkbook;
+    }
+
     public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass, String fileName,
                                    boolean isCreateHeader, HttpServletResponse response) {
         ExportParams exportParams = new ExportParams(title, sheetName);

+ 396 - 0
src/main/java/com/diagbot/util/VerifyUtil.java

@@ -0,0 +1,396 @@
+package com.diagbot.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @description: 校验工具类
+ * @author: zhoutg
+ * @time: 2019/8/12 14:44
+ */
+public class VerifyUtil {
+
+    /**
+     *  校验编码是否正确
+     *
+     * @param type 诊断依据类型
+     * @param val 值 ,如:1.1,1.99,点后最多2位
+     * @return 校验结果
+     */
+    public static boolean verifyCode(String type, String val) {
+        if (StringUtil.isEmpty(type)) {
+            return false;
+        }
+//        String regex = type + "\\.[1-9]\\d?";
+		String regex = type + "\\.(0|[1-9]\\d?)";
+        return Pattern.matches(regex, val);
+    }
+
+	/**
+	 * 校验是否包含无效字符
+	 *
+	 * @param text
+	 * @return
+	 */
+	public static boolean verifyText(String text) {
+    	if (StringUtil.isBlank(text)) {
+    		return false;
+		}
+		String regex = "任|一|二|三|四|五|六|七|八|九|十|\\[||\\]|\\+|、|\\d";
+		for (int i = 0; i < text.length(); i++) {
+			String s1 = String.valueOf(text.charAt(i));
+			boolean flag = s1.matches(regex);
+			if (!flag) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+    /**
+     * 校验公式编码
+     * @param coding 编码
+     * @param str  公式
+     * @return
+     */
+    public static boolean checkCodeEquation(List<String> coding, String str) {
+		boolean res = true;
+		// 分割出所有的数字
+		String[] split = str.split("\\+");
+		String[] digitalSplit = str.split("[+ ( / ) 任 一 二 三 四 五 六 七 八 九 十  ]");
+		List<String> numberList = new ArrayList<String>();
+		for (int i = 0; i < digitalSplit.length; i++) {
+			if (!digitalSplit[i].equals("")) {
+				numberList.add(digitalSplit[i]);
+			}
+		}
+
+		res = coding.containsAll(numberList);
+		if (res == true) {
+			for (int i = 0; i < split.length; i++) {
+				String str1 = split[i].substring(0, split[i].indexOf(")") + 1);
+				// 检查是否以括号开头,以括号结尾
+				boolean start = str1.startsWith("(");
+				boolean end = str1.endsWith(")");
+
+				if (start == false || end == false) {
+					res = false;
+					break;
+					//throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "公式格式有误");
+				}
+				String str2 = split[i].substring(split[i].indexOf(")") + 1);
+				String[] array = { "任一", "任二", "任三", "任四", "任五", "任六", "任七", "任八", "任九", "任十" };
+				if (str2.length() > 0) {
+					boolean pp = Arrays.asList(array).contains(str2);
+					if (pp == false) {
+						res = false;
+						break;
+					}
+				} else {
+					res = false;
+					break;
+				}
+			}
+		} else {
+			res = false;
+		}
+
+		return res;
+	}
+
+
+	/**
+	 * 校验括号中的值是否正确,大于等于任数,不能只有一个编码
+	 *
+	 * @param s
+	 * @return
+	 */
+	public static boolean verifyValue(String s) {
+		String regex = "\\[.*?\\]任"; // 非贪婪模式
+		Pattern pattern = Pattern.compile(regex);
+		Matcher matches = pattern.matcher(s);
+		while(matches.find()) {
+			String str = matches.group();
+			String numStr = s.substring(matches.end(), matches.end()+1);
+
+			int i = 0;
+			switch (numStr) {
+				case "一":
+					i = 1;
+					break;
+				case "二":
+					i = 2;
+					break;
+				case "三":
+					i = 3;
+					break;
+				case "四":
+					i = 4;
+					break;
+				case "五":
+					i = 5;
+					break;
+				case "六":
+					i = 6;
+					break;
+				case "七":
+					i = 7;
+					break;
+				case "八":
+					i = 8;
+					break;
+				case "九":
+					i = 9;
+					break;
+				case "十":
+					i = 10;
+					break;
+			}
+			int num = str.split("、").length;
+			if (i > num || 1 == num) { // 括号内只有一个编码
+				return true;
+			}
+		}
+		return false;
+	}
+
+
+	/**
+	 * 1、校验括号是否匹配,是否嵌套
+	 * 2、校验开头和结尾字符,开头不能是:)+/,结尾不能是:()+/
+	 * 3、校验公式分隔符
+	 * 4、校验公式中的编码值是否全部在编码中 (业务校验)
+	 * 5、校验括号中的值是否正确,大于等于任数,不能只有一个编码(业务校验)
+	 *
+	 * @param s
+	 * @return
+	 */
+	public static String verifyFormula(List<String> codeList, String s) {
+		String errMsg = String.format("%s 公式格式错误;  ",s);
+		try {
+			// 1、校验是否包含无效字符
+			if (!verifyText(s)) {
+				return errMsg;
+			}
+
+			// 2、校验括号是否匹配,是否嵌套
+			if (!verifyBracketNest(s)) {
+				return errMsg;
+			}
+
+			// 3、校验开头和结尾字符,开头不能是:)+/,结尾不能是:()+/
+			if (verifyStartEnd(s)) {
+				return errMsg;
+			}
+
+			// 4、校验公式分隔符
+			List<String> splitCode = verifySplit(s);
+			int i = 0;
+			for (String str : splitCode) {
+				// 如果中间出现空字符串,表明出错了
+				if (StringUtil.isEmpty(str) && i != 0 && i != splitCode.size() - 1) {
+					return errMsg;
+				}
+				i++;
+			}
+
+			// 5、校验公式中的编码值是否全部在编码中
+			List<String> codes = new ArrayList<>();
+			for (String str : splitCode) {
+				if (StringUtil.isNotEmpty(str)) {
+					codes.add(str);
+				}
+			}
+			if (!codeList.containsAll(codes)) {
+				return errMsg;
+			}
+
+			// 6、校验括号中的值是否正确,大于等于任数,不能只有一个编码
+			if (verifyValue(s)) {
+				return errMsg;
+			}
+
+			// 7、校验拟诊是否放首位
+			/*if (!verifyDiseaseType(s)) {
+				return errMsg;
+			}*/
+		} catch (Exception e) {
+			e.printStackTrace();
+			return errMsg;
+		}
+		return "";
+	}
+
+
+	/**
+	 * 校验开头和结尾字符,开头不能是:)+/,结尾不能是:()+/
+	 * @param s
+	 * @return
+	 */
+	public static boolean verifyStartEnd(String s) {
+		String startRegex =
+				"(\\]|\\+|/).*" ;
+		String endRegex =
+				".*(\\[|\\]|\\+|/)" ;
+		if (Pattern.matches(startRegex, s)) {
+			return true;
+		}
+		if (Pattern.matches(endRegex, s)) {
+			return true;
+		}
+		return false;
+	}
+
+
+	/**
+	 * 以最大长度分隔符分隔
+	 * @param s
+	 * @return
+	 */
+	public static List<String> verifySplit(String s) {
+		s = s.replaceAll("\\(", "(");
+		s = s.replaceAll("\\)", ")");
+		s = s.replaceAll(" ", "");
+		String regex =
+				"\\]任一\\+\\[" + "|\\]任二\\+\\[" + "|\\]任三\\+\\[" + "|\\]任四\\+\\[" + "|\\]任五\\+\\[" + "|\\]任六\\+\\[" + "|\\]任七\\+\\[" + "|\\]任八\\+\\[" + "|\\]任九\\+\\[" + "|\\]任十\\+\\[" +
+						"|\\]任一\\+" + "|\\]任二\\+"  + "|\\]任三\\+" + "|\\]任四\\+" + "|\\]任五\\+" + "|\\]任六\\+" + "|\\]任七\\+" + "|\\]任八\\+" + "|\\]任九\\+" + "|\\]任十\\+" +
+						"|\\]任一" + "|\\]任二" + "|\\]任三" + "|\\]任四" + "|\\]任五" + "|\\]任六" + "|\\]任七" + "|\\]任八" + "|\\]任九" + "|\\]任十" +
+						"|\\+\\[" +
+						"|\\[" +
+						"|\\]" +
+						"|\\+" +
+						"|\\、" +
+						"|/" ;
+		String[] arr = s.split(regex);
+		return Arrays.asList(arr);
+	}
+
+
+	/**
+	 * 校验括号是否匹配,是否嵌套
+	 * @param s
+	 * @return
+	 */
+	public static boolean verifyBracketNest(String s) {
+		Stack<Character> sc=new Stack<Character>();
+		char[] c=s.toCharArray();
+		for (int i = 0; i < c.length; i++) {
+			if (c[i]=='[') {
+				if(sc.isEmpty()) {
+					sc.push(c[i]);
+				} else {
+					if (sc.peek()=='[') {
+						return false;
+					}
+				}
+			}
+			else if (c[i]==']') {
+				if(sc.isEmpty()){
+					return false;
+				}
+				else{
+					if (sc.peek()=='[') {
+						sc.pop();
+					}
+				}
+			}
+		}
+		if (sc.empty()) {
+			return true;
+		}else {
+			return false;
+		}
+	}
+
+
+	/**
+	 * 校验任字前面是否“)”
+	 * @param s
+	 * @return
+	 */
+	public static boolean verifyRen(String s) {
+		int i = s.indexOf("任");
+		while(-1 != i) {
+			if(i == 0) {
+				return false;
+			} else {
+				char ch = s.charAt(i-1);
+				if (')' != ch) {
+					return false;
+				}
+				i =  s.indexOf("任", i + 1);
+			}
+		}
+		return true;
+	}
+
+
+	/**
+	 * 获取编码
+	 * @param s
+	 * @return
+	 */
+	public static List<String> splitCode(String s) {
+		List<String> res = new ArrayList<>();
+		String resg1 = "\\(|/|\\)|任一|任二|任三|任四|任五|任六|任七|任八|任九|任十|\\+";
+		String[] arr = s.split(resg1);
+		for(String str : arr) {
+			if (StringUtil.isNotEmpty(str)) {
+				res.add(str);
+			}
+		}
+		return res;
+	}
+
+
+	/**
+	 * 是否出现重复分隔符
+	 * @param s
+	 * @return
+	 */
+	public static boolean isRepeat(String s) {
+		String regex = ".*((\\()|(\\))|(\\+)|(//)|(任一)|(任二)|(任三)|(任四)|(任五)|(任六)|(任七)|(任八)|(任九)|(任十)){2,}.*";
+		return Pattern.matches(regex, s);
+	}
+
+
+	/**
+	 * 诊断类型(拟诊)匹配,拟诊两个字只能放首位
+	 * @param s
+	 * @return
+	 */
+	public static boolean verifyDiseaseType(String s) {
+		int index = s.indexOf("拟诊");
+		if (index > 0) {
+			return false;
+		}
+		index = s.indexOf( "拟诊", index+1); // 再次校验,防止出现多个拟诊
+		if (index > 0) {
+			return false;
+		}
+		return true;
+	}
+
+	public static void main(String[] args) {
+		List<String> strings = verifySplit("[1、3]任一+4");
+		System.out.println(strings);
+		//		System.out.println(verifyStartEnd("]1.1+1.2"));
+		//    	String str = "1.99";
+		//		System.out.println(verifyCode("1", str));
+		//
+		//    	List<String> code = new ArrayList<>();
+		//    	code.add("拟诊");
+		//    	code.add("1.1");
+		//		System.out.println(verifyFormula(code, str));
+		//    	List<String> list = new ArrayList<>();
+		//    	list.add("1.1");
+		//    	list.add("1.2");
+		//		checkCodeEquation(list, "(1.1/1.2)任一+");
+		String s = "";
+		System.out.println(verifyText(s));
+	}
+}

+ 24 - 0
src/main/java/com/diagbot/vo/DiagnoseImportVO.java

@@ -0,0 +1,24 @@
+package com.diagbot.vo;
+
+import com.google.common.collect.Lists;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * <p>
+ * 诊断依据
+ * </p>
+ *
+ * @author zhoutg
+ * @since 2020-07-28
+ */
+@Data
+public class DiagnoseImportVO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    // 诊断列表
+    private List<String> diags = Lists.newArrayList();
+}

+ 26 - 0
src/main/java/com/diagbot/vo/ImportDiagnoseResVO.java

@@ -0,0 +1,26 @@
+package com.diagbot.vo;
+
+import com.google.common.collect.Lists;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * <p>
+ * 诊断依据导入
+ * </p>
+ *
+ * @author zhoutg
+ * @since 2020-07-28
+ */
+@Data
+public class ImportDiagnoseResVO implements Serializable {
+
+    // 诊断id
+    private Long diseaseId;
+    // 诊断名称
+    private String diseaseName;
+    // 导入数据
+    private List<ImportDiagnoseVO> importDiagnoseVOList = Lists.newArrayList();
+}

+ 44 - 0
src/main/java/com/diagbot/vo/ImportDiagnoseVO.java

@@ -0,0 +1,44 @@
+package com.diagbot.vo;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 诊断依据导入
+ * </p>
+ *
+ * @author zhaops
+ * @since 2020-07-28
+ */
+@Data
+public class ImportDiagnoseVO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @Excel(name="类型")
+    private String type = "";
+    @Excel(name="序号")
+    private String orderNo = "";
+    @Excel(name="规则")
+    private String rule = "";
+    @Excel(name="等于")
+    private String eq;
+    @Excel(name="最大值")
+    private String max;
+    @Excel(name="最大值符号")
+    private String maxSymbol;
+    @Excel(name="单位")
+    private String unit;
+    @Excel(name="最小值")
+    private String min;
+    @Excel(name="最小值符号")
+    private String minSymbol;
+    // @Excel(name="单位")
+    // private String minUnit;
+
+    // 规则标准词id
+    private Long conceptId;
+}

+ 41 - 0
src/main/java/com/diagbot/web/KlDiagnoseImportController.java

@@ -0,0 +1,41 @@
+package com.diagbot.web;
+
+import com.diagbot.dto.RespDTO;
+import com.diagbot.facade.KlDiagnoseImportFacade;
+import com.diagbot.vo.DiagnoseImportVO;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Map;
+
+/**
+ * @author wangfeng
+ * @Description:
+ * @date 2021-03-19 14:52
+ */
+@RestController
+@RequestMapping("/klDiagnoseImport")
+@Api(value = "诊断依据维护导入API", tags = { "诊断依据维护导入API" })
+@SuppressWarnings("unchecked")
+public class KlDiagnoseImportController {
+
+    @Autowired
+    KlDiagnoseImportFacade klDiagnoseImportFacade;
+
+    @ApiOperation(value = "诊断依据导入API[zhoutg]",
+            notes = "")
+    @PostMapping("/importDiagnose")
+    @Transactional
+    public RespDTO<Map<String, Object>> importDiagnose(@RequestParam("file") MultipartFile file, DiagnoseImportVO diagnoseImportVO) {
+        return RespDTO.onSuc(klDiagnoseImportFacade.importDiagnose(file, diagnoseImportVO));
+    }
+
+
+}