From e180e3a496d6f29d3a3b34016400de9d997c6bd9 Mon Sep 17 00:00:00 2001
From: liusheng <337615773@qq.com>
Date: 星期二, 07 四月 2026 14:42:23 +0800
Subject: [PATCH] 省立同德满意度功能提交

---
 smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java |  391 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 388 insertions(+), 3 deletions(-)

diff --git a/smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java
index 918caac..46c43db 100644
--- a/smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java
@@ -1,13 +1,23 @@
 package com.smartor.service.impl;
 
-import java.util.List;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.*;
+import java.util.stream.Collectors;
 
+import com.ruoyi.common.utils.Arith;
 import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.DtoConversionUtils;
+import com.smartor.domain.*;
+import com.smartor.domain.DTO.ServiceSubtaskDetailDTO;
+import com.smartor.domain.VO.PatSatisfactionReqVO;
+import com.smartor.domain.VO.PatSatisfactionResVO;
+import com.smartor.domain.entity.PatSatisfactionDetailEntity;
+import com.smartor.domain.entity.ServiceSubtaskSatisfactionEntity;
+import com.smartor.mapper.*;
 import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import com.smartor.mapper.PatSatisfactionMapper;
-import com.smartor.domain.PatSatisfaction;
 import com.smartor.service.IPatSatisfactionService;
 
 /**
@@ -20,6 +30,30 @@
 public class PatSatisfactionServiceImpl implements IPatSatisfactionService {
     @Autowired
     private PatSatisfactionMapper patSatisfactionMapper;
+
+    @Autowired
+    private ServiceSubtaskMapper serviceSubtaskMapper;
+
+    @Autowired
+    private ServiceSubtaskDetailMapper serviceSubtaskDetailMapper;
+
+    @Autowired
+    private IvrLibaTemplateScriptMapper ivrLibaTemplateScriptMapper;
+
+    @Autowired
+    private IvrLibaScriptAssortMapper ivrLibaScriptAssortMapper;
+
+    @Autowired
+    private SvyLibScriptCategoryMapper svyLibScriptCategoryMapper;
+
+    @Autowired
+    private IvrLibaTemplateTargetoptionMapper ivrLibaTemplateTargetoptionMapper;
+
+    @Autowired
+    private SvyLibTemplateTargetoptionMapper svyLibTemplateTargetoptionMapper;
+
+    @Autowired
+    private SvyLibTemplateScriptMapper svyLibTemplateScriptMapper;
 
     /**
      * 鏌ヨ鎮h�呮弧鎰忓害
@@ -99,4 +133,355 @@
     public int deletePatSatisfactionById(Long id) {
         return patSatisfactionMapper.deletePatSatisfactionById(id);
     }
+
+    /**
+     * 鎮h�呮弧鎰忓害缁熻
+     *
+     * @param patSatisfactionReqVO 鎮h�呮弧鎰忓害缁熻鏉′欢
+     * @return 鎮h�呮弧鎰忓害缁熻缁撴灉
+     */
+    @Override
+    public PatSatisfactionResVO statistics(PatSatisfactionReqVO patSatisfactionReqVO) {
+        //瀹氫箟杩斿弬
+        PatSatisfactionResVO result = new PatSatisfactionResVO();
+        //绛旈鎬讳汉鏁�(宸茬粡鍥炵瓟闂鐨�)
+        int totalPerson = 0;
+        // 鎬讳汉鏁帮紙鍖呭惈鏈洖绛旂殑锛�
+        int allPerson = 0;
+        //鎮h�呮弧鎰忓害缁熻鎯�
+        List<PatSatisfactionDetailEntity> patSatisfactionDetailEntities = new ArrayList<>();
+
+        List<ServiceSubtask> serviceSubtasks = serviceSubtaskMapper.selectSatisfactionSubtaskList(patSatisfactionReqVO);
+        // 鎸塼ype鍒嗙粍锛�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. 鍏堣幏鍙杋vr_liba_script_assort鐨勬弧鎰忓害鍒嗙被ID
+            IvrLibaScriptAssort ivrLibaScriptAssort = new IvrLibaScriptAssort();
+            ivrLibaScriptAssort.setOrgid(patSatisfactionReqVO.getOrgid());
+            List<IvrLibaScriptAssort> ivrLibaScriptAssorts = ivrLibaScriptAssortMapper.selectIvrLibaScriptAssortList(ivrLibaScriptAssort);
+
+            List<Long> mydIdList = ivrLibaScriptAssorts.stream().filter(item -> item.getType() != null && item.getType().contains("myd")).map(IvrLibaScriptAssort::getId).collect(Collectors.toList());
+
+            //2 鍐嶈幏鍙栬闂婊℃剰搴﹀垎绫讳笅鐨処vrLibaTemplateScript鐨勯泦鍚�
+            List<IvrLibaTemplateScript> ivrLibaTemplateScripts = ivrLibaTemplateScriptMapper.queryLibTemplateIds(mydIdList);
+
+            //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);
+                    });
+                    // 浠巉illCount涓彇targetvalue锛�&鍒嗛殧鐨勫綋鍓嶉棶棰樼殑鎵�鏈夐�夐」锛夛紝琛ュ叏鏈嚭鐜扮殑閫夐」锛宑ount鍜宺atio鍧囦负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. 鍏堣幏鍙杝vy_lib_script_category鐨勬弧鎰忓害鍒嗙被ID
+            SvyLibScriptCategory svyLibScriptCategory = new SvyLibScriptCategory();
+            svyLibScriptCategory.setOrgid(patSatisfactionReqVO.getOrgid());
+            List<SvyLibScriptCategory> svyLibScriptCategories = svyLibScriptCategoryMapper.selectSvyLibScriptCategoryList(svyLibScriptCategory);
+            List<Long> mydIdList = svyLibScriptCategories.stream().filter(item -> item.getType() != null && item.getType().contains("myd")).map(SvyLibScriptCategory::getId).collect(Collectors.toList());
+
+            //2 鍐嶈幏鍙栬闂婊℃剰搴﹀垎绫讳笅鐨処vrLibaTemplateScript鐨勯泦鍚�
+            List<SvyLibTemplateScript> svyLibTemplateScripts = svyLibTemplateScriptMapper.querySvyLibTemplateIds(mydIdList);
+
+            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);
+                    });
+                    // 浠巉illCount涓彇targetvalue锛�&鍒嗛殧鐨勫綋鍓嶉棶棰樼殑鎵�鏈夐�夐」锛夛紝琛ュ叏鏈嚭鐜扮殑閫夐」锛宑ount鍜宺atio鍧囦负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=婊℃剰搴﹀垎绫讳笅鐨勬�讳汉鏁板拰濉姤浜烘暟锛�
+        Map<String, Object> zzt = new HashMap<>();
+
+        // 璁板綍涓�涓嬫瘡绉嶅垎绫荤殑濉姤鎯呭喌
+        Map<String, List<ServiceSubtaskDetailDTO>> assortNameFillCountMap = new HashMap<>();
+
+        if (patSatisfactionReqVO.getType() == null || patSatisfactionReqVO.getType() == 1) {
+            //1. 鍏堣幏鍙杋vr_liba_script_assort鐨勬弧鎰忓害鍒嗙被ID
+            IvrLibaScriptAssort ivrLibaScriptAssort = new IvrLibaScriptAssort();
+            ivrLibaScriptAssort.setOrgid(patSatisfactionReqVO.getOrgid());
+            List<IvrLibaScriptAssort> ivrLibaScriptAssorts = ivrLibaScriptAssortMapper.selectIvrLibaScriptAssortList(ivrLibaScriptAssort);
+            List<Long> mydIdList = ivrLibaScriptAssorts.stream().filter(item -> item.getType() != null && item.getType().contains("myd")).map(IvrLibaScriptAssort::getId).collect(Collectors.toList());
+
+            //2 鍐嶈幏鍙栬闂婊℃剰搴﹀垎绫讳笅鐨処vrLibaTemplateScript鐨勯泦鍚�
+            List<IvrLibaTemplateScript> ivrLibaTemplateScripts = ivrLibaTemplateScriptMapper.queryLibTemplateIds(mydIdList);
+
+
+            //3 鎸塻criptAssortname鍒嗙粍,骞惰幏鍙栨瘡涓泦鍚堣繘琛岄亶鍘嗭紝璁$畻姣忎釜鍒嗙被鐨勬�讳汉鏁板拰濉姤浜烘暟
+            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;
+                    //鑾峰彇璇ュ垎绫荤殑濉姤鎬绘暟閲�
+                    List<ServiceSubtaskDetailDTO> allFillCountList = new ArrayList<>();
+
+                    List<IvrLibaTemplateScript> ivrLibaTemplateScriptList = scriptGroupByAssortName.get(assortNameKey);
+                    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(assortNameKey, personCount);
+                    assortNameFillCountMap.put(assortNameKey, allFillCountList);
+                }
+            }
+        }
+
+        if (patSatisfactionReqVO.getType() == null || patSatisfactionReqVO.getType() == 2) {
+            //1. 鍏堣幏鍙杝vy_lib_script_category鐨勬弧鎰忓害鍒嗙被ID
+            SvyLibScriptCategory svyLibScriptCategory = new SvyLibScriptCategory();
+            svyLibScriptCategory.setOrgid(patSatisfactionReqVO.getOrgid());
+            List<SvyLibScriptCategory> svyLibScriptCategories = svyLibScriptCategoryMapper.selectSvyLibScriptCategoryList(svyLibScriptCategory);
+            List<Long> mydIdList = svyLibScriptCategories.stream().filter(item -> item.getType() != null && item.getType().contains("myd")).map(SvyLibScriptCategory::getId).collect(Collectors.toList());
+
+            //2 鍐嶈幏鍙栬闂婊℃剰搴﹀垎绫讳笅鐨処vrLibaTemplateScript鐨勯泦鍚�
+            List<SvyLibTemplateScript> svyLibTemplateScripts = svyLibTemplateScriptMapper.querySvyLibTemplateIds(mydIdList);
+
+            //3 鎸塻criptAssortname鍒嗙粍,骞惰幏鍙栨瘡涓泦鍚堣繘琛岄亶鍘嗭紝璁$畻姣忎釜鍒嗙被鐨勬�讳汉鏁板拰濉姤浜烘暟
+            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;
+                    //鑾峰彇璇ュ垎绫荤殑濉姤鎬绘暟閲�
+                    List<ServiceSubtaskDetailDTO> allFillCountList = new ArrayList<>();
+
+                    List<SvyLibTemplateScript> svyLibTemplateScriptList = scriptGroupByatCegoryName.get(categoryNameKey);
+                    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(categoryNameKey);
+                    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(categoryNameKey);
+                        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(categoryNameKey, personCount);
+                    }
+                }
+            }
+        }
+        return zzt;
+    }
+
+    /**
+     * 鑾峰彇鏈�楂樺垎
+     *
+     * @param options
+     * @return
+     */
+    private Double maxScore(List<IvrLibaTemplateTargetoption> options) {
+        if (CollectionUtils.isEmpty(options)) return 0.0;
+        OptionalDouble maxOpt = options.stream().filter(dto -> dto.getScore() != null).mapToDouble(dto -> dto.getScore().doubleValue()).max();
+        return maxOpt.isPresent() ? new BigDecimal(maxOpt.getAsDouble()).setScale(1, RoundingMode.HALF_UP).doubleValue() : 0.0;
+    }
+
+    /**
+     * 鑾峰彇鏈�浣庡垎
+     *
+     * @param options
+     * @return
+     */
+    private Double minScore(List<IvrLibaTemplateTargetoption> options) {
+        if (CollectionUtils.isEmpty(options)) return 0.0;
+        OptionalDouble minOpt = options.stream().filter(dto -> dto.getScore() != null).mapToDouble(dto -> dto.getScore().doubleValue()).min();
+        return minOpt.isPresent() ? new BigDecimal(minOpt.getAsDouble()).setScale(1, RoundingMode.HALF_UP).doubleValue() : 0.0;
+    }
+
+    /**
+     * 鑾峰彇骞冲潎鍒�
+     *
+     * @param fillCount
+     * @return
+     */
+    private Double averageScore(List<ServiceSubtaskDetailDTO> fillCount) {
+        if (CollectionUtils.isEmpty(fillCount)) return 0.0;
+        double sum = fillCount.stream().filter(dto -> dto.getScore() != null && !dto.getScore().isEmpty()).mapToDouble(dto -> Double.parseDouble(dto.getScore())).sum();
+        return new BigDecimal(sum / fillCount.size()).setScale(1, RoundingMode.HALF_UP).doubleValue();
+    }
 }

--
Gitblit v1.9.3