liusheng
2026-09-29 60ade5154522a042c816abaa1840751011ae0371
smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java
@@ -326,31 +326,40 @@
            //2 再获取该问题满意度分类下的IvrLibaTemplateScript的集合
            List<IvrLibaTemplateScript> ivrLibaTemplateScripts = ivrLibaTemplateScriptMapper.queryLibTemplateIds(mydIdList);
            //2.1 一次性把本次请求全部模板的发送量、填报量查回来(原来是每个模板问题各查两次)
            //2.1 一次性把本次请求全部模板的发送量、回收人数查回来(原来是每个模板问题各查两次)
            SatisfactionStatQuery statQuery = buildSatisfactionStatQuery(patSatisfactionReqVO, "1",
                    ivrLibaTemplateScripts.stream().map(IvrLibaTemplateScript::getTemplateid).collect(Collectors.toList()));
            Map<Long, Long> sendCountMap = mapSatisfactionSendCount(statQuery);
            SatisfactionFillStat fillStat = querySatisfactionFillStat(statQuery);
            Map<Long, Long> fillPersonCountMap = mapSatisfactionFillPersonCount(statQuery);
            //3 按scriptAssortname分组,并获取每个集合进行遍历,计算每个分类的总人数和填报人数
            Map<String, List<IvrLibaTemplateScript>> scriptGroupByAssortName = ivrLibaTemplateScripts.stream().filter(item -> item.getScriptAssortname() != null).collect(Collectors.groupingBy(IvrLibaTemplateScript::getScriptAssortname));
            if (scriptGroupByAssortName != null && !scriptGroupByAssortName.isEmpty()) {
                for (String assortNameKey : scriptGroupByAssortName.keySet()) {
                    //记录总人数
                    Double subidAll = 0.0;
                    //记录总的填报人数
                    Double fillCountAll = 0.0;
                    //获取该分类的填报总数量
                    // 该分类涉及的去重模板:发送人数/回收人数都按模板统计,
                    // 按题目循环累加会把同一个模板的量重复计成「题量」
                    Set<Long> categoryTemplateIds = new LinkedHashSet<>();
                    //获取该分类的填报总数量(只用于算平均分,按题目聚合的行数)
                    List<ScoreCount> allFillCountList = new ArrayList<>();
                    List<IvrLibaTemplateScript> ivrLibaTemplateScriptList = scriptGroupByAssortName.get(assortNameKey);
                    for (IvrLibaTemplateScript ivrLibaTemplateScript : ivrLibaTemplateScriptList) {
                        //通过模板id取问题发送总量(原来是把全部 sub_id 查回 Java 再取 size)
                        subidAll += sendCountMap.getOrDefault(ivrLibaTemplateScript.getTemplateid(), 0L);
                        //获取填报数量(原来是把明细行全部查回 Java 再取 size)
                        List<ScoreCount> fillCount = fillStat.get(ivrLibaTemplateScript.getTemplateid(), ivrLibaTemplateScript.getScriptContent());
                        Long templateId = ivrLibaTemplateScript.getTemplateid();
                        if (templateId != null) {
                            categoryTemplateIds.add(templateId);
                        }
                        //获取填报分值分布(只用于平均分)
                        List<ScoreCount> fillCount = fillStat.get(templateId, ivrLibaTemplateScript.getScriptContent());
                        if (CollectionUtils.isNotEmpty(fillCount)) allFillCountList.addAll(fillCount);
                        fillCountAll += countFillRows(fillCount);
                    }
                    //记录发送总人数、回收总人数
                    Double subidAll = 0.0;
                    Double fillCountAll = 0.0;
                    for (Long templateId : categoryTemplateIds) {
                        subidAll += sendCountMap.getOrDefault(templateId, 0L);
                        fillCountAll += fillPersonCountMap.getOrDefault(templateId, 0L);
                    }
                    // 这里先记录一下每个分类的总人数和填报人数
@@ -375,31 +384,40 @@
            //2 再获取该问题满意度分类下的IvrLibaTemplateScript的集合
            List<SvyLibTemplateScript> svyLibTemplateScripts = svyLibTemplateScriptMapper.querySvyLibTemplateIds(mydIdList);
            //2.1 一次性把本次请求全部模板的发送量、填报量查回来(原来是每个模板问题各查两次)
            //2.1 一次性把本次请求全部模板的发送量、回收人数查回来(原来是每个模板问题各查两次)
            SatisfactionStatQuery statQuery = buildSatisfactionStatQuery(patSatisfactionReqVO, "2",
                    svyLibTemplateScripts.stream().map(SvyLibTemplateScript::getSvyid).collect(Collectors.toList()));
            Map<Long, Long> sendCountMap = mapSatisfactionSendCount(statQuery);
            SatisfactionFillStat fillStat = querySatisfactionFillStat(statQuery);
            Map<Long, Long> fillPersonCountMap = mapSatisfactionFillPersonCount(statQuery);
            //3 按scriptAssortname分组,并获取每个集合进行遍历,计算每个分类的总人数和填报人数
            Map<String, List<SvyLibTemplateScript>> scriptGroupByatCegoryName = svyLibTemplateScripts.stream().filter(item -> item.getCategoryName() != null).collect(Collectors.groupingBy(SvyLibTemplateScript::getCategoryName));
            if (scriptGroupByatCegoryName != null && !scriptGroupByatCegoryName.isEmpty()) {
                for (String categoryNameKey : scriptGroupByatCegoryName.keySet()) {
                    //记录总人数
                    Double subidAll = 0.0;
                    //记录总的填报人数
                    Double fillCountAll = 0.0;
                    //获取该分类的填报总数量
                    // 该分类涉及的去重模板:发送人数/回收人数都按模板统计,
                    // 按题目循环累加会把同一个模板的量重复计成「题量」
                    Set<Long> categoryTemplateIds = new LinkedHashSet<>();
                    //获取该分类的填报总数量(只用于算平均分,按题目聚合的行数)
                    List<ScoreCount> allFillCountList = new ArrayList<>();
                    List<SvyLibTemplateScript> svyLibTemplateScriptList = scriptGroupByatCegoryName.get(categoryNameKey);
                    for (SvyLibTemplateScript svyLibTemplateScript : svyLibTemplateScriptList) {
                        //通过模板id取问题发送总量(原来是把全部 sub_id 查回 Java 再取 size)
                        subidAll += sendCountMap.getOrDefault(svyLibTemplateScript.getSvyid(), 0L);
                        //获取填报数量(原来是把明细行全部查回 Java 再取 size)
                        List<ScoreCount> fillCount = fillStat.get(svyLibTemplateScript.getSvyid(), svyLibTemplateScript.getScriptContent());
                        Long templateId = svyLibTemplateScript.getSvyid();
                        if (templateId != null) {
                            categoryTemplateIds.add(templateId);
                        }
                        //获取填报分值分布(只用于平均分)
                        List<ScoreCount> fillCount = fillStat.get(templateId, svyLibTemplateScript.getScriptContent());
                        if (CollectionUtils.isNotEmpty(fillCount)) allFillCountList.addAll(fillCount);
                        fillCountAll += countFillRows(fillCount);
                    }
                    //记录发送总人数、回收总人数
                    Double subidAll = 0.0;
                    Double fillCountAll = 0.0;
                    for (Long templateId : categoryTemplateIds) {
                        subidAll += sendCountMap.getOrDefault(templateId, 0L);
                        fillCountAll += fillPersonCountMap.getOrDefault(templateId, 0L);
                    }
@@ -453,28 +471,36 @@
                Map<String, List<IvrLibaTemplateScript>> groupByDimension = dimensionScripts.stream().collect(Collectors.groupingBy(IvrLibaTemplateScript::getDimension));
                if (groupByDimension != null && !groupByDimension.isEmpty()) {
                    //3.1 一次性把本次请求全部模板的发送量、填报量查回来(原来是每个模板问题各查两次)
                    //3.1 一次性把本次请求全部模板的发送量、回收人数查回来(原来是每个模板问题各查两次)
                    SatisfactionStatQuery statQuery = buildSatisfactionStatQuery(patSatisfactionReqVO, "1",
                            dimensionScripts.stream().map(IvrLibaTemplateScript::getTemplateid).collect(Collectors.toList()));
                    Map<Long, Long> sendCountMap = mapSatisfactionSendCount(statQuery);
                    SatisfactionFillStat fillStat = querySatisfactionFillStat(statQuery);
                    Map<Long, Long> fillPersonCountMap = mapSatisfactionFillPersonCount(statQuery);
                    for (String dimension : groupByDimension.keySet()) {
                        //记录总人数
                        Double subidAll = 0.0;
                        //记录总的填报人数
                        Double fillCountAll = 0.0;
                        //获取该维度的填报总数量
                        // 该维度涉及的去重模板:发送人数/回收人数都按模板统计,按题目累加会变成题量
                        Set<Long> dimensionTemplateIds = new LinkedHashSet<>();
                        //获取该维度的填报分值分布(只用于算平均分)
                        List<ScoreCount> allFillCountList = new ArrayList<>();
                        List<IvrLibaTemplateScript> ivrLibaTemplateScriptList = groupByDimension.get(dimension);
                        for (IvrLibaTemplateScript ivrLibaTemplateScript : ivrLibaTemplateScriptList) {
                            //通过模板id取问题发送总量(原来是把全部 sub_id 查回 Java 再取 size)
                            subidAll += sendCountMap.getOrDefault(ivrLibaTemplateScript.getTemplateid(), 0L);
                            //获取填报数量(原来是把明细行全部查回 Java 再取 size)
                            List<ScoreCount> fillCount = fillStat.get(ivrLibaTemplateScript.getTemplateid(), ivrLibaTemplateScript.getScriptContent());
                            Long templateId = ivrLibaTemplateScript.getTemplateid();
                            if (templateId != null) {
                                dimensionTemplateIds.add(templateId);
                            }
                            //获取填报分值分布(只用于平均分)
                            List<ScoreCount> fillCount = fillStat.get(templateId, ivrLibaTemplateScript.getScriptContent());
                            if (CollectionUtils.isNotEmpty(fillCount)) allFillCountList.addAll(fillCount);
                            fillCountAll += countFillRows(fillCount);
                        }
                        //记录发送总人数、回收总人数
                        Double subidAll = 0.0;
                        Double fillCountAll = 0.0;
                        for (Long templateId : dimensionTemplateIds) {
                            subidAll += sendCountMap.getOrDefault(templateId, 0L);
                            fillCountAll += fillPersonCountMap.getOrDefault(templateId, 0L);
                        }
                        // 这里先记录一下每个分类的总人数和填报人数
@@ -502,28 +528,36 @@
                List<SvyLibTemplateScript> dimensionScripts = svyLibTemplateScripts.stream().filter(item -> item.getDimension() != null).collect(Collectors.toList());
                Map<String, List<SvyLibTemplateScript>> groupByDimension = dimensionScripts.stream().collect(Collectors.groupingBy(SvyLibTemplateScript::getDimension));
                if (groupByDimension != null && !groupByDimension.isEmpty()) {
                    //3.1 一次性把本次请求全部模板的发送量、填报量查回来(原来是每个模板问题各查两次)
                    //3.1 一次性把本次请求全部模板的发送量、回收人数查回来(原来是每个模板问题各查两次)
                    SatisfactionStatQuery statQuery = buildSatisfactionStatQuery(patSatisfactionReqVO, "2",
                            dimensionScripts.stream().map(SvyLibTemplateScript::getSvyid).collect(Collectors.toList()));
                    Map<Long, Long> sendCountMap = mapSatisfactionSendCount(statQuery);
                    SatisfactionFillStat fillStat = querySatisfactionFillStat(statQuery);
                    Map<Long, Long> fillPersonCountMap = mapSatisfactionFillPersonCount(statQuery);
                    for (String dimension : groupByDimension.keySet()) {
                        //记录总人数
                        Double subidAll = 0.0;
                        //记录总的填报人数
                        Double fillCountAll = 0.0;
                        //获取该分类的填报总数量
                        // 该维度涉及的去重模板:发送人数/回收人数都按模板统计,按题目累加会变成题量
                        Set<Long> dimensionTemplateIds = new LinkedHashSet<>();
                        //获取该分类的填报分值分布(只用于算平均分)
                        List<ScoreCount> allFillCountList = new ArrayList<>();
                        List<SvyLibTemplateScript> svyLibTemplateScriptList = groupByDimension.get(dimension);
                        for (SvyLibTemplateScript svyLibTemplateScript : svyLibTemplateScriptList) {
                            //通过模板id取问题发送总量(原来是把全部 sub_id 查回 Java 再取 size)
                            subidAll += sendCountMap.getOrDefault(svyLibTemplateScript.getSvyid(), 0L);
                            //获取填报数量(原来是把明细行全部查回 Java 再取 size)
                            List<ScoreCount> fillCount = fillStat.get(svyLibTemplateScript.getSvyid(), svyLibTemplateScript.getScriptContent());
                            Long templateId = svyLibTemplateScript.getSvyid();
                            if (templateId != null) {
                                dimensionTemplateIds.add(templateId);
                            }
                            //获取填报分值分布(只用于平均分)
                            List<ScoreCount> fillCount = fillStat.get(templateId, svyLibTemplateScript.getScriptContent());
                            if (CollectionUtils.isNotEmpty(fillCount)) allFillCountList.addAll(fillCount);
                            fillCountAll += countFillRows(fillCount);
                        }
                        //记录发送总人数、回收总人数
                        Double subidAll = 0.0;
                        Double fillCountAll = 0.0;
                        for (Long templateId : dimensionTemplateIds) {
                            subidAll += sendCountMap.getOrDefault(templateId, 0L);
                            fillCountAll += fillPersonCountMap.getOrDefault(templateId, 0L);
                        }
@@ -644,6 +678,24 @@
    }
    /**
     * 一次查出全部模板的「回收人数」(按模板去重,同一个人答多道题只算一人)
     *
     * @return key=模板id,value=回收人数
     */
    private Map<Long, Long> mapSatisfactionFillPersonCount(SatisfactionStatQuery statQuery) {
        Map<Long, Long> fillPersonCountMap = new HashMap<>();
        if (statQuery == null || CollectionUtils.isEmpty(statQuery.getLibTemplateIds())) return fillPersonCountMap;
        List<Map<String, Object>> rows = serviceSubtaskDetailMapper.selectSatisfactionFillPersonCount(statQuery);
        if (CollectionUtils.isEmpty(rows)) return fillPersonCountMap;
        for (Map<String, Object> row : rows) {
            Long templateId = toLong(row.get("libtemplateid"));
            if (templateId == null) continue;
            fillPersonCountMap.put(templateId, toLong(row.get("cnt"), 0L));
        }
        return fillPersonCountMap;
    }
    /**
     * 一次查出全部模板的填报量(按 模板+问题+分值 分组)
     */
    private SatisfactionFillStat querySatisfactionFillStat(SatisfactionStatQuery statQuery) {
@@ -662,18 +714,6 @@
            fillStat.add(templateId, questiontextValue == null ? null : String.valueOf(questiontextValue), scoreCount);
        }
        return fillStat;
    }
    /**
     * 取填报明细行数(原 fillCount.size())
     */
    private long countFillRows(List<ScoreCount> fillCount) {
        if (CollectionUtils.isEmpty(fillCount)) return 0L;
        long rows = 0L;
        for (ScoreCount scoreCount : fillCount) {
            rows += scoreCount.getCount();
        }
        return rows;
    }
    /**