浏览代码

Merge branch 'dev/pacsRule20210915' into debug

zhoutg 3 年之前
父节点
当前提交
fda13d1787
共有 26 个文件被更改,包括 665 次插入152 次删除
  1. 31 29
      doc/002.20210629术语关联改版/cdss_init.sql
  2. 4 3
      src/main/java/com/diagbot/aggregate/AssembleAggregate.java
  3. 9 1
      src/main/java/com/diagbot/client/CdssCoreClient.java
  4. 13 1
      src/main/java/com/diagbot/client/hystrix/CdssCoreHystrix.java
  5. 4 1
      src/main/java/com/diagbot/config/ResourceServerConfigurer.java
  6. 4 1
      src/main/java/com/diagbot/config/security/UrlAccessDecisionManager.java
  7. 5 1
      src/main/java/com/diagbot/dto/GetAllForRelationDTO.java
  8. 1 0
      src/main/java/com/diagbot/dto/KlRuleByIdSubDTO.java
  9. 4 2
      src/main/java/com/diagbot/entity/MappingConfig.java
  10. 1 1
      src/main/java/com/diagbot/entity/OperationConfig.java
  11. 2 2
      src/main/java/com/diagbot/entity/TransfusionConfig.java
  12. 8 8
      src/main/java/com/diagbot/entity/wrapper/MappingConfigWrapper.java
  13. 14 2
      src/main/java/com/diagbot/facade/ConceptInfoFacade.java
  14. 286 82
      src/main/java/com/diagbot/facade/MappingConfigFacade.java
  15. 1 1
      src/main/java/com/diagbot/facade/PushFacade.java
  16. 4 4
      src/main/java/com/diagbot/util/CoreUtil.java
  17. 144 0
      src/main/java/com/diagbot/util/ReflectUtil.java
  18. 1 0
      src/main/java/com/diagbot/vo/KlRuleInfoSaveSubVO.java
  19. 19 0
      src/main/java/com/diagbot/vo/PrecDataVO.java
  20. 35 0
      src/main/java/com/diagbot/vo/PrecRecordVO.java
  21. 10 0
      src/main/java/com/diagbot/vo/PushJoinVO.java
  22. 6 1
      src/main/java/com/diagbot/vo/SearchConceptVO.java
  23. 10 0
      src/main/java/com/diagbot/vo/SearchData.java
  24. 8 8
      src/main/java/com/diagbot/web/ConceptInfoController.java
  25. 24 1
      src/main/java/com/diagbot/web/KlDiseaseController.java
  26. 17 3
      src/main/java/com/diagbot/web/MappingConfigController.java

+ 31 - 29
doc/002.20210629术语关联改版/cdss_init.sql

@@ -33,32 +33,34 @@ SET FOREIGN_KEY_CHECKS = 0;
 -- ----------------------------
 -- Table structure for tran_mapping_config
 -- ----------------------------
-DROP TABLE IF EXISTS `tran_mapping_config`;
-CREATE TABLE `tran_mapping_config`  (
-  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
-  `is_deleted` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N' COMMENT '是否删除,N:未删除,Y:删除',
-  `gmt_create` datetime(0) NOT NULL DEFAULT '1970-01-01 12:00:00' COMMENT '记录创建时间',
-  `gmt_modified` datetime(0) NOT NULL DEFAULT '1970-01-01 12:00:00' COMMENT '记录修改时间,如果时间是1970年则表示纪录未修改',
-  `creator` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '创建人,0表示无创建人值',
-  `modifier` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '修改人,如果为0则表示纪录未修改',
-  `hospital_id` bigint(20) NOT NULL COMMENT '医院id',
-  `type` int(4) NOT NULL COMMENT '医学术语类型( 1-检验套餐、2-检验细项、3-辅检、4-诊断、5-药品、6-手术和操作、7-科室、8-输血、10-量表、11-护理、12-中医疾病、13-中医证候、14-麻醉)',
-  `his_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '医院术语名称',
-  `his_code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '医院术语编码',
-  `his_detail_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '医院术语细项名称(检验细项)',
-  `concept_id` bigint(20) NULL DEFAULT NULL COMMENT '医学标准术语id',
-  `form_concept_id` bigint(20) NULL DEFAULT NULL COMMENT '药品剂型id',
-  `is_match` int(4) NOT NULL DEFAULT 0 COMMENT '是否匹配(0-未匹配、1-已匹配)',
-  `source` int(4) NULL DEFAULT NULL COMMENT '数据来源(1-标准词、2-同义词、3-编码、4-历史数据、5-相似词、99-数据迁移)',
-  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注',
-  PRIMARY KEY (`id`) USING BTREE,
-  INDEX `idx_his_detail_name`(`hospital_id`, `type`, `his_name`, `his_detail_name`) USING BTREE,
-  INDEX `idx_his_name`(`hospital_id`, `type`, `his_name`) USING BTREE,
-  INDEX `idx_concept_id`(`hospital_id`, `concept_id`) USING BTREE,
-  INDEX `idx_hospital_id`(`hospital_id`) USING BTREE,
-  INDEX `idx_detail_name`(`his_name`, `his_detail_name`) USING BTREE,
-  INDEX `idx_deleted_type`(`type`) USING BTREE,
-  INDEX `idx_type`(`hospital_id`, `type`, `is_deleted`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 797881 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '医学术语映射表' ROW_FORMAT = Dynamic;
-
-SET FOREIGN_KEY_CHECKS = 1;
+-- 已执行脚本
+-- DROP TABLE IF EXISTS `tran_mapping_config`;
+-- CREATE TABLE `tran_mapping_config`  (
+--   `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
+--   `is_deleted` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N' COMMENT '是否删除,N:未删除,Y:删除',
+--   `gmt_create` datetime(0) NOT NULL DEFAULT '1970-01-01 12:00:00' COMMENT '记录创建时间',
+--   `gmt_modified` datetime(0) NOT NULL DEFAULT '1970-01-01 12:00:00' COMMENT '记录修改时间,如果时间是1970年则表示纪录未修改',
+--   `creator` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '创建人,0表示无创建人值',
+--   `modifier` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '0' COMMENT '修改人,如果为0则表示纪录未修改',
+--   `hospital_id` bigint(20) NOT NULL COMMENT '医院id',
+--   `type` int(4) NOT NULL COMMENT '医学术语类型( 1-检验套餐、2-检验细项、3-辅检、4-诊断、5-药品、6-手术和操作、7-科室、8-输血、10-量表、11-护理、12-中医疾病、13-中医证候、14-麻醉)',
+--   `his_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '医院术语名称',
+--   `his_code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '医院术语编码',
+--   `his_detail_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '医院术语细项名称(检验细项)',
+--   `concept_id` bigint(20) NULL DEFAULT NULL COMMENT '医学标准术语id',
+--   `form_concept_id` bigint(20) NULL DEFAULT NULL COMMENT '药品剂型id',
+--   `is_match` int(4) NOT NULL DEFAULT 0 COMMENT '是否匹配(0-未匹配、1-已匹配)',
+--   `source` int(4) NULL DEFAULT NULL COMMENT '数据来源(1-标准词、2-同义词、3-编码、4-历史数据、5-相似词、99-数据迁移)',
+--   `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注',
+--   PRIMARY KEY (`id`) USING BTREE,
+--   INDEX `idx_his_detail_name`(`hospital_id`, `type`, `his_name`, `his_detail_name`) USING BTREE,
+--   INDEX `idx_his_name`(`hospital_id`, `type`, `his_name`) USING BTREE,
+--   INDEX `idx_concept_id`(`hospital_id`, `concept_id`) USING BTREE,
+--   INDEX `idx_hospital_id`(`hospital_id`) USING BTREE,
+--   INDEX `idx_detail_name`(`his_name`, `his_detail_name`) USING BTREE,
+--   INDEX `idx_deleted_type`(`type`) USING BTREE,
+--   INDEX `idx_type`(`hospital_id`, `type`, `is_deleted`) USING BTREE
+-- ) ENGINE = InnoDB AUTO_INCREMENT = 797881 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '医学术语映射表' ROW_FORMAT = Dynamic;
+--
+-- SET FOREIGN_KEY_CHECKS = 1;
+--

+ 4 - 3
src/main/java/com/diagbot/aggregate/AssembleAggregate.java

@@ -7,6 +7,7 @@ import com.diagbot.enums.ConceptTypeEnum;
 import com.diagbot.facade.MappingConfigFacade;
 import com.diagbot.util.BeanUtil;
 import com.diagbot.util.ListUtil;
+import com.diagbot.util.ReflectUtil;
 import com.diagbot.util.StringUtil;
 import com.diagbot.vo.Drug;
 import com.diagbot.vo.ItemExt;
@@ -388,13 +389,13 @@ public class AssembleAggregate {
 
         try {
             for (T item : list) {
-                String name = item.getClass().getMethod("getName").invoke(item).toString();
+                String name = ReflectUtil.getProperty(item, "name");
                 if (StringUtil.isBlank(name)) {
                     retList.add(item);
                     continue;
                 }
 
-                String uniqueName = item.getClass().getMethod("getUniqueName").invoke(item).toString();
+                String uniqueName = ReflectUtil.getProperty(item, "uniqueName");
                 if (StringUtil.isNotBlank(uniqueName)) {
                     retList.add(item);
                     continue;
@@ -402,7 +403,7 @@ public class AssembleAggregate {
 
                 String hisDetailName = "";
                 if(type.equals(ConceptTypeEnum.LisPack.getKey())) {
-                    hisDetailName = item.getClass().getMethod("getDetailName").invoke(item).toString();
+                    hisDetailName = ReflectUtil.getProperty(item, "detailName");
                     if (StringUtil.isBlank(hisDetailName)) {
                         hisDetailName = "";
                     }

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

@@ -245,9 +245,17 @@ public interface CdssCoreClient {
     @PostMapping("/klDisease/searchConcept")
     RespDTO<List<GetAllForRelationDTO>> searchConcept(@Valid @RequestBody SearchConceptVO searchConceptVO);
 
+    //术语集合新增
+    @PostMapping("/klDisease/addConceptClass")
+    RespDTO<List<GetAllForRelationDTO>> addConceptClass(@Valid @RequestBody SearchConceptVO searchConceptVO);
+
+    //规则维护术语查询
+    @PostMapping("/klDisease/searchConceptRuleClass")
+    RespDTO<List<GetAllForRelationDTO>> searchConceptRuleClass(@Valid @RequestBody SearchConceptVO searchConceptVO);
+
     @PostMapping("/cache/clearRuleInfoAll")
     RespDTO<Boolean> clearRuleAll();
 
     @PostMapping("/term/termMatching")
     public RespDTO<List<TermConceptDTO>> getTermMatching(@Valid @RequestBody TermMatchingVO termMatchingVO);
-}
+}

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

@@ -318,6 +318,18 @@ public class CdssCoreHystrix implements CdssCoreClient {
         return null;
     }
 
+    @Override
+    public RespDTO<List<GetAllForRelationDTO>> addConceptClass(@Valid SearchConceptVO searchConceptVO) {
+        log.error("【hystrix】调用{}异常", "addConceptClass");
+        return null;
+    }
+
+    @Override
+    public RespDTO<List<GetAllForRelationDTO>> searchConceptRuleClass(@Valid SearchConceptVO searchConceptVO) {
+        log.error("【hystrix】调用{}异常", "searchConceptRuleClass");
+        return null;
+    }
+
     @Override
     public RespDTO<Boolean> clearRuleAll() {
         log.error("【hystrix】调用{}异常", "clearRuleAll");
@@ -329,4 +341,4 @@ public class CdssCoreHystrix implements CdssCoreClient {
         log.error("【hystrix】调用{}异常", "getTermMatching");
         return null;
     }
-}
+}

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

@@ -46,6 +46,7 @@ public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
                 .antMatchers("/tran/mappingConfig/exportExcelModule").permitAll()
                 .antMatchers("/tran/mappingConfig/dataVerify").permitAll()
                 .antMatchers("/tran/mappingConfig/precDataMatch").permitAll()
+                .antMatchers("/tran/mappingConfig/precData").permitAll()
                 .antMatchers("/tran/mappingConfig/precDataMatch_remote").permitAll()
                 .antMatchers("/tran/mappingConfig/importExcel").permitAll()
                 .antMatchers("/tran/mappingConfig/exportExcel").permitAll()
@@ -125,6 +126,8 @@ public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
                 .antMatchers("/klRule/disableRuleInfo").permitAll()
                 .antMatchers("/klRule/startRuleInfo").permitAll()
                 .antMatchers("/klDisease/searchConcept").permitAll()
+                .antMatchers("/klDisease/addConceptClass").permitAll()
+                .antMatchers("/klDisease/searchConceptRuleClass").permitAll()
                 .antMatchers("/cache/clearRuleAll").permitAll()
                 .antMatchers("/term/termMatching").permitAll()
                 .antMatchers("/**").authenticated();
@@ -158,4 +161,4 @@ public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
         log.info("Created jwtTokenEnhancerClient success");
         return converter;
     }
-}
+}

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

@@ -89,6 +89,7 @@ public class UrlAccessDecisionManager implements AccessDecisionManager {
                 || matchers("/tran/mappingConfig/exportExcelModule", request)
                 || matchers("/tran/mappingConfig/dataVerify", request)
                 || matchers("/tran/mappingConfig/precDataMatch", request)
+                || matchers("/tran/mappingConfig/precData", request)
                 || matchers("/tran/mappingConfig/precDataMatch_remote", request)
                 || matchers("/tran/mappingConfig/importExcel", request)
                 || matchers("/tran/mappingConfig/exportExcel", request)
@@ -167,6 +168,8 @@ public class UrlAccessDecisionManager implements AccessDecisionManager {
                 || matchers("/klRule/disableRuleInfo", request)
                 || matchers("/klRule/startRuleInfo", request)
                 || matchers("/klDisease/searchConcept", request)
+                || matchers("/klDisease/addConceptClass", request)
+                || matchers("/klDisease/searchConceptRuleClass", request)
                 || matchers("/cache/clearRuleAll", request)
                 || matchers("/term/termMatching", request)
                 || matchers("/", request)) {
@@ -182,4 +185,4 @@ public class UrlAccessDecisionManager implements AccessDecisionManager {
         }
         return false;
     }
-}
+}

+ 5 - 1
src/main/java/com/diagbot/dto/GetAllForRelationDTO.java

@@ -36,7 +36,11 @@ public class GetAllForRelationDTO {
     @ApiModelProperty(value="概念名称(类型)")
     private String conceptNameType;
 
-
+    /**
+     * 说明
+     */
+    @ApiModelProperty(value="说明(remark)")
+    private String remark;
 
 }
 

+ 1 - 0
src/main/java/com/diagbot/dto/KlRuleByIdSubDTO.java

@@ -28,4 +28,5 @@ public class KlRuleByIdSubDTO {
     private String subEqOperator;//等于域比较符
     private String subEqValue;//等于域值
     private String subEqUnit;//等于域单位
+    private String subMsg;
 }

+ 4 - 2
src/main/java/com/diagbot/entity/MappingConfig.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.diagbot.util.StringUtil;
+import lombok.Data;
 
 import java.io.Serializable;
 import java.util.Date;
@@ -19,6 +20,7 @@ import java.util.Objects;
  * @author zhaops
  * @since 2021-06-09
  */
+@Data
 @TableName("tran_mapping_config")
 public class MappingConfig implements Serializable {
 
@@ -258,7 +260,7 @@ public class MappingConfig implements Serializable {
                 "}";
     }
 
-    @Override
+    /*@Override
     public boolean equals(Object o) {
         if (this == o) {
             return true;
@@ -284,7 +286,7 @@ public class MappingConfig implements Serializable {
     @Override
     public int hashCode() {
         return Objects.hash(id, isDeleted, hospitalId, type, hisName, hisCode, hisDetailName, conceptId, formConceptId, isMatch);
-    }
+    }*/
 
     public static boolean nonNull(MappingConfig o) {
         return !(o == null

+ 1 - 1
src/main/java/com/diagbot/entity/OperationConfig.java

@@ -76,7 +76,7 @@ public class OperationConfig{
     /**
      * 对应项编码
      */
-    //@Excel(name = "对应项编码", width = 40, orderNum = "2")
+    @Excel(name = "手术和操作代码", width = 40, orderNum = "2", isImportField = "true")
     private String code;
 
     /**

+ 2 - 2
src/main/java/com/diagbot/entity/TransfusionConfig.java

@@ -78,13 +78,13 @@ public class TransfusionConfig {
     /**
      * 是否匹配(0-未匹配、1-已匹配)
      */
-    @Excel(name = "是否匹配", width = 20, orderNum = "4", replace = { "未匹配_0", "已匹配_1" }, isImportField = "true")
+    @Excel(name = "是否匹配【未匹配、已匹配】", width = 20, orderNum = "4", 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 = "5", replace = { "标准词_1", "同义词_2", "编码_3", "历史数据_4", "相似词_5", "数据迁移_99", "_null" }, isImportField = "true")
     private Integer source;
 
     @Override

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

@@ -2,24 +2,24 @@ package com.diagbot.entity.wrapper;
 
 import com.diagbot.entity.MappingConfig;
 import com.diagbot.util.StringUtil;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.util.Objects;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
 
 /**
  * @Description:
  * @Author:zhaops
  * @time: 2021/6/10 19:27
  */
-@Getter
-@Setter
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
 public class MappingConfigWrapper extends MappingConfig {
     private String uniqueName;
     private String form;
     private String code;
 
-    @Override
+   /* @Override
     public boolean equals(Object o) {
         if (this == o) {
             return true;
@@ -37,7 +37,7 @@ public class MappingConfigWrapper extends MappingConfig {
     @Override
     public int hashCode() {
         return Objects.hash(uniqueName, form, code) + super.hashCode();
-    }
+    }*/
 
     public static boolean nonNull(MappingConfigWrapper o) {
         return !(o == null

+ 14 - 2
src/main/java/com/diagbot/facade/ConceptInfoFacade.java

@@ -688,7 +688,7 @@ public class ConceptInfoFacade extends ConceptInfoServiceImpl {
             case 9:
                 Map<String, Map<String, Map<String, List<String>>>> nurseConfigMap
                         = mappingConfigFacade.groupByHisNameWithName(ListUtil.arrayToList(new String[] { staticKnowledgeHISVO.getHisName() }),
-                        ConceptTypeEnum.Scale.getKey(), hospitalId);
+                        ConceptTypeEnum.Nurse.getKey(), hospitalId);
                 if (nurseConfigMap != null &&
                         nurseConfigMap.get(staticKnowledgeHISVO.getHisName()) != null) {
                     nameList = nurseConfigMap.get(staticKnowledgeHISVO.getHisName())
@@ -1029,4 +1029,16 @@ public class ConceptInfoFacade extends ConceptInfoServiceImpl {
         RespDTOUtil.respNGDeal(relationDTORespDTO, "查询诊断依据相关的类型术语失败");
         return relationDTORespDTO.data;
     }
-}
+
+    public List<GetAllForRelationDTO> addConceptClass(SearchConceptVO searchConceptVO) {
+        RespDTO<List<GetAllForRelationDTO>> relationDTORespDTO = cdssCoreClient.addConceptClass(searchConceptVO);
+        RespDTOUtil.respNGDeal(relationDTORespDTO, "术语集合新增失败");
+        return relationDTORespDTO.data;
+    }
+
+    public List<GetAllForRelationDTO> searchConceptRuleClass(SearchConceptVO searchConceptVO) {
+        RespDTO<List<GetAllForRelationDTO>> relationDTORespDTO = cdssCoreClient.searchConceptRuleClass(searchConceptVO);
+        RespDTOUtil.respNGDeal(relationDTORespDTO, "查询规则维护术语查询术语失败");
+        return relationDTORespDTO.data;
+    }
+}

+ 286 - 82
src/main/java/com/diagbot/facade/MappingConfigFacade.java

@@ -1,5 +1,6 @@
 package com.diagbot.facade;
 
+import cn.afterturn.easypoi.exception.excel.ExcelImportException;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -44,6 +45,7 @@ import com.diagbot.vo.IdVO;
 import com.diagbot.vo.KllisDetailVO;
 import com.diagbot.vo.MappingConfigPageVO;
 import com.diagbot.vo.MappingConfigVO;
+import com.diagbot.vo.PrecDataVO;
 import com.diagbot.vo.RetrievalVO;
 import com.google.common.collect.Lists;
 import org.springframework.beans.BeanUtils;
@@ -97,31 +99,43 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
         RespDTO<List<IndexBatchDTO>> respDTO = null;
 
         //todo 标准词转conceptId
+        List<Long> conceptIds = Lists.newLinkedList();
         if (StringUtil.isNotBlank(mappingConfigPageVO.getUniqueName())) {
             filterVO.setInputStr(mappingConfigPageVO.getUniqueName());
             respDTO = cdssCoreClient.filter(filterVO);
-            if (RespDTOUtil.respIsOK(respDTO) && ListUtil.isNotEmpty(respDTO.data)) {
-                mappingConfigPageVO.setConceptIds(respDTO.data
-                        .stream()
-                        .map(IndexBatchDTO::getId)
-                        .distinct()
-                        .collect(Collectors.toList()));
+            if (RespDTOUtil.respIsOK(respDTO)) {
+                if (ListUtil.isNotEmpty(respDTO.data)) {
+                    conceptIds.addAll(respDTO.data
+                            .stream()
+                            .map(IndexBatchDTO::getId)
+                            .distinct()
+                            .collect(Collectors.toList()));
+                } else {
+                    conceptIds.add(-1L);
+                }
             }
         }
+        mappingConfigPageVO.setConceptIds(conceptIds);
 
         //todo 药品剂型转 conceptId
+        List<Long> formConceptIds = Lists.newLinkedList();
         if (StringUtil.isNotBlank(mappingConfigPageVO.getForm())) {
             filterVO.setInputStr(mappingConfigPageVO.getForm());
             respDTO = cdssCoreClient.filter(filterVO);
-            if (RespDTOUtil.respIsOK(respDTO) && ListUtil.isNotEmpty(respDTO.data)) {
-                mappingConfigPageVO.setFormConceptIds(respDTO.data
-                        .stream()
-                        .filter(i -> i.getType().equals(ConceptTypeEnum.Form.getKey()))
-                        .map(IndexBatchDTO::getId)
-                        .distinct()
-                        .collect(Collectors.toList()));
+            if (RespDTOUtil.respIsOK(respDTO)) {
+                if (ListUtil.isNotEmpty(respDTO.data)) {
+                    formConceptIds.addAll(respDTO.data
+                            .stream()
+                            .filter(i -> i.getType().equals(ConceptTypeEnum.Form.getKey()))
+                            .map(IndexBatchDTO::getId)
+                            .distinct()
+                            .collect(Collectors.toList()));
+                } else {
+                    formConceptIds.add(-1L);
+                }
             }
         }
+        mappingConfigPageVO.setFormConceptIds(formConceptIds);
 
         //todo 多条匹配
         if (mappingConfigPageVO.getIsMatch() != null && mappingConfigPageVO.getIsMatch().equals(2)) {
@@ -290,61 +304,70 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
      *
      * @param file
      * @param type
+     * @param source 1-预匹配,2-导入
      * @return
      */
-    public List<MappingConfigWrapper> readImportData(MultipartFile file, Integer type) {
+    public List<MappingConfigWrapper> readImportData(MultipartFile file, Integer type, Integer source) {
         List<MappingConfigWrapper> originList = Lists.newLinkedList();
-        switch (type) {
-            case 1:
-                List<LisConfig> lisConfigList = ExcelUtils.importExcel(file, 0, 1, LisConfig.class);
-                originList = BeanUtil.listCopyTo(lisConfigList, MappingConfigWrapper.class);
-                break;
-            case 3:
-                List<PacsConfig> pacsConfigList = ExcelUtils.importExcel(file, 0, 1, PacsConfig.class);
-                originList = BeanUtil.listCopyTo(pacsConfigList, MappingConfigWrapper.class);
-                break;
-            case 4:
-                List<DiseaseConfig> diseaseConfigList = ExcelUtils.importExcel(file, 0, 1, DiseaseConfig.class);
-                originList = BeanUtil.listCopyTo(diseaseConfigList, MappingConfigWrapper.class);
-                break;
-            case 5:
-                List<DrugConfig> drugConfigList = ExcelUtils.importExcel(file, 1, 1, DrugConfig.class);
-                originList = BeanUtil.listCopyTo(drugConfigList, MappingConfigWrapper.class);
-                break;
-            case 6:
-                List<OperationConfig> operationConfigList = ExcelUtils.importExcel(file, 0, 1, OperationConfig.class);
-                originList = BeanUtil.listCopyTo(operationConfigList, MappingConfigWrapper.class);
-                break;
-            case 7:
-                List<DeptConfig> deptConfigList = ExcelUtils.importExcel(file, 0, 1, DeptConfig.class);
-                originList = BeanUtil.listCopyTo(deptConfigList, MappingConfigWrapper.class);
-                break;
-            case 8:
-                List<TransfusionConfig> transfusionConfigList = ExcelUtils.importExcel(file, 0, 1, TransfusionConfig.class);
-                originList = BeanUtil.listCopyTo(transfusionConfigList, MappingConfigWrapper.class);
-                break;
-            case 10:
-                List<ScaleConfig> scaleConfigList = ExcelUtils.importExcel(file, 0, 1, ScaleConfig.class);
-                originList = BeanUtil.listCopyTo(scaleConfigList, MappingConfigWrapper.class);
-                break;
-            case 11:
-                List<NurseConfig> nurseConfigList = ExcelUtils.importExcel(file, 0, 1, NurseConfig.class);
-                originList = BeanUtil.listCopyTo(nurseConfigList, MappingConfigWrapper.class);
-                break;
-            case 12:
-                List<TcmdiseaseConfig> tcmdiseaseConfigList = ExcelUtils.importExcel(file, 0, 1, TcmdiseaseConfig.class);
-                originList = BeanUtil.listCopyTo(tcmdiseaseConfigList, MappingConfigWrapper.class);
-                break;
-            case 13:
-                List<TcmsyndromeConfig> tcmsyndromeConfigList = ExcelUtils.importExcel(file, 0, 1, TcmsyndromeConfig.class);
-                originList = BeanUtil.listCopyTo(tcmsyndromeConfigList, MappingConfigWrapper.class);
-                break;
-            case 14:
-                List<AnesthesiaConfig> anesthesiaConfigList = ExcelUtils.importExcel(file, 0, 1, AnesthesiaConfig.class);
-                originList = BeanUtil.listCopyTo(anesthesiaConfigList, MappingConfigWrapper.class);
-                break;
-            default:
-                break;
+        try {
+            switch (type) {
+                case 1:
+                    List<LisConfig> lisConfigList = ExcelUtils.importExcel(file, 0, 1, LisConfig.class);
+                    originList = BeanUtil.listCopyTo(lisConfigList, MappingConfigWrapper.class);
+                    break;
+                case 3:
+                    List<PacsConfig> pacsConfigList = ExcelUtils.importExcel(file, 0, 1, PacsConfig.class);
+                    originList = BeanUtil.listCopyTo(pacsConfigList, MappingConfigWrapper.class);
+                    break;
+                case 4:
+                    List<DiseaseConfig> diseaseConfigList = ExcelUtils.importExcel(file, 0, 1, DiseaseConfig.class);
+                    originList = BeanUtil.listCopyTo(diseaseConfigList, MappingConfigWrapper.class);
+                    break;
+                case 5:
+                    List<DrugConfig> drugConfigList = ExcelUtils.importExcel(file, 1, 1, DrugConfig.class);
+                    originList = BeanUtil.listCopyTo(drugConfigList, MappingConfigWrapper.class);
+                    break;
+                case 6:
+                    List<OperationConfig> operationConfigList = ExcelUtils.importExcel(file, 0, 1, OperationConfig.class);
+                    originList = BeanUtil.listCopyTo(operationConfigList, MappingConfigWrapper.class);
+                    break;
+                case 7:
+                    List<DeptConfig> deptConfigList = ExcelUtils.importExcel(file, 0, 1, DeptConfig.class);
+                    originList = BeanUtil.listCopyTo(deptConfigList, MappingConfigWrapper.class);
+                    break;
+                case 8:
+                    List<TransfusionConfig> transfusionConfigList = ExcelUtils.importExcel(file, 0, 1, TransfusionConfig.class);
+                    originList = BeanUtil.listCopyTo(transfusionConfigList, MappingConfigWrapper.class);
+                    break;
+                case 10:
+                    List<ScaleConfig> scaleConfigList = ExcelUtils.importExcel(file, 0, 1, ScaleConfig.class);
+                    originList = BeanUtil.listCopyTo(scaleConfigList, MappingConfigWrapper.class);
+                    break;
+                case 11:
+                    List<NurseConfig> nurseConfigList = ExcelUtils.importExcel(file, 0, 1, NurseConfig.class);
+                    originList = BeanUtil.listCopyTo(nurseConfigList, MappingConfigWrapper.class);
+                    break;
+                case 12:
+                    List<TcmdiseaseConfig> tcmdiseaseConfigList = ExcelUtils.importExcel(file, 0, 1, TcmdiseaseConfig.class);
+                    originList = BeanUtil.listCopyTo(tcmdiseaseConfigList, MappingConfigWrapper.class);
+                    break;
+                case 13:
+                    List<TcmsyndromeConfig> tcmsyndromeConfigList = ExcelUtils.importExcel(file, 0, 1, TcmsyndromeConfig.class);
+                    originList = BeanUtil.listCopyTo(tcmsyndromeConfigList, MappingConfigWrapper.class);
+                    break;
+                case 14:
+                    List<AnesthesiaConfig> anesthesiaConfigList = ExcelUtils.importExcel(file, 0, 1, AnesthesiaConfig.class);
+                    originList = BeanUtil.listCopyTo(anesthesiaConfigList, MappingConfigWrapper.class);
+                    break;
+                default:
+                    break;
+            }
+        } catch (ExcelImportException e) {
+
+        } catch (CommonException e) {
+            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "校验失败,请使用模板进行数据" + (source == 1 ? "预匹配" : "导入"));
+        } catch (Exception e) {
+
         }
         return originList;
     }
@@ -356,7 +379,7 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
      * @return
      */
     public Boolean dataVerify(MultipartFile file, Integer type) {
-        List<MappingConfigWrapper> originList = readImportData(file, type);
+        List<MappingConfigWrapper> originList = readImportData(file, type, 1);
         List<MappingConfigWrapper> retList = precDataProcess(originList, type);
         return true;
     }
@@ -369,7 +392,7 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
      * @param response
      */
     public void precDataMatch(MultipartFile file, Integer type, HttpServletResponse response) {
-        List<MappingConfigWrapper> originList = readImportData(file, type);
+        List<MappingConfigWrapper> originList = readImportData(file, type, 1);
         List<MappingConfigWrapper> retList = precDataProcess(originList, type);
         exportExcel(response, retList, type, "关联数据(预匹配)");
     }
@@ -382,11 +405,26 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
      * @return
      */
     public List<MappingConfigWrapper> precDataMatch_remote(MultipartFile file, Integer type) {
-        List<MappingConfigWrapper> originList = readImportData(file, type);
+        List<MappingConfigWrapper> originList = readImportData(file, type, 1);
         List<MappingConfigWrapper> retList = precDataProcess(originList, type);
         return retList;
     }
 
+    /**
+     * 预匹配(非文件匹配)
+     *
+     * @param precDataVO
+     * @return
+     */
+    public List<MappingConfigWrapper> precData(PrecDataVO precDataVO) {
+        if (ListUtil.isEmpty(precDataVO.getOriginList())) {
+            throw new CommonException(CommonErrorCode.PARAM_IS_NULL, "请确认术语列表不为空");
+        }
+        List<MappingConfigWrapper> originList = BeanUtil.listCopyTo(precDataVO.getOriginList(), MappingConfigWrapper.class);
+        List<MappingConfigWrapper> data = precDataProcess(originList, precDataVO.getType());
+        return data;
+    }
+
     /**
      * 预匹配数据处理
      *
@@ -399,29 +437,71 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
         List<MappingConfigWrapper> standardList = Lists.newLinkedList();
         List<MappingConfigWrapper> synonymsList = Lists.newLinkedList();
         List<MappingConfigWrapper> codeList = Lists.newLinkedList();
+        List<MappingConfigWrapper> historyList = Lists.newLinkedList();
+        List<MappingConfigWrapper> drugList = Lists.newLinkedList();
+
+        //去除空行
+        /*originList = originList.stream()
+                .filter(MappingConfigWrapper::nonNull)
+                .collect(Collectors.toList());*/
 
         //数据完整性校验
+        List<Integer> emptyNumList = Lists.newLinkedList();
+        Integer rowId = 1;
         for (MappingConfigWrapper item : originList) {
+            ++rowId;
             //过滤医院术语名称为空的条目
-            if (StringUtil.isNotBlank(item.getHisName())) {
-                item.setHisName(item.getHisName().trim());
+            if (type.equals(ConceptTypeEnum.LisPack.getKey())) {
+                if (StringUtil.isBlank(item.getHisName())
+                        && StringUtil.isBlank(item.getHisDetailName())) {
+                    continue;
+                } else if (StringUtil.isBlank(item.getHisName())
+                        && StringUtil.isNotBlank(item.getHisDetailName())) {
+                    emptyNumList.add(rowId);
+                }
+            } else if (type.equals(ConceptTypeEnum.Disease.getKey())
+                    || type.equals(ConceptTypeEnum.Operation.getKey())
+                    || type.equals(ConceptTypeEnum.Tcmdisease.getKey())
+                    || type.equals(ConceptTypeEnum.Tcmsyndrome.getKey())) {
+                if (StringUtil.isBlank(item.getHisName())
+                        && StringUtil.isBlank(item.getCode())) {
+                    continue;
+                } else if (StringUtil.isBlank(item.getHisName())
+                        && StringUtil.isNotBlank(item.getCode())) {
+                    emptyNumList.add(rowId);
+                }
             } else {
-                continue;
+                if (StringUtil.isNotBlank(item.getHisName())) {
+                    item.setHisName(item.getHisName().trim());
+                } else {
+                    continue;
+                }
             }
             if (StringUtil.isNotBlank(item.getHisDetailName())) {
                 item.setHisDetailName(item.getHisDetailName().trim());
             } else {
                 item.setHisDetailName("");
             }
+
             if (StringUtil.isNotBlank(item.getHisCode())) {
                 item.setHisCode(item.getHisCode().trim());
             } else {
                 item.setHisCode("");
             }
             item.setUniqueName("");
+            item.setIsMatch(0);
+            item.setSource(null);
             dataList.add(item);
         }
 
+        //医院术语名称不允许为空
+        if (ListUtil.isNotEmpty(emptyNumList)) {
+            throw new CommonException(CommonErrorCode.PARAM_IS_NULL, "预匹配失败,上传文件内行("
+                    + emptyNumList.stream().map(Object::toString)
+                    .collect(Collectors.joining("、"))
+                    + ")医院术语" + (type.equals(ConceptTypeEnum.LisPack.getKey()) ? "的检验套餐项" : "") + "不可为空。\n");
+        }
+
         if (ListUtil.isEmpty(dataList)) {
             return retList;
         }
@@ -613,7 +693,7 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
 
             for (MappingConfigWrapper item : codeList) {
                 if (item.getIsMatch() != null && item.getIsMatch().equals(1)) {
-                    retList.add(item);
+                    historyList.add(item);
                     continue;
                 }
                 if (configMap.containsKey(item.getHisName())) {
@@ -621,7 +701,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) {
-                            retList.add(item);
+                            historyList.add(item);
                             continue;
                         }
                         for (Map.Entry<String, List<String>> thirdEntry : thirdMap.entrySet()) {
@@ -633,28 +713,95 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
                             if (type.equals(ConceptTypeEnum.Drug.getKey())) {
                                 List<String> forms = thirdEntry.getValue();
                                 if (ListUtil.isEmpty(forms)) {
-                                    retList.add(historyItem);
+                                    historyList.add(historyItem);
                                 } else {
                                     for (String form : forms) {
                                         MappingConfigWrapper formItem = new MappingConfigWrapper();
                                         BeanUtil.copyProperties(historyItem, formItem);
                                         formItem.setForm(form);
-                                        retList.add(formItem);
+                                        historyList.add(formItem);
                                     }
                                 }
                             } else {
-                                retList.add(historyItem);
+                                historyList.add(historyItem);
                             }
                         }
                     }
                 } else {
-                    retList.add(item);
+                    historyList.add(item);
                 }
             }
         } else {
-            retList = BeanUtil.listCopyTo(codeList, MappingConfigWrapper.class);
+            historyList = BeanUtil.listCopyTo(codeList, MappingConfigWrapper.class);
         }
 
+        //药品关联标准词、同义词匹配数据增加历史数据剂型
+        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);
+                                    }
+                                }
+                            }
+                        } else {
+                            drugList.add(item);
+                        }
+                    } else {
+                        drugList.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);
@@ -663,6 +810,7 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
 
         //添加编码
         retList = addCodes(retList, type);
+        retList = retList.stream().distinct().collect(Collectors.toList());
         return retList;
     }
 
@@ -683,7 +831,7 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
         if (StringUtil.isBlank(userId)) {
             userId = "0";
         }
-        List<MappingConfigWrapper> originList = readImportData(file, type);
+        List<MappingConfigWrapper> originList = readImportData(file, type, 2);
         if (ListUtil.isEmpty(originList)) {
             throw new CommonException(CommonErrorCode.PARAM_IS_NULL, "校验失败,导入数据不能为空");
         }
@@ -795,8 +943,6 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
                 it.remove();
             }
         }
-        tempList.addAll(matchList);
-        tempList.addAll(unMatchList);
 
         // 验证数据是否已存在,已存在的先删除
         // 没id的删除重新插入,有id的更新
@@ -859,7 +1005,24 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
                         deleteIds.add(item.getId());
                     }
                 }
+
+                //数据库中已存在匹配项,去除导入文件中未匹配项
+                it = unMatchList.iterator();
+                while (it.hasNext()) {
+                    MappingConfigWrapper item = it.next();
+                    String matchKey = item.getHisName() + "_"
+                            + item.getHisCode() + "_"
+                            + item.getHisDetailName();
+                    if (db_matchMap.containsKey(matchKey)) {
+                        it.remove();
+                    }
+                }
             }
+
+            //过滤后的导入结果集
+            tempList.addAll(matchList);
+            tempList.addAll(unMatchList);
+
             //标准术语校验
             ConceptVO conceptVO = new ConceptVO();
             conceptVO.setSource(MatchSourceEnum.StandWord.getKey());
@@ -980,7 +1143,10 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
             idListVO.setIds(deleteIds);
             deleteRecords(idListVO);
             List<MappingConfig> saveList = BeanUtil.listCopyTo(tempList, MappingConfig.class);
-            mappingConfigService.saveOrUpdateBatch(saveList);
+            saveList = saveList.stream().distinct().collect(Collectors.toList());
+            if (ListUtil.isNotEmpty(saveList)) {
+                mappingConfigService.saveOrUpdateBatch(saveList);
+            }
         }
         return true;
     }
@@ -1052,6 +1218,10 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
                 .eq("is_match", 1);
         if (StringUtil.isNotBlank(mappingConfigVO.getHisDetailName())) {
             queryWrapper.eq("his_detail_name", mappingConfigVO.getHisDetailName());
+        } else {
+            queryWrapper.and(i -> i.isNull("his_detail_name")
+                    .or()
+                    .eq("his_detail_name", ""));
         }
 
         List<MappingConfig> list = this.list(queryWrapper);
@@ -1093,6 +1263,19 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
             queryWrapper
                     .eq("his_detail_name", mappingConfig.getHisDetailName());
         }
+        if (StringUtil.isBlank(mappingConfig.getHisCode())) {
+            queryWrapper.and(i -> i.isNull("his_code")
+                    .or()
+                    .eq("his_code", ""));
+        } else {
+            queryWrapper
+                    .eq("his_code", mappingConfig.getHisCode());
+        }
+        if (mappingConfig.getFormConceptId() != null) {
+            queryWrapper.eq("form_concept_id", mappingConfig.getFormConceptId());
+        } else {
+            queryWrapper.isNull("form_concept_id");
+        }
         if (mappingConfig.getFormConceptId() != null) {
             queryWrapper.eq("form_concept_id", mappingConfig.getFormConceptId());
         }
@@ -1148,6 +1331,19 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
         } else {
             queryWrapper.eq("his_detail_name", mappingConfig.getHisDetailName());
         }
+        if (StringUtil.isBlank(mappingConfig.getHisCode())) {
+            queryWrapper.and(i -> i.isNull("his_code")
+                    .or()
+                    .eq("his_code", ""));
+        } else {
+            queryWrapper
+                    .eq("his_code", mappingConfig.getHisCode());
+        }
+        if (mappingConfig.getFormConceptId() != null) {
+            queryWrapper.eq("form_concept_id", mappingConfig.getFormConceptId());
+        } else {
+            queryWrapper.isNull("form_concept_id");
+        }
         MappingConfig oldRecord = this.getOne(queryWrapper, false);
         if (mappingConfig.getId() == null
                 && oldRecord != null) {
@@ -1182,6 +1378,14 @@ public class MappingConfigFacade extends MappingConfigServiceImpl {
         } else {
             qwUnMaptch.eq("his_detail_name", mappingConfig.getHisDetailName());
         }
+        if (StringUtil.isBlank(mappingConfig.getHisCode())) {
+            qwUnMaptch.and(i -> i.isNull("his_code")
+                    .or()
+                    .eq("his_code", ""));
+        } else {
+            qwUnMaptch
+                    .eq("his_code", mappingConfig.getHisCode());
+        }
         this.remove(qwUnMaptch);
 
         mappingConfig.setIsMatch(1);

+ 1 - 1
src/main/java/com/diagbot/facade/PushFacade.java

@@ -186,7 +186,7 @@ public class PushFacade {
             if (RespDTOUtil.respIsNG(respDTO)) {
                 return pushDTO;
             }
-            //1-诊断、2-药品、3-检验套餐、4-检验细项、5-检查、6-检查子项、7-手术和操作、8-量表、9-护理、10-法律法规
+            //1-诊断、2-药品、3-检验套餐、4-检验细项、5-检查、6-检查子项、7-手术和操作、8-量表、9-护理、10-政策法规
             Map<String, List<ConceptDetailDTO>> conceptDetailMap = respDTO.data;
             if (pushDTO.getDis() != null) {
                 for (Map.Entry<String, List<PushBaseDTO>> entry : pushDTO.getDis().entrySet()) {

+ 4 - 4
src/main/java/com/diagbot/util/CoreUtil.java

@@ -27,8 +27,8 @@ public class CoreUtil {
             if (isNumbers(ageStr)) {
                 return Double.parseDouble(ageStr);
             }
-            // 20日
-            if (ageStr.endsWith("日")) {
+            // 20日 | 20天
+            if (ageStr.endsWith("日") || ageStr.endsWith("天")) {
                 return getHalfUp((Double.parseDouble(ageStr.substring(0, ageStr.length() - 1))) / 365);
             }
             // 3岁
@@ -41,9 +41,9 @@ public class CoreUtil {
                 int indexSui = ageStr.indexOf("岁");
                 ageArr[0] = ageStr.substring(0, indexSui);
                 if (ageStr.indexOf("个月") > -1) { // 3岁7个月
-                    ageArr[1] = ageStr.substring(indexSui + 1,ageStr.indexOf("个月"));
+                    ageArr[1] = ageStr.substring(indexSui + 1, ageStr.indexOf("个月"));
                 } else { // 3岁7月
-                    ageArr[1] = ageStr.substring(indexSui + 1,ageStr.indexOf("月"));
+                    ageArr[1] = ageStr.substring(indexSui + 1, ageStr.indexOf("月"));
                 }
                 return Double.parseDouble(ageArr[0]) + getHalfUp(Double.parseDouble(ageArr[1]) / 12);
             }

+ 144 - 0
src/main/java/com/diagbot/util/ReflectUtil.java

@@ -0,0 +1,144 @@
+package com.diagbot.util;
+
+import com.google.common.collect.Lists;
+
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * @description: 反射工具类
+ * @author: zhoutg
+ * @date: 2021/4/27 13:29
+ */
+public class ReflectUtil {
+
+    /**
+     * 获取属性对应的值,以list形式返回
+     *
+     * @param list
+     * @param propertyName
+     * @param <T>
+     * @param <V>
+     * @return
+     */
+    public static <T, V> List<V> getPropertyList(List<T> list, String propertyName) {
+        List<V> res = Lists.newArrayList();
+        if (ListUtil.isEmpty(list)) {
+            return res;
+        }
+        for (T t : list) {
+            try {
+                V val = getProperty(t, propertyName);
+                if (val != null) {
+                    // 字符串类型不为空判断
+                    if (StringUtil.isNotBlank(String.valueOf(val))) {
+                        res.add(val);
+                    }
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return res;
+    }
+
+    /**
+     * 循环向上转型, 获取对象的 DeclaredField
+     *
+     * @param object    : 子类对象
+     * @param fieldName : 父类中的属性名
+     * @return 父类中的属性对象
+     */
+    public static Field getDeclaredField(Object object, String fieldName) {
+        Field field = null;
+        Class<?> clazz = object.getClass();
+        for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
+            try {
+                field = clazz.getDeclaredField(fieldName);
+                return field;
+            } catch (Exception e) {
+                //这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
+                //如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 获取对象的属性值,直接使用getDeclaredFields()方法只能获取当前类声明的字段,需要递归向上获取
+     *
+     * @param object    : 子类对象
+     * @param fieldName : 父类中的属性名
+     * @return : 父类中的属性值
+     */
+    public static <T> T getProperty(Object object, String fieldName) {
+        try {
+            //根据 对象和属性名通过反射获取Field对象
+            Field field = getDeclaredField(object, fieldName);
+            // 容错处理
+            if (field == null) {
+                return null;
+            }
+            //抑制Java对其的检查
+            field.setAccessible(true);
+            //获取 object 中 field 所代表的属性值
+            return (T) field.get(object);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 对象赋值
+     *
+     * @param object
+     * @param property
+     * @param value
+     */
+    public static void setProperty(Object object, String property, Object value) {
+        //根据 对象和属性名通过反射 调用上面的方法获取 Field对象
+        Field field = getDeclaredField(object, property);
+        //抑制Java对其的检查
+        field.setAccessible(true);
+        try {
+            field.set(object, value);
+        } catch (IllegalArgumentException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 根据指定字段按照字符串排序
+     *
+     * @param tList
+     * @param property
+     * @param <T>
+     */
+    public <T> void sort(List<T> tList, String property) {
+        if (ListUtil.isNotEmpty(tList) && tList.size() > 1) {
+            Collections.sort(tList, new Comparator<T>() {
+                @Override
+                public int compare(T o1, T o2) {
+                    String v1 = getProperty(o1, property);
+                    String v2 = getProperty(o2, property);
+                    if (StringUtil.isBlank(v1)) {
+                        return -1;
+                    }
+                    if (StringUtil.isBlank(v2)) {
+                        return 1;
+                    }
+                    return v1.compareTo(v2);
+                }
+            });
+        }
+    }
+
+    public static void main(String[] args) {
+
+    }
+}

+ 1 - 0
src/main/java/com/diagbot/vo/KlRuleInfoSaveSubVO.java

@@ -27,4 +27,5 @@ public class KlRuleInfoSaveSubVO {
     private String subEqOperator;//等于域比较符
     private String subEqValue;//等于域值
     private String subEqUnit;//等于域单位
+    private String subMsg;
 }

+ 19 - 0
src/main/java/com/diagbot/vo/PrecDataVO.java

@@ -0,0 +1,19 @@
+package com.diagbot.vo;
+
+import com.diagbot.entity.wrapper.MappingConfigWrapper;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * @Description:
+ * @Author:zhaops
+ * @time: 2021/9/15 11:38
+ */
+@Data
+public class PrecDataVO {
+    private List<PrecRecordVO> originList;
+    @NotNull(message = "请输入术语类型:1-化验、3-辅检、4-诊断、5-药品、6-手术和操作、7-科室、8-输血、10-量表、11-护理、12-中医诊断、13-中医证候、14-麻醉 ")
+    private Integer type;
+}

+ 35 - 0
src/main/java/com/diagbot/vo/PrecRecordVO.java

@@ -0,0 +1,35 @@
+package com.diagbot.vo;
+
+import lombok.Data;
+
+/**
+ * @Description:
+ * @Author:zhaops
+ * @time: 2021/9/15 13:15
+ */
+@Data
+public class PrecRecordVO {
+    /**
+     * 医院术语名称
+     */
+    private String hisName;
+
+    /**
+     * 医院术语编码
+     */
+    private String hisCode;
+
+    /**
+     * 医院术语细项名称(检验细项)
+     */
+    private String hisDetailName;
+
+    /**
+     * 手术编码、诊断编码、中医疾病编码、中医证候编码
+     */
+    private String code;
+    /**
+     * 药品国药准字
+     */
+    private String approval;
+}

+ 10 - 0
src/main/java/com/diagbot/vo/PushJoinVO.java

@@ -3,11 +3,13 @@ package com.diagbot.vo;
 import com.diagbot.biz.push.entity.Item;
 import com.diagbot.biz.push.entity.Lis;
 import com.diagbot.biz.push.entity.Pacs;
+import com.diagbot.biz.push.entity.Scale;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Getter;
 import lombok.Setter;
 
 import javax.validation.constraints.NotNull;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -185,6 +187,14 @@ public class PushJoinVO {
      * 其他指标
      */
     private Map<String, String> otherIndex;
+    /**
+     * 其他医嘱
+     */
+    private List<Item> otherAdvice = new ArrayList<>();
+    /**
+     * 量表结果
+     */
+    private List<Scale> scale = new ArrayList<>();
 
     //创建时间
     @ApiModelProperty(hidden = true)

+ 6 - 1
src/main/java/com/diagbot/vo/SearchConceptVO.java

@@ -17,7 +17,6 @@ import java.util.List;
 @Getter
 public class SearchConceptVO {
     @ApiModelProperty(value="名称")
-    @NotBlank(message = "请输入搜索名称")
     private String name;
     /**
      * 词性id
@@ -30,4 +29,10 @@ public class SearchConceptVO {
      */
     @ApiModelProperty(value="需要排除的概念id集合")
     private List<Long> excludedConceptIds;
+
+    /**
+     * 标志(新增 -1 修改 2)
+     */
+//    @ApiModelProperty(value="新增修改标志")
+//    private Integer sign;
 }

+ 10 - 0
src/main/java/com/diagbot/vo/SearchData.java

@@ -3,6 +3,7 @@ package com.diagbot.vo;
 import com.diagbot.biz.push.entity.Item;
 import com.diagbot.biz.push.entity.Lis;
 import com.diagbot.biz.push.entity.Pacs;
+import com.diagbot.biz.push.entity.Scale;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Getter;
 import lombok.Setter;
@@ -176,4 +177,13 @@ public class SearchData extends HospitalBaseVO {
      * 其他指标
      */
     private Map<String, String> otherIndex;
+    /**
+     * 其他医嘱
+     */
+    private List<Item> otherAdvice = new ArrayList<>();
+    /**
+     * 量表结果
+     */
+    private List<Scale> scale = new ArrayList<>();
+
 }

+ 8 - 8
src/main/java/com/diagbot/web/ConceptInfoController.java

@@ -53,7 +53,7 @@ public class ConceptInfoController {
     private KlConceptStaticFacade klConceptStaticFacade;
 
     @ApiOperation(value = "医学知识(静态知识)检索[zhaops]",
-            notes = "types: 类型(多选):0-全部、1-诊断、2-药品、3-检验、5-检查、6-手术和操作、8-量表、9-护理、10-法律法规 <br>" +
+            notes = "types: 类型(多选):0-全部、1-诊断、2-药品、3-检验、5-检查、6-手术和操作、8-量表、9-护理、10-政策法规 <br>" +
                     "inputStr: 检索内容<br>")
     @PostMapping("/staticKnowledgeIndex")
     @SysLogger("staticKnowledgeIndex")
@@ -64,7 +64,7 @@ public class ConceptInfoController {
     }
 
     @ApiOperation(value = "医学术语检索-新增静态知识[zhaops]",
-            notes = "types: 类型(多选):0-全部、1-诊断、2-药品、3-检验、5-检查、6-手术和操作、8-量表、9-护理、10-法律法规 <br>" +
+            notes = "types: 类型(多选):0-全部、1-诊断、2-药品、3-检验、5-检查、6-手术和操作、8-量表、9-护理、10-政策法规 <br>" +
                     "inputStr: 检索内容<br>")
     @PostMapping("/staticKnowledgeIndexWithoutInfo")
     @SysLogger("staticKnowledgeIndexWithoutInfo")
@@ -76,7 +76,7 @@ public class ConceptInfoController {
     }
 
     @ApiOperation(value = "页面获取静态知识[zhaops]",
-            notes = "type: 类型:1-诊断、2-药品、3-检验套餐、4-检验细项、5-检查、6-检查子项、7-手术和操作、8-量表、9-护理、10-法律法规 <br>" +
+            notes = "type: 类型:1-诊断、2-药品、3-检验套餐、4-检验细项、5-检查、6-检查子项、7-手术和操作、8-量表、9-护理、10-政策法规 <br>" +
                     "contentTypes: 内容类型(多选):1-静态信息、2-注意事项、3-临床路径、4-治疗方案<br>" +
                     "name: 标准术语名称<br>")
     @PostMapping("/getStaticKnowledge")
@@ -87,7 +87,7 @@ public class ConceptInfoController {
     }
 
     @ApiOperation(value = "对接获取静态知识[zhaops]",
-            notes = "type: 类型:1-诊断、2-药品、3-检验套餐、4-检验细项、5-检查、7-手术和操作、8-量表、9-护理、10-法律法规 <br>" +
+            notes = "type: 类型:1-诊断、2-药品、3-检验套餐、4-检验细项、5-检查、7-手术和操作、8-量表、9-护理、10-政策法规 <br>" +
                     "contentTypes: 内容类型(多选):1-静态信息、2-注意事项、3-临床路径、4-治疗方案 <br>" +
                     "hisName: HIS大项名称<br>" +
                     "hisDetailName: HIS小项名称<br>")
@@ -99,7 +99,7 @@ public class ConceptInfoController {
     }
 
     @ApiOperation(value = "获取静态知识列表[zhaops]",
-            notes = "type: 类型:1-诊断、2-药品、3-检验套餐、4-检验细项、5-检查、6-检查子项、7-手术和操作、8-量表、9-护理、10-法律法规 <br>" +
+            notes = "type: 类型:1-诊断、2-药品、3-检验套餐、4-检验细项、5-检查、6-检查子项、7-手术和操作、8-量表、9-护理、10-政策法规 <br>" +
                     "name: 术语名称<br>" +
                     "isDeleted: 启用状态:N-启用中、Y-已删除<br>")
     @PostMapping("/getPage")
@@ -111,7 +111,7 @@ public class ConceptInfoController {
     }
 
     @ApiOperation(value = "静态知识检索(分页返回)[zhaops]",
-            notes = "types: 类型(多选):0-全部、1-诊断、2-药品、3-检验、5-检查、6-手术和操作、8-量表、9-护理、10-法律法规 <br>" +
+            notes = "types: 类型(多选):0-全部、1-诊断、2-药品、3-检验、5-检查、6-手术和操作、8-量表、9-护理、10-政策法规 <br>" +
                     "inputStr: 检索内容<br>")
     @PostMapping("/staticIndexPage")
     @SysLogger("staticIndexPage")
@@ -124,7 +124,7 @@ public class ConceptInfoController {
     @ApiOperation(value = "保存静态知识-新增或修改[zhaops]",
             notes = "id: id <br>" +
                     "name: 术语名称 <br>" +
-                    "type: 类型:1-诊断、2-药品、3-检验套餐、4-检验细项、5-检查、6-检查子项、7-手术和操作、8-量表、9-护理、10-法律法规 <br>" +
+                    "type: 类型:1-诊断、2-药品、3-检验套餐、4-检验细项、5-检查、6-检查子项、7-手术和操作、8-量表、9-护理、10-政策法规 <br>" +
                     "clinicalPathwayName: 临床路径名称<br>" +
                     "noticeName: 注意事项名称<br>" +
                     "details: 明细<br>")
@@ -149,7 +149,7 @@ public class ConceptInfoController {
 
     @ApiOperation(value = "静态知识是否存在[zhaops]",
             notes = "name: 术语名称 <br>" +
-                    "type: 类型:1-诊断、2-药品、3-检验套餐、4-检验细项、5-检查、6-检查子项、7-手术和操作、8-量表、9-护理、10-法律法规 <br>")
+                    "type: 类型:1-诊断、2-药品、3-检验套餐、4-检验细项、5-检查、6-检查子项、7-手术和操作、8-量表、9-护理、10-政策法规 <br>")
     @PostMapping("/isExist")
     @SysLogger("isExist")
     public RespDTO<Boolean> isExist(@Valid @RequestBody KlConceptStaticVO klConceptStaticVO) {

+ 24 - 1
src/main/java/com/diagbot/web/KlDiseaseController.java

@@ -37,7 +37,8 @@ public class KlDiseaseController {
     @ApiOperation(value = "查询诊断依据相关的类型术语[by:kongwz]",
             notes = "name: 查询术语的名称<br>" +
                     "libType: 查询术语的词性<br>" +
-                    "excludedConceptIds: 需要排除的概念id集合")
+                    "excludedConceptIds: 需要排除的概念id集合"+
+                    "sign: 新增 -1 修改 2")
     @PostMapping("/searchConcept")
     @SysLogger("searchConcept")
     public RespDTO<List<GetAllForRelationDTO>> searchConcept(@Valid @RequestBody SearchConceptVO searchConceptVO) {
@@ -45,4 +46,26 @@ public class KlDiseaseController {
         return RespDTO.onSuc(getAllForRelationDTOS);
     }
 
+    @ApiOperation(value = "术语集合新增[by:kongwz]",
+            notes = "name: 查询术语的名称<br>" +
+                    "libType: 查询术语的词性<br>" +
+                    "excludedConceptIds: 需要排除的概念id集合")
+    @PostMapping("/addConceptClass")
+    @SysLogger("addConceptClass")
+    public RespDTO<List<GetAllForRelationDTO>> addConceptClass(@Valid @RequestBody SearchConceptVO searchConceptVO) {
+        List<GetAllForRelationDTO> getAllForRelationDTOS = klConceptFacade.addConceptClass(searchConceptVO);
+        return RespDTO.onSuc(getAllForRelationDTOS);
+    }
+
+    @ApiOperation(value = "规则维护术语查询[by:kongwz]",
+            notes = "name: 查询术语的名称<br>" +
+                    "libType: 查询术语的词性<br>" +
+                    "excludedConceptIds: 需要排除的概念id集合")
+    @PostMapping("/searchConceptRuleClass")
+    @SysLogger("searchConceptRuleClass")
+    public RespDTO<List<GetAllForRelationDTO>> searchConceptRuleClass(@Valid @RequestBody SearchConceptVO searchConceptVO) {
+        List<GetAllForRelationDTO> getAllForRelationDTOS = klConceptFacade.searchConceptRuleClass(searchConceptVO);
+        return RespDTO.onSuc(getAllForRelationDTOS);
+    }
+
 }

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

@@ -12,6 +12,7 @@ import com.diagbot.vo.IdListVO;
 import com.diagbot.vo.IdVO;
 import com.diagbot.vo.MappingConfigPageVO;
 import com.diagbot.vo.MappingConfigVO;
+import com.diagbot.vo.PrecDataVO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -83,6 +84,19 @@ public class MappingConfigController {
         return RespDTO.onSuc(data);
     }
 
+    @ApiOperation(value = "预匹配(非文件匹配)[by:zhaops]",
+            notes = "type(必填): 类型:1-化验、3-辅检、4-诊断、5-药品、6-手术和操作、7-科室、8-输血、10-量表、11-护理、12-中医诊断、13-中医证候、14-麻醉 <br>"+
+                    "hisName(必填):医院术语名称 <br>" +
+                    "hisDetailName(选填):医院术语名称-细项 <br>" +
+                    "code(选填):诊断ICD10编码、手术编码、中医疾病编码、中医证候编码 <br>" +
+                    "approval(选填):药品国药准字 <br>" )
+    @PostMapping(value = "/precData")
+    @SysLogger("precData")
+    public RespDTO<List<MappingConfigWrapper>> precData(@Valid @RequestBody PrecDataVO precDataVO) {
+        List<MappingConfigWrapper> data = mappingConfigFacade.precData(precDataVO);
+        return RespDTO.onSuc(data);
+    }
+
     @ApiOperation(value = "数据导入[by:zhaops]",
             notes = "file(必填):导入文件 <br>" +
                     "hospitalId(必填):医院id <br>" +
@@ -92,9 +106,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);
     }