package com.supervision.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.supervision.exception.BusinessException; import com.supervision.model.Process; import com.supervision.model.*; import com.supervision.pojo.vo.*; import com.supervision.service.*; import com.supervision.vo.ask.TreatmentPlanRecordVo; import com.supervision.vo.manage.DiseaseAncillaryResVo; import com.supervision.vo.manage.DiseasePhysicalResVo; import com.supervision.vo.manage.DiseaseTreatmentPlanResVo; import com.supervision.vo.result.AncillaryRecordByResultDTO; import com.supervision.vo.result.PhysicalRecordByResultDTO; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class AskDiagnosisResultServiceImpl implements AskDiagnosisResultService { private final DiagnosisPrimaryService diagnosisPrimaryService; private final AskPatientAnswerService askPatientAnswerService; private final MedicalRecService medicalRecService; private final DiagnosisQaRecordService diagnosisQaRecordService; private final DiagnosisPhysicalRecordService diagnosisPhysicalRecordService; private final DiagnosisAncillaryRecordService diagnosisAncillaryRecordService; private final ProcessService processService; private final ProcessEvaluationService processEvaluationService; private final DiseaseService diseaseService; private final TreatmentPlanRecordService treatmentPlanRecordService; private final DiseaseTreatmentPlanService diseaseTreatmentPlanService; private final DiseaseTreatmentPlanDrugService diseaseTreatmentPlanDrugService; private final DiseasePhysicalService diseasePhysicalService; private final DiseaseAncillaryService diseaseAncillaryService; @Override public DiagnosisResultResVO queryDiagnosisResult(String processId) { DiagnosisResultResVO diagnosisResultResVO = new DiagnosisResultResVO(); diagnosisResultResVO.setId(processId); Process process = processService.getById(processId); MedicalRec medicalRec = medicalRecService.getById(process.getMedicalRecId()); List diseasesList = diseaseService.listDiseaseNestIfComposite(medicalRec.getDiseaseId()); // 1.生成预期诊断结果 diagnosisResultResVO.setExpertDiagnosisResult(creatExpertDiagnosisResult(medicalRec, diseasesList, processId)); // 2.生成初步诊断依据 diagnosisResultResVO.setBasisPrimaryResultResVO(createBasisPrimaryResult(medicalRec, process)); // 3.生成证实诊断依据 diagnosisResultResVO.setBasisConfirmResultResVO(createBasisConfirmResult(medicalRec, processId)); // 4.生成鉴别诊断依据 diagnosisResultResVO.setBasisIdentificationResult(createBasisIdentificationResult(medicalRec, processId)); // 5.全面检查-(暂无相关数据) 后面再看 diagnosisResultResVO.setFullCheck(null); // 6.处置方案 diagnosisResultResVO.setDealPlan(createDealPlan(process.getDiseaseId(), processId)); return diagnosisResultResVO; } private DealPlanResVO createDealPlan(String diseaseId, String processId) { DealPlanResVO dealPlanResVO = new DealPlanResVO(); // 1. 查询处置计划记录 List treatmentPlanRecordList = treatmentPlanRecordService.queryByProcessId(processId); if (CollectionUtil.isEmpty(treatmentPlanRecordList)) { return dealPlanResVO; } // 2. 查询出疾病处置计划(疾病配置的处置计划) List diseaseTreatmentPlanResVos = diseaseTreatmentPlanService.queryListByDiseaseId(diseaseId); List treatmentPlanId = diseaseTreatmentPlanResVos.stream().map(DiseaseTreatmentPlanResVo::getTreatmentPlanId).distinct().collect(Collectors.toList()); // 3. 查出疾病处置计划用药(疾病配置的用药计划) List diseaseTreatmentPlanDrugList = diseaseTreatmentPlanDrugService.lambdaQuery().eq(DiseaseTreatmentPlanDrug::getDiseaseId, diseaseId).list(); List drugIds = diseaseTreatmentPlanDrugList.stream().map(DiseaseTreatmentPlanDrug::getDrugId).distinct().collect(Collectors.toList()); // 4. 组装数据 ArrayList drugTreatmentPlanResults = new ArrayList<>(); ArrayList otherTreatmentPlanResults = new ArrayList<>(); for (TreatmentPlanRecord treatmentPlanRecord : treatmentPlanRecordList) { TreatmentPlanRecordVo bean = BeanUtil.toBean(treatmentPlanRecord, TreatmentPlanRecordVo.class); // 是否正确 boolean flag = StrUtil.isNotEmpty(bean.getDrugId()) ? drugIds.contains(bean.getDrugId()) : treatmentPlanId.contains(bean.getTreatmentPlanId()); bean.setFlag(flag ? 1 : 0); if (StrUtil.isNotEmpty(bean.getDrugId())) { drugTreatmentPlanResults.add(bean); } else { otherTreatmentPlanResults.add(bean); } } dealPlanResVO.setUserTreatmentPlanType(CollectionUtil.getFirst(treatmentPlanRecordList).getDisposalMethod()); dealPlanResVO.setDrugTreatmentPlan(drugTreatmentPlanResults); dealPlanResVO.setOtherTreatmentPlan(otherTreatmentPlanResults.stream().sorted( Comparator.comparing(TreatmentPlanRecord::getDisposalPlan)).collect(Collectors.toList())); return dealPlanResVO; } private BasisIdentificationResultResVO createBasisIdentificationResult(MedicalRec medicalRec, String processId) { BasisIdentificationResultResVO basisIdentificationResultResVO = new BasisIdentificationResultResVO(); // 鉴别诊断依据,来自于medicalRec的DifferentialDiagnosisCriteria basisIdentificationResultResVO.setIdentificationDiagnosis(medicalRec.getDifferentialDiagnosisCriteria()); // 2.2 获取体格检查 List physicalRecordList = diagnosisPhysicalRecordService.queryPhysicalResultByProcessId(processId); List diseasePhysicalResVos = diseasePhysicalService.queryListByDiseaseId(medicalRec.getDiseaseId()); List nodeList = physicalRecordMergeListsIdentification(physicalRecordList, diseasePhysicalResVos); // 2.3 获取辅助检查 List ancillaryRecordList = diagnosisAncillaryRecordService.queryAncillaryResultByProcessId(processId); List diseaseAncillaryResVos = diseaseAncillaryService.queryListByDiseaseId(medicalRec.getDiseaseId()); nodeList.addAll(ancillaryRecordMergeListsIdentification(ancillaryRecordList, diseaseAncillaryResVos)); basisIdentificationResultResVO.setNodeList(nodeList); return basisIdentificationResultResVO; } private BasisConfirmResultResVO createBasisConfirmResult(MedicalRec medicalRec, String processId) { BasisConfirmResultResVO basisConfirmResultResVO = new BasisConfirmResultResVO(); // 证实诊断依据,来自于medicalRec的ConfirmDiagnosisCriteria basisConfirmResultResVO.setConfirmingDiagnosis(medicalRec.getConfirmDiagnosisCriteria()); // 2.2 获取体格检查的证实诊断依据 List physicalRecordList = diagnosisPhysicalRecordService.queryPhysicalResultByProcessId(processId); List diseasePhysicalResVos = diseasePhysicalService.queryListByDiseaseId(medicalRec.getDiseaseId()); List nodeList = physicalRecordMergeListsConfirm(physicalRecordList, diseasePhysicalResVos); // 2.3 获取辅助检查 List ancillaryRecordList = diagnosisAncillaryRecordService.queryAncillaryResultByProcessId(processId); List diseaseAncillaryResVos = diseaseAncillaryService.queryListByDiseaseId(medicalRec.getDiseaseId()); nodeList.addAll(ancillaryRecordMergeListsConfirm(ancillaryRecordList, diseaseAncillaryResVos)); basisConfirmResultResVO.setNodeList(nodeList); return basisConfirmResultResVO; } private BasisPrimaryResultResVO createBasisPrimaryResult(MedicalRec medicalRec, Process process) { BasisPrimaryResultResVO basisPrimaryResultResVO = new BasisPrimaryResultResVO(); // 初步诊断依据 vp_medical_rec的primarily_diagnosis_criteria basisPrimaryResultResVO.setPreliminaryDiagnosis(medicalRec.getPrimarilyDiagnosisCriteria()); // 根据record记录寻找符合初步诊断依据的项目 // 2.1 首先获取对话 List qaRecordList = diagnosisQaRecordService.lambdaQuery().eq(DiagnosisQaRecord::getProcessId, process.getId()).list(); List list = askPatientAnswerService.lambdaQuery() .eq(AskPatientAnswer::getMedicalId, medicalRec.getId()).list(); // 获取配置了答案的项目(配置了答案的,认为是正确,没有配置答案的,走默认回答的,不标记为以正确) List basisDiagnosisNodeResVOS = new ArrayList<>(qaRecordMergeListsBasisPrimary(qaRecordList, list)); // 2.2 获取体格检查 List physicalRecordList = diagnosisPhysicalRecordService.queryPhysicalResultByProcessId(process.getId()); List diseasePhysicalResVos = diseasePhysicalService.queryListByDiseaseId(medicalRec.getDiseaseId()); basisDiagnosisNodeResVOS.addAll(physicalRecordMergeListsBasisPrimary(physicalRecordList, diseasePhysicalResVos)); // 2.3 获取辅助检查 List ancillaryRecordList = diagnosisAncillaryRecordService.queryAncillaryResultByProcessId(process.getId()); List diseaseAncillaryResVos = diseaseAncillaryService.queryListByDiseaseId(medicalRec.getDiseaseId()); basisDiagnosisNodeResVOS.addAll(ancillaryRecordMergeListsBasisPrimary(ancillaryRecordList, diseaseAncillaryResVos)); basisPrimaryResultResVO.setNodeList(basisDiagnosisNodeResVOS); return basisPrimaryResultResVO; } private List qaRecordMergeListsBasisPrimary(List qaRecordList, List list) { BiFunction biFunction = (qaRecord, qa) -> qa.getLibraryQuestionId().equals(qaRecord.getQuestionLibraryId()); list = list.stream().filter(item -> !Integer.valueOf("0").equals(item.getAnswerType())).collect(Collectors.toList()); Set requireCheckIdSet = list.stream().map(AskPatientAnswer::getId).collect(Collectors.toSet()); Function t1 = r -> new BasisDiagnosisNodeResVO(0, r.getQuestion(), r.getId(), requireCheckIdSet.contains(r.getAnswerId()) ? 1 : 0); Function t2 = item -> new BasisDiagnosisNodeResVO(0, item.getQuestion(), item.getId(), 0); return mergeListsBasedOnCondition(qaRecordList, list, biFunction, t1, t2); } private List physicalRecordMergeLists(List physicalRecordList, List diseasePhysicalResVos, Function functionCorrect) { physicalRecordList = physicalRecordList.stream() .filter(distinctPredicateNotNull(PhysicalRecordByResultDTO::getToolLocationName)).collect(Collectors.toList()); // 工具id相等且 位置为空或者位置id相等 BiFunction biFunction = (r, diseasePhysical) -> StrUtil.equals(diseasePhysical.getToolId(), r.getToolId()) && ((StrUtil.isEmpty(diseasePhysical.getLocationId()) && StrUtil.isEmpty(diseasePhysical.getLocationId())) || StrUtil.equals(diseasePhysical.getLocationId(), (r.getLocationId()))); Function t1 = r -> new BasisDiagnosisNodeResVO(1, r.getToolLocationName(), r.getRecordId(), functionCorrect.apply(r)); // 这里的recordId只为了展示用diseasePhysical.getId()代替。只是为展示使用correct的值固定为不正确 Function t2 = diseasePhysical -> new BasisDiagnosisNodeResVO(1, diseasePhysical.getToolName() + (StrUtil.isEmpty(diseasePhysical.getLocationName()) ? "" : "|" + diseasePhysical.getLocationName()), diseasePhysical.getId(), 0); return mergeListsBasedOnCondition(physicalRecordList, diseasePhysicalResVos, biFunction, t1, t2); } private List ancillaryRecordMergeLists(List ancillaryRecordList, List diseaseAncillaryResVos, Function functionCorrect) { ancillaryRecordList = ancillaryRecordList.stream() .filter(distinctPredicateNotNull(AncillaryRecordByResultDTO::getItemName)).collect(Collectors.toList()); BiFunction biFunction = (r, diseaseAncillary) -> StrUtil.equals(diseaseAncillary.getItemId(), r.getItemId()); Function t1 = record -> new BasisDiagnosisNodeResVO(2, record.getItemName(), record.getRecordId(), functionCorrect.apply(record)); // 这里的recordId只为了展示用diseaseAncillary.getId()代替。只是为展示使用correct的值固定为不正确 Function t2 = diseaseAncillary -> new BasisDiagnosisNodeResVO(2, diseaseAncillary.getItemName(), diseaseAncillary.getId(), 0); return mergeListsBasedOnCondition(ancillaryRecordList, diseaseAncillaryResVos, biFunction, t1, t2); } private List physicalRecordMergeListsBasisPrimary(List physicalRecordList, List diseasePhysicalResVos) { diseasePhysicalResVos = diseasePhysicalResVos.stream() .filter(diseasePhysicalResVo -> Integer.valueOf(1).equals(diseasePhysicalResVo.getPrimarilyDiagnosisCriteriaFlag())).collect(Collectors.toList()); return physicalRecordMergeLists(physicalRecordList, diseasePhysicalResVos, PhysicalRecordByResultDTO::getPrimarilyDiagnosisCriteriaFlag); } private List physicalRecordMergeListsConfirm(List physicalRecordList, List diseasePhysicalResVos) { Function functionCorrect = record -> (ObjectUtil.isNotNull(record.getBasisConfirm()) && 1 == record.getBasisConfirm() && Objects.equals(record.getBasisConfirm(), record.getRecordBasisConfirmFlag())) ? 1 : 0; diseasePhysicalResVos = diseasePhysicalResVos.stream() .filter(diseasePhysicalResVo -> Integer.valueOf(1).equals(diseasePhysicalResVo.getBasisConfirmFlag())).collect(Collectors.toList()); return physicalRecordMergeLists(physicalRecordList, diseasePhysicalResVos, functionCorrect); } private List physicalRecordMergeListsIdentification(List physicalRecordList, List diseasePhysicalResVos) { Function functionCorrect = record -> (Integer.valueOf(1).equals(record.getBasisIdentification()) && Objects.equals(record.getBasisIdentification(), record.getRecordBasisIdentificationFlag())) ? 1 : 0; diseasePhysicalResVos = diseasePhysicalResVos.stream() .filter(diseasePhysicalResVo -> Integer.valueOf(1).equals(diseasePhysicalResVo.getBasisIdentificationFlag())).collect(Collectors.toList()); return physicalRecordMergeLists(physicalRecordList, diseasePhysicalResVos, functionCorrect); } private List ancillaryRecordMergeListsBasisPrimary(List ancillaryRecordList, List diseaseAncillaryResVos) { diseaseAncillaryResVos = diseaseAncillaryResVos.stream() .filter(diseaseAncillaryResVo -> Integer.valueOf(1).equals(diseaseAncillaryResVo.getPrimarilyDiagnosisCriteriaFlag())).collect(Collectors.toList()); return ancillaryRecordMergeLists(ancillaryRecordList, diseaseAncillaryResVos, AncillaryRecordByResultDTO::getPrimarilyDiagnosisCriteriaFlag); } private List ancillaryRecordMergeListsConfirm(List ancillaryRecordList, List diseaseAncillaryResVos) { Function functionCorrect = record -> ObjectUtil.isNotNull(record.getBasisConfirm()) && 1 == record.getBasisConfirm() && Objects.equals(record.getBasisConfirm(), record.getRecordBasisConfirmFlag()) ? 1 : 0; diseaseAncillaryResVos = diseaseAncillaryResVos.stream() .filter(diseaseAncillaryResVo -> Integer.valueOf(1).equals(diseaseAncillaryResVo.getBasisConfirmFlag())).collect(Collectors.toList()); return ancillaryRecordMergeLists(ancillaryRecordList, diseaseAncillaryResVos, functionCorrect); } private List ancillaryRecordMergeListsIdentification(List ancillaryRecordList, List diseaseAncillaryResVos) { Function functionCorrect = record -> (Integer.valueOf(1).equals(record.getBasisIdentification()) && Objects.equals(record.getBasisIdentification(), record.getRecordBasisIdentificationFlag())) ? 1 : 0; diseaseAncillaryResVos = diseaseAncillaryResVos.stream() .filter(diseaseAncillaryResVo -> Integer.valueOf(1).equals(diseaseAncillaryResVo.getBasisIdentificationFlag())).collect(Collectors.toList()); return ancillaryRecordMergeLists(ancillaryRecordList, diseaseAncillaryResVos, functionCorrect); } /** * 根据指定条件合并两个列表。 * * @param simpleList 要处理的简单列表。 * @param poolList 用于比较的池列表。 * @param biFunction 定义合并元素条件。 * @param t1 用于处理简单列表中元素的函数。 * @param t2 用于处理池列表中元素的函数。 * @return 包含根据条件合并的元素的列表。 */ private List mergeListsBasedOnCondition(List simpleList, List poolList, BiFunction biFunction, Function t1, Function t2) { List rs = new ArrayList<>(); // 检查两个列表是否都为空,在这种情况下返回空列表 if (CollUtil.isEmpty(simpleList) && CollUtil.isEmpty(poolList)) { return CollUtil.newArrayList(); } // 如果简单列表为空但池列表不为空,则映射和收集池列表元素 if (CollUtil.isEmpty(simpleList) && CollUtil.isNotEmpty(poolList)) { return poolList.stream().map(t2).collect(Collectors.toList()); } // 根据定义的条件合并列表 for (M m : poolList) { boolean find = false; for (T t : simpleList) { if (biFunction.apply(t, m)) { rs.add(t1.apply(t)); find = true; break; } } if (!find) { rs.add(t2.apply(m)); } } return rs; } /** * 预期诊断结果 */ private ExpertDiagnosisResultResVO creatExpertDiagnosisResult(MedicalRec medicalRec, List diseasesList, String processId) { ExpertDiagnosisResultResVO expertDiagnosisResultResVO = new ExpertDiagnosisResultResVO(); expertDiagnosisResultResVO.setDiagnosis(diseasesList.stream().map(Disease::getDiseaseNameAlias).collect(Collectors.joining(";"))); Set expertDiseaseIdSet = diseasesList.stream().map(Disease::getId).collect(Collectors.toSet()); // 从vp_diagnosis_primary中找到确认诊断时,确认的 List userPrimaryDiseaseList = diagnosisPrimaryService.lambdaQuery() .eq(DiagnosisPrimary::getProcessId, processId) // 1确诊 .eq(DiagnosisPrimary::getExcludeFlag, 1).list(); List userDiagnosisDiseaseList = CollUtil.isEmpty(userPrimaryDiseaseList) ? CollUtil.newArrayList() : diseaseService.listByIds(userPrimaryDiseaseList.stream().map(DiagnosisPrimary::getPrimaryDiagnosisId).collect(Collectors.toList())); // 用户的诊断 expertDiagnosisResultResVO.setUserDiagnosisResult(userDiagnosisDiseaseList.stream().map(e -> { DiagnosisDiseaseResultNodeVO userNode = new DiagnosisDiseaseResultNodeVO(); userNode.setDiseaseName(e.getDiseaseNameAlias()); // 如果用户诊断在预期诊断里面,则正确,否则错误 userNode.setCorrect(expertDiseaseIdSet.contains(e.getId()) ? 1 : 0); userNode.setDiseaseId(e.getId()); return userNode; }).collect(Collectors.toList())); // 预期诊断 expertDiagnosisResultResVO.setExpertDiagnosisResult(diseasesList.stream().map(e -> { DiagnosisDiseaseResultNodeVO node = new DiagnosisDiseaseResultNodeVO(); node.setDiseaseName(e.getDiseaseNameAlias()); node.setDiseaseId(e.getId()); return node; }).collect(Collectors.toList())); return expertDiagnosisResultResVO; } public static Predicate distinctPredicateNotNull(Function function) { ConcurrentHashMap map = new ConcurrentHashMap<>(); // 根据key进行去重,并排除为null的数据 return t -> null != function.apply(t) && null == map.putIfAbsent(function.apply(t), true); } /** * 生成雷达图 *

* ( 用户命中病历配置问题数 / 病历问题总数 ) * (用户提问命中病历配置问题数 / 用户实际提问的数量 ) *

* Q:是否要区分是否是正常的检查结果? * A:雷达图 不管正常异常检查结果 只看该不该检查这个项目 * Q:该不该,指的是病历的配置项是吗?只要配置了,就是该检查的 * A:是的 * * @param processId */ @Override public RadarChartResVO queryRadarChart(String processId) { Process process = Optional.ofNullable(processService.getById(processId)).orElseThrow(() -> new BusinessException("未找到流程")); // 生成问诊雷达图 ChartNodeVO askChart = computeAskChart(process); // 生成体格检查雷达图 ChartNodeVO physicalChart = computePhysicalChart(process); // 生成辅助检查雷达图 ChartNodeVO ancillaryChart = computeAncillaryChart(process); // 生成处置计划雷达图 ChartNodeVO treatmentPlanChart = computeTreatmentPlanChart(process); RadarChartResVO radarChartResVO = new RadarChartResVO(); radarChartResVO.setAskChart(askChart); radarChartResVO.setPhysicalChart(physicalChart); radarChartResVO.setAncillaryChart(ancillaryChart); radarChartResVO.setTreatmentPlanChart(treatmentPlanChart); BigDecimal clinicalThinking = NumberUtil.add(askChart.getNodePer(), physicalChart.getNodePer(), ancillaryChart.getNodePer(), treatmentPlanChart.getNodePer()).divide(BigDecimal.valueOf(4), 1, RoundingMode.HALF_UP); ChartNodeVO chartNodeVO = new ChartNodeVO(); chartNodeVO.setNodePer(clinicalThinking); chartNodeVO.setScoreLevel(chartNodeVO.computeScoreLevel()); chartNodeVO.setTotal(NumberUtil.add(askChart.getTotal(), physicalChart.getTotal(), ancillaryChart.getTotal(), treatmentPlanChart.getTotal()).intValue()); chartNodeVO.setCorrect(NumberUtil.add(askChart.getCorrect(), physicalChart.getCorrect(), ancillaryChart.getCorrect(), treatmentPlanChart.getCorrect()).intValue()); chartNodeVO.setUnCorrect(NumberUtil.add(askChart.getUnCorrect(), physicalChart.getUnCorrect(), ancillaryChart.getUnCorrect(), treatmentPlanChart.getUnCorrect()).intValue()); chartNodeVO.setStandard(NumberUtil.add(askChart.getStandard(), physicalChart.getStandard(), ancillaryChart.getStandard(), treatmentPlanChart.getStandard()).intValue()); radarChartResVO.setClinicalThinking(chartNodeVO); // 查询考核评估内容 ProcessEvaluation processEvaluation = processEvaluationService.lambdaQuery().eq(ProcessEvaluation::getProcessId, processId).one(); radarChartResVO.setProcessEvaluation(processEvaluation); return radarChartResVO; } /** * 生成处置计划雷达图 * ( 用户命中病历治疗计划配置问题数 / 疾病配置的治疗计划总数 ) * (用户命中病历治疗计划配置问题数 / 用户实际填写的治疗计划的数量 ) */ private ChartNodeVO computeTreatmentPlanChart(Process process) { // 查询用户填写的治疗计划(包含处置计划和用药计划) List userTreatmentPlanRecordList = treatmentPlanRecordService.lambdaQuery().eq(TreatmentPlanRecord::getProcessId, process.getId()).list(); int userTreatmentPlanCount = userTreatmentPlanRecordList.size(); // 2. 查询出疾病处置计划(疾病配置的处置计划) List diseaseTreatmentPlanResVos = diseaseTreatmentPlanService.queryListByDiseaseId(process.getDiseaseId()); Set treatmentPlanIdSet = diseaseTreatmentPlanResVos.stream().map(DiseaseTreatmentPlanResVo::getTreatmentPlanId).collect(Collectors.toSet()); // 3. 查出疾病处置计划用药(疾病配置的用药计划) List diseaseTreatmentPlanDrugList = diseaseTreatmentPlanDrugService.lambdaQuery().eq(DiseaseTreatmentPlanDrug::getDiseaseId, process.getDiseaseId()).list(); Set drugIdSet = diseaseTreatmentPlanDrugList.stream().map(DiseaseTreatmentPlanDrug::getDrugId).collect(Collectors.toSet()); // 计算总数时,只看疾病配置的处置计划(用药计划来自于处置计划) int medicalCount = diseaseTreatmentPlanResVos.size(); // 疾病配置的治疗计划ID集合,用来计算命中的数量 Collection planIdSet = CollUtil.union(treatmentPlanIdSet, drugIdSet); int hitPlanCount = 0; for (TreatmentPlanRecord treatmentPlanRecord : userTreatmentPlanRecordList) { // 需要分别看是否是药物计划 if (StrUtil.isNotBlank(treatmentPlanRecord.getTreatmentPlanId()) && planIdSet.contains(treatmentPlanRecord.getTreatmentPlanId())) { hitPlanCount++; continue; } if (StrUtil.isNotBlank(treatmentPlanRecord.getDrugId()) && planIdSet.contains(treatmentPlanRecord.getDrugId())) { hitPlanCount++; } } // 过程数据3:问诊vs问诊正确率 BigDecimal num3 = BigDecimal.ZERO; if (userTreatmentPlanCount > 0) { num3 = BigDecimal.valueOf(hitPlanCount).divide(BigDecimal.valueOf(userTreatmentPlanCount), 2, RoundingMode.HALF_UP); } // 过程数据2:问诊vs标准正确率 BigDecimal num2 = BigDecimal.ZERO; if (medicalCount > 0) { num2 = BigDecimal.valueOf(hitPlanCount).divide(BigDecimal.valueOf(medicalCount), 2, RoundingMode.HALF_UP); } ChartNodeVO chartNodeVO = new ChartNodeVO(); chartNodeVO.setNodePer(num2.multiply(num3).multiply(BigDecimal.valueOf(100))); chartNodeVO.setScoreLevel(chartNodeVO.computeScoreLevel()); chartNodeVO.setCorrect(hitPlanCount); chartNodeVO.setUnCorrect(medicalCount - hitPlanCount); chartNodeVO.setStandard(medicalCount); chartNodeVO.setTotal(NumberUtil.add(chartNodeVO.getUnCorrect(), chartNodeVO.getStandard(), chartNodeVO.getCorrect()).intValue()); return chartNodeVO; } /** * 生成辅助检查雷达图 * ( 用户命中病历配置问题数 / 病历问题总数 ) * (用户提问命中病历配置问题数 / 用户实际提问的数量 ) */ private ChartNodeVO computeAncillaryChart(Process process) { Long userHitCount = diagnosisAncillaryRecordService.lambdaQuery().isNotNull(DiagnosisAncillaryRecord::getAncillaryId) .eq(DiagnosisAncillaryRecord::getProcessId, process.getId()).count(); Long userCount = diagnosisAncillaryRecordService.lambdaQuery().eq(DiagnosisAncillaryRecord::getProcessId, process.getId()).count(); Long medicalCount = diseaseAncillaryService.lambdaQuery().eq(DiseaseAncillary::getDiseaseId, process.getDiseaseId()).count(); // 过程数据3:问诊vs问诊正确率 BigDecimal num3 = BigDecimal.ZERO; if (userCount > 0) { num3 = BigDecimal.valueOf(userHitCount).divide(BigDecimal.valueOf(userCount), 2, RoundingMode.HALF_UP); } // 过程数据2:问诊vs标准正确率 BigDecimal num2 = BigDecimal.ZERO; if (medicalCount > 0) { num2 = BigDecimal.valueOf(userHitCount).divide(BigDecimal.valueOf(medicalCount), 2, RoundingMode.HALF_UP); } ChartNodeVO chartNodeVO = new ChartNodeVO(); chartNodeVO.setNodePer(num2.multiply(num3).multiply(BigDecimal.valueOf(100))); chartNodeVO.setScoreLevel(chartNodeVO.computeScoreLevel()); chartNodeVO.setCorrect(Math.toIntExact(userHitCount)); chartNodeVO.setUnCorrect((int) (medicalCount - userHitCount)); chartNodeVO.setStandard(Math.toIntExact(medicalCount)); chartNodeVO.setTotal(NumberUtil.add(chartNodeVO.getUnCorrect(), chartNodeVO.getStandard(), chartNodeVO.getCorrect()).intValue()); return chartNodeVO; } /** * 计算体格检查雷达图 * 2. 体格检查:( 用户命中病历配置问题数 / 病历问题总数 ) * (用户提问命中病历配置问题数 / 用户实际提问的数量 ) */ private ChartNodeVO computePhysicalChart(Process process) { // 查询用户命中病历配置问题数 Long userHitCount = diagnosisPhysicalRecordService.lambdaQuery().isNotNull(DiagnosisPhysicalRecord::getPhysicalId) .eq(DiagnosisPhysicalRecord::getProcessId, process.getId()).count(); // 查询用户实际检查数量 Long userCount = diagnosisPhysicalRecordService.lambdaQuery().eq(DiagnosisPhysicalRecord::getProcessId, process.getId()).count(); // 查询病例配置的数量 Long medicalCount = diseasePhysicalService.lambdaQuery().eq(DiseasePhysical::getDiseaseId, process.getDiseaseId()).count(); // 过程数据3:问诊vs问诊正确率 BigDecimal num3 = BigDecimal.ZERO; if (userCount > 0) { num3 = BigDecimal.valueOf(userHitCount).divide(BigDecimal.valueOf(userCount), 2, RoundingMode.HALF_UP); } // 过程数据2:问诊vs标准正确率 BigDecimal num2 = BigDecimal.ZERO; if (medicalCount > 0) { num2 = BigDecimal.valueOf(userHitCount).divide(BigDecimal.valueOf(medicalCount), 2, RoundingMode.HALF_UP); } ChartNodeVO chartNodeVO = new ChartNodeVO(); chartNodeVO.setNodePer(num2.multiply(num3).multiply(BigDecimal.valueOf(100))); chartNodeVO.setScoreLevel(chartNodeVO.computeScoreLevel()); chartNodeVO.setCorrect(Math.toIntExact(userHitCount)); chartNodeVO.setUnCorrect((int) (medicalCount - userHitCount)); chartNodeVO.setStandard(Math.toIntExact(medicalCount)); chartNodeVO.setTotal(NumberUtil.add(chartNodeVO.getUnCorrect(), chartNodeVO.getStandard(), chartNodeVO.getCorrect()).intValue()); return chartNodeVO; } /** * 生成问诊雷达图数据 * 1. 问诊: ( 用户提问命中病历配置问题数 / 病历问题总数 ) * (用户提问命中病历配置问题数 / 用户实际提问的数量 ) * 问诊vs标准正确率 * 问诊vs问诊正确率 = 综合正确率 * 上面的数量都是去重的,未识别出来的问题,不包含在用户提问的数据里面 * 默认语句不参与统计 */ public ChartNodeVO computeAskChart(Process process) { // 首先查询用户提问的病历问题(这里questionId不为null,即为识别出来的用户问题) List qaRecordList = diagnosisQaRecordService.lambdaQuery().isNotNull(DiagnosisQaRecord::getQuestionLibraryId) .eq(DiagnosisQaRecord::getProcessId, process.getId()).list(); // 用户实际提问数量(包含默认问题) Set userQuestionIdSet = qaRecordList.stream().map(DiagnosisQaRecord::getQuestionLibraryId).collect(Collectors.toSet()); // 查询病例配置的问题 List answerList = askPatientAnswerService.lambdaQuery().eq(AskPatientAnswer::getMedicalId, process.getMedicalRecId()).list(); // 病历问题总数(统计非默认语句的病历问题总数) long medicalQuestionCount = answerList.stream().filter(e -> ObjectUtil.isNotEmpty(e.getAnswerType()) && 1 == e.getAnswerType()).count(); Set defaultqQuestionIdSet = answerList.stream().filter(e -> ObjectUtil.isNotEmpty(e.getAnswerType()) && 0 == e.getAnswerType()).map(AskPatientAnswer::getLibraryQuestionId).collect(Collectors.toSet()); userQuestionIdSet.removeAll(defaultqQuestionIdSet); // 用户实际提问的数量(去除默认问题) int userQuestionCount = userQuestionIdSet.size(); // 用户提问命中病历配置问题数(去除默认问题之后的数量) userQuestionIdSet.removeAll(defaultqQuestionIdSet); int userHitQuestionCount = userQuestionIdSet.size(); // 过程数据3:问诊vs问诊正确率 BigDecimal num3 = BigDecimal.ZERO; if (userQuestionCount > 0) { num3 = BigDecimal.valueOf(userHitQuestionCount).divide(BigDecimal.valueOf(userQuestionCount), 2, RoundingMode.HALF_UP); } // 过程数据2:问诊vs标准正确率 BigDecimal num2 = BigDecimal.ZERO; if (medicalQuestionCount > 0) { num2 = BigDecimal.valueOf(userHitQuestionCount).divide(BigDecimal.valueOf(medicalQuestionCount), 2, RoundingMode.HALF_UP); } ChartNodeVO chartNodeVO = new ChartNodeVO(); chartNodeVO.setNodePer(num2.multiply(num3).multiply(BigDecimal.valueOf(100))); chartNodeVO.setScoreLevel(chartNodeVO.computeScoreLevel()); chartNodeVO.setCorrect(userHitQuestionCount); chartNodeVO.setStandard(Integer.parseInt(String.valueOf(medicalQuestionCount))); chartNodeVO.setUnCorrect(NumberUtil.sub(chartNodeVO.getStandard(), chartNodeVO.getCorrect()).intValue()); chartNodeVO.setTotal(NumberUtil.add(chartNodeVO.getUnCorrect(), chartNodeVO.getStandard(), chartNodeVO.getCorrect()).intValue()); return chartNodeVO; } }