|
|
@@ -0,0 +1,250 @@
|
|
|
+package org.jeecg.modules.medical.ruleengine;
|
|
|
+
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
|
+import cn.hutool.core.collection.CollectionUtil;
|
|
|
+import cn.hutool.core.date.DatePattern;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
+import org.jeecg.common.api.vo.Result;
|
|
|
+import org.jeecg.common.util.dynamic.db.DynamicDBUtil;
|
|
|
+import org.jeecg.modules.medical.Constant;
|
|
|
+import org.jeecg.modules.medical.SystemEventAttrConstant;
|
|
|
+import org.jeecg.modules.medical.common.CommonUtil;
|
|
|
+import org.jeecg.modules.medical.entity.AdviceDetailsVO;
|
|
|
+import org.jeecg.modules.medical.entity.DiagnosesVO;
|
|
|
+import org.jeecg.modules.medical.entity.HospMidIncidentWarningVO;
|
|
|
+import org.jeecg.modules.medical.entity.MedicalInsRuleProject;
|
|
|
+import org.jeecg.modules.medical.entity.MidIncidentAudit;
|
|
|
+import org.jeecg.modules.medical.entity.MidIncidentAuditDetail;
|
|
|
+import org.jeecg.modules.medical.entity.MidIncidentWarningVO;
|
|
|
+import org.jeecg.modules.medical.entity.MidResult;
|
|
|
+import org.jeecg.modules.medical.entity.MidRule;
|
|
|
+import org.jeecg.modules.medical.ruleengine.dict.DictUtil;
|
|
|
+import org.jeecg.modules.medical.ruleengine.plugin.InterfItemListPlugin;
|
|
|
+import org.jeecg.modules.medical.service.IMedicalInsRuleProjectDiagnoseService;
|
|
|
+import org.jeecg.modules.medical.service.IMedicalInsRuleProjectService;
|
|
|
+import org.jeecg.modules.medical.service.IMidIncidentAuditDetailService;
|
|
|
+import org.jeecg.modules.medical.threadpool.MidRunRuleEngineCallable;
|
|
|
+import org.jeecg.modules.utils.DateTimeUtil;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
|
|
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.concurrent.Future;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+public class HospGetDataToRuleEngine {
|
|
|
+ @Autowired
|
|
|
+ InterfItemListPlugin interfItemListPlugin;
|
|
|
+ @Autowired
|
|
|
+ IMedicalInsRuleProjectDiagnoseService medicalInsRuleProjectDiagnoseService;
|
|
|
+ @Autowired
|
|
|
+ IMedicalInsRuleProjectService medicalInsRuleProjectService;
|
|
|
+ @Autowired
|
|
|
+ RuleEngine ruleEngine;
|
|
|
+ @Autowired
|
|
|
+ DictUtil dictUtil;
|
|
|
+ @Resource(name = "commonTaskAsyncPool")
|
|
|
+ ThreadPoolTaskExecutor threadPoolTaskExecutor;
|
|
|
+ @Autowired
|
|
|
+ IMidIncidentAuditDetailService midIncidentAuditDetailService;
|
|
|
+
|
|
|
+ NamedParameterJdbcTemplate namedParameterJdbcTemplate = DynamicDBUtil.getNamedParameterJdbcTemplate(Constant.FY_ORACLE);
|
|
|
+ String detailSql = "select * from V_YBKF_ADVICE_DETAILS where patient_id=:PATIENT_ID and visit_no=:VISIT_NO and medical_project_code is not null";
|
|
|
+ String diagnoseSql = "select * from V_YBKF_DIAGNOSES where patient_id=:PATIENT_ID and visit_no=:VISIT_NO and medical_diagnose_code is not null";
|
|
|
+
|
|
|
+ public Result getHopsDataByVisiVo(HospMidIncidentWarningVO hospMidIncidentWarningVO) {
|
|
|
+ log.info("接收报文:{}", JSON.toJSONString(hospMidIncidentWarningVO));
|
|
|
+ MidResult midResult = new MidResult();
|
|
|
+ Map<String, Object> paramMap = new HashMap<>();
|
|
|
+ paramMap.put("PATIENT_ID", hospMidIncidentWarningVO.getPatient_id());
|
|
|
+ paramMap.put("VISIT_NO", hospMidIncidentWarningVO.getVisit_no());
|
|
|
+ List<Map<String, Object>> detailList = namedParameterJdbcTemplate.queryForList(detailSql, paramMap);
|
|
|
+ List<Map<String, Object>> diagnoseList = namedParameterJdbcTemplate.queryForList(diagnoseSql, paramMap);
|
|
|
+ List<Map<String, Object>> detailMapList = new ArrayList<>();
|
|
|
+ Double totalAmount = 0.0;
|
|
|
+ Map<String, String> categoriesItemMap = CommonUtil.getCategoriesItemsMap();
|
|
|
+ String visitTime = DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN);
|
|
|
+ for (Map<String, Object> detailMap : detailList) {
|
|
|
+ if (CollectionUtil.isNotEmpty(diagnoseList)) {
|
|
|
+ detailMap.putAll(diagnoseList.get(0));
|
|
|
+ }
|
|
|
+ String pCategory = detailMap.getOrDefault("EXPENSE_CATEGORY", "").toString();
|
|
|
+ if (StringUtils.isNotBlank(pCategory)) {
|
|
|
+ detailMap.put("EXPENSE_CATEGORY", categoriesItemMap.getOrDefault(pCategory, pCategory));
|
|
|
+ }
|
|
|
+ CommonUtil.setDockerLevel(detailMap);
|
|
|
+ CommonUtil.setProjectType(detailMap);
|
|
|
+ Map<String, Object> lowercaseMap = new HashMap<>();
|
|
|
+ for (Map.Entry<String, Object> entry : detailMap.entrySet()) {
|
|
|
+ String lowercaseKey = entry.getKey().toLowerCase();
|
|
|
+ lowercaseMap.put(lowercaseKey, entry.getValue());
|
|
|
+ }
|
|
|
+ if (!lowercaseMap.containsKey("visit_time")) {
|
|
|
+ lowercaseMap.put("visit_time", visitTime);
|
|
|
+ }
|
|
|
+ if (!lowercaseMap.containsKey("visit_type")) {
|
|
|
+ lowercaseMap.put("visit_type", "1");
|
|
|
+ }
|
|
|
+ Double amount = (Double) lowercaseMap.get("amount");
|
|
|
+ totalAmount = totalAmount + amount;
|
|
|
+ Object patientGender = lowercaseMap.get("patient_gender");
|
|
|
+ lowercaseMap.put("patient_gender", CommonUtil.getMedicalSex(patientGender));
|
|
|
+ Object quantity = lowercaseMap.get("quantity");
|
|
|
+ if (null != quantity) {
|
|
|
+ Integer quantityInt = (Integer) quantity;
|
|
|
+ if (quantityInt <= 0) {
|
|
|
+ lowercaseMap.put("quantity", 1);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ lowercaseMap.put("quantity", 1);
|
|
|
+ }
|
|
|
+ detailMapList.add(lowercaseMap);
|
|
|
+ }
|
|
|
+ List<Map<String, Object>> diagnoseMapList = new ArrayList<>();
|
|
|
+ for (Map<String, Object> detailMap : diagnoseList) {
|
|
|
+ Map<String, Object> lowercaseMap = new HashMap<>();
|
|
|
+ for (Map.Entry<String, Object> entry : detailMap.entrySet()) {
|
|
|
+ String lowercaseKey = entry.getKey().toLowerCase();
|
|
|
+ lowercaseMap.put(lowercaseKey, entry.getValue());
|
|
|
+ }
|
|
|
+ diagnoseMapList.add(lowercaseMap);
|
|
|
+ }
|
|
|
+ dealMidInterfaceEngin(detailMapList, diagnoseMapList, totalAmount);
|
|
|
+ log.info("返回报文:{}", JSON.toJSONString(midResult));
|
|
|
+ return Result.OK();
|
|
|
+ }
|
|
|
+
|
|
|
+ public Result dealMidInterfaceEngin(List<Map<String, Object>> detailMapList, List<Map<String, Object>> diagnoseList, Double totalAmount) {
|
|
|
+ MidIncidentWarningVO midIncidentWarningVO = null;
|
|
|
+ midIncidentWarningVO = BeanUtil.mapToBean(detailMapList.get(0), MidIncidentWarningVO.class, true);
|
|
|
+ List<AdviceDetailsVO> adviceDetailsVOList = getAdviceDetailVOList(detailMapList);
|
|
|
+ midIncidentWarningVO.setAdvice_details(adviceDetailsVOList);
|
|
|
+ String patientAge = null;
|
|
|
+ if (null == midIncidentWarningVO.getPatient_age()) {
|
|
|
+ patientAge = "0天";
|
|
|
+ }
|
|
|
+ Integer days = DateTimeUtil.getDayByAgeStr(patientAge);
|
|
|
+ midIncidentWarningVO.setPatientAgeDays(days);
|
|
|
+ midIncidentWarningVO.setTotoal_amount(totalAmount);
|
|
|
+// midIncidentWarningVO.setVisit_type("1");
|
|
|
+ List<String> diagnoseStrList = new ArrayList<>();
|
|
|
+ List<String> medicalDiagnoseStrList = new ArrayList<>();
|
|
|
+ List<DiagnosesVO> diagnosesVOList = new ArrayList<>();
|
|
|
+ if (CollectionUtil.isNotEmpty(diagnoseList)) {
|
|
|
+ for (Map<String, Object> diagnoseMap : diagnoseList) {
|
|
|
+ diagnoseStrList.add(diagnoseMap.get("diagnose_code").toString());
|
|
|
+ medicalDiagnoseStrList.add(diagnoseMap.get("medical_diagnose_code").toString());
|
|
|
+ DiagnosesVO diagnosesVO = new DiagnosesVO();
|
|
|
+ diagnosesVO.setDiagnose_code(diagnoseMap.get("diagnose_code").toString());
|
|
|
+ diagnosesVO.setDiagnose_desc(diagnoseMap.get("diagnose_desc").toString());
|
|
|
+ diagnosesVO.setMedical_diagnose_code(diagnoseMap.get("medical_diagnose_code").toString());
|
|
|
+ diagnosesVO.setMedical_diagnose_name(diagnoseMap.get("medical_diagnose_name").toString());
|
|
|
+ diagnosesVOList.add(diagnosesVO);
|
|
|
+ }
|
|
|
+ midIncidentWarningVO.setDiagnoses(diagnosesVOList);
|
|
|
+ }
|
|
|
+ MidResult midResult = new MidResult();
|
|
|
+ try {
|
|
|
+ MidIncidentAudit midIncidentAudit = ruleEngine.insertMidWarning(midIncidentWarningVO);
|
|
|
+ ruleEngine.insertLog(midIncidentWarningVO);
|
|
|
+ //callScenario 1=事前 2=事后 3=事前/事后 4=事中 5=事后/事中
|
|
|
+ List<String> callScenarioList = Arrays.asList("4", "5");
|
|
|
+ boolean sendFlag = false;
|
|
|
+ MidRunRuleEngineCallable midRunRuleEngineCallable = null;
|
|
|
+ List<Future> futureList = new ArrayList();
|
|
|
+ for (Map<String, Object> itemMap : detailMapList) {
|
|
|
+ itemMap.put(Constant.MEDICAL_DIAGNOSE_CODE_KEY, medicalDiagnoseStrList);
|
|
|
+ List<MedicalInsRuleProject> medicalInsRuleProjectList = medicalInsRuleProjectService.getRuleProjectByMedicalProjectCode(itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY).toString(), callScenarioList);
|
|
|
+ if (CollectionUtil.isEmpty(medicalInsRuleProjectList)) {
|
|
|
+ log.error("项目编码未匹配到对应的医保规则:{} 在规则库数据库中未检索到数据", itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY));
|
|
|
+ } else {
|
|
|
+ Set<Integer> medicalInsRuleInfoIdList = medicalInsRuleProjectList.stream().map(MedicalInsRuleProject::getMedicalInsRuleInfoId).collect(Collectors.toSet());
|
|
|
+ log.info("项目编码:{} 数据库检索到匹配规则ID列表:{}", itemMap.get(Constant.MEDICAL_PROJECT_CODE_KEY), medicalInsRuleInfoIdList);
|
|
|
+ }
|
|
|
+ if (CollectionUtil.isNotEmpty(medicalDiagnoseStrList)) {
|
|
|
+ //获取诊断编码配置的规则ID,加入需要执行的规则
|
|
|
+ ruleEngine.getAndSetDiagRule(medicalDiagnoseStrList, medicalInsRuleProjectList);
|
|
|
+ }
|
|
|
+ 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));
|
|
|
+ itemMap.put(SystemEventAttrConstant.ADVICE_DETAILS_LIST_KEY, detailMapList);
|
|
|
+ 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);
|
|
|
+ ruleEngine.setProjectToLocalMap(itemMap, medicalInsRuleProject);
|
|
|
+ itemMap.put(SystemEventAttrConstant.MEDICAL_INS_CORRELATIONMEDICALDIAGNOSECODE, medicalInsCorrProjectCodeList);
|
|
|
+ ruleEngine.setItemCodeListToItemMap(detailMapList, itemMap);
|
|
|
+
|
|
|
+ try {
|
|
|
+ midRunRuleEngineCallable = new MidRunRuleEngineCallable(itemMap, medicalInsRuleInfoId, midIncidentAudit, detailMapList);
|
|
|
+ Future future = threadPoolTaskExecutor.submit(midRunRuleEngineCallable);
|
|
|
+ futureList.add(future);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (Future future : futureList) {
|
|
|
+ try {
|
|
|
+ boolean auditFlag = (boolean) future.get();
|
|
|
+ sendFlag = auditFlag || sendFlag;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ midResult.setId(midIncidentAudit.getId());
|
|
|
+ midResult.setViolationFlag(sendFlag);
|
|
|
+ if(sendFlag){
|
|
|
+ List<MidIncidentAuditDetail> midIncidentAuditDetailList = midIncidentAuditDetailService.lambdaQuery().eq(MidIncidentAuditDetail::getMidIncidentAuditId, midIncidentAudit.getId()).list();
|
|
|
+ List<MidRule> midRuleList = new ArrayList<>();
|
|
|
+ for(MidIncidentAuditDetail midIncidentAuditDetail : midIncidentAuditDetailList){
|
|
|
+ MidRule midRule = new MidRule();
|
|
|
+ midRule.setRuleCode(midIncidentAuditDetail.getMedicalInsRuleInfoCode());
|
|
|
+ midRule.setRuleName(midIncidentAuditDetail.getMedicalInsRuleInfoName());
|
|
|
+ midRule.setDescription(midIncidentAuditDetail.getDescription());
|
|
|
+ midRule.setAbnormalAmount(midIncidentAuditDetail.getAmount());
|
|
|
+ midRule.setTreatmentType(midIncidentAuditDetail.getTreatmentType());
|
|
|
+ midRuleList.add(midRule);
|
|
|
+ }
|
|
|
+ midResult.setRuleCodeList(midRuleList);
|
|
|
+ }
|
|
|
+ if (!sendFlag) {
|
|
|
+ log.error("无违规,事中审核无需提醒 门诊/住院号:{}", midIncidentWarningVO.getVisit_no());
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
+ }
|
|
|
+
|
|
|
+ return Result.ok(midResult);
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<AdviceDetailsVO> getAdviceDetailVOList(List<Map<String, Object>> detailList) {
|
|
|
+ List<AdviceDetailsVO> adviceDetailsVOList = new ArrayList<>();
|
|
|
+ for (Map<String, Object> detailMap : detailList) {
|
|
|
+ AdviceDetailsVO adviceDetailsVO = BeanUtil.mapToBean(detailMap, AdviceDetailsVO.class, true);
|
|
|
+ adviceDetailsVOList.add(adviceDetailsVO);
|
|
|
+ }
|
|
|
+ return adviceDetailsVOList;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|