Преглед на файлове

Merge branch 'develop' into dev/mapping_20210824

gaodm преди 3 години
родител
ревизия
0ef1172289

+ 35 - 0
src/main/java/com/diagbot/aggregate/RuleAggregate.java

@@ -6,13 +6,17 @@ import com.diagbot.dto.RuleConditionDTO;
 import com.diagbot.dto.RuleConditionInitDTO;
 import com.diagbot.dto.RuleDTO;
 import com.diagbot.dto.RuleInitDTO;
+import com.diagbot.enums.BaseTypeEnum;
+import com.diagbot.enums.LexiconEnum;
 import com.diagbot.enums.RedisEnum;
+import com.diagbot.enums.RuleTypeEnum;
 import com.diagbot.exception.CommonErrorCode;
 import com.diagbot.exception.CommonException;
 import com.diagbot.facade.KlRuleFacade;
 import com.diagbot.util.BeanUtil;
 import com.diagbot.util.EntityUtil;
 import com.diagbot.util.ListUtil;
+import com.diagbot.util.RedisUtil;
 import io.github.lvyahui8.spring.annotation.DataConsumer;
 import io.github.lvyahui8.spring.annotation.DataProvider;
 import lombok.extern.slf4j.Slf4j;
@@ -35,6 +39,8 @@ import java.util.Map;
 public class RuleAggregate {
     @Autowired
     private KlRuleFacade klRuleFacade;
+    @Autowired
+    private RedisUtil redisUtil;
 
     @DataProvider("getAllRules")
     public Map<String, RuleDTO> getAllRules(
@@ -43,6 +49,8 @@ public class RuleAggregate {
             @DataConsumer("getRuleBaseInit") Map<Integer, List<RuleBaseInitDTO>> ruleBaseInits) {
         try {
             Map<String, RuleDTO> res = new HashMap();
+            //药物过敏源
+            Map<String, Integer> drugAllergen = new HashMap<>();
             //结果判空第一层规则类型
             if (MapUtils.isNotEmpty(ruleInits)) {
                 for (String ruleKey : ruleInits.keySet()) {
@@ -51,6 +59,12 @@ public class RuleAggregate {
                     ruleDTO.setLibName(ruleInitZeroDTO.getLibName());
                     ruleDTO.setLibType(ruleInitZeroDTO.getLibType());
                     ruleDTO.setRuleType(ruleInitZeroDTO.getRuleType());
+                    //药物过敏源相关
+                    Boolean allergenAdd = false;
+                    if (ruleDTO.getRuleType().equals(RuleTypeEnum.bill.getKey())
+                            && ruleDTO.getLibType().equals(LexiconEnum.Medicine.getKey())) {
+                        allergenAdd = true;
+                    }
                     Map<String, Integer> ruleConditionMap = new HashMap<>();
                     for (RuleInitDTO ruleInitDTO : ruleInits.get(ruleKey)) {
                         if (ruleInitDTO.getHasSubCond().equals(1)) {
@@ -75,6 +89,11 @@ public class RuleAggregate {
                                         //笛卡尔积
                                         List<List<RuleBaseDTO>> ruleBaseGroup = new ArrayList<>();
                                         descartes(ruleBaseList, ruleBaseGroup, 0, new ArrayList<>());
+                                        //药物过敏源相关
+                                        if (allergenAdd
+                                                && ruleBaseGroup.size() == 1) {
+                                            allergenAdd = true;
+                                        }
                                         for (List<RuleBaseDTO> ruleBaseDTOList : ruleBaseGroup) {
                                             RuleConditionDTO ruleConditionDTO1 = new RuleConditionDTO();
                                             ruleConditionDTO1.setHasSubCond(ruleConditionDTO.getHasSubCond());
@@ -83,6 +102,18 @@ public class RuleAggregate {
                                             ruleConditionDTO1.getRuleBaseDTOList().addAll(ruleBaseDTOList);
                                             if (!ruleConditionMap.containsKey(ruleConditionDTO1.toString())) {
                                                 ruleDTO.getRuleConditionDTOList().add(ruleConditionDTO1);
+                                                //药物过敏源相关
+                                                if (allergenAdd
+                                                        && ruleBaseDTOList.size() == 1) {
+                                                    RuleBaseDTO ruleBaseDTO = ruleBaseDTOList.get(0);
+                                                    if (ruleBaseDTO.getBaseType().equals(BaseTypeEnum.B4.getKey())
+                                                            && ruleDTO.getLibType().equals(ruleBaseDTO.getBaseLibType())
+                                                            && ruleDTO.getLibName().equals(ruleBaseDTO.getBaseLibName())) {
+                                                        if (!drugAllergen.containsKey(ruleDTO.getLibName())) {
+                                                            drugAllergen.put(ruleDTO.getLibName(), 1);
+                                                        }
+                                                    }
+                                                }
                                                 ruleConditionMap.put(ruleConditionDTO1.toString(), 1);
                                             }
                                         }
@@ -104,6 +135,10 @@ public class RuleAggregate {
                     }
                     res.put(RedisEnum.allRule.getName() + ruleDTO.getLibType() + "_" + ruleDTO.getLibName() + "_" + ruleDTO.getRuleType(), ruleDTO);
                 }
+                //直接加载缓存
+                if (MapUtils.isNotEmpty(drugAllergen)) {
+                    redisUtil.set(RedisEnum.drugAllergen.getName(), drugAllergen);
+                }
             }
             return res;
         } catch (Exception e) {

+ 2 - 1
src/main/java/com/diagbot/client/hystrix/CRFServiceHystrix.java

@@ -1,6 +1,7 @@
 package com.diagbot.client.hystrix;
 
 import com.diagbot.client.CRFServiceClient;
+import com.diagbot.util.GsonUtil;
 import com.diagbot.vo.CRFVo;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
@@ -11,7 +12,7 @@ import org.springframework.web.bind.annotation.RequestBody;
 public class CRFServiceHystrix implements CRFServiceClient {
     @Override
     public String getAnnotation(@RequestBody CRFVo crfVo) {
-        log.error("【hystrix】调用{}异常", "CRF-getAnnotation");
+        log.error("CRF解析文本【超时】或【服务出错】,参数如下{}", GsonUtil.toJson(crfVo));
         return null;
     }
 }

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

@@ -28,7 +28,8 @@ public enum RedisEnum implements KeyedNamed {
     deptPush(15, "deptPush"),
     frequency(20, "frequency"),
     msg(21, "msg"),
-    vteAdvice(22, "vteAdvice:");
+    vteAdvice(22, "vteAdvice:"),
+    drugAllergen(23, "drugAllergen");
 
     @Setter
     private int key;

+ 14 - 0
src/main/java/com/diagbot/facade/BillFacade.java

@@ -9,6 +9,9 @@ import com.diagbot.enums.LexiconEnum;
 import com.diagbot.enums.RuleTypeEnum;
 import com.diagbot.enums.TypeEnum;
 import com.diagbot.process.BillProcess;
+import com.diagbot.rule.DrugRule;
+import com.diagbot.rule.OtherRule;
+import com.diagbot.util.MsgNewUtil;
 import com.diagbot.util.RedisUtil;
 import com.diagbot.util.StringUtil;
 import com.diagbot.vo.Drug;
@@ -36,6 +39,12 @@ public class BillFacade {
     CommonFacade commonFacade;
     @Autowired
     RedisUtil redisUtil;
+    @Autowired
+    DrugRule drugRule;
+    @Autowired
+    MsgNewUtil msgNewUtil;
+    @Autowired
+    OtherRule otherRule;
 
     /**
      * 开单合理性业务
@@ -48,6 +57,11 @@ public class BillFacade {
         List<RuleVO> ruleVOList = getRuleVO(wordCrfDTO);
         billProcess.processRule(ruleVOList, wordCrfDTO, res);
 
+        // 【特殊规则】过敏原自身过敏
+        otherRule.allergy(wordCrfDTO, res);
+        // 【特殊规则】七院:非阻塞性睡眠呼吸暂停综合征且非混合性睡眠呼吸暂停综合征,不宜同时开立睡眠呼吸监测和眼电图(EOG)(双眼)
+        otherRule.smhxjcAndYdteog(wordCrfDTO, res);
+
         // 结果去重处理
         commonFacade.dealMsg(res.getBillMsgList());
     }

+ 2 - 4
src/main/java/com/diagbot/facade/CacheFacade.java

@@ -118,6 +118,7 @@ public class CacheFacade {
      */
     public void loadAllRuleCache(){
         redisUtil.deleteByPrex(RedisEnum.allRule.getName());
+        redisUtil.delete(RedisEnum.drugAllergen.getName());
         neoFacade.allRuleCache();
     }
 
@@ -147,10 +148,7 @@ public class CacheFacade {
      */
     public Boolean reloadPushDB(){
         PushReloadDTO pushReloadDTO = pushNewServiceClient.reloadPushDB();
-        if (pushReloadDTO == null || !pushReloadDTO.getStatus().equals(0)) {
-            return false;
-        }
-        return true;
+        return pushReloadDTO != null && pushReloadDTO.getStatus().equals(0);
     }
 
     /**

+ 7 - 12
src/main/java/com/diagbot/facade/NeoFacade.java

@@ -38,8 +38,6 @@ import io.github.lvyahui8.spring.facade.DataFacade;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.MapUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
 
 import java.util.ArrayList;
@@ -67,9 +65,6 @@ public class NeoFacade {
     @Autowired
     RedisUtil redisUtil;
     @Autowired
-    @Qualifier("redisTemplateForSimilar")
-    RedisTemplate redisTemplate;
-    @Autowired
     SymptomFeatureService symptomFeatureService;
     @Autowired
     KlDiseaseCorrespondingService klDiseaseCorrespondingService;
@@ -102,7 +97,7 @@ public class NeoFacade {
                 Collectors.toMap(k -> RedisEnum.drugType.getName() + k.getDrugType(),
                         v -> v.getDrugs(), (v1, v2) -> (v2)));
         if (redisMap != null && redisMap.size() > 0) {
-            redisTemplate.opsForValue().multiSet(redisMap);
+            redisUtil.multiSet(redisMap);
         }
     }
 
@@ -120,7 +115,7 @@ public class NeoFacade {
                     },
                     (v1, v2) -> (v2)
             ));
-            redisTemplate.opsForValue().multiSet(map);
+            redisUtil.multiSet(map);
         }
     }
 
@@ -135,7 +130,7 @@ public class NeoFacade {
                 Map<String, Long> collect = y.stream().collect(Collectors.toMap(TranHospitalFilter::getUniqueName, TranHospitalFilter::getDocNum, (existing, replacement) -> replacement));
                 data.put(RedisEnum.diseaseFilter.getName() + x.toString(), collect);
             });
-            redisTemplate.opsForValue().multiSet(data);
+            redisUtil.multiSet(data);
         }
     }
 
@@ -159,7 +154,7 @@ public class NeoFacade {
                     },
                     (v1, v2) -> (v2)
             ));
-            redisTemplate.opsForValue().multiSet(map);
+            redisUtil.multiSet(map);
         }
     }
 
@@ -499,7 +494,7 @@ public class NeoFacade {
         try {
             Map<String, Object> invokeParams = new HashMap<>();
             Map<String, RuleDTO> map = DataFacade.get("getAllRules", invokeParams, Map.class);
-            redisTemplate.opsForValue().multiSet(map);
+            redisUtil.multiSet(map);
         } catch (Exception e) {
             throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "获取所有规则失败" + e.getMessage());
         }
@@ -508,14 +503,14 @@ public class NeoFacade {
     public void allBaseDiagnose() {
         List<BaseDiagnoseDTO> list = klDiagnoseBaseFacade.getAllBaseDiagnose();
         if (ListUtil.isNotEmpty(list)) {
-            redisTemplate.opsForValue().set(RedisEnum.allBaseDiagnose.getName(), list);
+            redisUtil.set(RedisEnum.allBaseDiagnose.getName(), list);
         }
     }
 
     public void allBaseRegulation() {
         List<BaseRegulationDTO> list = klRegulationBaseFacade.getSelectBase(new ArrayList<>());
         if (ListUtil.isNotEmpty(list)) {
-            redisTemplate.opsForValue().set(RedisEnum.allBaseRegulation.getName(), list);
+            redisUtil.set(RedisEnum.allBaseRegulation.getName(), list);
         }
     }
 }

+ 1 - 1
src/main/java/com/diagbot/model/ai/BeHospitalizedAI.java

@@ -242,7 +242,7 @@ public class BeHospitalizedAI extends ModelAI {
             try {
                 midData = loadAI(crfContent, crfServiceClient);
             } catch (Exception e) {
-                throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "CRF模型【服务器】挂了!" + e.getMessage());
+                throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "CRF解析文本【超时】或【服务出错】!");
             }
             /* 处理主诉 */
             if (StringUtil.isNotBlank(wordCrfDTO.getChiefLabel().getText())) {

+ 4 - 2
src/main/java/com/diagbot/model/ai/process/EntityProcessLis.java

@@ -111,8 +111,10 @@ public class EntityProcessLis extends EntityProcess {
         if (value.trim().length() > 0) {
             val_unit = extract_digit_new(value);
         }
-        pd.setValue(val_unit[0]);
-        pd.setUnit(val_unit[1]);
+        if (val_unit != null && val_unit.length == 2) {
+            pd.setValue(val_unit[0]);
+            pd.setUnit(val_unit[1].trim()); // 单位去空格
+        }
         return pd;
     }
 

+ 134 - 0
src/main/java/com/diagbot/rule/OtherRule.java

@@ -0,0 +1,134 @@
+package com.diagbot.rule;
+
+import com.diagbot.biz.push.entity.Item;
+import com.diagbot.biz.push.entity.Pacs;
+import com.diagbot.dto.BillMsg;
+import com.diagbot.dto.IndicationDTO;
+import com.diagbot.dto.RuleSimpleDTO;
+import com.diagbot.dto.WordCrfDTO;
+import com.diagbot.enums.ConEnum;
+import com.diagbot.enums.RedisEnum;
+import com.diagbot.enums.TypeEnum;
+import com.diagbot.model.entity.AllergyMedicine;
+import com.diagbot.model.entity.Negative;
+import com.diagbot.model.label.PastLabel;
+import com.diagbot.util.CoreUtil;
+import com.diagbot.util.ListUtil;
+import com.diagbot.util.MsgNewUtil;
+import com.diagbot.util.RedisUtil;
+import com.diagbot.util.StringUtil;
+import com.diagbot.vo.Drug;
+import com.google.common.collect.Lists;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @description: 其他特殊规则
+ * @author: zhoutg
+ * @time: 2020/8/3 14:47
+ */
+@Component
+public class OtherRule {
+
+    @Autowired
+    MsgNewUtil msgNewUtil;
+    @Autowired
+    RedisUtil redisUtil;
+
+    /**
+     * 过敏原自身过敏,如果规则已维护,就不再比较;如果没有维护,比较是否与自身过敏
+     *
+     * @param
+     * @return
+     */
+    public void allergy(WordCrfDTO wordCrfDTO, IndicationDTO res) {
+        // 药物过敏源
+        PastLabel pastLabel = wordCrfDTO.getPastLabel();
+        List<AllergyMedicine> allergyMedicines = pastLabel.getAllergyMedicines();
+        if (ListUtil.isEmpty(wordCrfDTO.getDrugOrder()) || ListUtil.isEmpty(allergyMedicines)) {
+            return;
+        }
+        // 获取已维护的自身过敏规则,如果包含standName就不用再比较
+        Map<String, Integer> allergyMap = redisUtil.get(RedisEnum.drugAllergen.getName());
+        for (Drug drug : wordCrfDTO.getDrugOrder()) {
+            for (AllergyMedicine allergy : allergyMedicines) {
+                String name = allergy.getName();
+                String standName = allergy.getStandName();
+                Negative negative = allergy.getNegative(); // null表示阳性
+                if (allergyMap == null || !allergyMap.containsKey(standName)) {
+                    // 执行到这里说明自身过敏的规则没有维护
+                    if (negative == null && StringUtil.isNotBlank(drug.getUniqueName()) && drug.getUniqueName().equals(standName)) {
+                        RuleSimpleDTO ruleSimpleDTO = new RuleSimpleDTO();
+                        ruleSimpleDTO.setInputName(drug.getName());
+                        ruleSimpleDTO.setLibName(drug.getUniqueName());
+                        ruleSimpleDTO.setLibTypeName(TypeEnum.drug.getName());
+                        ruleSimpleDTO.setContent(name);
+                        ruleSimpleDTO.setConType(ConEnum.allergicmeds.getName());
+                        BillMsg billMsg = msgNewUtil.getCommonBillMsg(ruleSimpleDTO);
+                        CoreUtil.addBeanToList(res.getBillMsgList(), billMsg);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 七院需求:
+     * 非阻塞性睡眠呼吸暂停综合征和非混合性睡眠呼吸暂停综合征,不宜同时开立呼吸睡眠监测和眼电图(EOG)
+     *
+     * @param
+     * @return
+     */
+    public void smhxjcAndYdteog(WordCrfDTO wordCrfDTO, IndicationDTO res) {
+        // 七院特有
+        if (6 != wordCrfDTO.getHospitalId()) {
+            return;
+        }
+        // 1、比较是否包含2种诊断
+        List<Item> diagAllList = wordCrfDTO.getDiag(); // 结构化诊断
+        List<String> zsxList = Lists.newArrayList();// 阻塞性睡眠呼吸暂停综合征医院名称
+        List<String> hhxList = Lists.newArrayList();// 混合性睡眠呼吸暂停综合征医院名称
+        for (Item item : diagAllList) {
+            if ("阻塞性睡眠呼吸暂停综合征".equals(item.getUniqueName())) {
+                zsxList.add(item.getName());
+            } else if ("混合性睡眠呼吸暂停综合征".equals(item.getUniqueName())) {
+                hhxList.add((item.getName()));
+            }
+        }
+        // 如果两种疾病有其一,就不提示
+        if (ListUtil.isNotEmpty(zsxList) || ListUtil.isNotEmpty(hhxList)) {
+            return;
+        }
+
+        // 2、比较是否包含2种辅检开单项
+        List<Pacs> pacsList = wordCrfDTO.getPacsOrder(); // 辅检开单项
+        List<String> hxsmjcList = Lists.newArrayList();// 呼吸睡眠监测医院名称
+        List<String> ydteogList = Lists.newArrayList();// 眼电图(EOG)医院名称
+        for (Pacs pacs : pacsList) {
+            if ("呼吸睡眠监测".equals(pacs.getUniqueName())) {
+                hxsmjcList.add(pacs.getName());
+            } else if ("眼电图(EOG)".equals(pacs.getUniqueName())) {
+                ydteogList.add(pacs.getName());
+            }
+        }
+        // 辅检开单项必须有两个,否则就不提示
+        if (ListUtil.isEmpty(hxsmjcList) || ListUtil.isEmpty(ydteogList)) {
+            return;
+        }
+
+        // 3、提示语组合
+        List<BillMsg> billMsgList = res.getBillMsgList();
+        for (String hxsm : hxsmjcList) {
+            for (String ydt : ydteogList) {
+                BillMsg billMsg = new BillMsg();
+                billMsg.setType(TypeEnum.pacs.getName());
+                billMsg.setMsg(String.format("非阻塞性睡眠呼吸暂停综合征和非混合性睡眠呼吸暂停综合征患者,不宜同时开立%s和%s",
+                        hxsm, ydt));
+                billMsgList.add(billMsg);
+            }
+        }
+    }
+
+}

+ 11 - 23
src/main/java/com/diagbot/util/RedisUtil.java

@@ -67,10 +67,10 @@ public class RedisUtil {
      * 根据指定key设置obj
      *
      * @param key
-     * @param obj
+     * @param t
      */
-    public void set(String key, Object obj) {
-        redisTemplate.opsForValue().set(key, obj);
+    public <T> void set(String key, T t) {
+        redisTemplate.opsForValue().set(key, t);
     }
 
     /**
@@ -89,7 +89,7 @@ public class RedisUtil {
      * @param map
      * @return
      */
-    public void multiSet(Map<String, Object> map) {
+    public <T> void multiSet(Map<String, T> map) {
         redisTemplate.opsForValue().multiSet(map);
     }
 
@@ -262,40 +262,28 @@ public class RedisUtil {
         return redisTemplate.renameIfAbsent(oldKey, newKey);
     }
 
-    /** -------------------string相关操作--------------------- */
-
-    /**
-     * 设置指定 key 的值
-     *
-     * @param key
-     * @param value
-     */
-    public void set(String key, String value) {
-        redisTemplate.opsForValue().set(key, value);
-    }
-
     /**
      * 将值 value 关联到 key ,并将 key 的过期时间设为 timeout
      *
      * @param key
-     * @param value
+     * @param t
      * @param timeout 过期时间
      * @param unit    时间单位, 天:TimeUnit.DAYS 小时:TimeUnit.HOURS 分钟:TimeUnit.MINUTES
      *                秒:TimeUnit.SECONDS 毫秒:TimeUnit.MILLISECONDS
      */
-    public void setEx(String key, String value, long timeout, TimeUnit unit) {
-        redisTemplate.opsForValue().set(key, value, timeout, unit);
+    public <T> void setEx(String key, T t, long timeout, TimeUnit unit) {
+        redisTemplate.opsForValue().set(key, t, timeout, unit);
     }
 
     /**
      * 只有在 key 不存在时设置 key 的值
      *
      * @param key
-     * @param value
+     * @param t
      * @return 之前已经存在返回false, 不存在返回true
      */
-    public boolean setIfAbsent(String key, String value) {
-        return redisTemplate.opsForValue().setIfAbsent(key, value);
+    public <T> boolean setIfAbsent(String key, T t) {
+        return redisTemplate.opsForValue().setIfAbsent(key, t);
     }
 
     /**
@@ -304,7 +292,7 @@ public class RedisUtil {
      * @param key
      * @param map
      */
-    public void putHashMap(String key, Map<String, Object> map) {
+    public <T> void putHashMap(String key, Map<String, T> map) {
         if (MapUtils.isNotEmpty(map)) {
             redisTemplate.opsForHash().putAll(key, map);
         }