smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java
@@ -315,6 +315,182 @@
        return result;
    }
    /**
     * 患者满意度统计(维度)
     *
     * @param patSatisfactionReqVO 患者满意度统计条件
     * @return 患者满意度统计结果
     */
    @Override
    public PatSatisfactionResVO statisticsByDimension(PatSatisfactionReqVO patSatisfactionReqVO) {
        //定义返参
        PatSatisfactionResVO result = new PatSatisfactionResVO();
        //答题总人数(已经回答问题的)
        int totalPerson = 0;
        // 总人数(包含未回答的)
        int allPerson = 0;
        //患者满意度统详情
        List<PatSatisfactionDetailEntity> patSatisfactionDetailEntities = new ArrayList<>();
        List<ServiceSubtask> serviceSubtasks = serviceSubtaskMapper.selectSatisfactionSubtaskList(patSatisfactionReqVO);
        // 按type分组:1-语音,2-问卷
        Map<String, List<ServiceSubtask>> groupByType = serviceSubtasks.stream().filter(s -> s.getType() != null).collect(Collectors.groupingBy(ServiceSubtask::getType));
        List<ServiceSubtask> voiceList = groupByType.getOrDefault("1", Collections.emptyList());
        List<ServiceSubtask> questionnaireList = groupByType.getOrDefault("2", Collections.emptyList());
        if (CollectionUtils.isNotEmpty(voiceList)) {
            //1. 先获取入参中的维护集合
            IvrLibaTemplateScript iltscript = new IvrLibaTemplateScript();
            iltscript.setDimensionList(patSatisfactionReqVO.getDimensionList());
            //2 再获取该问题满意度分类下的IvrLibaTemplateScript的集合
            List<IvrLibaTemplateScript> ivrLibaTemplateScripts = ivrLibaTemplateScriptMapper.selectILTSBydimension(iltscript);
            if (CollectionUtils.isNotEmpty(ivrLibaTemplateScripts)) {
                //3 再通过单个ivr_liba_template获取到所有的满意度问题 和 使用该模板的subTask人数
                for (IvrLibaTemplateScript ivrLibaTemplateScript : ivrLibaTemplateScripts) {
                    //记录单个明细信息
                    PatSatisfactionDetailEntity patSatisfactionDetailEntity = new PatSatisfactionDetailEntity();
                    //通过问题ID,获取问题选项(为了获取选项上的最高分最低分)
                    IvrLibaTemplateTargetoption ivrLibaTemplateTargetoption = new IvrLibaTemplateTargetoption();
                    ivrLibaTemplateTargetoption.setScriptid(ivrLibaTemplateScript.getScriptid());
                    List<IvrLibaTemplateTargetoption> ivrLibaTemplateTargetoptions = ivrLibaTemplateTargetoptionMapper.selectIvrLibaTemplateTargetoptionList(ivrLibaTemplateTargetoption);
                    //获取libTemplateId
                    List<Long> libTemplateIds = new ArrayList<>();
                    libTemplateIds.add(ivrLibaTemplateScript.getTemplateid());
                    // 再通过模板id获取问题发送总量
                    ServiceSubtaskSatisfactionEntity serviceSubtaskSatisfactionEntity = DtoConversionUtils.sourceToTarget(patSatisfactionReqVO, ServiceSubtaskSatisfactionEntity.class);
                    serviceSubtaskSatisfactionEntity.setLibTemplateIds(libTemplateIds);
                    serviceSubtaskSatisfactionEntity.setType(1);
                    List<Long> subids = serviceSubtaskMapper.querySendCount(serviceSubtaskSatisfactionEntity);
                    //获取填报数量
                    List<ServiceSubtaskDetailDTO> fillCount = null;
                    if (CollectionUtils.isNotEmpty(subids))
                        fillCount = serviceSubtaskDetailMapper.queryFillCount(subids, ivrLibaTemplateScript.getScriptContent());
                    // 根据matchedtext分组,统计各选项数量及占比
                    Map<String, Map<String, Object>> matchedtextStats = new HashMap<>();
                    if (CollectionUtils.isNotEmpty(fillCount)) {
                        int totalFill = fillCount.size();
                        fillCount.stream().filter(dto -> dto.getMatchedtext() != null).collect(Collectors.groupingBy(ServiceSubtaskDetailDTO::getMatchedtext, Collectors.counting())).forEach((matchedtext, count) -> {
                            Map<String, Object> stat = new HashMap<>();
                            stat.put("count", count);
                            stat.put("ratio", new BigDecimal((double) count / totalFill * 100).setScale(1, RoundingMode.HALF_UP).doubleValue());
                            matchedtextStats.put(matchedtext, stat);
                        });
                        // 从fillCount中取targetvalue(&分隔的当前问题的所有选项),补全未出现的选项,count和ratio均为0
                        fillCount.stream().filter(dto -> dto.getTargetvalue() != null).findFirst().ifPresent(dto -> {
                            for (String option : dto.getTargetvalue().split("&")) {
                                String optionTrim = option.trim();
                                if (!matchedtextStats.containsKey(optionTrim)) {
                                    Map<String, Object> emptyStat = new HashMap<>();
                                    emptyStat.put("count", 0L);
                                    emptyStat.put("ratio", 0.0);
                                    matchedtextStats.put(optionTrim, emptyStat);
                                }
                            }
                        });
                    }
                    patSatisfactionDetailEntity.setScriptContent(ivrLibaTemplateScript.getScriptContent());
                    patSatisfactionDetailEntity.setAnswerPerson(CollectionUtils.isEmpty(fillCount) ? 0 : fillCount.size());
                    patSatisfactionDetailEntity.setNoAnswerPerson(CollectionUtils.isNotEmpty(fillCount) && CollectionUtils.isNotEmpty(subids) ? (subids.size() - fillCount.size()) : CollectionUtils.isNotEmpty(subids) ? subids.size() : 0);
                    patSatisfactionDetailEntity.setAverageScore(averageScore(fillCount));
                    patSatisfactionDetailEntity.setMaxScore(maxScore(ivrLibaTemplateTargetoptions));
                    patSatisfactionDetailEntity.setMinScore(minScore(ivrLibaTemplateTargetoptions));
                    patSatisfactionDetailEntity.setAnswerRate(CollectionUtils.isEmpty(subids) ? 0 : CollectionUtils.isEmpty(fillCount) ? 0 : fillCount.size() * 1.0 / subids.size());
                    patSatisfactionDetailEntity.setMatchedtextStats(matchedtextStats);
                    patSatisfactionDetailEntities.add(patSatisfactionDetailEntity);
                    totalPerson += CollectionUtils.isEmpty(fillCount) ? 0 : fillCount.size();
                    allPerson += subids.size();
                }
            }
        }
        if (CollectionUtils.isNotEmpty(questionnaireList)) {
            //1. 先获取入参中的满意度维度
            SvyLibTemplateScriptVO svyLibTemplateScriptVO = new SvyLibTemplateScriptVO();
            svyLibTemplateScriptVO.setDimensionList(patSatisfactionReqVO.getDimensionList());
            //2 再获取该问题满意度分类下的IvrLibaTemplateScript的集合
            List<SvyLibTemplateScript> svyLibTemplateScripts = svyLibTemplateScriptMapper.selectSLTScriptListBydimension(svyLibTemplateScriptVO);
            if (CollectionUtils.isNotEmpty(svyLibTemplateScripts)) {
                for (SvyLibTemplateScript svyLibTemplateScript : svyLibTemplateScripts) {
                    //记录单个明细信息
                    PatSatisfactionDetailEntity patSatisfactionDetailEntity = new PatSatisfactionDetailEntity();
                    //通过问题ID,获取问题选项(为了获取选项上的最高分最低分)
                    SvyLibTemplateTargetoption svyLibTemplateTargetoption = new SvyLibTemplateTargetoption();
                    svyLibTemplateTargetoption.setScriptid(svyLibTemplateScript.getId());
                    List<SvyLibTemplateTargetoption> svyLibTemplateTargetoptions = svyLibTemplateTargetoptionMapper.selectSvyLibTemplateTargetoptionList(svyLibTemplateTargetoption);
                    //获取libTemplateId
                    List<Long> libTemplateIds = new ArrayList<>();
                    libTemplateIds.add(svyLibTemplateScript.getSvyid());
                    // 再通过模板id获取问题发送总量
                    ServiceSubtaskSatisfactionEntity serviceSubtaskSatisfactionEntity = DtoConversionUtils.sourceToTarget(patSatisfactionReqVO, ServiceSubtaskSatisfactionEntity.class);
                    serviceSubtaskSatisfactionEntity.setLibTemplateIds(libTemplateIds);
                    serviceSubtaskSatisfactionEntity.setType(2);
                    List<Long> subids = serviceSubtaskMapper.querySendCount(serviceSubtaskSatisfactionEntity);
                    //获取填报数量
                    List<ServiceSubtaskDetailDTO> fillCount = null;
                    if (CollectionUtils.isNotEmpty(subids))
                        fillCount = serviceSubtaskDetailMapper.queryFillCount(subids, svyLibTemplateScript.getScriptContent());
                    // 根据matchedtext分组,统计各选项数量及占比
                    Map<String, Map<String, Object>> matchedtextStats = new HashMap<>();
                    if (CollectionUtils.isNotEmpty(fillCount)) {
                        int totalFill = fillCount.size();
                        fillCount.stream().filter(dto -> dto.getMatchedtext() != null).collect(Collectors.groupingBy(ServiceSubtaskDetailDTO::getMatchedtext, Collectors.counting())).forEach((matchedtext, count) -> {
                            Map<String, Object> stat = new HashMap<>();
                            stat.put("count", count);
                            stat.put("ratio", new BigDecimal((double) count / totalFill * 100).setScale(1, RoundingMode.HALF_UP).doubleValue());
                            matchedtextStats.put(matchedtext, stat);
                        });
                        // 从fillCount中取targetvalue(&分隔的当前问题的所有选项),补全未出现的选项,count和ratio均为0
                        fillCount.stream().filter(dto -> dto.getTargetvalue() != null).findFirst().ifPresent(dto -> {
                            for (String option : dto.getTargetvalue().split("&")) {
                                String optionTrim = option.trim();
                                if (!matchedtextStats.containsKey(optionTrim)) {
                                    Map<String, Object> emptyStat = new HashMap<>();
                                    emptyStat.put("count", 0L);
                                    emptyStat.put("ratio", 0.0);
                                    matchedtextStats.put(optionTrim, emptyStat);
                                }
                            }
                        });
                    }
                    patSatisfactionDetailEntity.setScriptContent(svyLibTemplateScript.getScriptContent());
                    patSatisfactionDetailEntity.setAnswerPerson(CollectionUtils.isEmpty(fillCount) ? 0 : fillCount.size());
                    patSatisfactionDetailEntity.setNoAnswerPerson(CollectionUtils.isNotEmpty(fillCount) && CollectionUtils.isNotEmpty(subids) ? (subids.size() - fillCount.size()) : CollectionUtils.isNotEmpty(subids) ? subids.size() : 0);
                    patSatisfactionDetailEntity.setAverageScore(averageScore(fillCount));
                    OptionalDouble maxOpt = svyLibTemplateTargetoptions.stream().filter(dto -> dto.getScore() != null).mapToDouble(dto -> dto.getScore().doubleValue()).max();
                    patSatisfactionDetailEntity.setMaxScore(maxOpt.isPresent() ? new BigDecimal(maxOpt.getAsDouble()).setScale(1, RoundingMode.HALF_UP).doubleValue() : 0.0);
                    OptionalDouble minOpt = svyLibTemplateTargetoptions.stream().filter(dto -> dto.getScore() != null).mapToDouble(dto -> dto.getScore().doubleValue()).min();
                    patSatisfactionDetailEntity.setMinScore(minOpt.isPresent() ? new BigDecimal(minOpt.getAsDouble()).setScale(1, RoundingMode.HALF_UP).doubleValue() : 0.0);
                    patSatisfactionDetailEntity.setAnswerRate(CollectionUtils.isEmpty(subids) ? 0 : CollectionUtils.isEmpty(fillCount) ? 0 : fillCount.size() * 1.0 / subids.size());
                    patSatisfactionDetailEntity.setMatchedtextStats(matchedtextStats);
                    patSatisfactionDetailEntities.add(patSatisfactionDetailEntity);
                    totalPerson += CollectionUtils.isEmpty(fillCount) ? 0 : fillCount.size();
                    allPerson += subids.size();
                }
            }
        }
        result.setTotalAnswerRate(Arith.div(totalPerson, allPerson));
        result.setPatSatisfactionDetailEntities(patSatisfactionDetailEntities);
        result.setTotalPerson(totalPerson);
        return result;
    }
    @Override
    public Map<String, Object> satisfactionGraph(PatSatisfactionReqVO patSatisfactionReqVO) {
        //用来记录柱状图信息(key=满意度分类名称,value=满意度分类下的总人数和填报人数)
@@ -449,6 +625,139 @@
        return zzt;
    }
    @Override
    public Map<String, Object> satisfactionGraphDimension(PatSatisfactionReqVO patSatisfactionReqVO) {
        //用来记录柱状图信息(key=满意度分类名称,value=满意度分类下的总人数和填报人数)
        Map<String, Object> zzt = new HashMap<>();
        // 记录一下每种分类的填报情况
        Map<String, List<ServiceSubtaskDetailDTO>> assortNameFillCountMap = new HashMap<>();
        if (patSatisfactionReqVO.getType() == null || patSatisfactionReqVO.getType() == 1) {
            //1. 从入参中获取满意度维维度
            IvrLibaTemplateScript ivrLibaTemplateScript2 = new IvrLibaTemplateScript();
            ivrLibaTemplateScript2.setDimensionList(patSatisfactionReqVO.getDimensionList());
            //2 再获取该问题满意度分类下的IvrLibaTemplateScript的集合
            List<IvrLibaTemplateScript> ivrLibaTemplateScripts = ivrLibaTemplateScriptMapper.selectILTSBydimension(ivrLibaTemplateScript2);
            if (ivrLibaTemplateScripts != null && !ivrLibaTemplateScripts.isEmpty()) {
                //3 按dimension维度分组,并获取每个集合进行遍历,计算每个分类的总人数和填报人数
                Map<String, List<IvrLibaTemplateScript>> groupByDimension = ivrLibaTemplateScripts.stream().filter(item -> item.getDimension() != null).collect(Collectors.groupingBy(IvrLibaTemplateScript::getDimension));
                if (groupByDimension != null && !groupByDimension.isEmpty()) {
                    for (String dimension : groupByDimension.keySet()) {
                        //记录总人数
                        Double subidAll = 0.0;
                        //记录总的填报人数
                        Double fillCountAll = 0.0;
                        //获取该维度的填报总数量
                        List<ServiceSubtaskDetailDTO> allFillCountList = new ArrayList<>();
                        List<IvrLibaTemplateScript> ivrLibaTemplateScriptList = groupByDimension.get(dimension);
                        for (IvrLibaTemplateScript ivrLibaTemplateScript : ivrLibaTemplateScriptList) {
                            //获取libTemplateId
                            List<Long> libTemplateIds = new ArrayList<>();
                            libTemplateIds.add(ivrLibaTemplateScript.getTemplateid());
                            // 再通过模板id获取问题发送总量
                            ServiceSubtaskSatisfactionEntity serviceSubtaskSatisfactionEntity = DtoConversionUtils.sourceToTarget(patSatisfactionReqVO, ServiceSubtaskSatisfactionEntity.class);
                            serviceSubtaskSatisfactionEntity.setLibTemplateIds(libTemplateIds);
                            serviceSubtaskSatisfactionEntity.setType(1);
                            List<Long> subids = serviceSubtaskMapper.querySendCount(serviceSubtaskSatisfactionEntity);
                            //获取填报数量
                            List<ServiceSubtaskDetailDTO> fillCount = null;
                            if (CollectionUtils.isNotEmpty(subids)) {
                                fillCount = serviceSubtaskDetailMapper.queryFillCount(subids, ivrLibaTemplateScript.getScriptContent());
                                if (CollectionUtils.isNotEmpty(fillCount)) allFillCountList.addAll(fillCount);
                            }
                            subidAll += subids.size();
                            fillCountAll += CollectionUtils.isEmpty(fillCount) ? 0 : fillCount.size();
                        }
                        // 这里先记录一下每个分类的总人数和填报人数
                        Map<String, Object> personCount = new HashMap<>();
                        personCount.put("fillCountAll", fillCountAll);
                        personCount.put("subidAll", subidAll);
                        personCount.put("receiveRate", Arith.div(fillCountAll, subidAll));
                        personCount.put("averageScore", averageScore(allFillCountList));
                        zzt.put(dimension, personCount);
                        assortNameFillCountMap.put(dimension, allFillCountList);
                    }
                }
            }
        }
        if (patSatisfactionReqVO.getType() == null || patSatisfactionReqVO.getType() == 2) {
            //1.  从入参中获取满意度维维度
            SvyLibTemplateScriptVO svyLibTemplateScriptVO = new SvyLibTemplateScriptVO();
            svyLibTemplateScriptVO.setDimensionList(patSatisfactionReqVO.getDimensionList());
            //2 再获取该问题满意度分类下的IvrLibaTemplateScript的集合
            List<SvyLibTemplateScript> svyLibTemplateScripts = svyLibTemplateScriptMapper.selectSLTScriptListBydimension(svyLibTemplateScriptVO);
            if (svyLibTemplateScripts != null && !svyLibTemplateScripts.isEmpty()) {
                //3 按scriptAssortname分组,并获取每个集合进行遍历,计算每个分类的总人数和填报人数
                Map<String, List<SvyLibTemplateScript>> groupByDimension = svyLibTemplateScripts.stream().filter(item -> item.getDimension() != null).collect(Collectors.groupingBy(SvyLibTemplateScript::getDimension));
                if (groupByDimension != null && !groupByDimension.isEmpty()) {
                    for (String dimension : groupByDimension.keySet()) {
                        //记录总人数
                        Double subidAll = 0.0;
                        //记录总的填报人数
                        Double fillCountAll = 0.0;
                        //获取该分类的填报总数量
                        List<ServiceSubtaskDetailDTO> allFillCountList = new ArrayList<>();
                        List<SvyLibTemplateScript> svyLibTemplateScriptList = groupByDimension.get(dimension);
                        for (SvyLibTemplateScript svyLibTemplateScript : svyLibTemplateScriptList) {
                            //获取libTemplateId
                            List<Long> libTemplateIds = new ArrayList<>();
                            libTemplateIds.add(svyLibTemplateScript.getSvyid());
                            // 再通过模板id获取问题发送总量
                            ServiceSubtaskSatisfactionEntity serviceSubtaskSatisfactionEntity = DtoConversionUtils.sourceToTarget(patSatisfactionReqVO, ServiceSubtaskSatisfactionEntity.class);
                            serviceSubtaskSatisfactionEntity.setLibTemplateIds(libTemplateIds);
                            serviceSubtaskSatisfactionEntity.setType(2);
                            List<Long> subids = serviceSubtaskMapper.querySendCount(serviceSubtaskSatisfactionEntity);
                            //获取填报数量
                            List<ServiceSubtaskDetailDTO> fillCount = null;
                            if (CollectionUtils.isNotEmpty(subids)) {
                                fillCount = serviceSubtaskDetailMapper.queryFillCount(subids, svyLibTemplateScript.getScriptContent());
                                if (CollectionUtils.isNotEmpty(fillCount)) allFillCountList.addAll(fillCount);
                            }
                            subidAll += subids.size();
                            fillCountAll += CollectionUtils.isEmpty(fillCount) ? 0 : fillCount.size();
                        }
                        // 这里先记录一下每个分类的总人数和填报人数
                        Map<String, Object> personCount = (Map<String, Object>) zzt.get(dimension);
                        if (!Objects.isNull(personCount)) {
                            Double fillCountAll2 = (Double) personCount.get("fillCountAll");
                            Double subidAll2 = (Double) personCount.get("subidAll");
                            personCount.put("fillCountAll", fillCountAll2 + fillCountAll);
                            personCount.put("subidAll", subidAll2 + subidAll);
                            personCount.put("receiveRate", Arith.div((Double) personCount.get("fillCountAll"), (Double) personCount.get("subidAll")));
                            //看一下之前有没有该分类的填报量
                            List<ServiceSubtaskDetailDTO> serviceSubtaskDetailDTOS = assortNameFillCountMap.get(dimension);
                            if (CollectionUtils.isNotEmpty(serviceSubtaskDetailDTOS))
                                allFillCountList.addAll(serviceSubtaskDetailDTOS);
                            personCount.put("averageScore", averageScore(allFillCountList));
                        } else {
                            personCount = new HashMap<>();
                            personCount.put("fillCountAll", fillCountAll);
                            personCount.put("subidAll", subidAll);
                            personCount.put("receiveRate", Arith.div(fillCountAll, subidAll));
                            personCount.put("averageScore", averageScore(allFillCountList));
                            zzt.put(dimension, personCount);
                        }
                    }
                }
            }
        }
        return zzt;
    }
    /**
     * 获取最高分
     *