From 87b79ea739ec32bd7d0e493a6ea8525212f6c763 Mon Sep 17 00:00:00 2001
From: liusheng <337615773@qq.com>
Date: 星期六, 10 十月 2026 15:11:17 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into smartor_ls_261008
---
smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java | 1070 ++++++++++++++++++++++++++++++++++++++---------------------
1 files changed, 689 insertions(+), 381 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 f1802b9..9e07d77 100644
--- a/smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/PatSatisfactionServiceImpl.java
@@ -5,7 +5,11 @@
import java.util.*;
import java.util.stream.Collectors;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.domain.entity.SysUserDept;
+import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.Arith;
+import com.ruoyi.common.utils.ArrayListUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DtoConversionUtils;
import com.smartor.domain.*;
@@ -13,12 +17,15 @@
import com.smartor.domain.VO.PatSatisfactionReqVO;
import com.smartor.domain.VO.PatSatisfactionResVO;
import com.smartor.domain.entity.PatSatisfactionDetailEntity;
+import com.smartor.domain.entity.SatisfactionStatQuery;
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.service.IPatSatisfactionService;
+
+import static com.ruoyi.common.utils.SecurityUtils.getLoginUser;
/**
* 鎮h�呮弧鎰忓害Service涓氬姟灞傚鐞�
@@ -101,6 +108,50 @@
}
/**
+ * 鏂板鎮h�呮弧鎰忓害
+ *
+ * @param patSatisfactions 鎮h�呮弧鎰忓害
+ * @return 缁撴灉
+ */
+ @Override
+ public int batchInsert(List<PatSatisfaction> patSatisfactions) {
+ if(CollectionUtils.isEmpty(patSatisfactions)){
+ return 0;
+ }
+ List<Long> ids = patSatisfactions.stream().map(PatSatisfaction::getId).
+ distinct().collect(Collectors.toList());
+ List<PatSatisfaction> patSatisfactionsOld = new ArrayList<>();
+ PatSatisfaction patSatisfactionVo = new PatSatisfaction();
+ patSatisfactionVo.setIds(ids);
+ patSatisfactionsOld = patSatisfactionMapper.selectPatSatisfactionList(patSatisfactionVo);
+ Map<String, List<PatSatisfaction>> maps = ArrayListUtils.splitListsById(patSatisfactions,
+ patSatisfactionsOld, PatSatisfaction::getId);
+ //鍙湪patSatisfactions鐨勬暟鎹紝鎵ц鏂板鎿嶄綔
+ List<PatSatisfaction> addItems = maps.get("onlyIn1");
+ //鍙湪patSatisfactionsOld鐨勬暟鎹紝鎵ц鍒犻櫎鎿嶄綔
+// List<PatSatisfaction> delItems = maps.get("onlyIn2");
+ //閲嶅彔鐨勬暟鎹紝鎵ц鏇存柊鎿嶄綔
+ List<PatSatisfaction> editItems = maps.get("common");
+ Integer count = 0;
+ LoginUser loginUser = getLoginUser();
+ SysUser user = loginUser.getUser();
+ for (PatSatisfaction patSatisfaction0 : editItems) {
+ patSatisfaction0.setUpdateBy(user.getNickName());
+ patSatisfaction0.setUpdateTime(DateUtils.getNowDate());
+ count = count + patSatisfactionMapper.updatePatSatisfaction(patSatisfaction0);
+ }
+
+ for (PatSatisfaction patSatisfaction1 : addItems) {
+ patSatisfaction1.setCreateBy(user.getNickName());
+ patSatisfaction1.setOrgid(user.getOrgid());
+ patSatisfaction1.setCreateTime(DateUtils.getNowDate());
+ patSatisfaction1.setUpdateTime(DateUtils.getNowDate());
+ count = count + patSatisfactionMapper.insertPatSatisfaction(patSatisfaction1);
+ }
+ return count;
+ }
+
+ /**
* 淇敼鎮h�呮弧鎰忓害
*
* @param patSatisfaction 鎮h�呮弧鎰忓害
@@ -144,95 +195,35 @@
public PatSatisfactionResVO statistics(PatSatisfactionReqVO patSatisfactionReqVO) {
//瀹氫箟杩斿弬
PatSatisfactionResVO result = new PatSatisfactionResVO();
- //绛旈鎬讳汉鏁�(宸茬粡鍥炵瓟闂鐨�)
- int totalPerson = 0;
- // 鎬讳汉鏁帮紙鍖呭惈鏈洖绛旂殑锛�
- int allPerson = 0;
//鎮h�呮弧鎰忓害缁熻鎯�
List<PatSatisfactionDetailEntity> patSatisfactionDetailEntities = new ArrayList<>();
+ // [0]=绛旈鎬讳汉鏁�(宸茬粡鍥炵瓟闂鐨�) [1]=鎬讳汉鏁帮紙鍖呭惈鏈洖绛旂殑锛�
+ int[] personTotals = new int[2];
- 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());
+ // 鍙煡鏈鏉′欢涓嬪疄闄呭瓨鍦ㄥ摢浜� type锛堝師鏉ユ槸鎶婃帴杩戝叏琛ㄧ殑涓婄櫨涓瓧娈垫煡鍥炴潵锛屼粎鐢ㄤ簬鍒ゆ柇涓嬮潰涓や釜鍒嗘敮鏄惁涓虹┖锛�
+ List<String> types = serviceSubtaskMapper.selectSatisfactionSubtaskTypes(patSatisfactionReqVO);
+ boolean hasVoice = types != null && types.contains("1");
+ boolean hasQuestionnaire = types != null && types.contains("2");
- if (CollectionUtils.isNotEmpty(voiceList)) {
+ if (hasVoice) {
//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浜烘暟
+ //3 涓�娆$粺璁″叏閮ㄩ棶棰樼殑鍙戦�侀噺/濉姤閲�/閫夐」鍒嗗�硷紙鍘熸潵鏄瘡涓棶棰樺悇鏌� 3 娆★級
+ List<SatScriptRef> scriptRefs = new ArrayList<>();
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();
+ scriptRefs.add(new SatScriptRef(ivrLibaTemplateScript.getTemplateid(), ivrLibaTemplateScript.getScriptid(), ivrLibaTemplateScript.getScriptContent()));
}
+ buildSatisfactionDetailEntities(patSatisfactionReqVO, "1", true, scriptRefs, patSatisfactionDetailEntities, personTotals);
}
- if (CollectionUtils.isNotEmpty(questionnaireList)) {
+ if (hasQuestionnaire) {
//1. 鍏堣幏鍙杝vy_lib_script_category鐨勬弧鎰忓害鍒嗙被ID
SvyLibScriptCategory svyLibScriptCategory = new SvyLibScriptCategory();
svyLibScriptCategory.setOrgid(patSatisfactionReqVO.getOrgid());
@@ -242,75 +233,17 @@
//2 鍐嶈幏鍙栬闂婊℃剰搴﹀垎绫讳笅鐨処vrLibaTemplateScript鐨勯泦鍚�
List<SvyLibTemplateScript> svyLibTemplateScripts = svyLibTemplateScriptMapper.querySvyLibTemplateIds(mydIdList);
+ //3 涓�娆$粺璁″叏閮ㄩ棶棰樼殑鍙戦�侀噺/濉姤閲�/閫夐」鍒嗗�硷紙鍘熸潵鏄瘡涓棶棰樺悇鏌� 3 娆★級
+ List<SatScriptRef> scriptRefs = new ArrayList<>();
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();
+ // 闂嵎鐨勯�夐」琛ㄦ寜 svy_lib_template_script 鐨勪富閿叧鑱�
+ scriptRefs.add(new SatScriptRef(svyLibTemplateScript.getSvyid(), svyLibTemplateScript.getId(), svyLibTemplateScript.getScriptContent()));
}
+ buildSatisfactionDetailEntities(patSatisfactionReqVO, "2", false, scriptRefs, patSatisfactionDetailEntities, personTotals);
}
- result.setTotalAnswerRate(Arith.div(totalPerson, allPerson));
+ result.setTotalAnswerRate(Arith.div(personTotals[0], personTotals[1]));
result.setPatSatisfactionDetailEntities(patSatisfactionDetailEntities);
- result.setTotalPerson(totalPerson);
+ result.setTotalPerson(personTotals[0]);
return result;
}
@@ -325,19 +258,17 @@
public PatSatisfactionResVO statisticsByDimension(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());
+ // [0]=绛旈鎬讳汉鏁�(宸茬粡鍥炵瓟闂鐨�) [1]=鎬讳汉鏁帮紙鍖呭惈鏈洖绛旂殑锛�
+ int[] personTotals = new int[2];
- if (CollectionUtils.isNotEmpty(voiceList)) {
+ // 鍙煡鏈鏉′欢涓嬪疄闄呭瓨鍦ㄥ摢浜� type锛堝師鏉ユ槸鎶婃帴杩戝叏琛ㄧ殑涓婄櫨涓瓧娈垫煡鍥炴潵锛屼粎鐢ㄤ簬鍒ゆ柇涓嬮潰涓や釜鍒嗘敮鏄惁涓虹┖锛�
+ List<String> types = serviceSubtaskMapper.selectSatisfactionSubtaskTypes(patSatisfactionReqVO);
+ boolean hasVoice = types != null && types.contains("1");
+ boolean hasQuestionnaire = types != null && types.contains("2");
+
+ if (hasVoice) {
//1. 鍏堣幏鍙栧叆鍙備腑鐨勭淮鎶ら泦鍚�
IvrLibaTemplateScript iltscript = new IvrLibaTemplateScript();
iltscript.setDimensionList(patSatisfactionReqVO.getDimensionList());
@@ -345,148 +276,34 @@
//2 鍐嶈幏鍙栬闂婊℃剰搴﹀垎绫讳笅鐨処vrLibaTemplateScript鐨勯泦鍚�
List<IvrLibaTemplateScript> ivrLibaTemplateScripts = ivrLibaTemplateScriptMapper.selectILTSBydimension(iltscript);
if (CollectionUtils.isNotEmpty(ivrLibaTemplateScripts)) {
- //3 鍐嶉�氳繃鍗曚釜ivr_liba_template鑾峰彇鍒版墍鏈夌殑婊℃剰搴﹂棶棰� 鍜� 浣跨敤璇ユā鏉跨殑subTask浜烘暟
+ //3 涓�娆$粺璁″叏閮ㄩ棶棰樼殑鍙戦�侀噺/濉姤閲�/閫夐」鍒嗗�硷紙鍘熸潵鏄瘡涓棶棰樺悇鏌� 3 娆★級
+ List<SatScriptRef> scriptRefs = new ArrayList<>();
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();
+ scriptRefs.add(new SatScriptRef(ivrLibaTemplateScript.getTemplateid(), ivrLibaTemplateScript.getScriptid(), ivrLibaTemplateScript.getScriptContent()));
}
+ buildSatisfactionDetailEntities(patSatisfactionReqVO, "1", true, scriptRefs, patSatisfactionDetailEntities, personTotals);
}
}
- if (CollectionUtils.isNotEmpty(questionnaireList)) {
+ if (hasQuestionnaire) {
//1. 鍏堣幏鍙栧叆鍙備腑鐨勬弧鎰忓害缁村害
SvyLibTemplateScriptVO svyLibTemplateScriptVO = new SvyLibTemplateScriptVO();
svyLibTemplateScriptVO.setDimensionList(patSatisfactionReqVO.getDimensionList());
//2 鍐嶈幏鍙栬闂婊℃剰搴﹀垎绫讳笅鐨処vrLibaTemplateScript鐨勯泦鍚�
List<SvyLibTemplateScript> svyLibTemplateScripts = svyLibTemplateScriptMapper.selectSLTScriptListBydimension(svyLibTemplateScriptVO);
if (CollectionUtils.isNotEmpty(svyLibTemplateScripts)) {
+ //3 涓�娆$粺璁″叏閮ㄩ棶棰樼殑鍙戦�侀噺/濉姤閲�/閫夐」鍒嗗�硷紙鍘熸潵鏄瘡涓棶棰樺悇鏌� 3 娆★級
+ List<SatScriptRef> scriptRefs = new ArrayList<>();
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();
+ // 闂嵎鐨勯�夐」琛ㄦ寜 svy_lib_template_script 鐨勪富閿叧鑱�
+ scriptRefs.add(new SatScriptRef(svyLibTemplateScript.getSvyid(), svyLibTemplateScript.getId(), svyLibTemplateScript.getScriptContent()));
}
+ buildSatisfactionDetailEntities(patSatisfactionReqVO, "2", false, scriptRefs, patSatisfactionDetailEntities, personTotals);
}
}
- result.setTotalAnswerRate(Arith.div(totalPerson, allPerson));
+ result.setTotalAnswerRate(Arith.div(personTotals[0], personTotals[1]));
result.setPatSatisfactionDetailEntities(patSatisfactionDetailEntities);
- result.setTotalPerson(totalPerson);
+ result.setTotalPerson(personTotals[0]);
return result;
}
@@ -496,8 +313,8 @@
//鐢ㄦ潵璁板綍鏌辩姸鍥句俊鎭紙key=婊℃剰搴﹀垎绫诲悕绉帮紝value=婊℃剰搴﹀垎绫讳笅鐨勬�讳汉鏁板拰濉姤浜烘暟锛�
Map<String, Object> zzt = new HashMap<>();
- // 璁板綍涓�涓嬫瘡绉嶅垎绫荤殑濉姤鎯呭喌
- Map<String, List<ServiceSubtaskDetailDTO>> assortNameFillCountMap = new HashMap<>();
+ // 璁板綍涓�涓嬫瘡绉嶅垎绫荤殑濉姤鎯呭喌锛堝彧璁板垎鍊间笌鏉℃暟锛屼笉鍐嶆妸鏄庣粏琛屽叏閮ㄦ煡鍥� Java锛�
+ Map<String, List<ScoreCount>> assortNameFillCountMap = new HashMap<>();
if (patSatisfactionReqVO.getType() == null || patSatisfactionReqVO.getType() == 1) {
//1. 鍏堣幏鍙杋vr_liba_script_assort鐨勬弧鎰忓害鍒嗙被ID
@@ -509,37 +326,40 @@
//2 鍐嶈幏鍙栬闂婊℃剰搴﹀垎绫讳笅鐨処vrLibaTemplateScript鐨勯泦鍚�
List<IvrLibaTemplateScript> ivrLibaTemplateScripts = ivrLibaTemplateScriptMapper.queryLibTemplateIds(mydIdList);
+ //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 鎸塻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<>();
+ // 璇ュ垎绫绘秹鍙婄殑鍘婚噸妯℃澘锛氬彂閫佷汉鏁�/鍥炴敹浜烘暟閮芥寜妯℃澘缁熻锛�
+ // 鎸夐鐩惊鐜疮鍔犱細鎶婂悓涓�涓ā鏉跨殑閲忛噸澶嶈鎴愩�岄閲忋��
+ Set<Long> categoryTemplateIds = new LinkedHashSet<>();
+ //鑾峰彇璇ュ垎绫荤殑濉姤鎬绘暟閲忥紙鍙敤浜庣畻骞冲潎鍒嗭紝鎸夐鐩仛鍚堢殑琛屾暟锛�
+ List<ScoreCount> 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);
+ Long templateId = ivrLibaTemplateScript.getTemplateid();
+ if (templateId != null) {
+ categoryTemplateIds.add(templateId);
}
- subidAll += subids.size();
- fillCountAll += CollectionUtils.isEmpty(fillCount) ? 0 : fillCount.size();
+ //鑾峰彇濉姤鍒嗗�煎垎甯冿紙鍙敤浜庡钩鍧囧垎锛�
+ List<ScoreCount> fillCount = fillStat.get(templateId, ivrLibaTemplateScript.getScriptContent());
+ if (CollectionUtils.isNotEmpty(fillCount)) allFillCountList.addAll(fillCount);
+ }
+
+ //璁板綍鍙戦�佹�讳汉鏁般�佸洖鏀舵�讳汉鏁�
+ Double subidAll = 0.0;
+ Double fillCountAll = 0.0;
+ for (Long templateId : categoryTemplateIds) {
+ subidAll += sendCountMap.getOrDefault(templateId, 0L);
+ fillCountAll += fillPersonCountMap.getOrDefault(templateId, 0L);
}
// 杩欓噷鍏堣褰曚竴涓嬫瘡涓垎绫荤殑鎬讳汉鏁板拰濉姤浜烘暟
@@ -547,7 +367,7 @@
personCount.put("fillCountAll", fillCountAll);
personCount.put("subidAll", subidAll);
personCount.put("receiveRate", Arith.div(fillCountAll, subidAll));
- personCount.put("averageScore", averageScore(allFillCountList));
+ personCount.put("averageScore", averageScoreByStat(allFillCountList));
zzt.put(assortNameKey, personCount);
assortNameFillCountMap.put(assortNameKey, allFillCountList);
}
@@ -564,36 +384,40 @@
//2 鍐嶈幏鍙栬闂婊℃剰搴﹀垎绫讳笅鐨処vrLibaTemplateScript鐨勯泦鍚�
List<SvyLibTemplateScript> svyLibTemplateScripts = svyLibTemplateScriptMapper.querySvyLibTemplateIds(mydIdList);
+ //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 鎸塻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<>();
+ // 璇ュ垎绫绘秹鍙婄殑鍘婚噸妯℃澘锛氬彂閫佷汉鏁�/鍥炴敹浜烘暟閮芥寜妯℃澘缁熻锛�
+ // 鎸夐鐩惊鐜疮鍔犱細鎶婂悓涓�涓ā鏉跨殑閲忛噸澶嶈鎴愩�岄閲忋��
+ Set<Long> categoryTemplateIds = new LinkedHashSet<>();
+ //鑾峰彇璇ュ垎绫荤殑濉姤鎬绘暟閲忥紙鍙敤浜庣畻骞冲潎鍒嗭紝鎸夐鐩仛鍚堢殑琛屾暟锛�
+ List<ScoreCount> 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);
+ Long templateId = svyLibTemplateScript.getSvyid();
+ if (templateId != null) {
+ categoryTemplateIds.add(templateId);
}
- subidAll += subids.size();
- fillCountAll += CollectionUtils.isEmpty(fillCount) ? 0 : fillCount.size();
+ //鑾峰彇濉姤鍒嗗�煎垎甯冿紙鍙敤浜庡钩鍧囧垎锛�
+ List<ScoreCount> fillCount = fillStat.get(templateId, svyLibTemplateScript.getScriptContent());
+ if (CollectionUtils.isNotEmpty(fillCount)) allFillCountList.addAll(fillCount);
+ }
+
+ //璁板綍鍙戦�佹�讳汉鏁般�佸洖鏀舵�讳汉鏁�
+ Double subidAll = 0.0;
+ Double fillCountAll = 0.0;
+ for (Long templateId : categoryTemplateIds) {
+ subidAll += sendCountMap.getOrDefault(templateId, 0L);
+ fillCountAll += fillPersonCountMap.getOrDefault(templateId, 0L);
}
@@ -607,16 +431,16 @@
personCount.put("receiveRate", Arith.div((Double) personCount.get("fillCountAll"), (Double) personCount.get("subidAll")));
//鐪嬩竴涓嬩箣鍓嶆湁娌℃湁璇ュ垎绫荤殑濉姤閲�
- List<ServiceSubtaskDetailDTO> serviceSubtaskDetailDTOS = assortNameFillCountMap.get(categoryNameKey);
+ List<ScoreCount> serviceSubtaskDetailDTOS = assortNameFillCountMap.get(categoryNameKey);
if (CollectionUtils.isNotEmpty(serviceSubtaskDetailDTOS))
allFillCountList.addAll(serviceSubtaskDetailDTOS);
- personCount.put("averageScore", averageScore(allFillCountList));
+ personCount.put("averageScore", averageScoreByStat(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));
+ personCount.put("averageScore", averageScoreByStat(allFillCountList));
zzt.put(categoryNameKey, personCount);
}
}
@@ -628,11 +452,11 @@
@Override
public Map<String, Object> satisfactionGraphDimension(PatSatisfactionReqVO patSatisfactionReqVO) {
- //鐢ㄦ潵璁板綍鏌辩姸鍥句俊鎭紙key=婊℃剰搴﹀垎绫诲悕绉帮紝value=婊℃剰搴﹀垎绫讳笅鐨勬�讳汉鏁板拰濉姤浜烘暟锛�
+ //鐢ㄦ潵璁板綍鏌辩姸鍥句俊鎭紙key=婊℃剰搴︾淮搴﹀悕绉帮紝value=璇ョ淮搴︿笅鐨勬�讳汉鏁板拰濉姤浜烘暟锛�
Map<String, Object> zzt = new HashMap<>();
- // 璁板綍涓�涓嬫瘡绉嶅垎绫荤殑濉姤鎯呭喌
- Map<String, List<ServiceSubtaskDetailDTO>> assortNameFillCountMap = new HashMap<>();
+ // 璁板綍涓�涓嬫瘡涓淮搴︾殑濉姤鎯呭喌锛堝彧璁板垎鍊间笌鏉℃暟锛屼笉鍐嶆妸鏄庣粏琛屽叏閮ㄦ煡鍥� Java锛�
+ Map<String, List<ScoreCount>> assortNameFillCountMap = new HashMap<>();
if (patSatisfactionReqVO.getType() == null || patSatisfactionReqVO.getType() == 1) {
//1. 浠庡叆鍙備腑鑾峰彇婊℃剰搴︾淮缁村害
@@ -643,36 +467,40 @@
List<IvrLibaTemplateScript> ivrLibaTemplateScripts = ivrLibaTemplateScriptMapper.selectILTSBydimension(ivrLibaTemplateScript2);
if (ivrLibaTemplateScripts != null && !ivrLibaTemplateScripts.isEmpty()) {
//3 鎸塪imension缁村害鍒嗙粍,骞惰幏鍙栨瘡涓泦鍚堣繘琛岄亶鍘嗭紝璁$畻姣忎釜鍒嗙被鐨勬�讳汉鏁板拰濉姤浜烘暟
- Map<String, List<IvrLibaTemplateScript>> groupByDimension = ivrLibaTemplateScripts.stream().filter(item -> item.getDimension() != null).collect(Collectors.groupingBy(IvrLibaTemplateScript::getDimension));
+ List<IvrLibaTemplateScript> dimensionScripts = ivrLibaTemplateScripts.stream().filter(item -> item.getDimension() != null).collect(Collectors.toList());
+ Map<String, List<IvrLibaTemplateScript>> groupByDimension = dimensionScripts.stream().collect(Collectors.groupingBy(IvrLibaTemplateScript::getDimension));
if (groupByDimension != null && !groupByDimension.isEmpty()) {
+ //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;
- //鑾峰彇璇ョ淮搴︾殑濉姤鎬绘暟閲�
- List<ServiceSubtaskDetailDTO> allFillCountList = new ArrayList<>();
+ // 璇ョ淮搴︽秹鍙婄殑鍘婚噸妯℃澘锛氬彂閫佷汉鏁�/鍥炴敹浜烘暟閮芥寜妯℃澘缁熻锛屾寜棰樼洰绱姞浼氬彉鎴愰閲�
+ Set<Long> dimensionTemplateIds = new LinkedHashSet<>();
+ //鑾峰彇璇ョ淮搴︾殑濉姤鍒嗗�煎垎甯冿紙鍙敤浜庣畻骞冲潎鍒嗭級
+ List<ScoreCount> 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);
+ Long templateId = ivrLibaTemplateScript.getTemplateid();
+ if (templateId != null) {
+ dimensionTemplateIds.add(templateId);
}
- subidAll += subids.size();
- fillCountAll += CollectionUtils.isEmpty(fillCount) ? 0 : fillCount.size();
+ //鑾峰彇濉姤鍒嗗�煎垎甯冿紙鍙敤浜庡钩鍧囧垎锛�
+ List<ScoreCount> fillCount = fillStat.get(templateId, ivrLibaTemplateScript.getScriptContent());
+ if (CollectionUtils.isNotEmpty(fillCount)) allFillCountList.addAll(fillCount);
+ }
+
+ //璁板綍鍙戦�佹�讳汉鏁般�佸洖鏀舵�讳汉鏁�
+ Double subidAll = 0.0;
+ Double fillCountAll = 0.0;
+ for (Long templateId : dimensionTemplateIds) {
+ subidAll += sendCountMap.getOrDefault(templateId, 0L);
+ fillCountAll += fillPersonCountMap.getOrDefault(templateId, 0L);
}
// 杩欓噷鍏堣褰曚竴涓嬫瘡涓垎绫荤殑鎬讳汉鏁板拰濉姤浜烘暟
@@ -680,7 +508,7 @@
personCount.put("fillCountAll", fillCountAll);
personCount.put("subidAll", subidAll);
personCount.put("receiveRate", Arith.div(fillCountAll, subidAll));
- personCount.put("averageScore", averageScore(allFillCountList));
+ personCount.put("averageScore", averageScoreByStat(allFillCountList));
zzt.put(dimension, personCount);
assortNameFillCountMap.put(dimension, allFillCountList);
}
@@ -696,36 +524,40 @@
//2 鍐嶈幏鍙栬闂婊℃剰搴﹀垎绫讳笅鐨処vrLibaTemplateScript鐨勯泦鍚�
List<SvyLibTemplateScript> svyLibTemplateScripts = svyLibTemplateScriptMapper.selectSLTScriptListBydimension(svyLibTemplateScriptVO);
if (svyLibTemplateScripts != null && !svyLibTemplateScripts.isEmpty()) {
- //3 鎸塻criptAssortname鍒嗙粍,骞惰幏鍙栨瘡涓泦鍚堣繘琛岄亶鍘嗭紝璁$畻姣忎釜鍒嗙被鐨勬�讳汉鏁板拰濉姤浜烘暟
- Map<String, List<SvyLibTemplateScript>> groupByDimension = svyLibTemplateScripts.stream().filter(item -> item.getDimension() != null).collect(Collectors.groupingBy(SvyLibTemplateScript::getDimension));
+ //3 鎸塪imension缁村害鍒嗙粍,骞惰幏鍙栨瘡涓泦鍚堣繘琛岄亶鍘嗭紝璁$畻姣忎釜鍒嗙被鐨勬�讳汉鏁板拰濉姤浜烘暟
+ 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 涓�娆℃�ф妸鏈璇锋眰鍏ㄩ儴妯℃澘鐨勫彂閫侀噺銆佸洖鏀朵汉鏁版煡鍥炴潵锛堝師鏉ユ槸姣忎釜妯℃澘闂鍚勬煡涓ゆ锛�
+ 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;
- //鑾峰彇璇ュ垎绫荤殑濉姤鎬绘暟閲�
- List<ServiceSubtaskDetailDTO> allFillCountList = new ArrayList<>();
+ // 璇ョ淮搴︽秹鍙婄殑鍘婚噸妯℃澘锛氬彂閫佷汉鏁�/鍥炴敹浜烘暟閮芥寜妯℃澘缁熻锛屾寜棰樼洰绱姞浼氬彉鎴愰閲�
+ Set<Long> dimensionTemplateIds = new LinkedHashSet<>();
+ //鑾峰彇璇ュ垎绫荤殑濉姤鍒嗗�煎垎甯冿紙鍙敤浜庣畻骞冲潎鍒嗭級
+ List<ScoreCount> 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);
+ Long templateId = svyLibTemplateScript.getSvyid();
+ if (templateId != null) {
+ dimensionTemplateIds.add(templateId);
}
- subidAll += subids.size();
- fillCountAll += CollectionUtils.isEmpty(fillCount) ? 0 : fillCount.size();
+ //鑾峰彇濉姤鍒嗗�煎垎甯冿紙鍙敤浜庡钩鍧囧垎锛�
+ List<ScoreCount> fillCount = fillStat.get(templateId, svyLibTemplateScript.getScriptContent());
+ if (CollectionUtils.isNotEmpty(fillCount)) allFillCountList.addAll(fillCount);
+ }
+
+ //璁板綍鍙戦�佹�讳汉鏁般�佸洖鏀舵�讳汉鏁�
+ Double subidAll = 0.0;
+ Double fillCountAll = 0.0;
+ for (Long templateId : dimensionTemplateIds) {
+ subidAll += sendCountMap.getOrDefault(templateId, 0L);
+ fillCountAll += fillPersonCountMap.getOrDefault(templateId, 0L);
}
@@ -739,16 +571,16 @@
personCount.put("receiveRate", Arith.div((Double) personCount.get("fillCountAll"), (Double) personCount.get("subidAll")));
//鐪嬩竴涓嬩箣鍓嶆湁娌℃湁璇ュ垎绫荤殑濉姤閲�
- List<ServiceSubtaskDetailDTO> serviceSubtaskDetailDTOS = assortNameFillCountMap.get(dimension);
+ List<ScoreCount> serviceSubtaskDetailDTOS = assortNameFillCountMap.get(dimension);
if (CollectionUtils.isNotEmpty(serviceSubtaskDetailDTOS))
allFillCountList.addAll(serviceSubtaskDetailDTOS);
- personCount.put("averageScore", averageScore(allFillCountList));
+ personCount.put("averageScore", averageScoreByStat(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));
+ personCount.put("averageScore", averageScoreByStat(allFillCountList));
zzt.put(dimension, personCount);
}
}
@@ -766,8 +598,13 @@
*/
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;
+ Double maxScore = options.stream()
+ .map(IvrLibaTemplateTargetoption::getScore)
+ .filter(scoreStr -> scoreStr != null && !scoreStr.isEmpty())
+ .mapToDouble(Double::parseDouble)
+ .max()
+ .orElse(0.0);
+ return maxScore;
}
/**
@@ -778,8 +615,13 @@
*/
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;
+ Double minScore = options.stream()
+ .map(IvrLibaTemplateTargetoption::getScore)
+ .filter(scoreStr -> scoreStr != null && !scoreStr.isEmpty())
+ .mapToDouble(Double::parseDouble)
+ .min()
+ .orElse(0.0);
+ return minScore;
}
/**
@@ -793,4 +635,470 @@
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();
}
+
+ // ==================== satisfactionGraph 鑱氬悎缁熻锛堟浛浠i�愪釜妯℃澘鏌ュ簱锛� ====================
+
+ /**
+ * 鏋勫缓鑱氬悎缁熻鍏ュ弬锛堝彇鍊兼潵婧愪笌鍘� DtoConversionUtils.sourceToTarget(patSatisfactionReqVO, ServiceSubtaskSatisfactionEntity.class) 涓�鑷达級
+ *
+ * @param reqVO 鍘熷璇锋眰
+ * @param type service_subtask.type锛�1 璇煶銆�2 闂嵎锛夛紝鐢ㄥ瓧绗︿覆姣旇緝閬垮厤闅愬紡杞崲
+ * @param templateIds 鏈璇锋眰娑夊強鐨勬ā鏉縤d锛坕vr 鐢� templateid锛岄棶鍗风敤 svyid锛�
+ */
+ private SatisfactionStatQuery buildSatisfactionStatQuery(PatSatisfactionReqVO reqVO, String type, List<Long> templateIds) {
+ SatisfactionStatQuery statQuery = new SatisfactionStatQuery();
+ statQuery.setOrgid(reqVO.getOrgid());
+ statQuery.setCampusid(reqVO.getCampusid());
+ statQuery.setType(type);
+ statQuery.setStartTime(reqVO.getStartTime());
+ statQuery.setEndTime(reqVO.getEndTime());
+ statQuery.setDeptcodes(reqVO.getDeptcodes());
+ statQuery.setHospitaldistrictcodes(reqVO.getHospitaldistrictcodes());
+ statQuery.setLibTemplateIds(CollectionUtils.isEmpty(templateIds) ? templateIds
+ : templateIds.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList()));
+ return statQuery;
+ }
+
+ /**
+ * 涓�娆℃煡鍑哄叏閮ㄦā鏉跨殑鍙戦�侀噺
+ *
+ * @return key=妯℃澘id锛寁alue=鍙戦�侀噺锛堢瓑浠蜂簬鍘� querySendCount 缁撴灉鐨� size锛�
+ */
+ private Map<Long, Long> mapSatisfactionSendCount(SatisfactionStatQuery statQuery) {
+ Map<Long, Long> sendCountMap = new HashMap<>();
+ if (statQuery == null || CollectionUtils.isEmpty(statQuery.getLibTemplateIds())) return sendCountMap;
+ List<Map<String, Object>> rows = serviceSubtaskMapper.selectSatisfactionSendCount(statQuery);
+ if (CollectionUtils.isEmpty(rows)) return sendCountMap;
+ for (Map<String, Object> row : rows) {
+ Long templateId = toLong(row.get("libtemplateid"));
+ if (templateId == null) continue;
+ sendCountMap.put(templateId, toLong(row.get("cnt"), 0L));
+ }
+ return sendCountMap;
+ }
+
+ /**
+ * 涓�娆℃煡鍑哄叏閮ㄦā鏉跨殑銆屽洖鏀朵汉鏁般�嶏紙鎸夋ā鏉垮幓閲嶏紝鍚屼竴涓汉绛斿閬撻鍙畻涓�浜猴級
+ *
+ * @return key=妯℃澘id锛寁alue=鍥炴敹浜烘暟
+ */
+ 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) {
+ SatisfactionFillStat fillStat = new SatisfactionFillStat();
+ if (statQuery == null || CollectionUtils.isEmpty(statQuery.getLibTemplateIds())) return fillStat;
+ List<Map<String, Object>> rows = serviceSubtaskDetailMapper.selectSatisfactionFillStat(statQuery);
+ if (CollectionUtils.isEmpty(rows)) return fillStat;
+ for (Map<String, Object> row : rows) {
+ Long templateId = toLong(row.get("libtemplateid"));
+ if (templateId == null) continue;
+ long cnt = toLong(row.get("cnt"), 0L);
+ if (cnt <= 0L) continue;
+ Object scoreValue = row.get("score");
+ Object questiontextValue = row.get("questiontext");
+ ScoreCount scoreCount = new ScoreCount(scoreValue == null ? null : String.valueOf(scoreValue), cnt);
+ fillStat.add(templateId, questiontextValue == null ? null : String.valueOf(questiontextValue), scoreCount);
+ }
+ return fillStat;
+ }
+
+ /**
+ * 鑾峰彇骞冲潎鍒嗭紙鑱氬悎鐗堬細鍒嗗�间笌鏉℃暟锛�
+ * <p>
+ * 鍙e緞涓� {@link #averageScore(List)} 瀹屽叏涓�鑷达細鍒嗗瓙涓哄彲瑙f瀽鍒嗗�间箣鍜岋紝鍒嗘瘝涓烘槑缁嗚鏁帮紙鍖呭惈鍒嗗�间负绌虹殑琛岋級銆�
+ * 娉ㄦ剰涓嶈兘鏀规垚 sql 鐨� avg() 鎴栥�屾湁鍒嗗�肩殑琛屾暟銆嶅仛鍒嗘瘝锛屽惁鍒欒繑鍥炵殑 averageScore 浼氬彉銆�
+ */
+ private Double averageScoreByStat(List<ScoreCount> fillCount) {
+ if (CollectionUtils.isEmpty(fillCount)) return 0.0;
+ double sum = 0.0;
+ long rows = 0L;
+ for (ScoreCount scoreCount : fillCount) {
+ if (scoreCount.getCount() <= 0L) continue;
+ rows += scoreCount.getCount();
+ if (scoreCount.getScore() != null && !scoreCount.getScore().isEmpty()) {
+ sum += Double.parseDouble(scoreCount.getScore()) * scoreCount.getCount();
+ }
+ }
+ if (rows == 0L) return 0.0;
+ return new BigDecimal(sum / rows).setScale(1, RoundingMode.HALF_UP).doubleValue();
+ }
+
+ /**
+ * 鍒嗗�煎垎缁勯敭锛氭ā鏉縤d + 鍒嗛殧绗� + 瑙勮寖鍖栧悗鐨勯棶棰樺唴瀹�
+ * <p>
+ * MySQL 閲� questiontext = #{questiontext} 鏄�屽拷鐣ュぇ灏忓啓銆佸拷鐣ュ熬閮ㄧ┖鏍笺�嶇殑姣旇緝锛�
+ * 杩欓噷鐢� trim + 灏忓啓鍋氱瓑浠峰尮閰嶃��
+ */
+ private static String statKey(Long templateId, String questiontext) {
+ return templateId + "\u0001" + (questiontext == null ? "" : questiontext.trim().toLowerCase(Locale.ROOT));
+ }
+
+ private static Long toLong(Object value) {
+ if (value == null) return null;
+ if (value instanceof Number) return ((Number) value).longValue();
+ String text = String.valueOf(value).trim();
+ return text.isEmpty() ? null : Long.valueOf(text);
+ }
+
+ private static long toLong(Object value, long defaultValue) {
+ Long result = toLong(value);
+ return result == null ? defaultValue : result;
+ }
+
+ /**
+ * 婊℃剰搴﹀垎鍊艰仛鍚堢粨鏋滐細鍒嗗�� + 璇ュ垎鍊煎搴旂殑鏄庣粏琛屾暟
+ */
+ private static class ScoreCount {
+ private final String score;
+ private final long count;
+
+ ScoreCount(String score, long count) {
+ this.score = score;
+ this.count = count;
+ }
+
+ String getScore() {
+ return score;
+ }
+
+ long getCount() {
+ return count;
+ }
+ }
+
+ /**
+ * 婊℃剰搴﹀~鎶ラ噺鑱氬悎缁撴灉
+ * <p>
+ * byTemplateQuestion锛氭寜 妯℃澘+闂 鍒嗙粍锛�
+ * byTemplate锛氭寜妯℃澘鍒嗙粍锛堣妯℃澘鍏ㄩ儴闂锛夛紝鐢ㄤ簬鍏煎鍘� queryFillCount 鍦�
+ * script_content 涓� null 鏃朵笉鎷� questiontext 鏉′欢鐨勮涓恒��
+ */
+ private static class SatisfactionFillStat {
+ private final Map<String, List<ScoreCount>> byTemplateQuestion = new HashMap<>();
+ private final Map<Long, List<ScoreCount>> byTemplate = new HashMap<>();
+
+ void add(Long templateId, String questiontext, ScoreCount scoreCount) {
+ byTemplate.computeIfAbsent(templateId, key -> new ArrayList<>()).add(scoreCount);
+ if (questiontext != null) {
+ byTemplateQuestion.computeIfAbsent(statKey(templateId, questiontext), key -> new ArrayList<>()).add(scoreCount);
+ }
+ }
+
+ List<ScoreCount> get(Long templateId, String scriptContent) {
+ if (templateId == null) return null;
+ if (scriptContent == null) return byTemplate.get(templateId);
+ return byTemplateQuestion.get(statKey(templateId, scriptContent));
+ }
+ }
+
+ // ==================== statistics / statisticsByDimension 鎵归噺缁熻锛堟浛浠i�愪釜闂鏌ュ簱锛� ====================
+
+ /**
+ * 婊℃剰搴︽槑缁嗙粺璁★紙statistics銆乻tatisticsByDimension 鍏辩敤锛�
+ * <p>
+ * 鎶婂師鏉ャ�屾瘡涓棶棰� 3 鏉� SQL銆嶆敼鎴愩�屾暣涓姹� 3 鏉℃煡璇� + 鍐呭瓨缁勮銆嶏細
+ * 鈶� 鍙戦�侀噺鎸� libtemplateid 鍒嗙粍锛涒憽 濉姤閲忔寜 妯℃澘+闂+matchedtext+score 鍒嗙粍锛涒憿 閫夐」鍒嗗�兼寜 scriptid 鍒嗙粍銆�
+ *
+ * @param reqVO 鍘熷璇锋眰
+ * @param type service_subtask.type锛�1 璇煶銆�2 闂嵎锛�
+ * @param voice true=璇煶闂锛堥�夐」鍒嗗�煎彇 ivr_liba_template_targetoption锛�
+ * @param scriptRefs 鏈瑕佺粺璁$殑闂锛堥『搴忓嵆杩斿洖椤哄簭锛�
+ * @param out 鏄庣粏缁撴灉
+ * @param totals [0]=totalPerson, [1]=allPerson
+ */
+ private void buildSatisfactionDetailEntities(PatSatisfactionReqVO reqVO, String type, boolean voice,
+ List<SatScriptRef> scriptRefs,
+ List<PatSatisfactionDetailEntity> out, int[] totals) {
+ if (CollectionUtils.isEmpty(scriptRefs)) return;
+
+ List<Long> templateIds = scriptRefs.stream().map(SatScriptRef::getTemplateId)
+ .filter(Objects::nonNull).distinct().collect(Collectors.toList());
+ SatisfactionStatQuery statQuery = buildSatisfactionStatQuery(reqVO, type, templateIds);
+ Map<Long, Long> sendCountMap = mapSatisfactionSendCount(statQuery);
+ SatisfactionFillStatByMatchedtext fillStat = querySatisfactionFillStatByMatchedtext(statQuery);
+ Map<Long, List<String>> optionScores = loadTargetOptionScores(voice, scriptRefs);
+
+ for (SatScriptRef scriptRef : scriptRefs) {
+ Long templateId = scriptRef.getTemplateId();
+ //鍙戦�佹�婚噺锛堝師鏉ユ槸鎶婂叏閮� sub_id 鏌ュ洖 Java 鍐嶅彇 size锛�
+ long sendCount = templateId == null ? 0L : sendCountMap.getOrDefault(templateId, 0L);
+ //濉姤鏁伴噺锛堝師鏉ユ槸鎶婃槑缁嗚鍏ㄩ儴鏌ュ洖 Java 鍐嶇粺璁★級
+ List<MatchedtextCount> fillRows = fillStat.get(templateId, scriptRef.getScriptContent());
+ long fillCount = countFillRowsByMatchedtext(fillRows);
+
+ PatSatisfactionDetailEntity detail = new PatSatisfactionDetailEntity();
+ detail.setScriptContent(scriptRef.getScriptContent());
+ detail.setAnswerPerson((int) fillCount);
+ detail.setNoAnswerPerson(fillCount > 0L && sendCount > 0L ? (int) (sendCount - fillCount) : sendCount > 0L ? (int) sendCount : 0);
+ detail.setAverageScore(String.valueOf(averageScoreByMatchedtext(fillRows)));
+ List<String> scores = optionScores.get(scriptRef.getOptionScriptId());
+ detail.setMaxScore(String.valueOf(maxScoreOf(scores)));
+ detail.setMinScore(String.valueOf(minScoreOf(scores)));
+ detail.setAnswerRate(sendCount == 0L ? 0 : fillCount == 0L ? 0 : fillCount * 1.0 / sendCount);
+ detail.setMatchedtextStats(buildMatchedtextStats(fillRows, fillCount));
+ out.add(detail);
+
+ totals[0] += (int) fillCount;
+ totals[1] += (int) sendCount;
+ }
+ }
+
+ /**
+ * 涓�娆℃煡鍑哄叏閮ㄩ棶棰樼殑濉姤閲忥紙鎸� 妯℃澘+闂+matchedtext+score 鍒嗙粍锛屽惈 targetvalue锛�
+ */
+ private SatisfactionFillStatByMatchedtext querySatisfactionFillStatByMatchedtext(SatisfactionStatQuery statQuery) {
+ SatisfactionFillStatByMatchedtext fillStat = new SatisfactionFillStatByMatchedtext();
+ if (statQuery == null || CollectionUtils.isEmpty(statQuery.getLibTemplateIds())) return fillStat;
+ List<Map<String, Object>> rows = serviceSubtaskDetailMapper.selectSatisfactionFillStatByMatchedtext(statQuery);
+ if (CollectionUtils.isEmpty(rows)) return fillStat;
+ for (Map<String, Object> row : rows) {
+ Long templateId = toLong(row.get("libtemplateid"));
+ if (templateId == null) continue;
+ long cnt = toLong(row.get("cnt"), 0L);
+ if (cnt <= 0L) continue;
+ Object questiontext = row.get("questiontext");
+ Object matchedtext = row.get("matchedtext");
+ Object score = row.get("score");
+ Object targetvalue = row.get("targetvalue");
+ fillStat.add(templateId, questiontext == null ? null : String.valueOf(questiontext),
+ new MatchedtextCount(matchedtext == null ? null : String.valueOf(matchedtext),
+ score == null ? null : String.valueOf(score),
+ targetvalue == null ? null : String.valueOf(targetvalue), cnt));
+ }
+ return fillStat;
+ }
+
+ /**
+ * 涓�娆℃煡鍑哄叏閮ㄩ棶棰樼殑閫夐」鍒嗗�硷紙鍙彇 scriptid銆乻core 涓ゅ垪锛�
+ * <p>
+ * 鍘熷疄鐜版槸姣忎釜闂鏌ヤ竴娆℃暣琛岋紝鑰岃皟鐢ㄦ柟鍙敤鍒� score 绠楁渶楂�/鏈�浣庡垎锛�
+ * 闂 id 涓� null 鏃跺師瀹炵幇涓嶆嫾 scriptid 鏉′欢锛堢瓑浜庡彇璇ヨ〃鍏ㄩ儴鍒嗗�硷級锛岃繖閲岀敤 null 浣滀负 key 瀛樿繖涓�浠姐��
+ */
+ private Map<Long, List<String>> loadTargetOptionScores(boolean voice, List<SatScriptRef> scriptRefs) {
+ Map<Long, List<String>> optionScores = new HashMap<>();
+ List<Long> scriptIds = scriptRefs.stream().map(SatScriptRef::getOptionScriptId)
+ .filter(Objects::nonNull).distinct().collect(Collectors.toList());
+ if (CollectionUtils.isNotEmpty(scriptIds)) {
+ addTargetOptionScores(optionScores, voice
+ ? ivrLibaTemplateTargetoptionMapper.selectIvrLibaTargetoptionScores(scriptIds)
+ : svyLibTemplateTargetoptionMapper.selectSvyLibTargetoptionScores(scriptIds));
+ }
+ if (scriptRefs.stream().anyMatch(ref -> ref.getOptionScriptId() == null)) {
+ optionScores.put(null, collectTargetOptionScores(voice
+ ? ivrLibaTemplateTargetoptionMapper.selectIvrLibaTargetoptionScores(null)
+ : svyLibTemplateTargetoptionMapper.selectSvyLibTargetoptionScores(null)));
+ }
+ return optionScores;
+ }
+
+ private void addTargetOptionScores(Map<Long, List<String>> optionScores, List<Map<String, Object>> rows) {
+ if (CollectionUtils.isEmpty(rows)) return;
+ for (Map<String, Object> row : rows) {
+ Long scriptId = toLong(row.get("scriptid"));
+ if (scriptId == null) continue;
+ Object score = row.get("score");
+ optionScores.computeIfAbsent(scriptId, key -> new ArrayList<>())
+ .add(score == null ? null : String.valueOf(score));
+ }
+ }
+
+ private List<String> collectTargetOptionScores(List<Map<String, Object>> rows) {
+ List<String> scores = new ArrayList<>();
+ if (CollectionUtils.isEmpty(rows)) return scores;
+ for (Map<String, Object> row : rows) {
+ Object score = row.get("score");
+ scores.add(score == null ? null : String.valueOf(score));
+ }
+ return scores;
+ }
+
+ /**
+ * 鍚勯�夐」锛坢atchedtext锛夋暟閲忓強鍗犳瘮
+ * <p>
+ * 鍙e緞涓庡師瀹炵幇涓�鑷达細鍒嗘瘝鏄叏閮ㄦ槑缁嗚鏁帮紙鍚� matchedtext 涓� null 鐨勮锛夛紱
+ * targetvalue 鐢ㄤ簬琛ュ叏鏈嚭鐜扮殑閫夐」锛坈ount=0銆乺atio=0锛夈��
+ */
+ private Map<String, Map<String, Object>> buildMatchedtextStats(List<MatchedtextCount> fillRows, long totalFill) {
+ Map<String, Map<String, Object>> matchedtextStats = new HashMap<>();
+ if (CollectionUtils.isEmpty(fillRows) || totalFill <= 0L) return matchedtextStats;
+
+ Map<String, Long> matchedtextCounts = new LinkedHashMap<>();
+ String targetvalue = null;
+ for (MatchedtextCount row : fillRows) {
+ if (row.getMatchedtext() != null) {
+ matchedtextCounts.merge(row.getMatchedtext(), row.getCount(), Long::sum);
+ }
+ if (targetvalue == null && row.getTargetvalue() != null) {
+ targetvalue = row.getTargetvalue();
+ }
+ }
+ for (Map.Entry<String, Long> entry : matchedtextCounts.entrySet()) {
+ Map<String, Object> stat = new HashMap<>();
+ stat.put("count", entry.getValue());
+ stat.put("ratio", new BigDecimal((double) entry.getValue() / totalFill * 100).setScale(1, RoundingMode.HALF_UP).doubleValue());
+ matchedtextStats.put(entry.getKey(), stat);
+ }
+ // 浠庢槑缁嗛噷鍙杢argetvalue锛�&鍒嗛殧鐨勫綋鍓嶉棶棰樼殑鎵�鏈夐�夐」锛夛紝琛ュ叏鏈嚭鐜扮殑閫夐」锛宑ount鍜宺atio鍧囦负0
+ if (targetvalue != null) {
+ for (String option : targetvalue.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);
+ }
+ }
+ }
+ return matchedtextStats;
+ }
+
+ /**
+ * 鍙栧~鎶ユ槑缁嗚鏁帮紙鍘� fillCount.size()锛�
+ */
+ private long countFillRowsByMatchedtext(List<MatchedtextCount> fillRows) {
+ if (CollectionUtils.isEmpty(fillRows)) return 0L;
+ long rows = 0L;
+ for (MatchedtextCount row : fillRows) {
+ rows += row.getCount();
+ }
+ return rows;
+ }
+
+ /**
+ * 鑾峰彇骞冲潎鍒嗭紙鑱氬悎鐗堬細鍒嗗�间笌鏉℃暟锛�
+ * <p>
+ * 鍙e緞涓� {@link #averageScore(List)} 涓�鑷达細鍒嗗瓙涓哄彲瑙f瀽鍒嗗�间箣鍜岋紝鍒嗘瘝涓烘槑缁嗚鏁帮紙鍚垎鍊间负绌虹殑琛岋級銆�
+ */
+ private Double averageScoreByMatchedtext(List<MatchedtextCount> fillRows) {
+ if (CollectionUtils.isEmpty(fillRows)) return 0.0;
+ double sum = 0.0;
+ long rows = 0L;
+ for (MatchedtextCount row : fillRows) {
+ if (row.getCount() <= 0L) continue;
+ rows += row.getCount();
+ if (row.getScore() != null && !row.getScore().isEmpty()) {
+ sum += Double.parseDouble(row.getScore()) * row.getCount();
+ }
+ }
+ if (rows == 0L) return 0.0;
+ return new BigDecimal(sum / rows).setScale(1, RoundingMode.HALF_UP).doubleValue();
+ }
+
+ /**
+ * 鑾峰彇鏈�楂樺垎锛堣仛鍚堢増锛屽彛寰勫悓 {@link #maxScore(List)}锛氱┖鍒楄〃杩斿洖 0.0锛�
+ */
+ private Double maxScoreOf(List<String> scores) {
+ if (CollectionUtils.isEmpty(scores)) return 0.0;
+ return scores.stream().filter(scoreStr -> scoreStr != null && !scoreStr.isEmpty())
+ .mapToDouble(Double::parseDouble).max().orElse(0.0);
+ }
+
+ /**
+ * 鑾峰彇鏈�浣庡垎锛堣仛鍚堢増锛屽彛寰勫悓 {@link #minScore(List)}锛氱┖鍒楄〃杩斿洖 0.0锛�
+ */
+ private Double minScoreOf(List<String> scores) {
+ if (CollectionUtils.isEmpty(scores)) return 0.0;
+ return scores.stream().filter(scoreStr -> scoreStr != null && !scoreStr.isEmpty())
+ .mapToDouble(Double::parseDouble).min().orElse(0.0);
+ }
+
+ /**
+ * 婊℃剰搴︾粺璁$敤鐨勯棶棰樺紩鐢細妯℃澘id銆侀�夐」琛ㄥ叧鑱旂殑闂id锛堝彲鑳戒负 null锛夈�侀棶棰樺唴瀹�
+ */
+ private static class SatScriptRef {
+ private final Long templateId;
+ private final Long optionScriptId;
+ private final String scriptContent;
+
+ SatScriptRef(Long templateId, Long optionScriptId, String scriptContent) {
+ this.templateId = templateId;
+ this.optionScriptId = optionScriptId;
+ this.scriptContent = scriptContent;
+ }
+
+ Long getTemplateId() {
+ return templateId;
+ }
+
+ Long getOptionScriptId() {
+ return optionScriptId;
+ }
+
+ String getScriptContent() {
+ return scriptContent;
+ }
+ }
+
+ /**
+ * 婊℃剰搴﹀~鎶ヨ仛鍚堢粨鏋滐細matchedtext + score + targetvalue + 鏉℃暟
+ */
+ private static class MatchedtextCount {
+ private final String matchedtext;
+ private final String score;
+ private final String targetvalue;
+ private final long count;
+
+ MatchedtextCount(String matchedtext, String score, String targetvalue, long count) {
+ this.matchedtext = matchedtext;
+ this.score = score;
+ this.targetvalue = targetvalue;
+ this.count = count;
+ }
+
+ String getMatchedtext() {
+ return matchedtext;
+ }
+
+ String getScore() {
+ return score;
+ }
+
+ String getTargetvalue() {
+ return targetvalue;
+ }
+
+ long getCount() {
+ return count;
+ }
+ }
+
+ /**
+ * 婊℃剰搴﹀~鎶ヨ仛鍚堢粨鏋滐紙鎸� matchedtext 鐗堬級
+ * <p>
+ * byTemplateQuestion锛氭寜 妯℃澘+闂 鍒嗙粍锛�
+ * byTemplate锛氭寜妯℃澘鍒嗙粍锛堣妯℃澘鍏ㄩ儴闂锛夛紝鐢ㄤ簬鍏煎鍘� queryFillCount 鍦�
+ * script_content 涓� null 鏃朵笉鎷� questiontext 鏉′欢鐨勮涓恒��
+ */
+ private static class SatisfactionFillStatByMatchedtext {
+ private final Map<String, List<MatchedtextCount>> byTemplateQuestion = new HashMap<>();
+ private final Map<Long, List<MatchedtextCount>> byTemplate = new HashMap<>();
+
+ void add(Long templateId, String questiontext, MatchedtextCount row) {
+ byTemplate.computeIfAbsent(templateId, key -> new ArrayList<>()).add(row);
+ if (questiontext != null) {
+ byTemplateQuestion.computeIfAbsent(statKey(templateId, questiontext), key -> new ArrayList<>()).add(row);
+ }
+ }
+
+ List<MatchedtextCount> get(Long templateId, String scriptContent) {
+ if (templateId == null) return null;
+ if (scriptContent == null) return byTemplate.get(templateId);
+ return byTemplateQuestion.get(statKey(templateId, scriptContent));
+ }
+ }
}
--
Gitblit v1.9.3