Przeglądaj źródła

事后规则匹配优化

0027005599 1 rok temu
rodzic
commit
0c577561c5

+ 5 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/medical/SystemEventAttrConstant.java

@@ -123,6 +123,11 @@ public class SystemEventAttrConstant {
      */
     public static final String MEDICAL_INS_MEDICALDIAGNOSECODE = "medical_ins_medicalDiagnoseCode";
 
+
+    public static final String MEDICAL_INS_RULE_PROJECT_ID = "medical_ins_id";
+
+    public static final String ITEMMAP_AFTER_INCIDENT_DETAIL_LOG_ID = "id";
+
     /**
      * 事前工单idkey
      */

+ 3 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/medical/entity/AfterwardsAuditDetail.java

@@ -163,6 +163,9 @@ public class AfterwardsAuditDetail implements Serializable {
     @ApiModelProperty(value = "更新时间")
     private java.util.Date updateTime;
 
+    private java.lang.Integer medicalRuleProjectId;
+
+    private java.lang.Integer afterIncidentDetailLogId;
     @TableField(exist = false)
     private String startTime;
     @TableField(exist = false)

+ 13 - 29
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/medical/job/AfterWaringJob.java

@@ -8,19 +8,26 @@ import org.jeecg.modules.medical.Constant;
 import org.jeecg.modules.medical.entity.AfterIncidentDetailLog;
 import org.jeecg.modules.medical.entity.AfterIncidentLog;
 import org.jeecg.modules.medical.entity.AfterwardsAudit;
+import org.jeecg.modules.medical.ruleengine.AfterDealTask;
 import org.jeecg.modules.medical.ruleengine.RuleEngine;
 import org.jeecg.modules.medical.service.IAfterIncidentDetailLogService;
 import org.jeecg.modules.medical.service.IAfterIncidentLogService;
+import org.jeecg.modules.medical.threadpool.AfterRunRuleEngineCallable;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Component;
 
+import javax.annotation.Resource;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
 
 /**
  * 事后触发监管
@@ -28,24 +35,22 @@ import java.util.Map;
 @Component
 @Slf4j
 public class AfterWaringJob {
+
     @Autowired
-    IAfterIncidentLogService afterIncidentLogService;
-    @Autowired
-    IAfterIncidentDetailLogService afterIncidentDetailLogService;
+    AfterDealTask afterDealTask;
     @Autowired
-    RuleEngine ruleEngine;
+    IAfterIncidentLogService afterIncidentLogService;
 
     //    @Override
     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
         QueryWrapper<AfterIncidentLog> queryWrapper = new QueryWrapper();
         queryWrapper.eq("state", Constant.WATING);
-
         queryWrapper.last(" limit 1000");
         List<AfterIncidentLog> afterIncidentLogList = afterIncidentLogService.list(queryWrapper);
         if (CollectionUtil.isNotEmpty(afterIncidentLogList)) {
             for (AfterIncidentLog afterIncidentLog : afterIncidentLogList) {
                 log.info("开始处理 afterIncidentLog:{} 记录", afterIncidentLog);
-                dealAftertask(afterIncidentLog);
+                afterDealTask.dealAftertask(afterIncidentLog);
             }
         } else {
             log.error("没有待处理的事后工单记录");
@@ -54,27 +59,6 @@ public class AfterWaringJob {
     }
 
 
-    @Async("commonTaskAsyncPool")
-    public void dealAftertask(AfterIncidentLog afterIncidentLog) {
-        AfterwardsAudit afterwardsAudit = ruleEngine.insertAfterWarning(afterIncidentLog);
-        afterIncidentLogService.lambdaUpdate().set(AfterIncidentLog::getState, Constant.DEALING).eq(AfterIncidentLog::getId, afterIncidentLog.getId()).update();
-        List<AfterIncidentDetailLog> afterIncidentDetailLogList = afterIncidentDetailLogService.lambdaQuery().eq(AfterIncidentDetailLog::getAfterIncidentLogId, afterIncidentLog.getId()).list();
-        if(CollectionUtil.isEmpty(afterIncidentDetailLogList)){
-            String desc = "住院结算主单 未查询到对应的住院明细记录";
-            log.error("住院结算主单 afterIncidentLog.id :{} 未查询到对应的住院明细记录", afterIncidentLog.getId());
-            afterIncidentLogService.lambdaUpdate().set(AfterIncidentLog::getState, Constant.FAIL).set(AfterIncidentLog::getDescription, desc)
-                    .set(AfterIncidentLog::getStateTime, new Date()).eq(AfterIncidentLog::getId, afterIncidentLog.getId()).update();
-            return;
-        }
-        String jsonStr = JSON.toJSONString(afterIncidentDetailLogList);
-        List<Map> itemList = JSON.parseArray(jsonStr, Map.class);
-        List<Map<String, Object>> realItemList = new ArrayList<>();
-        for (Map itemMap : itemList) {
-            realItemList.add(itemMap);
-        }
-        for (AfterIncidentDetailLog afterIncidentDetailLog : afterIncidentDetailLogList) {
-            ruleEngine.dealAfterInterfaceEngin(afterwardsAudit, afterIncidentDetailLog, realItemList);
-        }
-        afterIncidentLogService.lambdaUpdate().set(AfterIncidentLog::getState, Constant.SUCCESS).eq(AfterIncidentLog::getId, afterIncidentLog.getId()).update();
-    }
+
+
 }

+ 83 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/medical/ruleengine/AfterDealTask.java

@@ -0,0 +1,83 @@
+package org.jeecg.modules.medical.ruleengine;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.modules.medical.Constant;
+import org.jeecg.modules.medical.entity.AfterIncidentDetailLog;
+import org.jeecg.modules.medical.entity.AfterIncidentLog;
+import org.jeecg.modules.medical.entity.AfterwardsAudit;
+import org.jeecg.modules.medical.service.IAfterIncidentDetailLogService;
+import org.jeecg.modules.medical.service.IAfterIncidentLogService;
+import org.jeecg.modules.medical.threadpool.AfterRunRuleEngineCallable;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+@Component
+@Slf4j
+public class AfterDealTask {
+    @Autowired
+    IAfterIncidentLogService afterIncidentLogService;
+    @Autowired
+    IAfterIncidentDetailLogService afterIncidentDetailLogService;
+    @Autowired
+    RuleEngine ruleEngine;
+    @Resource(name = "commonTaskAsyncPool")
+    ThreadPoolTaskExecutor threadPoolTaskExecutor;
+
+    public void dealAftertask(AfterIncidentLog afterIncidentLog) {
+        AfterwardsAudit afterwardsAudit = ruleEngine.insertAfterWarning(afterIncidentLog);
+        afterIncidentLogService.lambdaUpdate().set(AfterIncidentLog::getState, Constant.DEALING).eq(AfterIncidentLog::getId, afterIncidentLog.getId()).update();
+        List<AfterIncidentDetailLog> afterIncidentDetailLogList = afterIncidentDetailLogService.lambdaQuery().eq(AfterIncidentDetailLog::getAfterIncidentLogId, afterIncidentLog.getId()).list();
+        if (CollectionUtil.isEmpty(afterIncidentDetailLogList)) {
+            String desc = "住院结算主单 未查询到对应的住院明细记录";
+            log.error("住院结算主单 afterIncidentLog.id :{} 未查询到对应的住院明细记录", afterIncidentLog.getId());
+            afterIncidentLogService.lambdaUpdate().set(AfterIncidentLog::getState, Constant.FAIL).set(AfterIncidentLog::getDescription, desc)
+                    .set(AfterIncidentLog::getStateTime, new Date()).eq(AfterIncidentLog::getId, afterIncidentLog.getId()).update();
+            return;
+        }
+        String jsonStr = JSON.toJSONString(afterIncidentDetailLogList);
+        List<Map> itemList = JSON.parseArray(jsonStr, Map.class);
+        List<Map<String, Object>> realItemList = new ArrayList<>();
+        for (Map itemMap : itemList) {
+            realItemList.add(itemMap);
+        }
+        String state = Constant.SUCCESS;
+        String errorMsg = null;
+        List<Future> futureList = new ArrayList<>();
+        try {
+            AfterRunRuleEngineCallable afterCallable = null;
+
+            for (AfterIncidentDetailLog afterIncidentDetailLog : afterIncidentDetailLogList) {
+                afterCallable = new AfterRunRuleEngineCallable(afterwardsAudit, afterIncidentDetailLog, realItemList);
+                Future future = threadPoolTaskExecutor.submit(afterCallable);
+                futureList.add(future);
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            state = Constant.FAIL;
+            errorMsg = e.getMessage();
+        }
+
+        for (Future future : futureList) {
+            try {
+                future.get();
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+        log.info("更新主单记录状态和描述,主单id:{}", afterIncidentLog.getId());
+        afterIncidentLogService.lambdaUpdate().set(AfterIncidentLog::getState, state)
+                .set(AfterIncidentLog::getDescription, errorMsg)
+                .eq(AfterIncidentLog::getId, afterIncidentLog.getId()).update();
+    }
+}

+ 7 - 4
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/medical/ruleengine/FactorEnchangeFactory.java

@@ -112,14 +112,13 @@ public class FactorEnchangeFactory {
         }
     }
 
-    public boolean runFactorEnchange(Integer medicalInfoRuleInfoId, MedicalInsRuleInfo medicalInsRuleInfo, Object audit, Map<String, Object> localMap, List<RuleFactorRela> ruleFactorRelaList, List<FactorEnchance> factorEnchanceList, List<Map<String, Object>> itemList) {
+    public boolean runFactorEnchange(Integer medicalInfoRuleInfoId, MedicalInsRuleInfo medicalInsRuleInfo, Object audit, Map<String, Object> localMap, List<RuleFactorRela> ruleFactorRelaList, List<FactorEnchance> factorEnchanceList, List<Map<String, Object>> itemList) throws Exception {
         if(CollectionUtil.isEmpty(factorEnchanceList)) {
             log.error("工单记录:{} 匹配到的规则ID:{} 未配置处理流程-请到规则配置管理页面配置医保规则对应处理流程", audit, medicalInfoRuleInfoId);
             return false;
         }
         Map<Integer, FactorEnchance> factorEnchanceMap = factorEnchanceList.stream().collect(Collectors.toMap(FactorEnchance::getId, v -> v, (v1, v2) -> v1));
         boolean result = false;
-        log.info("表达式执行执行map:{}", JSON.toJSONString(localMap));
         for (RuleFactorRela ruleFactorRela : ruleFactorRelaList) {
             Integer factorEnchanceId = ruleFactorRela.getFactorEnhanceId();
             FactorEnchance factorEnchance = factorEnchanceMap.get(factorEnchanceId);
@@ -268,6 +267,8 @@ public class FactorEnchangeFactory {
                 afterwardsAuditDetail.setCreateBy("auto");
                 afterwardsAuditDetail.setQuantity(otherMap.get(SystemEventAttrConstant.QUANTITY) != null ? Integer.parseInt(otherMap.get(SystemEventAttrConstant.QUANTITY).toString()) : 1);
                 afterwardsAuditDetail.setMedicalInsuranceMark(otherMap.get(Constant.MEDICAL_INSURANCE_MARK_KEY) != null ? otherMap.get(Constant.MEDICAL_INSURANCE_MARK_KEY).toString() : "0");
+                afterwardsAuditDetail.setAfterIncidentDetailLogId((Integer)itemMap.get(SystemEventAttrConstant.ITEMMAP_AFTER_INCIDENT_DETAIL_LOG_ID));
+                afterwardsAuditDetail.setMedicalInsRuleInfoId((Integer)itemMap.get(SystemEventAttrConstant.MEDICAL_INS_RULE_PROJECT_ID));
                 afterwardsAuditDetailList.add(afterwardsAuditDetail);
 
             }
@@ -300,13 +301,15 @@ public class FactorEnchangeFactory {
             afterwardsAuditDetail.setPrescriptionNumber(afterwardsAudit.getPrescriptionNumber());
 //            afterwardsAuditDetail.setReminderLevel();
             afterwardsAuditDetail.setCreateBy("auto");
+
             afterwardsAuditDetail.setQuantity(itemMap.get(SystemEventAttrConstant.QUANTITY) != null ? Integer.parseInt(itemMap.get(SystemEventAttrConstant.QUANTITY).toString()) : 1);
             afterwardsAuditDetail.setViolationLevel(medicalInsRuleInfo.getViolationLevel());
             afterwardsAuditDetail.setTreatmentType(medicalInsRuleInfo.getTreatmentType());
             afterwardsAuditDetail.setAfterwardsAuditId(afterwardsAudit.getId());
             afterwardsAuditDetail.setMedicalInsuranceMark(itemMap.get(Constant.MEDICAL_INSURANCE_MARK_KEY) != null ? itemMap.get(Constant.MEDICAL_INSURANCE_MARK_KEY).toString() : "0");
             afterwardsAuditDetail.setPrice(itemMap.get(SystemEventAttrConstant.PRICE) != null ? new BigDecimal(itemMap.get(SystemEventAttrConstant.PRICE).toString()) : null);
-
+            afterwardsAuditDetail.setMedicalRuleProjectId((Integer)itemMap.get(SystemEventAttrConstant.MEDICAL_INS_RULE_PROJECT_ID));
+            afterwardsAuditDetail.setAfterIncidentDetailLogId((Integer)itemMap.get(SystemEventAttrConstant.ITEMMAP_AFTER_INCIDENT_DETAIL_LOG_ID));
             afterwardsAuditService.lambdaUpdate().setSql("amount = amount +" + amount.doubleValue()).eq(AfterwardsAudit::getId, afterwardsAudit.getId()).update();
             afterwardsAuditDetailService.save(afterwardsAuditDetail);
         }
@@ -428,7 +431,7 @@ public class FactorEnchangeFactory {
      * @param localMap
      * @param factorEnchance
      */
-    public boolean setLogicalExpressionResultByFactorEnchance(Map<String, Object> localMap, FactorEnchance factorEnchance) {
+    public boolean setLogicalExpressionResultByFactorEnchance(Map<String, Object> localMap, FactorEnchance factorEnchance) throws Exception {
         if (StringUtils.isNotBlank(factorEnchance.getEnhanceValue())) {
             Boolean resultTemp = (Boolean) spelUtil.runSpelExpression(localMap, factorEnchance.getEnhanceValue());
             return resultTemp;

+ 204 - 91
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/medical/ruleengine/RuleEngine.java

@@ -64,6 +64,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat
 import org.springframework.context.annotation.Conditional;
 import org.springframework.context.annotation.Profile;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.PostConstruct;
@@ -517,7 +518,6 @@ public class RuleEngine {
         return Result.ok();
     }
 
-
     public Result dealMidInterfaceEngin(String intefName, MidIncidentWarningVO midIncidentWarningVO, String ipStr) {
         midIncidentWarningVOThreadLocal.set(midIncidentWarningVO);
         JSONObject sendJson = new JSONObject();
@@ -534,27 +534,76 @@ public class RuleEngine {
             MidIncidentAudit midIncidentAudit = insertMidWarning(midIncidentWarningVO);
             insertLog(midIncidentWarningVO);
             midIncidentAudit.setInterfName(intefName);
-            Set<String> auditDetailSet = new HashSet<>();
+
             boolean sendFlag = false;
             for (Map<String, Object> itemMap : itemList) {
                 Set<Integer> medicalInsRuleInfoIdList = itemCodeAndRuleIdMap.get(itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
+                List<MedicalInsRuleProject> medicalInsRuleProjectList = null;
                 if (CollectionUtil.isEmpty(medicalInsRuleInfoIdList)) {
-                    log.error("项目编码未匹配到对应的医保规则:{}", itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
-                    continue;
+                    log.error("项目编码未匹配到对应的医保规则:{} 再次从数据库检索", itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
+                    medicalInsRuleProjectList = medicalInsRuleProjectService.getRuleProjectByMedicalProjectCode(itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY).toString());
+                    if(CollectionUtil.isEmpty(medicalInsRuleProjectList)){
+                        log.error("项目编码未匹配到对应的医保规则:{} 在规则库数据库中未检索到数据", itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
+                    }else {
+                        medicalInsRuleInfoIdList = medicalInsRuleProjectList.stream().map(MedicalInsRuleProject::getMedicalInsRuleInfoId).collect(Collectors.toSet());
+                        log.info("数据库检索到匹配规则ID列表:{}", medicalInsRuleInfoIdList);
+                    }
+                }else{
+                    medicalInsRuleProjectList = medicalInsRuleProjectService.getRuleProjectByRuleIdAndProjectCode(new ArrayList<>(medicalInsRuleInfoIdList), itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY).toString());
                 }
+
                 Object diagnose = itemMap.get(Constant.MEDICAL_DIAGNOSE_CODE_KEY);
                 if (null != diagnose) {
-                    List<Object> diagnoseList = (List<Object>) diagnose;
                     //获取诊断编码配置的规则ID,加入需要执行的规则
-                    for (Object diagnoseObject : diagnoseList) {
-                        Set<Integer> diagnoseMedicalInsRuleInfoIdList = itemCodeAndRuleIdMap.get(diagnoseObject.toString());
-                        if (CollectionUtil.isNotEmpty(diagnoseMedicalInsRuleInfoIdList)) {
-                            medicalInsRuleInfoIdList.addAll(diagnoseMedicalInsRuleInfoIdList);
+                    Set<Integer> diagnoseMedicalInsRuleInfoIdList = itemCodeAndRuleIdMap.get(diagnose.toString());
+                    List<MedicalInsRuleProject> medicalInsRuleProjectTempList = null;
+                    if (CollectionUtil.isEmpty(diagnoseMedicalInsRuleInfoIdList)) {
+                        medicalInsRuleProjectTempList = medicalInsRuleProjectService.getRuleProjectByDiagCode(diagnose.toString());
+                        if(CollectionUtil.isEmpty(medicalInsRuleProjectTempList)){
+                            log.info("诊断编码未匹配到对应的医保规则:{} 在规则库数据库中未检索到数据", diagnose);
+                        }
+                        Set<Integer> medicalInsRuleInfoIdDiagSet = medicalInsRuleProjectTempList.stream().map(MedicalInsRuleProject::getMedicalInsRuleInfoId).collect(Collectors.toSet());
+                        log.info("数据库检索到匹配规则ID列表:{} 诊断编码为:{}", medicalInsRuleInfoIdDiagSet, diagnose);
+                    }else{
+                        medicalInsRuleProjectTempList = medicalInsRuleProjectService.getRuleProjectByRuleIdAndDiagCode(new ArrayList<>(diagnoseMedicalInsRuleInfoIdList), diagnose.toString());
+                    }
+                    if(CollectionUtil.isNotEmpty(medicalInsRuleProjectTempList)){
+                        if(CollectionUtil.isEmpty(medicalInsRuleProjectList)){
+                            medicalInsRuleProjectList = new ArrayList<>();
+                        }
+                        for(MedicalInsRuleProject medicalInsRuleProject : medicalInsRuleProjectTempList){
+                            MedicalInsRuleInfo projectRuleInfo = allMedicalMap.get(medicalInsRuleProject.getMedicalInsRuleInfoId());
+                            String selectedRoles = projectRuleInfo.getSelectedRoles();
+                            if (StringUtils.isNotBlank(selectedRoles)) {
+                                String[] selectedRolesArr = selectedRoles.split(",");
+                                boolean diagnoseFlag = Arrays.stream(selectedRolesArr).anyMatch(attr -> attr.equals("medicalDiagnoseCode"));
+                                if(diagnoseFlag){
+                                    medicalInsRuleProjectList.add(medicalInsRuleProject);
+                                }
+                            }
                         }
                     }
                 }
+                if(CollectionUtil.isEmpty(medicalInsRuleProjectList)){
+                    log.error("项目编码未匹配到对应的医保规则:{} 在规则库数据库中未检索到数据,退出规则执行", itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
+                    continue;
+                }
+                Map<Integer,List<MedicalInsRuleProject>> ruleAndProjectMap = medicalInsRuleProjectList.stream().collect(Collectors.groupingBy(MedicalInsRuleProject::getMedicalInsRuleInfoId));
                 paramMap.put(SystemEventAttrConstant.ADVICE_DETAILS_LIST_KEY, itemList);
-                sendFlag = runMidEngine(auditDetailSet, itemMap, medicalInsRuleInfoIdList, midIncidentAudit, itemList);
+                for(Integer medicalInsRuleInfoId : ruleAndProjectMap.keySet()){
+                    List<String> medicalInsCorrProjectCodeList = ruleAndProjectMap.get(medicalInsRuleInfoId).stream().map(MedicalInsRuleProject::getCorrelationProjectCode).collect(Collectors.toList());
+                    MedicalInsRuleProject medicalInsRuleProject = ruleAndProjectMap.get(medicalInsRuleInfoId).get(0);
+                    setProjectToLocalMap(itemMap, medicalInsRuleProject);
+                    itemMap.put(SystemEventAttrConstant.MEDICAL_INS_CORRELATIONMEDICALDIAGNOSECODE, medicalInsCorrProjectCodeList);
+                    setItemCodeListToItemMap(itemList, itemMap);
+                    boolean sendFlagTemp = false;
+                    try {
+                        sendFlagTemp = runMidEngine(itemMap, medicalInsRuleInfoId, midIncidentAudit, itemList);
+                    }catch (Exception e){
+                        log.error(e.getMessage(), e);
+                    }
+                    sendFlag = sendFlagTemp || sendFlag;
+                }
             }
             sendJson.put("id", midIncidentAudit.getId());
             sendJson.put("violationFlag", sendFlag);
@@ -586,27 +635,75 @@ public class RuleEngine {
             MidIncidentAudit midIncidentAudit = insertMidWarning(midIncidentWarningVO);
             insertLog(midIncidentWarningVO);
             midIncidentAudit.setInterfName(intefName);
-            Set<String> auditDetailSet = new HashSet<>();
+
             boolean sendFlag = false;
             for (Map<String, Object> itemMap : itemList) {
                 Set<Integer> medicalInsRuleInfoIdList = itemCodeAndRuleIdMap.get(itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
+                List<MedicalInsRuleProject> medicalInsRuleProjectList = null;
                 if (CollectionUtil.isEmpty(medicalInsRuleInfoIdList)) {
-                    log.error("项目编码未匹配到对应的医保规则:{}", itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
-                    continue;
+                    log.error("项目编码未匹配到对应的医保规则:{} 再次从数据库检索", itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
+                    medicalInsRuleProjectList = medicalInsRuleProjectService.getRuleProjectByMedicalProjectCode(itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY).toString());
+                    if(CollectionUtil.isEmpty(medicalInsRuleProjectList)){
+                        log.error("项目编码未匹配到对应的医保规则:{} 在规则库数据库中未检索到数据", itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
+                    }else {
+                        medicalInsRuleInfoIdList = medicalInsRuleProjectList.stream().map(MedicalInsRuleProject::getMedicalInsRuleInfoId).collect(Collectors.toSet());
+                        log.info("数据库检索到匹配规则ID列表:{}", medicalInsRuleInfoIdList);
+                    }
+                }else{
+                    medicalInsRuleProjectList = medicalInsRuleProjectService.getRuleProjectByRuleIdAndProjectCode(new ArrayList<>(medicalInsRuleInfoIdList), itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY).toString());
                 }
                 Object diagnose = itemMap.get(Constant.MEDICAL_DIAGNOSE_CODE_KEY);
                 if (null != diagnose) {
-                    List<Object> diagnoseList = (List<Object>) diagnose;
                     //获取诊断编码配置的规则ID,加入需要执行的规则
-                    for (Object diagnoseObject : diagnoseList) {
-                        Set<Integer> diagnoseMedicalInsRuleInfoIdList = itemCodeAndRuleIdMap.get(diagnoseObject.toString());
-                        if (CollectionUtil.isNotEmpty(diagnoseMedicalInsRuleInfoIdList)) {
-                            medicalInsRuleInfoIdList.addAll(diagnoseMedicalInsRuleInfoIdList);
+                    Set<Integer> diagnoseMedicalInsRuleInfoIdList = itemCodeAndRuleIdMap.get(diagnose.toString());
+                    List<MedicalInsRuleProject> medicalInsRuleProjectTempList = null;
+                    if (CollectionUtil.isEmpty(diagnoseMedicalInsRuleInfoIdList)) {
+                        medicalInsRuleProjectTempList = medicalInsRuleProjectService.getRuleProjectByDiagCode(diagnose.toString());
+                        if(CollectionUtil.isEmpty(medicalInsRuleProjectTempList)){
+                            log.info("诊断编码未匹配到对应的医保规则:{} 在规则库数据库中未检索到数据,退出规则执行", diagnose);
+                        }
+                        Set<Integer> medicalInsRuleInfoIdDiagSet = medicalInsRuleProjectTempList.stream().map(MedicalInsRuleProject::getMedicalInsRuleInfoId).collect(Collectors.toSet());
+                        log.info("数据库检索到匹配规则ID列表:{} 诊断编码为:{}", medicalInsRuleInfoIdDiagSet, diagnose);
+                    }else{
+                        medicalInsRuleProjectTempList = medicalInsRuleProjectService.getRuleProjectByRuleIdAndDiagCode(new ArrayList<>(diagnoseMedicalInsRuleInfoIdList), diagnose.toString());
+                    }
+                    if(CollectionUtil.isNotEmpty(medicalInsRuleProjectTempList)){
+                        if(CollectionUtil.isEmpty(medicalInsRuleProjectList)){
+                            medicalInsRuleProjectList = new ArrayList<>();
+                        }
+                        for(MedicalInsRuleProject medicalInsRuleProject : medicalInsRuleProjectTempList){
+                            MedicalInsRuleInfo projectRuleInfo = allMedicalMap.get(medicalInsRuleProject.getMedicalInsRuleInfoId());
+                            String selectedRoles = projectRuleInfo.getSelectedRoles();
+                            if (StringUtils.isNotBlank(selectedRoles)) {
+                                String[] selectedRolesArr = selectedRoles.split(",");
+                                boolean diagnoseFlag = Arrays.stream(selectedRolesArr).anyMatch(attr -> attr.equals("medicalDiagnoseCode"));
+                                if(diagnoseFlag){
+                                    medicalInsRuleProjectList.add(medicalInsRuleProject);
+                                }
+                            }
                         }
                     }
                 }
+                if(CollectionUtil.isEmpty(medicalInsRuleProjectList)){
+                    log.error("项目编码未匹配到对应的医保规则:{} 在规则库数据库中未检索到数据,退出规则执行", itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
+                    continue;
+                }
+                Map<Integer,List<MedicalInsRuleProject>> ruleAndProjectMap = medicalInsRuleProjectList.stream().collect(Collectors.groupingBy(MedicalInsRuleProject::getMedicalInsRuleInfoId));
                 paramMap.put(SystemEventAttrConstant.ADVICE_DETAILS_LIST_KEY, itemList);
-                sendFlag = runMidEngine(auditDetailSet, itemMap, medicalInsRuleInfoIdList, midIncidentAudit, itemList);
+                for(Integer medicalInsRuleInfoId : ruleAndProjectMap.keySet()){
+                    List<String> medicalInsCorrProjectCodeList = ruleAndProjectMap.get(medicalInsRuleInfoId).stream().map(MedicalInsRuleProject::getCorrelationProjectCode).collect(Collectors.toList());
+                    MedicalInsRuleProject medicalInsRuleProject = ruleAndProjectMap.get(medicalInsRuleInfoId).get(0);
+                    setProjectToLocalMap(itemMap, medicalInsRuleProject);
+                    itemMap.put(SystemEventAttrConstant.MEDICAL_INS_CORRELATIONMEDICALDIAGNOSECODE, medicalInsCorrProjectCodeList);
+                    setItemCodeListToItemMap(itemList, itemMap);
+                    boolean sendFlagTemp = false;
+                    try {
+                        sendFlagTemp = runMidEngine(itemMap, medicalInsRuleInfoId, midIncidentAudit, itemList);
+                    }catch (Exception e){
+                        log.error(e.getMessage(), e);
+                    }
+                    sendFlag = sendFlagTemp || sendFlag;
+                }
             }
 
             if (sendFlag) {
@@ -634,25 +731,22 @@ public class RuleEngine {
      * @param afterIncidentDetailLog
      */
     public void dealAfterInterfaceEngin(AfterwardsAudit afterwardsAudit, AfterIncidentDetailLog afterIncidentDetailLog, List<Map<String, Object>> itemList) {
-
         try {
             dictUtil.transferAfterIncidentWarning(afterIncidentDetailLog);
             String jsonStr = JSON.toJSONString(afterIncidentDetailLog);
             log.info("事后处理日志:{}", jsonStr);
             JSONObject itemMap = JSON.parseObject(jsonStr);
-
-            Set<String> auditDetailSet = new HashSet<>();
             Set<Integer> medicalInsRuleInfoIdList = itemCodeAndRuleIdMap.get(itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
             List<MedicalInsRuleProject> medicalInsRuleProjectList = null;
             if (CollectionUtil.isEmpty(medicalInsRuleInfoIdList)) {
                 log.error("项目编码未匹配到对应的医保规则:{} 再次从数据库检索", itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
                 medicalInsRuleProjectList = medicalInsRuleProjectService.getRuleProjectByMedicalProjectCode(itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY).toString());
                 if(CollectionUtil.isEmpty(medicalInsRuleProjectList)){
-                    log.error("项目编码未匹配到对应的医保规则:{} 在规则库数据库中未检索到数据,退出规则执行", itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
-                    return;
+                    log.error("项目编码未匹配到对应的医保规则:{} 在规则库数据库中未检索到数据", itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
+                }else {
+                    medicalInsRuleInfoIdList = medicalInsRuleProjectList.stream().map(MedicalInsRuleProject::getMedicalInsRuleInfoId).collect(Collectors.toSet());
+                    log.info("数据库检索到匹配规则ID列表:{}", medicalInsRuleInfoIdList);
                 }
-                medicalInsRuleInfoIdList = medicalInsRuleProjectList.stream().map(MedicalInsRuleProject::getMedicalInsRuleInfoId).collect(Collectors.toSet());
-                log.info("数据库检索到匹配规则ID列表:{}", medicalInsRuleInfoIdList);
             }else{
                 medicalInsRuleProjectList = medicalInsRuleProjectService.getRuleProjectByRuleIdAndProjectCode(new ArrayList<>(medicalInsRuleInfoIdList), itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY).toString());
             }
@@ -661,31 +755,46 @@ public class RuleEngine {
                 //获取诊断编码配置的规则ID,加入需要执行的规则
                 Set<Integer> diagnoseMedicalInsRuleInfoIdList = itemCodeAndRuleIdMap.get(diagnose.toString());
                 List<MedicalInsRuleProject> medicalInsRuleProjectTempList = null;
-                if (CollectionUtil.isNotEmpty(diagnoseMedicalInsRuleInfoIdList)) {
+                if (CollectionUtil.isEmpty(diagnoseMedicalInsRuleInfoIdList)) {
                     medicalInsRuleProjectTempList = medicalInsRuleProjectService.getRuleProjectByDiagCode(diagnose.toString());
                     if(CollectionUtil.isEmpty(medicalInsRuleProjectTempList)){
                         log.info("诊断编码未匹配到对应的医保规则:{} 在规则库数据库中未检索到数据,退出规则执行", diagnose);
                     }
-                    Set<Integer> medicalInsRuleInfoIdDiagSet = medicalInsRuleProjectList.stream().map(MedicalInsRuleProject::getMedicalInsRuleInfoId).collect(Collectors.toSet());
+                    Set<Integer> medicalInsRuleInfoIdDiagSet = medicalInsRuleProjectTempList.stream().map(MedicalInsRuleProject::getMedicalInsRuleInfoId).collect(Collectors.toSet());
                     log.info("数据库检索到匹配规则ID列表:{} 诊断编码为:{}", medicalInsRuleInfoIdDiagSet, diagnose);
                 }else{
-                    medicalInsRuleProjectTempList = medicalInsRuleProjectService.getRuleProjectByRuleIdAndDiagCode(new ArrayList<>(medicalInsRuleInfoIdList), diagnose.toString());
+                    medicalInsRuleProjectTempList = medicalInsRuleProjectService.getRuleProjectByRuleIdAndDiagCode(new ArrayList<>(diagnoseMedicalInsRuleInfoIdList), diagnose.toString());
                 }
                 if(CollectionUtil.isNotEmpty(medicalInsRuleProjectTempList)){
-                    if(CollectionUtil.isNotEmpty(medicalInsRuleProjectList)){
-                        medicalInsRuleProjectList.addAll(medicalInsRuleProjectTempList);
-                    }else {
-                        medicalInsRuleProjectList = medicalInsRuleProjectTempList;
+                    if(CollectionUtil.isEmpty(medicalInsRuleProjectList)){
+                        medicalInsRuleProjectList = new ArrayList<>();
+                    }
+                    for(MedicalInsRuleProject medicalInsRuleProject : medicalInsRuleProjectTempList){
+                        MedicalInsRuleInfo projectRuleInfo = allMedicalMap.get(medicalInsRuleProject.getMedicalInsRuleInfoId());
+                        String selectedRoles = projectRuleInfo.getSelectedRoles();
+                        if (StringUtils.isNotBlank(selectedRoles)) {
+                            String[] selectedRolesArr = selectedRoles.split(",");
+                            boolean diagnoseFlag = Arrays.stream(selectedRolesArr).anyMatch(attr -> attr.equals("medicalDiagnoseCode"));
+                            if(diagnoseFlag){
+                                medicalInsRuleProjectList.add(medicalInsRuleProject);
+                            }
+                        }
                     }
                 }
             }
             if(CollectionUtil.isEmpty(medicalInsRuleProjectList)){
-                log.error("医保规则对象被误删,请联系管理员");
+                log.error("项目编码未匹配到对应的医保规则:{} 在规则库数据库中未检索到数据,退出执行规则", itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
                 return;
             }
-            for(MedicalInsRuleProject medicalInsRuleProject : medicalInsRuleProjectList) {
+            Map<Integer,List<MedicalInsRuleProject>> ruleAndProjectMap = medicalInsRuleProjectList.stream().collect(Collectors.groupingBy(MedicalInsRuleProject::getMedicalInsRuleInfoId));
+            log.info("明细记录ID:{} 匹配到规则:{}", afterIncidentDetailLog.getId(), ruleAndProjectMap.keySet());
+            for(Integer medicalInsRuleInfoId : ruleAndProjectMap.keySet()){
+                List<String> medicalInsCorrProjectCodeList = ruleAndProjectMap.get(medicalInsRuleInfoId).stream().map(MedicalInsRuleProject::getCorrelationProjectCode).collect(Collectors.toList());
+                MedicalInsRuleProject medicalInsRuleProject = ruleAndProjectMap.get(medicalInsRuleInfoId).get(0);
                 setProjectToLocalMap(itemMap, medicalInsRuleProject);
-                runAfterEngine(itemMap, medicalInsRuleProject.getMedicalInsRuleInfoId(), afterwardsAudit, itemList);
+                itemMap.put(SystemEventAttrConstant.MEDICAL_INS_CORRELATIONMEDICALDIAGNOSECODE, medicalInsCorrProjectCodeList);
+                setItemCodeListToItemMap(itemList, itemMap);
+                runAfterEngine(itemMap, medicalInsRuleInfoId, afterwardsAudit, itemList);
             }
 
         } catch (Exception e) {
@@ -694,6 +803,21 @@ public class RuleEngine {
 
     }
 
+    /**
+     * 把当前明细记录的主单下的所有项目编码设置到当前项目记录
+     */
+    public void setItemCodeListToItemMap(List<Map<String,Object>> itemList, Map<String,Object> itemMap){
+        List<String> medicalProjectCodeList = new ArrayList<>();
+        for(Map<String,Object> itemTempMap : itemList){
+            Object medicalProjectCode = itemTempMap.get(SystemEventAttrConstant.MEDICAL_PROJECT_CODE_KEY);
+            if(null != medicalProjectCode){
+                medicalProjectCodeList.add(medicalProjectCode.toString());
+            }
+        }
+        itemMap.put(SystemEventAttrConstant.MEDICAL_PROJECT_CODE_LSIT, medicalProjectCodeList);
+    }
+
+
     /**
      *
      * @param itemMap
@@ -904,13 +1028,12 @@ public class RuleEngine {
         afterwardsAuditService.save(afterwardsAudit);
         if (StringUtils.isNotBlank(afterIncidentLog.getDiagnoses())) {
             List<String> diagonseCodeList = Arrays.asList(afterIncidentLog.getDiagnoses().split(","));
-//            List<String> diagonseNameList = Arrays.asList(afterIncidentDetailLog.getDiagnose_desc().split(","));
             List<AfterwardsIncidentAuditDiagnose> afterIncidentAuditDiagnoseList = new ArrayList<>();
             for (int i = 0; i < diagonseCodeList.size(); i++) {
                 String diagonseCode = diagonseCodeList.get(i);
 //                String diagonseName = diagonseNameList.get(i);
 //                Object value = redisTemplate.opsForHash().get(Constant.HIS_MEDICAL_DICT_KEY, afterIncidentDetailLog.getDiagnose_code());
-                String medicalDiagonseCode = dictUtil.getMedicalDiagnoseCode(diagonseCode);
+                String medicalDiagonseCode = dictUtil.getMedicalDiagnoseCode(diagonseCode.trim());
                 String medicalDiagnoseName = dictUtil.getMedicalDiagnoseName(medicalDiagonseCode);
                 AfterwardsIncidentAuditDiagnose afterIncidentAuditDiagnose = new AfterwardsIncidentAuditDiagnose();
                 afterIncidentAuditDiagnose.setAfterwardsAuditId(afterwardsAudit.getId());
@@ -953,12 +1076,16 @@ public class RuleEngine {
             List<FactorEnchance> factorEnchanceList = factorEnchanceService.listByIds(factorEnchangeIdList);
             Map<Integer, List<FactorEnchance>> enchanceTypeMap = factorEnchanceList.stream().collect(Collectors.groupingBy(FactorEnchance::getFactorCatalog));
             for (Integer medicalRuleInsInfoId : enchanceTypeMap.keySet()) {
-                List<FactorEnchance> factorEnchanceListTemp = enchanceTypeMap.get(medicalRuleInsInfoId);
-                paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_ID, medicalRuleInsInfoId);
-                paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_CODE, medicalInsRuleInfo.getRuleCode());
-                paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_NAME, medicalInsRuleInfo.getRuleName());
-                paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_DESC, medicalInsRuleInfo.getDescription());
-                factorEnchangeFactory.runFactorEnchange(medicalRuleInsInfoId, medicalInsRuleInfo, audit, paramMap, ruleFactorRelaList, factorEnchanceListTemp, null);
+                try {
+                    List<FactorEnchance> factorEnchanceListTemp = enchanceTypeMap.get(medicalRuleInsInfoId);
+                    paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_ID, medicalRuleInsInfoId);
+                    paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_CODE, medicalInsRuleInfo.getRuleCode());
+                    paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_NAME, medicalInsRuleInfo.getRuleName());
+                    paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_DESC, medicalInsRuleInfo.getDescription());
+                    factorEnchangeFactory.runFactorEnchange(medicalRuleInsInfoId, medicalInsRuleInfo, audit, paramMap, ruleFactorRelaList, factorEnchanceListTemp, null);
+                }catch (Exception e){
+                    log.error(e.getMessage(), e);
+                }
             }
         }
     }
@@ -984,15 +1111,18 @@ public class RuleEngine {
             List<FactorEnchance> factorEnchanceList = factorEnchanceService.listByIds(factorEnchangeIdList);
             Map<Integer, List<FactorEnchance>> enchanceTypeMap = factorEnchanceList.stream().collect(Collectors.groupingBy(FactorEnchance::getFactorCatalog));
             for (Integer medicalRuleInsInfoId : enchanceTypeMap.keySet()) {
-
-                List<FactorEnchance> factorEnchanceListTemp = enchanceTypeMap.get(medicalRuleInsInfoId);
-                paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_ID, medicalRuleInsInfoId);
-                paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_CODE, medicalInsRuleInfo.getRuleCode());
-                paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_NAME, medicalInsRuleInfo.getRuleName());
-                boolean auditFlag = factorEnchangeFactory.runFactorEnchange(medicalRuleInsInfoId, medicalInsRuleInfo, null, paramMap, ruleFactorRelaList, factorEnchanceListTemp, null);
-                if (Constant.VALIDATION_HANDER_METHOD_RETURN.equals(medicalInsRuleInfo.getViolationHandingMethod()) && auditFlag) {
-                    log.error("事后统计数据:{} 规则名:{} 触发诊断类规则,直接全金额,后续规则无需再跑", paramMap, medicalInsRuleInfo);
-                    return;
+                try {
+                    List<FactorEnchance> factorEnchanceListTemp = enchanceTypeMap.get(medicalRuleInsInfoId);
+                    paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_ID, medicalRuleInsInfoId);
+                    paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_CODE, medicalInsRuleInfo.getRuleCode());
+                    paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_NAME, medicalInsRuleInfo.getRuleName());
+                    boolean auditFlag = factorEnchangeFactory.runFactorEnchange(medicalRuleInsInfoId, medicalInsRuleInfo, null, paramMap, ruleFactorRelaList, factorEnchanceListTemp, null);
+                    if (Constant.VALIDATION_HANDER_METHOD_RETURN.equals(medicalInsRuleInfo.getViolationHandingMethod()) && auditFlag) {
+                        log.error("事后统计数据:{} 规则名:{} 触发诊断类规则,直接全金额,后续规则无需再跑", paramMap, medicalInsRuleInfo);
+                        return;
+                    }
+                }catch (Exception e){
+                    log.error(e.getMessage(), e);
                 }
             }
         }
@@ -1004,7 +1134,7 @@ public class RuleEngine {
      *
      * @param paramMap
      */
-    public void runAfterEngine(Map<String, Object> paramMap, Integer medicalRuleInsInfoId, AfterwardsAudit afterIncidentAudit, List<Map<String, Object>> itemList) {
+    public void runAfterEngine(Map<String, Object> paramMap, Integer medicalRuleInsInfoId, AfterwardsAudit afterIncidentAudit, List<Map<String, Object>> itemList) throws Exception {
         if (null == medicalRuleInsInfoId) {
             log.error("未有对应的规则,接口数据:{}", paramMap);
             return;
@@ -1033,46 +1163,29 @@ public class RuleEngine {
      *
      * @param paramMap
      */
-    public boolean runMidEngine(Set<String> auditDetailSet, Map<String, Object> paramMap, Set<Integer> medicalInsRuleInfoIdList, MidIncidentAudit midIncidentAudit, List<Map<String, Object>> itemList) {
-        if (CollectionUtil.isEmpty(medicalInsRuleInfoIdList)) {
+    @Async("commonTaskAsyncPool")
+    public boolean runMidEngine(Map<String, Object> paramMap, Integer medicalRuleInsInfoId, MidIncidentAudit midIncidentAudit, List<Map<String, Object>> itemList) throws Exception {
+        boolean auditFlag = false;
+        if (null == medicalRuleInsInfoId) {
             log.error("未有对应的规则,接口数据:{}", paramMap);
-            return false;
-        }
-//        LambdaQueryWrapper<RuleFactorRela> query = new LambdaQueryWrapper<RuleFactorRela>();
-//        query.eq(RuleFactorRela::getDelFlag, CommonConstant.DEL_FLAG_0);
-//        query.in(RuleFactorRela::getMedicalInsRuleInfoId, medicalInsRuleInfoIdList);
-//        query.orderByAsc(RuleFactorRela::getSeqNum);
-//        List<RuleFactorRela> ruleFactorRelaList = ruleFactorRelaService.list(query);
-        Map<Integer, List<FactorEnchance>> enchanceTypeMap = new HashMap<>();
-        for(Integer medicalRuleINfoId : medicalInsRuleInfoIdList){
-            enchanceTypeMap.put(medicalRuleINfoId, allEnchanceTypeMap.get(medicalRuleINfoId));
+            return auditFlag;
         }
-        boolean auditFlag = false;
-        if (CollectionUtil.isNotEmpty(enchanceTypeMap)) {
-//            Map<Integer, List<RuleFactorRela>> ruleIdAndFatorEnchanceIdMap = ruleFactorRelaList.stream().collect(Collectors.groupingBy(RuleFactorRela::getMedicalInsRuleInfoId));
-//            Set<Integer> factorEnchangeIdList = ruleFactorRelaList.stream().map(RuleFactorRela::getFactorEnhanceId).collect(Collectors.toSet());
-//            List<FactorEnchance> factorEnchanceList = factorEnchanceService.listByIds(factorEnchangeIdList);
-//            Map<Integer, List<FactorEnchance>> enchanceTypeMap = factorEnchanceList.stream().collect(Collectors.groupingBy(FactorEnchance::getFactorCatalog));
-            for (Integer medicalRuleInsInfoId : enchanceTypeMap.keySet()) {
-                String auditDetailKeyStr = paramMap.get(Constant.MEDICAL_PROJECT_NAME_KEY) + "_" + medicalRuleInsInfoId;
-                if (auditDetailSet.contains(auditDetailKeyStr)) {
-                    log.error("项目编码:{} 规则ID:{} 已经执行过规则引擎,此次忽略", paramMap.get(Constant.MEDICAL_PROJECT_NAME_KEY), medicalRuleInsInfoId);
-                    continue;
-                }
-                auditDetailSet.add(auditDetailKeyStr);
-                MedicalInsRuleInfo medicalInsRuleInfo = medicalInsRuleInfoService.getById(medicalRuleInsInfoId);
-                List<FactorEnchance> factorEnchanceListTemp = enchanceTypeMap.get(medicalRuleInsInfoId);
-                paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_ID, medicalRuleInsInfoId);
-                paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_CODE, medicalInsRuleInfo.getRuleCode());
-                paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_NAME, medicalInsRuleInfo.getRuleName());
-                List<RuleFactorRela> ruleFactorRelaSortList = ruleIdAndFatorEnchanceIdMap.get(medicalRuleInsInfoId);
-                getRuleProjectIntoMap(medicalInsRuleInfo, paramMap);
-                auditFlag = factorEnchangeFactory.runFactorEnchange(medicalRuleInsInfoId, medicalInsRuleInfo, midIncidentAudit, paramMap, ruleFactorRelaSortList, factorEnchanceListTemp, itemList);
-                if (Constant.VALIDATION_HANDER_METHOD_RETURN.equals(medicalInsRuleInfo.getViolationHandingMethod()) && auditFlag) {
-                    log.error("事中提醒数据:{} 规则名:{} 触发诊断类规则,直接全金额,后续规则无需再跑", paramMap, medicalInsRuleInfo);
-                    return auditFlag;
-                }
+        if (allEnchanceTypeMap.containsKey(medicalRuleInsInfoId)) {
+            MedicalInsRuleInfo medicalInsRuleInfo = allMedicalMap.get(medicalRuleInsInfoId);
+            List<FactorEnchance> factorEnchanceListTemp = allEnchanceTypeMap.get(medicalRuleInsInfoId);
+            paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_ID, medicalRuleInsInfoId);
+            paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_CODE, medicalInsRuleInfo.getRuleCode());
+            paramMap.put(SystemEventAttrConstant.MEDICAL_INS_RULE_INFO_NAME, medicalInsRuleInfo.getRuleName());
+            List<RuleFactorRela> ruleFactorRelaSortList = ruleIdAndFatorEnchanceIdMap.get(medicalRuleInsInfoId);
+            getRuleProjectIntoMap(medicalInsRuleInfo, paramMap);
+            paramMap.put(SystemEventAttrConstant.ADVICE_DETAILS_LIST_KEY, itemList);
+            auditFlag = factorEnchangeFactory.runFactorEnchange(medicalRuleInsInfoId, medicalInsRuleInfo, midIncidentAudit, paramMap, ruleFactorRelaSortList, factorEnchanceListTemp, itemList);
+            if (Constant.VALIDATION_HANDER_METHOD_RETURN.equals(medicalInsRuleInfo.getViolationHandingMethod()) && auditFlag) {
+                log.error("事后提醒数据:{} 规则名:{} 触发诊断类规则,直接全金额,后续规则无需再跑", paramMap, medicalInsRuleInfo);
+                return auditFlag;
             }
+        }else{
+            log.error("该医保规则ID:{} 未有配置医保规则处理流程-请到规则配置页面进行配置", medicalRuleInsInfoId);
         }
         return auditFlag;
     }

+ 29 - 6
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/medical/ruleengine/SPELUtil.java

@@ -120,20 +120,28 @@ public class SPELUtil {
     }
 
 
-    public Object runSpelExpression(Map<String, Object> contentMap, String condStr) {
+    public Object runSpelExpression(Map<String, Object> contentMap, String condStr) throws Exception {
 
         StandardEvaluationContext ctx = new StandardEvaluationContext();
         Method[] methods = this.getClass().getMethods();
         for (Method method : methods) {
-            log.info("methodName:{} method:{}", method.getName(), method);
-            if (!"runSpelExpression".equals(method.getName())) {
+//            log.info("methodName:{} method:{}", method.getName(), method);
+            if (!"runSpelExpression".equals(method.getName()) && method.getName().startsWith("is")) {
                 ctx.registerFunction(method.getName(), method);
             }
         }
         ctx.setVariables(contentMap);
         Expression expression = parser.parseExpression(condStr);
-        Object defResult = expression.getValue(ctx);
-        log.info("执行语句:{} 执行结果:{} 对象数据:{} ", condStr, defResult, contentMap);
+        Object defResult = null;
+        try {
+            defResult = expression.getValue(ctx);
+        }catch (Exception e){
+            log.error("执行语句:{} 数据对象:{}", condStr, contentMap);
+            log.error(e.getMessage(), e);
+            throw new Exception("执行失败el表达式:"+ condStr);
+        }
+
+        log.info("执行语句:{} 执行结果:{}  ", condStr, defResult);
 //        Object defResult = expression.getValue(ctx, Object.class);
 
         return defResult;
@@ -273,7 +281,17 @@ public class SPELUtil {
 
 
     public static Boolean isMemberLeftObject(Object inValue, List<Object> memberList) {
+
         if (null != inValue && CollectionUtil.isNotEmpty(memberList)) {
+            if(inValue instanceof  List){
+                List<Object> lList = (List<Object>) inValue;
+                for (Object value : lList) {
+                    boolean flag = isMemberLeftObject(value, memberList);
+                    if (flag) {
+                        return true;
+                    }
+                }
+            }
             if (memberList.contains(inValue)) {
                 return true;
             }
@@ -353,7 +371,12 @@ public class SPELUtil {
         itemMap1.put("medical_diagnose_code", Arrays.asList("1", "2", "3"));
         itemMap1.put("medical_ins_medicalDiagnoseCodeList", Arrays.asList("3", "5", "6"));
         String condStr = "'1' != 1";
-        System.out.println(spelUtil.runSpelExpression(itemMap1, condStr));
+        try {
+            System.out.println(spelUtil.runSpelExpression(itemMap1, condStr));
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error(e.getMessage(), e);
+        }
 //        String test ="A0123123";
 //        System.out.println(isNumeric(test));
 //        String[] rolesArr = new String []{"correlationMedicalDiagnoseCode","111"};

+ 4 - 4
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/medical/service/impl/MedicalInsRuleProjectServiceImpl.java

@@ -631,7 +631,7 @@ public class MedicalInsRuleProjectServiceImpl extends ServiceImpl<MedicalInsRule
     public List<MedicalInsRuleProject> getRuleProjectByMedicalProjectCode(String medicalProjectCode) {
         QueryWrapper<MedicalInsRuleProject> queryWrapper = new QueryWrapper<MedicalInsRuleProject>();
         queryWrapper.eq("STATE", Constant.EFF_STATE);
-        queryWrapper.last(" and (INSTR('"+medicalProjectCode+"',project_code)>0 or INSTR('"+medicalProjectCode+"',correlation_project_code)>0) ");
+        queryWrapper.last(" and INSTR('"+medicalProjectCode+"',project_code)=1");
 
         return this.list(queryWrapper);
     }
@@ -641,7 +641,7 @@ public class MedicalInsRuleProjectServiceImpl extends ServiceImpl<MedicalInsRule
         QueryWrapper<MedicalInsRuleProject> queryWrapper = new QueryWrapper<MedicalInsRuleProject>();
         queryWrapper.in("medical_ins_rule_info_id", medicalInsRuleInfoIdList);
         queryWrapper.eq("STATE", Constant.EFF_STATE);
-        queryWrapper.last(" and (INSTR('"+medicalProjectCode+"',project_code)=1 or INSTR('"+medicalProjectCode+"',correlation_project_code)=1) ");
+        queryWrapper.last(" and INSTR('"+medicalProjectCode+"',project_code)=1  ");
 
         return this.list(queryWrapper);
     }
@@ -651,7 +651,7 @@ public class MedicalInsRuleProjectServiceImpl extends ServiceImpl<MedicalInsRule
     public List<MedicalInsRuleProject> getRuleProjectByDiagCode(String medicalDiagnoseCode) {
         QueryWrapper<MedicalInsRuleProject> queryWrapper = new QueryWrapper<MedicalInsRuleProject>();
         queryWrapper.eq("STATE", Constant.EFF_STATE);
-        queryWrapper.last(" and (INSTR('"+medicalDiagnoseCode+"',project_code)=1 or INSTR('"+medicalDiagnoseCode+"',correlation_project_code)=1) ");
+        queryWrapper.last(" and INSTR('"+medicalDiagnoseCode+"',project_code)=1 ");
 
         return this.list(queryWrapper);
     }
@@ -661,7 +661,7 @@ public class MedicalInsRuleProjectServiceImpl extends ServiceImpl<MedicalInsRule
         QueryWrapper<MedicalInsRuleProject> queryWrapper = new QueryWrapper<MedicalInsRuleProject>();
         queryWrapper.in("medical_ins_rule_info_id", medicalInsRuleInfoIdList);
         queryWrapper.eq("STATE", Constant.EFF_STATE);
-        queryWrapper.last(" and (INSTR('"+medicalDiagnoseCode+"',medical_diagnose_code)=1 or INSTR('"+medicalDiagnoseCode+"',correlation_medical_diagnose_code)=1) ");
+        queryWrapper.last(" and INSTR('"+medicalDiagnoseCode+"',medical_diagnose_code)=1 ");
 
         return this.list(queryWrapper);
     }

+ 31 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/medical/threadpool/AfterRunRuleEngineCallable.java

@@ -0,0 +1,31 @@
+package org.jeecg.modules.medical.threadpool;
+
+import org.jeecg.common.util.SpringContextUtils;
+import org.jeecg.modules.medical.entity.AfterIncidentDetailLog;
+import org.jeecg.modules.medical.entity.AfterwardsAudit;
+import org.jeecg.modules.medical.ruleengine.RuleEngine;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+public class AfterRunRuleEngineCallable implements Callable {
+
+    RuleEngine ruleEngine = SpringContextUtils.getBean(RuleEngine.class);
+
+    private AfterwardsAudit afterwardsAudit;
+    private AfterIncidentDetailLog afterIncidentDetailLog;
+    private List<Map<String, Object>> itemList;
+
+    public AfterRunRuleEngineCallable(AfterwardsAudit afterwardsAudit, AfterIncidentDetailLog afterIncidentDetailLog, List<Map<String, Object>> itemList) {
+        this.afterwardsAudit = afterwardsAudit;
+        this.afterIncidentDetailLog = afterIncidentDetailLog;
+        this.itemList = itemList;
+    }
+
+    @Override
+    public Object call() throws Exception {
+        ruleEngine.dealAfterInterfaceEngin(afterwardsAudit, afterIncidentDetailLog, itemList);
+        return true;
+    }
+}

+ 17 - 1
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/medical/threadpool/CommonExecutePool.java

@@ -23,7 +23,7 @@ public class CommonExecutePool {
     private CommonThreadPoolConfig config;
 
     @Bean
-    public Executor commonTaskAsyncPool() {
+    public ThreadPoolTaskExecutor commonTaskAsyncPool() {
         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
         executor.setCorePoolSize(config.getCorePoolSize());
         executor.setMaxPoolSize(config.getMaxPoolSize());
@@ -36,4 +36,20 @@ public class CommonExecutePool {
         return executor;
     }
 
+
+    @Bean
+    public ThreadPoolTaskExecutor logTaskAsyncPool() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(config.getCorePoolSize());
+        executor.setMaxPoolSize(config.getMaxPoolSize());
+        executor.setQueueCapacity(config.getQueueCapacity());
+        executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
+        executor.setThreadNamePrefix("logtask-");
+        // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        executor.initialize();
+        return executor;
+    }
+
+
 }

+ 33 - 1
jeecg-module-system/jeecg-system-start/src/main/resources/logback-spring.xml

@@ -13,6 +13,8 @@
 		</encoder>
 	</appender>
 
+
+
 	<!-- 按照每天生成日志文件 -->
 	<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
 		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
@@ -20,13 +22,42 @@
 			<FileNamePattern>${LOG_HOME}/jeecgboot-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
 			<!--日志文件保留天数 -->
 			<MaxHistory>30</MaxHistory>
-			<maxFileSize>100MB</maxFileSize>
+			<maxFileSize>10MB</maxFileSize>
 		</rollingPolicy>
 		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
 			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
 			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>
 		</encoder>
 	</appender>
+	<!-- 按照每天生成日志文件 -->
+	<appender name="businessLogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<file>${LOG_HOME}/spel.log</file>
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<!--日志文件输出的文件名-->
+			<FileNamePattern>${LOG_HOME}/spel.%d{yyyy-MM-dd_HH}-%i.log</FileNamePattern>
+			<TimeBasedFileNamingAndTriggeringPolicy
+					class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<MaxFileSize>10MB</MaxFileSize>
+			</TimeBasedFileNamingAndTriggeringPolicy>
+			<!--日志文件保留天数-->
+			<MaxHistory>30</MaxHistory>
+		</rollingPolicy>
+		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}.%M\(%line\) - %msg%n</pattern>
+			<charset>UTF-8</charset>
+		</encoder>
+		<!--日志文件最大的大小-->
+		<!--<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">-->
+		<!--<MaxFileSize>1024MB</MaxFileSize>-->
+		<!--</triggeringPolicy>-->
+	</appender>
+
+	<logger name="org.jeecg.modules.medical.ruleengine.SPELUtil" additivity="true" level="info">
+		<appender-ref ref="businessLogFile"/>
+	</logger>
+
+
 
 
 	<!--myibatis log configure -->
@@ -39,6 +70,7 @@
 	<root level="INFO">
 		<appender-ref ref="STDOUT" />
 		<appender-ref ref="FILE" />
+		<appender-ref ref="businessLogFile" />
 	</root>
 
 </configuration>