From efde7398c10bdd10cb4612c162f14169084fdc50 Mon Sep 17 00:00:00 2001 From: liu Date: Mon, 5 Feb 2024 13:12:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E9=9B=B7=E8=BE=BE=E5=9B=BE?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AskDiagnosisResultController.java | 14 +- .../supervision/pojo/vo/RadarChartResVO.java | 20 ++ .../service/AskDiagnosisResultService.java | 5 +- .../impl/AskDiagnosisResultServiceImpl.java | 171 +++++++++++++++++- 4 files changed, 204 insertions(+), 6 deletions(-) create mode 100644 virtual-patient-web/src/main/java/com/supervision/pojo/vo/RadarChartResVO.java diff --git a/virtual-patient-web/src/main/java/com/supervision/controller/AskDiagnosisResultController.java b/virtual-patient-web/src/main/java/com/supervision/controller/AskDiagnosisResultController.java index 313e5b9e..e4245d1b 100644 --- a/virtual-patient-web/src/main/java/com/supervision/controller/AskDiagnosisResultController.java +++ b/virtual-patient-web/src/main/java/com/supervision/controller/AskDiagnosisResultController.java @@ -1,12 +1,14 @@ package com.supervision.controller; import com.supervision.pojo.vo.DiagnosisResultResVO; -import com.supervision.pojo.vo.FinishAskReqVO; +import com.supervision.pojo.vo.RadarChartResVO; import com.supervision.service.AskDiagnosisResultService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; @Api(tags = "评估详情") @RestController @@ -18,7 +20,13 @@ public class AskDiagnosisResultController { @ApiOperation("查询最终诊断结果") @GetMapping("queryDiagnosisResult") - public DiagnosisResultResVO queryDiagnosisResult(String processId){ + public DiagnosisResultResVO queryDiagnosisResult(String processId) { return askDiagnosisResultService.queryDiagnosisResult(processId); } + + @ApiOperation("查询诊断结果的雷达图") + @GetMapping("queryRadarChart") + public RadarChartResVO queryRadarChart(String processId) { + return askDiagnosisResultService.queryRadarChart(processId); + } } diff --git a/virtual-patient-web/src/main/java/com/supervision/pojo/vo/RadarChartResVO.java b/virtual-patient-web/src/main/java/com/supervision/pojo/vo/RadarChartResVO.java new file mode 100644 index 00000000..99d7cf2d --- /dev/null +++ b/virtual-patient-web/src/main/java/com/supervision/pojo/vo/RadarChartResVO.java @@ -0,0 +1,20 @@ +package com.supervision.pojo.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class RadarChartResVO { + + // 生成问诊雷达图 + private BigDecimal askChart; + // 生成体格检查雷达图 + private BigDecimal physicalChart; + // 生成辅助检查雷达图 + private BigDecimal ancillaryChart; + // 生成处置计划雷达图 + private BigDecimal treatmentPlanChart; + // 临床思维=前面几项平均值 + private BigDecimal clinicalThinking; +} diff --git a/virtual-patient-web/src/main/java/com/supervision/service/AskDiagnosisResultService.java b/virtual-patient-web/src/main/java/com/supervision/service/AskDiagnosisResultService.java index b76ce9e6..feb6da81 100644 --- a/virtual-patient-web/src/main/java/com/supervision/service/AskDiagnosisResultService.java +++ b/virtual-patient-web/src/main/java/com/supervision/service/AskDiagnosisResultService.java @@ -1,10 +1,11 @@ package com.supervision.service; import com.supervision.pojo.vo.DiagnosisResultResVO; -import com.supervision.pojo.vo.FinishAskReqVO; -import org.springframework.web.bind.annotation.RequestBody; +import com.supervision.pojo.vo.RadarChartResVO; public interface AskDiagnosisResultService { DiagnosisResultResVO queryDiagnosisResult(String processId); + + RadarChartResVO queryRadarChart(String processId); } diff --git a/virtual-patient-web/src/main/java/com/supervision/service/impl/AskDiagnosisResultServiceImpl.java b/virtual-patient-web/src/main/java/com/supervision/service/impl/AskDiagnosisResultServiceImpl.java index 1f3a5429..47feeb7b 100644 --- a/virtual-patient-web/src/main/java/com/supervision/service/impl/AskDiagnosisResultServiceImpl.java +++ b/virtual-patient-web/src/main/java/com/supervision/service/impl/AskDiagnosisResultServiceImpl.java @@ -4,10 +4,12 @@ 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.model.*; +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; @@ -17,6 +19,8 @@ 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.Function; @@ -49,6 +53,10 @@ public class AskDiagnosisResultServiceImpl implements AskDiagnosisResultService private final DiseaseTreatmentPlanDrugService diseaseTreatmentPlanDrugService; + private final DiseasePhysicalService diseasePhysicalService; + + private final DiseaseAncillaryService diseaseAncillaryService; + @Override public DiagnosisResultResVO queryDiagnosisResult(String processId) { @@ -284,4 +292,165 @@ public class AskDiagnosisResultServiceImpl implements AskDiagnosisResultService } + /** + * 生成雷达图 + *

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

+ * Q:是否要区分是否是正常的检查结果? + * A:雷达图 不管正常异常检查结果 只看该不该检查这个项目 + * Q:该不该,指的是病历的配置项是吗?只要配置了,就是该检查的 + * A:是的 + * + * @param processId + */ + @Override + public RadarChartResVO queryRadarChart(String processId) { + Process process = Optional.ofNullable(processService.getById(processId)).orElseThrow(() -> new BusinessException("未找到流程")); + // 生成问诊雷达图 + BigDecimal askChart = computeAskChart(process); + // 生成体格检查雷达图 + BigDecimal physicalChart = computePhysicalChart(process); + // 生成辅助检查雷达图 + BigDecimal ancillaryChart = computeAncillaryChart(process); + // 生成处置计划雷达图 + BigDecimal treatmentPlanChart = computeTreatmentPlanChart(process); + RadarChartResVO radarChartResVO = new RadarChartResVO(); + radarChartResVO.setAskChart(askChart); + radarChartResVO.setPhysicalChart(physicalChart); + radarChartResVO.setAncillaryChart(ancillaryChart); + radarChartResVO.setTreatmentPlanChart(treatmentPlanChart); + BigDecimal clinicalThinking = NumberUtil.add(askChart, physicalChart, ancillaryChart, treatmentPlanChart).divide(BigDecimal.valueOf(4), 1, RoundingMode.HALF_UP); + radarChartResVO.setClinicalThinking(clinicalThinking); + return radarChartResVO; + + + } + + /** + * 生成处置计划雷达图 + * ( 用户命中病历治疗计划配置问题数 / 疾病配置的治疗计划总数 ) * (用户命中病历治疗计划配置问题数 / 用户实际填写的治疗计划的数量 ) + */ + private BigDecimal computeTreatmentPlanChart(Process process) { + // 查询用户填写的治疗计划 + List userTreatmentPlanRecordList = treatmentPlanRecordService.lambdaQuery().eq(TreatmentPlanRecord::getProcessId, process.getId()).list(); + int userTreatmentPlanCount = userTreatmentPlanRecordList.size(); + // 查询疾病配置的治疗计划 + List planList = diseaseTreatmentPlanService.lambdaQuery().eq(DiseaseTreatmentPlan::getDiseaseId, process.getDiseaseId()).select(DiseaseTreatmentPlan::getId).list(); + List planIdList = planList.stream().map(DiseaseTreatmentPlan::getId).collect(Collectors.toList()); + // 疾病配置的治疗计划总数 + int medicalCount = planIdList.size(); + // 找到用户配置的药物计划 + List drugList = diseaseTreatmentPlanDrugService.lambdaQuery().eq(DiseaseTreatmentPlanDrug::getDiseaseId, process.getDiseaseId()).select(DiseaseTreatmentPlanDrug::getDrugId).list(); + List drugIdList = drugList.stream().map(DiseaseTreatmentPlanDrug::getDrugId).collect(Collectors.toList()); + int hitPlanCount = 0; + for (TreatmentPlanRecord treatmentPlanRecord : userTreatmentPlanRecordList) { + // 需要分别看是否是药物计划 + if (StrUtil.isNotBlank(treatmentPlanRecord.getTreatmentPlanId()) && planIdList.contains(treatmentPlanRecord.getTreatmentPlanId())) { + hitPlanCount++; + } + if (StrUtil.isNotBlank(treatmentPlanRecord.getDrugId()) && drugIdList.contains(treatmentPlanRecord.getDrugId())) { + hitPlanCount++; + } + } + // 过程数据3:问诊vs问诊正确率 + BigDecimal num3 = BigDecimal.ZERO; + if (userTreatmentPlanCount > 0) { + num3 = BigDecimal.valueOf(hitPlanCount).divide(BigDecimal.valueOf(userTreatmentPlanCount), 1, RoundingMode.HALF_UP); + } + // 过程数据2:问诊vs标准正确率 + BigDecimal num2 = BigDecimal.ZERO; + if (medicalCount > 0) { + num2 = BigDecimal.valueOf(hitPlanCount).divide(BigDecimal.valueOf(medicalCount), 1, RoundingMode.HALF_UP); + } + return num2.multiply(num3); + + } + + /** + * 生成辅助检查雷达图 + * ( 用户命中病历配置问题数 / 病历问题总数 ) * (用户提问命中病历配置问题数 / 用户实际提问的数量 ) + */ + private BigDecimal computeAncillaryChart(Process process) { + Integer userHitCount = diagnosisAncillaryRecordService.lambdaQuery().isNotNull(DiagnosisAncillaryRecord::getAncillaryId) + .eq(DiagnosisAncillaryRecord::getProcessId, process.getId()).count(); + Integer userCount = diagnosisAncillaryRecordService.lambdaQuery().eq(DiagnosisAncillaryRecord::getProcessId, process.getId()).count(); + Integer 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), 1, RoundingMode.HALF_UP); + } + // 过程数据2:问诊vs标准正确率 + BigDecimal num2 = BigDecimal.ZERO; + if (medicalCount > 0) { + num2 = BigDecimal.valueOf(userHitCount).divide(BigDecimal.valueOf(medicalCount), 1, RoundingMode.HALF_UP); + } + return num2.multiply(num3); + } + + /** + * 计算体格检查雷达图 + * 2. 体格检查:( 用户命中病历配置问题数 / 病历问题总数 ) * (用户提问命中病历配置问题数 / 用户实际提问的数量 ) + */ + private BigDecimal computePhysicalChart(Process process) { + // 查询用户命中病历配置问题数 + Integer userHitCount = diagnosisPhysicalRecordService.lambdaQuery().isNotNull(DiagnosisPhysicalRecord::getPhysicalId) + .eq(DiagnosisPhysicalRecord::getProcessId, process.getId()).count(); + // 查询用户实际检查数量 + Integer userCount = diagnosisPhysicalRecordService.lambdaQuery().eq(DiagnosisPhysicalRecord::getProcessId, process.getId()).count(); + // 查询病例配置的数量 + Integer 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), 1, RoundingMode.HALF_UP); + } + // 过程数据2:问诊vs标准正确率 + BigDecimal num2 = BigDecimal.ZERO; + if (medicalCount > 0) { + num2 = BigDecimal.valueOf(userHitCount).divide(BigDecimal.valueOf(medicalCount), 1, RoundingMode.HALF_UP); + } + return num2.multiply(num3); + } + + + /** + * 生成问诊雷达图数据 + * 1. 问诊: ( 用户提问命中病历配置问题数 / 病历问题总数 ) * (用户提问命中病历配置问题数 / 用户实际提问的数量 ) + * 问诊vs标准正确率 * 问诊vs问诊正确率 = 综合正确率 + * 上面的数量都是去重的,未识别出来的问题,不包含在用户提问的数据里面 + * 默认语句不参与统计 + */ + public BigDecimal 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(); + // 用户提问命中病历配置问题数(去除默认问题之后的交集) + Collection intersection = CollUtil.intersection(defaultqQuestionIdSet, answerList.stream().map(AskPatientAnswer::getLibraryQuestionId).collect(Collectors.toSet())); + int userHitQuestionCount = intersection.size(); + + // 过程数据3:问诊vs问诊正确率 + BigDecimal num3 = BigDecimal.ZERO; + if (userQuestionCount > 0) { + num3 = BigDecimal.valueOf(userHitQuestionCount).divide(BigDecimal.valueOf(userQuestionCount), 1, RoundingMode.HALF_UP); + } + // 过程数据2:问诊vs标准正确率 + BigDecimal num2 = BigDecimal.ZERO; + if (medicalQuestionCount > 0) { + num2 = BigDecimal.valueOf(userHitQuestionCount).divide(BigDecimal.valueOf(medicalQuestionCount), 1, RoundingMode.HALF_UP); + } + + return num2.multiply(num3); + } }