Prechádzať zdrojové kódy

1、术语关联映射-非标准词包含禁用词
2、术语关联映射-国药准字匹配

zhaops 3 rokov pred
rodič
commit
1c57709289

+ 9 - 0
src/main/java/com/diagbot/client/CdssCoreClient.java

@@ -59,6 +59,15 @@ public interface CdssCoreClient {
     @PostMapping("/retrieval/index")
     RespDTO<RetrievalDTO> index(@RequestBody @Valid RetrievalVO retrievalVO);
 
+    /**
+     * 国药准字匹配
+     *
+     * @param indexByApprovalVO
+     * @return
+     */
+    @PostMapping("/retrieval/indexByApproval")
+    RespDTO<List<IndexBatchDTO>> indexByApproval(@Valid @RequestBody IndexByApprovalVO indexByApprovalVO);
+
     /**
      * 静态知识检索
      *

+ 14 - 1
src/main/java/com/diagbot/client/hystrix/CdssCoreHystrix.java

@@ -72,6 +72,19 @@ public class CdssCoreHystrix implements CdssCoreClient {
         return null;
     }
 
+
+    /**
+     * 国药准字匹配
+     *
+     * @param indexByApprovalVO
+     * @return
+     */
+    @Override
+    public RespDTO<List<IndexBatchDTO>> indexByApproval(@Valid @RequestBody IndexByApprovalVO indexByApprovalVO) {
+        log.error("【hystrix】调用{}异常", "indexByApproval");
+        return null;
+    }
+
     /**
      * 静态知识检索
      *
@@ -341,4 +354,4 @@ public class CdssCoreHystrix implements CdssCoreClient {
         log.error("【hystrix】调用{}异常", "getTermMatching");
         return null;
     }
-}
+}

+ 1 - 0
src/main/java/com/diagbot/config/ResourceServerConfigurer.java

@@ -47,6 +47,7 @@ public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
                 .antMatchers("/tran/mappingConfig/dataVerify").permitAll()
                 .antMatchers("/tran/mappingConfig/precDataMatch").permitAll()
                 .antMatchers("/tran/mappingConfig/precDataMatch_remote").permitAll()
+                .antMatchers("/tran/mappingConfig/importExcelDataVerify").permitAll()
                 .antMatchers("/tran/mappingConfig/importExcel").permitAll()
                 .antMatchers("/tran/mappingConfig/exportExcel").permitAll()
                 .antMatchers("/tran/mappingConfig/exportExcel_remote").permitAll()

+ 1 - 0
src/main/java/com/diagbot/config/security/UrlAccessDecisionManager.java

@@ -90,6 +90,7 @@ public class UrlAccessDecisionManager implements AccessDecisionManager {
                 || matchers("/tran/mappingConfig/dataVerify", request)
                 || matchers("/tran/mappingConfig/precDataMatch", request)
                 || matchers("/tran/mappingConfig/precDataMatch_remote", request)
+                || matchers("/tran/mappingConfig/importExcelDataVerify", request)
                 || matchers("/tran/mappingConfig/importExcel", request)
                 || matchers("/tran/mappingConfig/exportExcel", request)
                 || matchers("/tran/mappingConfig/exportExcel_remote", request)

+ 12 - 0
src/main/java/com/diagbot/dto/IndexBatchDTO.java

@@ -16,4 +16,16 @@ public class IndexBatchDTO {
     private String code;
     private String synonyms;
     private Integer type;
+    /**
+     * 国药准字
+     */
+    private String approval;
+    /**
+     * 药品剂型
+     */
+    private String form;
+    /**
+     * 药品剂型id
+     */
+    private Long formConceptId;
 }

+ 6 - 60
src/main/java/com/diagbot/entity/DrugConfig.java

@@ -1,15 +1,10 @@
 package com.diagbot.entity;
 
 import cn.afterturn.easypoi.excel.annotation.Excel;
-import com.baomidou.mybatisplus.annotation.FieldStrategy;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.diagbot.util.StringUtil;
-import lombok.Getter;
-import lombok.Setter;
+import lombok.Data;
 
 import javax.validation.constraints.NotBlank;
 import java.util.Date;
-import java.util.Objects;
 
 /**
  * <p>
@@ -19,8 +14,7 @@ import java.util.Objects;
  * @author zhaops
  * @since 2020-07-28
  */
-@Getter
-@Setter
+@Data
 public class DrugConfig {
     /**
      * 主键
@@ -80,68 +74,20 @@ public class DrugConfig {
      * 剂型
      */
     @Excel(name = "药品剂型", width = 60, orderNum = "3", isImportField = "true")
-    @TableField(updateStrategy = FieldStrategy.IGNORED)
     private String form;
 
+    @Excel(name = "国药准字", width = 40, orderNum = "4", isImportField = "true")
+    private String approval;
 
     /**
      * 是否匹配(0-未匹配、1-已匹配)
      */
-    @Excel(name = "是否匹配【未匹配、已匹配】", width = 20, orderNum = "4", replace = { "未匹配_0", "已匹配_1" }, isImportField = "true")
+    @Excel(name = "是否匹配【未匹配、已匹配】", width = 20, orderNum = "5", replace = { "未匹配_0", "已匹配_1" }, isImportField = "true")
     private Integer isMatch;
 
     /**
      * 数据来源(1-标准词、2-同义词、3-编码、4-历史数据、5-相似词、99-数据迁移)
      */
-    @Excel(name = "数据来源【不填、标准词、同义词、编码、历史数据、相似词】", width = 20, orderNum = "5", replace = { "标准词_1", "同义词_2", "编码_3", "历史数据_4", "相似词_5", "数据迁移_99", "_null" }, isImportField = "true")
+    @Excel(name = "数据来源【不填、标准词、同义词、编码、历史数据、相似词】", width = 20, orderNum = "6", replace = { "标准词_1", "同义词_2", "编码_3", "历史数据_4", "相似词_5", "国药准字_6", "数据迁移_99", "_null" }, isImportField = "true")
     private Integer source;
-
-    @Override
-    public String toString() {
-        return "DrugConfig{" +
-                "id=" + id +
-                ", isDeleted=" + isDeleted +
-                ", gmtCreate=" + gmtCreate +
-                ", gmtModified=" + gmtModified +
-                ", creator=" + creator +
-                ", modifier=" + modifier +
-                ", hospitalId=" + hospitalId +
-                ", hisName=" + hisName +
-                ", uniqueName=" + uniqueName +
-                ", code=" + code +
-                ", form=" + form +
-                "}";
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        DrugConfig drugConfig = (DrugConfig) o;
-        return Objects.equals(id, drugConfig.id)
-                && Objects.equals(isDeleted, drugConfig.isDeleted)
-                && Objects.equals(hospitalId, drugConfig.hospitalId)
-                && Objects.equals(hisName, drugConfig.hisName)
-                && Objects.equals(form, drugConfig.form)
-                && Objects.equals(uniqueName, drugConfig.uniqueName)
-                && Objects.equals(code, drugConfig.code);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(id, isDeleted, hospitalId, hisName, form, uniqueName, code);
-    }
-
-    public static boolean nonNull(DrugConfig o) {
-        return !(o == null
-                || (o.hospitalId == null
-                && StringUtil.isBlank(o.hisName)
-                && StringUtil.isBlank(o.uniqueName)
-                && StringUtil.isBlank(o.code)
-                && StringUtil.isBlank(o.form)));
-    }
 }

+ 4 - 0
src/main/java/com/diagbot/entity/wrapper/MappingConfigWrapper.java

@@ -18,6 +18,10 @@ public class MappingConfigWrapper extends MappingConfig {
     private String uniqueName;
     private String form;
     private String code;
+    /**
+     * 国药准字
+     */
+    private String approval;
 
    /* @Override
     public boolean equals(Object o) {

+ 2 - 1
src/main/java/com/diagbot/enums/MatchSourceEnum.java

@@ -13,7 +13,8 @@ public enum MatchSourceEnum implements KeyedNamed {
     SynonymsWord(2, "同义词"),
     Code(3,"编码"),
     History(4,"历史数据"),
-    SimilarWord(5,"相似词");
+    SimilarWord(5,"相似词"),
+    Approval(6,"国药准字");
 
     @Setter
     private int key;

+ 478 - 133
src/main/java/com/diagbot/facade/MappingConfigFacade.java

@@ -42,11 +42,13 @@ import com.diagbot.vo.ConceptVO;
 import com.diagbot.vo.FilterVO;
 import com.diagbot.vo.IdListVO;
 import com.diagbot.vo.IdVO;
+import com.diagbot.vo.IndexByApprovalVO;
 import com.diagbot.vo.KllisDetailVO;
 import com.diagbot.vo.MappingConfigPageVO;
 import com.diagbot.vo.MappingConfigVO;
 import com.diagbot.vo.RetrievalVO;
 import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -61,6 +63,7 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
@@ -496,14 +499,71 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
             return retList;
         }
 
+        //国药准字匹配:药品
+        if(type.equals(ConceptTypeEnum.Drug.getKey())) {
+            dataList = matchWithApproval(dataList, type);
+        }
+
         //标准词匹配
-        List<String> nameList = dataList.stream()
+        dataList = matchWithStandWord(dataList, type);
+
+        //同义词匹配
+        dataList = matchWithSynonymsWord(dataList, type);
+
+        //编码匹配:手术、中医疾病、中医证候
+        if (type.equals(ConceptTypeEnum.Operation.getKey())
+                || type.equals(ConceptTypeEnum.Tcmdisease.getKey())
+                || type.equals(ConceptTypeEnum.Tcmsyndrome.getKey())) {
+            dataList = matchWithCode(dataList, type);
+        }
+
+        //历史匹配
+        dataList = matchWithHistory(dataList, type);
+
+        //编码匹配:诊断
+        if (type.equals(ConceptTypeEnum.Disease.getKey())) {
+            dataList = matchWithCode(dataList, type);
+        }
+
+        //药品关联标准词、同义词匹配数据增加历史数据剂型
+        if (type.equals(ConceptTypeEnum.Drug.getKey())) {
+            dataList = addDrugForm(dataList, type);
+        }
+
+        retList = BeanUtil.listCopyTo(dataList, MappingConfigWrapper.class);
+        for (MappingConfigWrapper item : retList) {
+            if (item.getIsMatch() == null) {
+                item.setIsMatch(0);
+            }
+        }
+
+        //添加编码
+        retList = addCodes(retList, type);
+        retList = retList.stream().distinct().collect(Collectors.toList());
+        return retList;
+    }
+
+    /**
+     * 标准词匹配
+     *
+     * @param list
+     * @param type
+     * @return
+     */
+    public List<MappingConfigWrapper> matchWithStandWord(List<MappingConfigWrapper> list, Integer type) {
+        List<MappingConfigWrapper> retList = Lists.newLinkedList();
+        if (ListUtil.isEmpty(list) || null == type) {
+            return list;
+        }
+        List<String> nameList = list.stream()
                 .filter(i -> StringUtil.isBlank(i.getHisDetailName()))
+                .filter(i -> (i.getIsMatch() == null || i.getIsMatch().equals(0)))
                 .map(MappingConfigWrapper::getHisName)
                 .distinct()
                 .collect(Collectors.toList());
-        List<String> subNameList = dataList.stream()
+        List<String> subNameList = list.stream()
                 .filter(i -> StringUtil.isNotBlank(i.getHisDetailName()))
+                .filter(i -> (i.getIsMatch() == null || i.getIsMatch().equals(0)))
                 .map(MappingConfigWrapper::getHisDetailName)
                 .distinct()
                 .collect(Collectors.toList());
@@ -526,7 +586,11 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
         if (ListUtil.isNotEmpty(subRespDTO.data)) {
             subNameMap = subRespDTO.data.stream().collect(Collectors.groupingBy(IndexBatchDTO::getName));
         }
-        for (MappingConfigWrapper item : dataList) {
+        for (MappingConfigWrapper item : list) {
+            if (item.getIsMatch() != null && item.getIsMatch().equals(1)) {
+                retList.add(item);
+                continue;
+            }
             List<IndexBatchDTO> indexList = Lists.newArrayList();
             if (type.equals(ConceptTypeEnum.LisPack.getKey()) && StringUtil.isNotBlank(item.getHisDetailName())) {
                 if (subNameMap.containsKey(item.getHisDetailName())) {
@@ -539,7 +603,7 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
             }
 
             if (ListUtil.isEmpty(indexList)) {
-                standardList.add(item);
+                retList.add(item);
                 continue;
             }
             //标准词默认取第一个
@@ -550,30 +614,44 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
             standardItem.setCode(indexList.get(0).getCode());
             standardItem.setIsMatch(1);
             standardItem.setSource(MatchSourceEnum.StandWord.getKey());
-            standardList.add(standardItem);
+            retList.add(standardItem);
         }
+        return retList;
+    }
 
-        //同义词匹配
-        List<String> synonymsNameList = standardList.stream()
+    /**
+     * 同义词匹配
+     *
+     * @param list
+     * @param type
+     * @return
+     */
+    public List<MappingConfigWrapper> matchWithSynonymsWord(List<MappingConfigWrapper> list, Integer type) {
+        List<MappingConfigWrapper> retList = Lists.newLinkedList();
+        if (ListUtil.isEmpty(list) || null == type) {
+            return list;
+        }
+        List<String> synonymsNameList = list.stream()
                 .filter(i -> (i.getIsMatch() == null || i.getIsMatch().equals(0))
                         && StringUtil.isBlank(i.getHisDetailName()))
                 .map(MappingConfigWrapper::getHisName)
                 .distinct()
                 .collect(Collectors.toList());
-        List<String> synonymsSubNameList = standardList.stream()
+        List<String> synonymsSubNameList = list.stream()
                 .filter(i -> (i.getIsMatch() == null || i.getIsMatch().equals(0))
                         && StringUtil.isNotBlank(i.getHisDetailName()))
                 .map(MappingConfigWrapper::getHisDetailName)
                 .distinct()
                 .collect(Collectors.toList());
+        ConceptVO conceptVO = new ConceptVO();
         conceptVO.setSource(MatchSourceEnum.SynonymsWord.getKey());
         conceptVO.setType(type);
         conceptVO.setNames(synonymsNameList);
-        respDTO = cdssCoreClient.getConceptNames(conceptVO);
+        RespDTO<List<IndexBatchDTO>> respDTO = cdssCoreClient.getConceptNames(conceptVO);
         RespDTOUtil.respNGDealCover(respDTO, "标准术语校验失败");
         conceptVO.setType(ConceptTypeEnum.Lis.getKey());
         conceptVO.setNames(synonymsSubNameList);
-        subRespDTO = cdssCoreClient.getConceptNames(conceptVO);
+        RespDTO<List<IndexBatchDTO>> subRespDTO = cdssCoreClient.getConceptNames(conceptVO);
         RespDTOUtil.respNGDealCover(subRespDTO, "标准术语校验失败");
         Map<String, List<IndexBatchDTO>> synonymsNameMap = new HashMap<>();
         Map<String, List<IndexBatchDTO>> synonymsSubNameMap = new HashMap<>();
@@ -583,9 +661,9 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
         if (ListUtil.isNotEmpty(subRespDTO.data)) {
             synonymsSubNameMap = subRespDTO.data.stream().collect(Collectors.groupingBy(IndexBatchDTO::getSynonyms));
         }
-        for (MappingConfigWrapper item : standardList) {
+        for (MappingConfigWrapper item : list) {
             if (item.getIsMatch() != null && item.getIsMatch().equals(1)) {
-                synonymsList.add(item);
+                retList.add(item);
                 continue;
             }
             List<IndexBatchDTO> indexList = Lists.newLinkedList();
@@ -600,7 +678,7 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
             }
 
             if (ListUtil.isEmpty(indexList)) {
-                synonymsList.add(item);
+                retList.add(item);
                 continue;
             }
 
@@ -612,62 +690,88 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
                 synonymsItem.setCode(index.getCode());
                 synonymsItem.setIsMatch(1);
                 synonymsItem.setSource(MatchSourceEnum.SynonymsWord.getKey());
-                synonymsList.add(synonymsItem);
+                retList.add(synonymsItem);
             }
         }
+        return retList;
+    }
 
-        //todo 编码匹配
-        if (type.equals(ConceptTypeEnum.Disease.getKey())
+    /**
+     * 编码匹配
+     *
+     * @param list
+     * @param type
+     * @return
+     */
+    public List<MappingConfigWrapper> matchWithCode(List<MappingConfigWrapper> list, Integer type) {
+        List<MappingConfigWrapper> retList = Lists.newLinkedList();
+        if (ListUtil.isEmpty(list) || null == type) {
+            return list;
+        }
+        if (!(type.equals(ConceptTypeEnum.Disease.getKey())
                 || type.equals(ConceptTypeEnum.Operation.getKey())
                 || type.equals(ConceptTypeEnum.Tcmdisease.getKey())
-                || type.equals(ConceptTypeEnum.Tcmsyndrome.getKey())) {
-            List<String> codes = synonymsList.stream()
-                    .filter(i -> (i.getIsMatch() == null || i.getIsMatch().equals(0))
-                            && StringUtil.isNotBlank(i.getCode()))
-                    .map(MappingConfigWrapper::getCode)
-                    .distinct()
-                    .collect(Collectors.toList());
-            if (ListUtil.isEmpty(codes)) {
-                codeList = BeanUtil.listCopyTo(synonymsList, MappingConfigWrapper.class);
-            } else {
-                conceptVO.setSource(MatchSourceEnum.Code.getKey());
-                conceptVO.setType(type);
-                conceptVO.setNames(codes);
-                respDTO = cdssCoreClient.getConceptNames(conceptVO);
-                RespDTOUtil.respNGDealCover(respDTO, "标准术语校验失败");
-                Map<String, List<IndexBatchDTO>> codeMap = new HashMap<>();
-                if (ListUtil.isNotEmpty(respDTO.data)) {
-                    codeMap = respDTO.data.stream().collect(Collectors.groupingBy(IndexBatchDTO::getCode));
+                || type.equals(ConceptTypeEnum.Tcmsyndrome.getKey()))) {
+            return list;
+        }
+        List<String> codes = list.stream()
+                .filter(i -> (i.getIsMatch() == null || i.getIsMatch().equals(0))
+                        && StringUtil.isNotBlank(i.getCode()))
+                .map(MappingConfigWrapper::getCode)
+                .distinct()
+                .collect(Collectors.toList());
+        if (ListUtil.isEmpty(codes)) {
+            retList = BeanUtil.listCopyTo(list, MappingConfigWrapper.class);
+        } else {
+            ConceptVO conceptVO = new ConceptVO();
+            conceptVO.setSource(MatchSourceEnum.Code.getKey());
+            conceptVO.setType(type);
+            conceptVO.setNames(codes);
+            RespDTO<List<IndexBatchDTO>> respDTO = cdssCoreClient.getConceptNames(conceptVO);
+            RespDTOUtil.respNGDealCover(respDTO, "标准术语校验失败");
+            Map<String, List<IndexBatchDTO>> codeMap = new HashMap<>();
+            if (ListUtil.isNotEmpty(respDTO.data)) {
+                codeMap = respDTO.data.stream().collect(Collectors.groupingBy(IndexBatchDTO::getCode));
+            }
+            for (MappingConfigWrapper item : list) {
+                if (item.getIsMatch() != null && item.getIsMatch().equals(1)) {
+                    retList.add(item);
+                    continue;
                 }
-                for (MappingConfigWrapper item : synonymsList) {
-                    if (item.getIsMatch() != null && item.getIsMatch().equals(1)) {
-                        codeList.add(item);
-                        continue;
-                    }
-                    if (StringUtil.isNotBlank(item.getCode()) && codeMap.containsKey(item.getCode())) {
-                        List<IndexBatchDTO> indexList = codeMap.get(item.getCode());
-                        for (IndexBatchDTO index : indexList) {
-                            MappingConfigWrapper codeItem = new MappingConfigWrapper();
-                            BeanUtils.copyProperties(item, codeItem);
-                            codeItem.setUniqueName(index.getName());
-                            codeItem.setConceptId(index.getId());
-                            codeItem.setCode(index.getCode());
-                            codeItem.setIsMatch(1);
-                            codeItem.setSource(MatchSourceEnum.Code.getKey());
-                            codeList.add(codeItem);
-                        }
-                    } else {
-                        codeList.add(item);
-                        continue;
+                if (StringUtil.isNotBlank(item.getCode()) && codeMap.containsKey(item.getCode())) {
+                    List<IndexBatchDTO> indexList = codeMap.get(item.getCode());
+                    for (IndexBatchDTO index : indexList) {
+                        MappingConfigWrapper codeItem = new MappingConfigWrapper();
+                        BeanUtils.copyProperties(item, codeItem);
+                        codeItem.setUniqueName(index.getName());
+                        codeItem.setConceptId(index.getId());
+                        codeItem.setCode(index.getCode());
+                        codeItem.setIsMatch(1);
+                        codeItem.setSource(MatchSourceEnum.Code.getKey());
+                        retList.add(codeItem);
                     }
+                } else {
+                    retList.add(item);
+                    continue;
                 }
             }
-        } else {
-            codeList = BeanUtil.listCopyTo(synonymsList, MappingConfigWrapper.class);
         }
+        return retList;
+    }
 
-        //todo 历史匹配
-        List<String> hisNames = codeList.stream()
+    /**
+     * 历史数据匹配
+     *
+     * @param list
+     * @param type
+     * @return
+     */
+    public List<MappingConfigWrapper> matchWithHistory(List<MappingConfigWrapper> list, Integer type) {
+        List<MappingConfigWrapper> retList = Lists.newLinkedList();
+        if (ListUtil.isEmpty(list) || null == type) {
+            return list;
+        }
+        List<String> hisNames = list.stream()
                 .filter(i -> i.getIsMatch() == null || i.getIsMatch().equals(0))
                 .map(MappingConfigWrapper::getHisName)
                 .distinct()
@@ -675,9 +779,9 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
         if (ListUtil.isNotEmpty(hisNames)) {
             Map<String, Map<String, Map<String, List<String>>>> configMap = groupByHisNameWithName(hisNames, type, null);
 
-            for (MappingConfigWrapper item : codeList) {
+            for (MappingConfigWrapper item : list) {
                 if (item.getIsMatch() != null && item.getIsMatch().equals(1)) {
-                    historyList.add(item);
+                    retList.add(item);
                     continue;
                 }
                 if (configMap.containsKey(item.getHisName())) {
@@ -685,7 +789,7 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
                     if (subMap != null && subMap.size() > 0) {
                         Map<String, List<String>> thirdMap = subMap.get(item.getHisDetailName());
                         if (thirdMap == null || thirdMap.size() == 0) {
-                            historyList.add(item);
+                            retList.add(item);
                             continue;
                         }
                         for (Map.Entry<String, List<String>> thirdEntry : thirdMap.entrySet()) {
@@ -697,104 +801,168 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
                             if (type.equals(ConceptTypeEnum.Drug.getKey())) {
                                 List<String> forms = thirdEntry.getValue();
                                 if (ListUtil.isEmpty(forms)) {
-                                    historyList.add(historyItem);
+                                    retList.add(historyItem);
                                 } else {
                                     for (String form : forms) {
                                         MappingConfigWrapper formItem = new MappingConfigWrapper();
                                         BeanUtil.copyProperties(historyItem, formItem);
                                         formItem.setForm(form);
-                                        historyList.add(formItem);
+                                        retList.add(formItem);
                                     }
                                 }
                             } else {
-                                historyList.add(historyItem);
+                                retList.add(historyItem);
                             }
                         }
                     }
                 } else {
-                    historyList.add(item);
+                    retList.add(item);
                 }
             }
         } else {
-            historyList = BeanUtil.listCopyTo(codeList, MappingConfigWrapper.class);
+            retList = BeanUtil.listCopyTo(list, MappingConfigWrapper.class);
         }
+        return retList;
+    }
 
-        //药品关联标准词、同义词匹配数据增加历史数据剂型
-        if (type.equals(ConceptTypeEnum.Drug.getKey())) {
-            List<String> hisDrugNames = historyList.stream()
-                    .filter(i -> i.getIsMatch() != null
-                            && i.getIsMatch().equals(1)
-                            && i.getSource() != null
-                            && (i.getSource().equals(MatchSourceEnum.StandWord.getKey())))
-                    .map(MappingConfigWrapper::getHisName)
-                    .distinct()
-                    .collect(Collectors.toList());
-            hisDrugNames.addAll(historyList.stream()
-                    .filter(i -> i.getIsMatch() != null
-                            && i.getIsMatch().equals(1)
-                            && i.getSource() != null
-                            && i.getSource().equals(MatchSourceEnum.SynonymsWord.getKey()))
-                    .map(MappingConfigWrapper::getUniqueName)
-                    .distinct()
-                    .collect(Collectors.toList()));
-            if (ListUtil.isNotEmpty(hisDrugNames)) {
-                Map<String, Map<String, Map<String, List<String>>>> configMap = groupByHisNameWithName(hisDrugNames, type, null);
-                for (MappingConfigWrapper item : historyList) {
-                    if (item.getIsMatch() != null && item.getIsMatch().equals(1)
-                            && item.getSource() != null
-                            && (item.getSource().equals(MatchSourceEnum.StandWord.getKey())
-                            || item.getSource().equals(MatchSourceEnum.SynonymsWord.getKey()))) {
-                        if ((item.getSource().equals(MatchSourceEnum.StandWord.getKey())
-                                && configMap.containsKey(item.getHisName()))
-                                || (item.getSource().equals(MatchSourceEnum.SynonymsWord.getKey())
-                                && configMap.containsKey(item.getUniqueName()))) {
-                            Map<String, Map<String, List<String>>> subMap
-                                    = configMap.get(item.getSource().equals(MatchSourceEnum.StandWord.getKey())
-                                    ? item.getHisName()
-                                    : item.getUniqueName());
-                            if (subMap != null && subMap.size() > 0) {
-                                Map<String, List<String>> thirdMap = subMap.get(item.getHisDetailName());
-                                if (thirdMap == null || thirdMap.size() == 0) {
-                                    drugList.add(item);
-                                    continue;
-                                }
-                                List<String> forms = thirdMap.get(item.getUniqueName());
-                                if (ListUtil.isEmpty(forms)) {
-                                    drugList.add(item);
-                                } else {
-                                    for (String form : forms) {
-                                        MappingConfigWrapper formItem = new MappingConfigWrapper();
-                                        BeanUtil.copyProperties(item, formItem);
-                                        formItem.setForm(form);
-                                        drugList.add(formItem);
-                                    }
+    /**
+     * 国药准字匹配(药品)
+     * @param list
+     * @param type
+     * @return
+     */
+    public List<MappingConfigWrapper> matchWithApproval(List<MappingConfigWrapper> list,Integer type) {
+        List<MappingConfigWrapper> retList = Lists.newLinkedList();
+        if (ListUtil.isEmpty(list) || null == type) {
+            return list;
+        }
+        IndexByApprovalVO indexByApprovalVO = new IndexByApprovalVO();
+        indexByApprovalVO.setApprovalList(list.stream().map(MappingConfigWrapper::getApproval).collect(Collectors.toList()));
+
+        RespDTO<List<IndexBatchDTO>> respDTO = cdssCoreClient.indexByApproval(indexByApprovalVO);
+        RespDTOUtil.respNGDealCover(respDTO, "标准术语校验失败");
+
+        List<IndexBatchDTO> indexBatchDTOList = respDTO.data;
+
+        //国药准字取字母+数字编码
+        String regex = "[a-zA-Z]+\\d{8}";
+        Pattern pattern = Pattern.compile(regex);
+
+        Map<String, IndexBatchDTO> approvalMap = new HashMap<>();
+        for (IndexBatchDTO indexDTO : indexBatchDTOList) {
+            Matcher matcher = pattern.matcher(indexDTO.getApproval());
+            if (matcher.find()) {
+                approvalMap.put(matcher.group(), indexDTO);
+            }
+        }
+
+        for (MappingConfigWrapper item : list) {
+            if (StringUtil.isBlank(item.getApproval())) {
+                item.setIsMatch(0);
+                retList.add(item);
+                continue;
+            }
+            Matcher matcher = pattern.matcher(item.getApproval());
+            String approval = "";
+            if (matcher.find()) {
+                approval = matcher.group();
+            }
+            if (StringUtils.isNotBlank(approval) && approvalMap.containsKey(approval)) {
+                IndexBatchDTO indexBatchDTO = approvalMap.get(approval);
+                item.setUniqueName(indexBatchDTO.getName());
+                item.setConceptId(indexBatchDTO.getId());
+                if (indexBatchDTO.getFormConceptId() != null) {
+                    item.setForm(indexBatchDTO.getForm());
+                    item.setFormConceptId(indexBatchDTO.getFormConceptId());
+                }
+                item.setSource(MatchSourceEnum.Approval.getKey());
+                item.setIsMatch(1);
+            } else {
+                item.setIsMatch(0);
+            }
+            retList.add(item);
+        }
+        return retList;
+    }
+
+    /**
+     * 药品关联标准词、同义词匹配数据增加历史数据剂型
+     *
+     * @param list
+     * @param type
+     * @return
+     */
+    public List<MappingConfigWrapper> addDrugForm(List<MappingConfigWrapper> list, Integer type) {
+        List<MappingConfigWrapper> retList = Lists.newLinkedList();
+        if (ListUtil.isEmpty(list) || null == type) {
+            return list;
+        }
+        if (!type.equals(ConceptTypeEnum.Drug.getKey())) {
+            return list;
+        }
+        List<String> hisDrugNames = list.stream()
+                .filter(i -> i.getIsMatch() != null
+                        && i.getIsMatch().equals(1)
+                        && i.getSource() != null
+                        && (i.getSource().equals(MatchSourceEnum.StandWord.getKey())))
+                .map(MappingConfigWrapper::getHisName)
+                .distinct()
+                .collect(Collectors.toList());
+        hisDrugNames.addAll(list.stream()
+                .filter(i -> i.getIsMatch() != null
+                        && i.getIsMatch().equals(1)
+                        && i.getSource() != null
+                        && i.getSource().equals(MatchSourceEnum.SynonymsWord.getKey()))
+                .map(MappingConfigWrapper::getUniqueName)
+                .distinct()
+                .collect(Collectors.toList()));
+        if (ListUtil.isNotEmpty(hisDrugNames)) {
+            Map<String, Map<String, Map<String, List<String>>>> configMap = groupByHisNameWithName(hisDrugNames, type, null);
+            for (MappingConfigWrapper item : list) {
+                if (item.getIsMatch() != null && item.getIsMatch().equals(1)
+                        && item.getSource() != null
+                        && (item.getSource().equals(MatchSourceEnum.StandWord.getKey())
+                        || item.getSource().equals(MatchSourceEnum.SynonymsWord.getKey()))) {
+                    if (item.getFormConceptId() != null && StringUtils.isNotBlank(item.getForm())) {
+                        retList.add(item);
+                        continue;
+                    }
+                    if ((item.getSource().equals(MatchSourceEnum.StandWord.getKey())
+                            && configMap.containsKey(item.getHisName()))
+                            || (item.getSource().equals(MatchSourceEnum.SynonymsWord.getKey())
+                            && configMap.containsKey(item.getUniqueName()))) {
+                        Map<String, Map<String, List<String>>> subMap
+                                = configMap.get(item.getSource().equals(MatchSourceEnum.StandWord.getKey())
+                                ? item.getHisName()
+                                : item.getUniqueName());
+                        if (subMap != null && subMap.size() > 0) {
+                            Map<String, List<String>> thirdMap = subMap.get(item.getHisDetailName());
+                            if (thirdMap == null || thirdMap.size() == 0) {
+                                retList.add(item);
+                                continue;
+                            }
+                            List<String> forms = thirdMap.get(item.getUniqueName());
+                            if (ListUtil.isEmpty(forms)) {
+                                retList.add(item);
+                            } else {
+                                for (String form : forms) {
+                                    MappingConfigWrapper formItem = new MappingConfigWrapper();
+                                    BeanUtil.copyProperties(item, formItem);
+                                    formItem.setForm(form);
+                                    retList.add(formItem);
                                 }
                             }
-                        } else {
-                            drugList.add(item);
                         }
                     } else {
-                        drugList.add(item);
+                        retList.add(item);
                     }
+                } else {
+                    retList.add(item);
                 }
-            } else {
-                drugList = BeanUtil.listCopyTo(historyList, MappingConfigWrapper.class);
             }
         } else {
-            drugList = BeanUtil.listCopyTo(historyList, MappingConfigWrapper.class);
-        }
-
-
-        retList = BeanUtil.listCopyTo(drugList, MappingConfigWrapper.class);
-        for (MappingConfigWrapper item : retList) {
-            if (item.getIsMatch() == null) {
-                item.setIsMatch(0);
-            }
+            retList = BeanUtil.listCopyTo(list, MappingConfigWrapper.class);
         }
-
-        //添加编码
-        retList = addCodes(retList, type);
-        retList = retList.stream().distinct().collect(Collectors.toList());
         return retList;
     }
 
@@ -823,6 +991,183 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
         return data;
     }
 
+    /**
+     * 数据导入
+     *
+     * @param file
+     * @param hospitalId
+     * @param type
+     */
+    public Boolean importExcelDataVerify(MultipartFile file, Long hospitalId, Integer type, String userId) {
+        if (hospitalId == null) {
+            hospitalId = Long.valueOf(SysUserUtils.getCurrentHospitalID());
+        }
+        if (StringUtil.isBlank(userId)) {
+            userId = SysUserUtils.getCurrentPrincipleID();
+        }
+        if (StringUtil.isBlank(userId)) {
+            userId = "0";
+        }
+        List<MappingConfigWrapper> originList = readImportData(file, type, 2);
+        if (ListUtil.isEmpty(originList)) {
+            throw new CommonException(CommonErrorCode.PARAM_IS_NULL, "校验失败,导入数据不能为空");
+        }
+        Boolean data = importDataVerify(originList, hospitalId, type, userId);
+        return data;
+    }
+
+    /**
+     * 导入数据校验
+     * @param originList
+     * @param hospitalId
+     * @param type
+     * @param userId
+     * @return
+     */
+    public Boolean importDataVerify(List<MappingConfigWrapper> originList, Long hospitalId, Integer type, String userId) {
+        //过滤空数据,保留重复数据,方便计行
+        //去除空格、回车、换行符、制表符
+        originList = originList.stream()
+                .filter(MappingConfigWrapper::nonNull)
+                .collect(Collectors.toList());
+        if (ListUtil.isEmpty(originList)) {
+            throw new CommonException(CommonErrorCode.PARAM_IS_NULL, "校验失败,导入数据不能为空");
+        }
+        List<Integer> emptyNumList = Lists.newLinkedList();
+        Integer rowId = 1;
+        for (MappingConfigWrapper item : originList) {
+            if (StringUtil.isBlank(item.getHisName())) {
+                if (type.equals(ConceptTypeEnum.Drug.getKey())) {
+                    emptyNumList.add(rowId + 2);
+                } else {
+                    emptyNumList.add(rowId + 1);
+                }
+            } else {
+                item.setHisName(pattern.matcher(item.getHisName()).replaceAll(""));
+            }
+            if (StringUtil.isNotBlank(item.getHisCode())) {
+                item.setHisCode(pattern.matcher(item.getHisCode()).replaceAll(""));
+            } else {
+                item.setHisCode("");
+            }
+            if (StringUtil.isNotBlank(item.getHisDetailName())) {
+                item.setHisDetailName(pattern.matcher(item.getHisDetailName()).replaceAll(""));
+            } else {
+                item.setHisDetailName("");
+            }
+            if (StringUtil.isNotBlank(item.getUniqueName())) {
+                item.setUniqueName(pattern.matcher(item.getUniqueName()).replaceAll(""));
+                item.setIsMatch(1);
+            } else {
+                item.setUniqueName("");
+                item.setIsMatch(0);
+            }
+            if (StringUtil.isNotBlank(item.getForm())) {
+                item.setForm(pattern.matcher(item.getForm()).replaceAll(""));
+            } else {
+                item.setForm("");
+            }
+            if (StringUtil.isNotBlank(item.getCode())) {
+                item.setCode(pattern.matcher(item.getCode()).replaceAll(""));
+            } else {
+                item.setCode("");
+            }
+            rowId++;
+        }
+
+        //医院术语名称不允许为空
+        if (ListUtil.isNotEmpty(emptyNumList)) {
+            throw new CommonException(CommonErrorCode.PARAM_IS_NULL, "以下行数(不计入空行)存在不完整数据:"
+                    + emptyNumList.stream().map(Object::toString)
+                    .collect(Collectors.joining("、"))
+                    + "。导入取消,请修改后再试。\n");
+        }
+
+        //标准术语校验
+        List<Integer> errorNumList = Lists.newLinkedList();
+        rowId = 1;
+        ConceptVO conceptVO = new ConceptVO();
+        conceptVO.setSource(MatchSourceEnum.StandWord.getKey());
+        if (type.equals(ConceptTypeEnum.LisPack.getKey())) {
+            conceptVO.setType(ConceptTypeEnum.LisPack.getKey());
+            conceptVO.setNames(originList.stream()
+                    .filter(i -> StringUtil.isBlank(i.getHisDetailName())
+                            && StringUtil.isNotBlank(i.getUniqueName()))
+                    .map(MappingConfigWrapper::getUniqueName)
+                    .distinct()
+                    .collect(Collectors.toList()));
+            RespDTO<List<IndexBatchDTO>> respDTO = cdssCoreClient.getConceptNames(conceptVO);
+            RespDTOUtil.respNGDealCover(respDTO, "标准术语校验失败");
+            Map<String, List<Long>> packMap = respDTO.data.stream()
+                    .collect(Collectors.groupingBy(IndexBatchDTO::getName,
+                            Collectors.mapping(IndexBatchDTO::getId, Collectors.toList())));
+            conceptVO.setType(ConceptTypeEnum.Lis.getKey());
+            conceptVO.setNames(originList.stream()
+                    .filter(i -> StringUtil.isNotBlank(i.getHisDetailName())
+                            && StringUtil.isNotBlank(i.getUniqueName()))
+                    .map(MappingConfigWrapper::getUniqueName)
+                    .distinct()
+                    .collect(Collectors.toList()));
+            respDTO = cdssCoreClient.getConceptNames(conceptVO);
+            RespDTOUtil.respNGDealCover(respDTO, "标准术语校验失败");
+            Map<String, List<Long>> lisMap = respDTO.data.stream()
+                    .collect(Collectors.groupingBy(IndexBatchDTO::getName,
+                            Collectors.mapping(IndexBatchDTO::getId, Collectors.toList())));
+
+            for (MappingConfigWrapper item : originList) {
+                if (StringUtil.isBlank(item.getUniqueName())) {
+                    continue;
+                }
+                if (StringUtil.isBlank(item.getHisDetailName())) {
+                    if (packMap.containsKey(item.getUniqueName())) {
+                    } else {
+                        errorNumList.add(rowId + 1);
+                    }
+                } else {
+                    if (lisMap.containsKey(item.getUniqueName())) {
+                    } else {
+                        errorNumList.add(rowId + 1);
+                    }
+                }
+                rowId++;
+            }
+        } else {
+            conceptVO.setType(type);
+            conceptVO.setNames(originList.stream()
+                    .filter(i -> StringUtil.isNotBlank(i.getUniqueName()))
+                    .map(MappingConfigWrapper::getUniqueName)
+                    .distinct()
+                    .collect(Collectors.toList()));
+            RespDTO<List<IndexBatchDTO>> respDTO = cdssCoreClient.getConceptNames(conceptVO);
+            if (RespDTOUtil.respIsOK(respDTO)) {
+                Map<String, List<Long>> map = respDTO.data.stream()
+                        .collect(Collectors.groupingBy(IndexBatchDTO::getName,
+                                Collectors.mapping(IndexBatchDTO::getId, Collectors.toList())));
+                for (MappingConfigWrapper item : originList) {
+                    if (StringUtil.isBlank(item.getUniqueName())) {
+                        continue;
+                    }
+                    if (map.containsKey(item.getUniqueName())) {
+                    } else {
+                        if (type.equals(ConceptTypeEnum.Drug.getKey())) {
+                            errorNumList.add(rowId + 2);
+                        } else {
+                            errorNumList.add(rowId + 1);
+                        }
+                    }
+                    rowId++;
+                }
+            }
+        }
+        if (ListUtil.isNotEmpty(errorNumList)) {
+            throw new CommonException(CommonErrorCode.NOT_EXISTS, "以下行数(不计入空行)标准术语校验失败:"
+                    + errorNumList.stream().map(Object::toString)
+                    .collect(Collectors.joining("、"))
+                    + "。继续导入则错误术语将会丢失,请确认是否继续导入。\n");
+        }
+        return true;
+    }
+
     /**
      * 导入数据处理
      *

+ 18 - 0
src/main/java/com/diagbot/vo/IndexByApprovalVO.java

@@ -0,0 +1,18 @@
+package com.diagbot.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author:zhaops
+ * @time: 2021/8/24 15:49
+ */
+@Data
+public class IndexByApprovalVO {
+    /**
+     * 国药准字列表
+     */
+    private List<String> approvalList;
+}

+ 18 - 3
src/main/java/com/diagbot/web/MappingConfigController.java

@@ -83,6 +83,21 @@ public class MappingConfigController {
         return RespDTO.onSuc(data);
     }
 
+    @ApiOperation(value = "数据导入校验[by:zhaops]",
+            notes = "file(必填):导入文件 <br>" +
+                    "hospitalId(必填):医院id <br>" +
+                    "uesrId(必填):操作人id <br>" +
+                    "type(必填): 类型:1-化验、3-辅检、4-诊断、5-药品、6-手术和操作、7-科室、8-输血、10-量表、11-护理、12-中医诊断、13-中医证候、14-麻醉 <br>")
+    @PostMapping(value = "/importExcelDataVerify", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    @SysLogger("importExcelDataVerify")
+    public RespDTO<Boolean> importExcelDataVerify(@RequestParam("file") MultipartFile file,
+                                                  @RequestParam("hospitalId") Long hospitalId,
+                                                  @RequestParam("type") Integer type,
+                                                  @RequestParam("uesrId") String userId) {
+        Boolean data = mappingConfigFacade.importExcelDataVerify(file, hospitalId, type, userId);
+        return RespDTO.onSuc(data);
+    }
+
     @ApiOperation(value = "数据导入[by:zhaops]",
             notes = "file(必填):导入文件 <br>" +
                     "hospitalId(必填):医院id <br>" +
@@ -92,9 +107,9 @@ public class MappingConfigController {
     @SysLogger("importExcel")
     @Transactional
     public RespDTO<Boolean> importExcel(@RequestParam("file") MultipartFile file,
-                            @RequestParam("hospitalId") Long hospitalId,
-                            @RequestParam("type") Integer type,
-                            @RequestParam("uesrId") String userId) {
+                                        @RequestParam("hospitalId") Long hospitalId,
+                                        @RequestParam("type") Integer type,
+                                        @RequestParam("uesrId") String userId) {
         Boolean data = mappingConfigFacade.importExcel(file, hospitalId, type, userId);
         return RespDTO.onSuc(data);
     }