| | |
| | | } else { |
| | | groupKey = "deptcode"; |
| | | } |
| | | } else if (serviceSubtaskCountReq.getStatisticaltype() != null && serviceSubtaskCountReq.getStatisticaltype() == 3) { |
| | | // 病种统计:按任务ID分组,每个任务即一个病种随访任务 |
| | | groupKey = "taskid"; |
| | | } |
| | | List<ServiceSubtaskStatistic> serviceSubtaskStatistics = new ArrayList<>(); |
| | | // 根据条件进行分组 |
| | |
| | | case "leavehospitaldistrictcode": |
| | | collect = rawData.stream().collect(Collectors.groupingBy(subtask -> Optional.ofNullable(subtask.getLeavehospitaldistrictcode()).orElse("Unknown"))); |
| | | break; |
| | | case "taskid": |
| | | collect = rawData.stream().collect(Collectors.groupingBy(subtask -> Optional.ofNullable(subtask.getTaskid()).map(String::valueOf).orElse("Unknown"))); |
| | | break; |
| | | default: |
| | | collect = rawData.stream().collect(Collectors.groupingBy(subtask -> Optional.ofNullable(subtask.getDrcode()).orElse("Unknown"))); |
| | | break; |
| | |
| | | continue; |
| | | } |
| | | ServiceSubtaskStatistic statistic = getStatistic(serviceSubtaskList, serviceSubtaskCountReq.getFollowUpCountStyle(), serviceSubtaskCountReq.getVisitCount()); |
| | | if ("taskid".equals(groupKey)) { |
| | | applyTaskGroupInfo(statistic, serviceSubtaskList); |
| | | } |
| | | if (ObjectUtils.isNotEmpty(jsRates)) { |
| | | Map<String, Object> jsRateMap = jsRates.get(collectKey); |
| | | BigDecimal jsRate = new BigDecimal("0"); |
| | |
| | | ssRate.setRateDay(serviceSubtaskCountReq.getRateDay()); |
| | | Map<String, Map<String, Object>> jsRates = new HashMap<>(); |
| | | if (!collect.isEmpty()) { |
| | | jsRates = serviceSubtaskMapper.selectTimelyRateBatch(ssRate); |
| | | Map<String, Map<String, Object>> rateResult = serviceSubtaskMapper.selectTimelyRateBatch(ssRate); |
| | | if (rateResult != null && !rateResult.isEmpty()) { |
| | | // taskid 为数值类型,MyBatis 返回的 Map key 可能是 Long,这里统一转成 String 与分组 key 对齐 |
| | | for (Map.Entry<String, Map<String, Object>> entry : rateResult.entrySet()) { |
| | | jsRates.put(String.valueOf(entry.getKey()), entry.getValue()); |
| | | } |
| | | } |
| | | } |
| | | return jsRates; |
| | | } |
| | |
| | | ServiceSubtaskStatistic totalRow = calculateTotalRow(sfStatistics); |
| | | totalRow.setLeavehospitaldistrictname("总计"); |
| | | totalRow.setDeptname("总计"); |
| | | if (serviceSubtaskCountReq.getStatisticaltype() != null && serviceSubtaskCountReq.getStatisticaltype() == 3) { |
| | | totalRow.setTaskName("总计"); |
| | | } |
| | | sfStatistics.add(totalRow); |
| | | } |
| | | |
| | |
| | | return map; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 病种统计(按 taskid 分组)时补齐任务ID、任务名称和疾病病种。 |
| | | * |
| | | * @param statistic 统计结果 |
| | | * @param serviceSubtaskList 当前任务分组下的子任务 |
| | | */ |
| | | private void applyTaskGroupInfo(ServiceSubtaskStatistic statistic, List<ServiceSubtask> serviceSubtaskList) { |
| | | if (statistic == null || CollectionUtils.isEmpty(serviceSubtaskList)) { |
| | | return; |
| | | } |
| | | ServiceSubtask first = serviceSubtaskList.get(0); |
| | | statistic.setTaskId(first.getTaskid()); |
| | | statistic.setTaskName(first.getTaskName()); |
| | | statistic.setDiagType(first.getDiagType()); |
| | | } |
| | | |
| | | private ServiceSubtaskStatistic getStatistic(List<ServiceSubtask> serviceSubtaskList, String followUpCountStyle, Integer visitCount) { |
| | | ServiceSubtaskStatistic serviceSubtaskStatistic = new ServiceSubtaskStatistic(); |
| | |
| | | } |
| | | |
| | | /** |
| | | * 市一统计口径:再次待随访、已发送及人工电话超时。 |
| | | * 再次随访附加统计:待随访、已发送、人工电话超时及回院复诊复查(suggest=6)。 |
| | | */ |
| | | private void applyAgainFollowUpExtraStatistics(ServiceSubtaskStatistic statistic, ServiceSubtask serviceSubtask) { |
| | | if (serviceSubtask.getVisitCount() == null || serviceSubtask.getVisitCount() <= 1 || serviceSubtask.getSendstate() == null) { |
| | | if (serviceSubtask.getVisitCount() == null || serviceSubtask.getVisitCount() <= 1) { |
| | | return; |
| | | } |
| | | if (serviceSubtask.getSendstate() == null) { |
| | | return; |
| | | } |
| | | Long sendstate = serviceSubtask.getSendstate(); |
| | | // 回院复诊复查:再次随访中按处理意见 suggest=6 统计 |
| | | if (StringUtils.equals("6", StringUtils.trim(serviceSubtask.getSuggest()))) { |
| | | statistic.setSuggest6CountAgain(statistic.getSuggest6CountAgain() + 1L); |
| | | } |
| | | if (sendstate.equals(3L)) { |
| | | statistic.setSentAgain(statistic.getSentAgain() + 1L); |
| | | } |
| | |
| | | * pendingFollowUpSentAgainInfo - visitCount > 1 && sendstate in (3,7) |
| | | * sentInfo - visitCount = 1 && sendstate = 3 |
| | | * sentAgainInfo - visitCount > 1 && sendstate = 3 |
| | | * suggest6CountAgainInfo - visitCount > 1 && suggest = 6 |
| | | * filterCountList - taskSituation = 6 && sendstate = 4 |
| | | * |
| | | */ |
| | |
| | | serviceSubtaskCountReq.setExcep(null); |
| | | serviceSubtaskCountReq.setTaskSituation(null); |
| | | serviceSubtaskCountReq.setFinishState(null); |
| | | serviceSubtaskCountReq.setSuggest(null); |
| | | |
| | | switch (hyperLinkInfoType) { |
| | | case "dischargeCountInfo": |
| | |
| | | serviceSubtaskCountReq.setVisitCount(2); |
| | | serviceSubtaskCountReq.setExcep("1"); |
| | | break; |
| | | case "suggest6CountAgainInfo": |
| | | // 再次随访回院复诊复查:visitCount > 1 且 suggest = 6 |
| | | serviceSubtaskCountReq.setVisitCount(2); |
| | | serviceSubtaskCountReq.setSuggest("6"); |
| | | break; |
| | | case "taskSituation1Info": |
| | | serviceSubtaskCountReq.setTaskSituation(1); |
| | | break; |
| | |
| | | } else { |
| | | groupKey = "deptcode"; |
| | | } |
| | | } else if (serviceSubtaskCountReq.getStatisticaltype() != null && serviceSubtaskCountReq.getStatisticaltype() == 3) { |
| | | // 病种统计:按任务ID分组 |
| | | groupKey = "taskid"; |
| | | } |
| | | serviceSubtaskCountReq.setGroupKey(groupKey); |
| | | List<String> groupKeyList = serviceSubtaskMapper.getSfStatisticsGroupKey(serviceSubtaskCountReq); |
| | |
| | | break; |
| | | case "leavehospitaldistrictcode": |
| | | collect = rawData.stream().collect(Collectors.groupingBy(subtask -> Optional.ofNullable(subtask.getLeavehospitaldistrictcode()).orElse("Unknown"))); |
| | | break; |
| | | case "taskid": |
| | | collect = rawData.stream().collect(Collectors.groupingBy(subtask -> Optional.ofNullable(subtask.getTaskid()).map(String::valueOf).orElse("Unknown"))); |
| | | break; |
| | | default: |
| | | collect = rawData.stream().collect(Collectors.groupingBy(subtask -> Optional.ofNullable(subtask.getDrcode()).orElse("Unknown"))); |
| | |
| | | continue; |
| | | } |
| | | ServiceSubtaskStatistic statistic = getStatisticCategory(serviceSubtaskList, serviceSubtaskCountReq, subCounts); |
| | | if ("taskid".equals(groupKey)) { |
| | | applyTaskGroupInfo(statistic, serviceSubtaskList); |
| | | } |
| | | if (ObjectUtils.isNotEmpty(jsRates)) { |
| | | Map<String, Object> jsRateMap = jsRates.get(collectKey); |
| | | BigDecimal jsRate = new BigDecimal("0"); |
| | |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 问题选项数字下钻:返回选择了指定选项的 service_subtask 列表。 |
| | | * <p> |
| | | * 统计明细中的选项数量来自 service_subtask_detail 的 |
| | | * IFNULL(matchedtext, asrtext),因此下钻必须使用同一题目的相同选项进行匹配。 |
| | | * |
| | | * @param serviceSubtaskCountReq 下钻条件 |
| | | * @return service_subtask 列表 |
| | | */ |
| | | @Override |
| | | public List<ServiceSubtask> getSfStatisticsScriptDetailsHyperlink(ServiceSubtaskCountReq serviceSubtaskCountReq) { |
| | | log.info("getSfStatisticsScriptDetailsHyperlink的入参为:{}", serviceSubtaskCountReq); |
| | | if (serviceSubtaskCountReq == null) { |
| | | return new ArrayList<>(); |
| | | } |
| | | // 兼容前端直接回传统计明细行中的 subtaskType |
| | | if (StringUtils.isBlank(serviceSubtaskCountReq.getType()) |
| | | && StringUtils.isNotBlank(serviceSubtaskCountReq.getSubtaskType())) { |
| | | serviceSubtaskCountReq.setType(serviceSubtaskCountReq.getSubtaskType()); |
| | | } |
| | | resolveScriptContentAndType(serviceSubtaskCountReq); |
| | | if (StringUtils.isBlank(serviceSubtaskCountReq.getScriptContent()) |
| | | && serviceSubtaskCountReq.getScriptid() == null) { |
| | | log.warn("getSfStatisticsScriptDetailsHyperlink-题目scriptid和scriptContent均为空,返回空列表"); |
| | | return new ArrayList<>(); |
| | | } |
| | | if (serviceSubtaskCountReq.getOptionText() == null) { |
| | | log.warn("getSfStatisticsScriptDetailsHyperlink-选项optionText为空,返回空列表"); |
| | | return new ArrayList<>(); |
| | | } |
| | | return serviceSubtaskMapper.getSfStatisticsScriptDetailsHyperlink(serviceSubtaskCountReq); |
| | | } |
| | | |
| | | /** |
| | | * 根据 scriptid 补齐题目内容和任务类型。 |
| | | * <p> |
| | | * 统计明细按“题目内容 + 任务类型”合并,同一道题复制到多个任务模板时 scriptid 可能不同, |
| | | * 因此优先按题目内容下钻;只有查不到题目内容时才退化为 scriptid 精确匹配。 |
| | | */ |
| | | private void resolveScriptContentAndType(ServiceSubtaskCountReq serviceSubtaskCountReq) { |
| | | if (serviceSubtaskCountReq.getScriptid() == null) { |
| | | return; |
| | | } |
| | | // 已有题目内容和任务类型时无需再查模板问题表 |
| | | if (StringUtils.isNotBlank(serviceSubtaskCountReq.getScriptContent()) |
| | | && StringUtils.isNotBlank(serviceSubtaskCountReq.getType())) { |
| | | return; |
| | | } |
| | | |
| | | String type = serviceSubtaskCountReq.getType(); |
| | | if (StringUtils.isBlank(type) || "1".equals(type)) { |
| | | IvrTaskTemplateScript ivrTaskTemplateScript = |
| | | iIvrTaskTemplateScriptService.selectIvrTaskTemplateScriptByID(serviceSubtaskCountReq.getScriptid()); |
| | | if (ObjectUtils.isNotEmpty(ivrTaskTemplateScript)) { |
| | | if (StringUtils.isBlank(serviceSubtaskCountReq.getType())) { |
| | | serviceSubtaskCountReq.setType("1"); |
| | | } |
| | | if (StringUtils.isBlank(serviceSubtaskCountReq.getScriptContent())) { |
| | | serviceSubtaskCountReq.setScriptContent(ivrTaskTemplateScript.getScriptContent()); |
| | | } |
| | | return; |
| | | } |
| | | // 明确指定了语音类型时不再尝试问卷表 |
| | | if (StringUtils.isNotBlank(type)) { |
| | | return; |
| | | } |
| | | } |
| | | |
| | | if (StringUtils.isBlank(serviceSubtaskCountReq.getType()) || "2".equals(type)) { |
| | | SvyTaskTemplateScript svyTaskTemplateScript = |
| | | svyTaskTemplateScriptService.selectSvyTaskTemplateScriptByID(serviceSubtaskCountReq.getScriptid()); |
| | | if (ObjectUtils.isNotEmpty(svyTaskTemplateScript)) { |
| | | if (StringUtils.isBlank(serviceSubtaskCountReq.getType())) { |
| | | serviceSubtaskCountReq.setType("2"); |
| | | } |
| | | if (StringUtils.isBlank(serviceSubtaskCountReq.getScriptContent())) { |
| | | serviceSubtaskCountReq.setScriptContent(svyTaskTemplateScript.getScriptContent()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @param serviceSubtask |
| | |
| | | total.setSentAgain(0L); |
| | | total.setFollowUpSuccessAgain(0L); |
| | | total.setFollowUpFailAgain(0L); |
| | | total.setSuggest6CountAgain(0L); |
| | | total.setManualAgain(0L); |
| | | total.setSmsAgain(0L); |
| | | total.setWeChatAgain(0L); |
| | |
| | | total.setSentAgain(total.getSentAgain() + (stat.getSentAgain() != null ? stat.getSentAgain() : 0L)); |
| | | total.setFollowUpSuccessAgain(total.getFollowUpSuccessAgain() + (stat.getFollowUpSuccessAgain() != null ? stat.getFollowUpSuccessAgain() : 0L)); |
| | | total.setFollowUpFailAgain(total.getFollowUpFailAgain() + (stat.getFollowUpFailAgain() != null ? stat.getFollowUpFailAgain() : 0L)); |
| | | total.setSuggest6CountAgain(total.getSuggest6CountAgain() + (stat.getSuggest6CountAgain() != null ? stat.getSuggest6CountAgain() : 0L)); |
| | | total.setManualAgain(total.getManualAgain() + (stat.getManualAgain() != null ? stat.getManualAgain() : 0L)); |
| | | total.setSmsAgain(total.getSmsAgain() + (stat.getSmsAgain() != null ? stat.getSmsAgain() : 0L)); |
| | | total.setWeChatAgain(total.getWeChatAgain() + (stat.getWeChatAgain() != null ? stat.getWeChatAgain() : 0L)); |