From c24d16a37523a49080392610357872ce580cbc38 Mon Sep 17 00:00:00 2001
From: liusheng <337615773@qq.com>
Date: 星期一, 26 十月 2026 14:03:33 +0800
Subject: [PATCH] 代码提交

---
 ruoyi-satisfaction/src/main/java/com/ruoyi/satisfaction/service/impl/PatSatisfactionServiceImpl.java |  142 +++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 124 insertions(+), 18 deletions(-)

diff --git a/ruoyi-satisfaction/src/main/java/com/ruoyi/satisfaction/service/impl/PatSatisfactionServiceImpl.java b/ruoyi-satisfaction/src/main/java/com/ruoyi/satisfaction/service/impl/PatSatisfactionServiceImpl.java
index 5d1078a..16e57c9 100644
--- a/ruoyi-satisfaction/src/main/java/com/ruoyi/satisfaction/service/impl/PatSatisfactionServiceImpl.java
+++ b/ruoyi-satisfaction/src/main/java/com/ruoyi/satisfaction/service/impl/PatSatisfactionServiceImpl.java
@@ -216,8 +216,10 @@
             //3 涓�娆$粺璁″叏閮ㄩ棶棰樼殑鍙戦�侀噺/濉姤閲�/閫夐」鍒嗗�硷紙鍘熸潵鏄瘡涓棶棰樺悇鏌� 3 娆★級
             List<SatScriptRef> scriptRefs = new ArrayList<>();
             for (SatisfactionIvrScriptRow ivrLibaTemplateScript : ivrLibaTemplateScripts) {
-                scriptRefs.add(new SatScriptRef(ivrLibaTemplateScript.getTemplateid(), ivrLibaTemplateScript.getScriptid(), ivrLibaTemplateScript.getScriptContent()));
+                scriptRefs.add(new SatScriptRef(ivrLibaTemplateScript.getTemplateid(), ivrLibaTemplateScript.getScriptid(), ivrLibaTemplateScript.getScriptContent(), ivrLibaTemplateScript.getDimension()));
             }
+            // 鍙繚鐣欐湰鏈熺湡姝d笅鍙戣繃浠诲姟鐨勬ā鏉匡細棰樺簱閲屾寕鐫�鐨勫巻鍙叉ā鏉匡紙浠庢湭涓嬪彂锛変笉鍐嶅崰琛�
+            scriptRefs = keepActiveTemplates(scriptRefs, activeTemplateIds(patSatisfactionReqVO, "1"));
             buildSatisfactionDetailEntities(patSatisfactionReqVO, "1", true, scriptRefs, patSatisfactionDetailEntities, personTotals);
         }
 
@@ -231,8 +233,10 @@
             List<SatScriptRef> scriptRefs = new ArrayList<>();
             for (SatisfactionSvyScriptRow svyLibTemplateScript : svyLibTemplateScripts) {
                 // 闂嵎鐨勯�夐」琛ㄦ寜 svy_lib_template_script 鐨勪富閿叧鑱�
-                scriptRefs.add(new SatScriptRef(svyLibTemplateScript.getSvyid(), svyLibTemplateScript.getId(), svyLibTemplateScript.getScriptContent()));
+                scriptRefs.add(new SatScriptRef(svyLibTemplateScript.getSvyid(), svyLibTemplateScript.getId(), svyLibTemplateScript.getScriptContent(), svyLibTemplateScript.getDimension()));
             }
+            // 鍙繚鐣欐湰鏈熺湡姝d笅鍙戣繃浠诲姟鐨勬ā鏉匡細棰樺簱閲屾寕鐫�鐨勫巻鍙叉ā鏉匡紙浠庢湭涓嬪彂锛変笉鍐嶅崰琛�
+            scriptRefs = keepActiveTemplates(scriptRefs, activeTemplateIds(patSatisfactionReqVO, "2"));
             buildSatisfactionDetailEntities(patSatisfactionReqVO, "2", false, scriptRefs, patSatisfactionDetailEntities, personTotals);
         }
         result.setTotalAnswerRate(Arith.div(personTotals[0], personTotals[1]));
@@ -270,8 +274,10 @@
                 //3 涓�娆$粺璁″叏閮ㄩ棶棰樼殑鍙戦�侀噺/濉姤閲�/閫夐」鍒嗗�硷紙鍘熸潵鏄瘡涓棶棰樺悇鏌� 3 娆★級
                 List<SatScriptRef> scriptRefs = new ArrayList<>();
                 for (SatisfactionIvrScriptRow ivrLibaTemplateScript : ivrLibaTemplateScripts) {
-                    scriptRefs.add(new SatScriptRef(ivrLibaTemplateScript.getTemplateid(), ivrLibaTemplateScript.getScriptid(), ivrLibaTemplateScript.getScriptContent()));
+                    scriptRefs.add(new SatScriptRef(ivrLibaTemplateScript.getTemplateid(), ivrLibaTemplateScript.getScriptid(), ivrLibaTemplateScript.getScriptContent(), ivrLibaTemplateScript.getDimension()));
                 }
+                // 鍙繚鐣欐湰鏈熺湡姝d笅鍙戣繃浠诲姟鐨勬ā鏉匡細棰樺簱閲屾寕鐫�鐨勫巻鍙叉ā鏉匡紙浠庢湭涓嬪彂锛変笉鍐嶅崰琛�
+                scriptRefs = keepActiveTemplates(scriptRefs, activeTemplateIds(patSatisfactionReqVO, "1"));
                 buildSatisfactionDetailEntities(patSatisfactionReqVO, "1", true, scriptRefs, patSatisfactionDetailEntities, personTotals);
             }
         }
@@ -284,8 +290,10 @@
                 List<SatScriptRef> scriptRefs = new ArrayList<>();
                 for (SatisfactionSvyScriptRow svyLibTemplateScript : svyLibTemplateScripts) {
                     // 闂嵎鐨勯�夐」琛ㄦ寜 svy_lib_template_script 鐨勪富閿叧鑱�
-                    scriptRefs.add(new SatScriptRef(svyLibTemplateScript.getSvyid(), svyLibTemplateScript.getId(), svyLibTemplateScript.getScriptContent()));
+                    scriptRefs.add(new SatScriptRef(svyLibTemplateScript.getSvyid(), svyLibTemplateScript.getId(), svyLibTemplateScript.getScriptContent(), svyLibTemplateScript.getDimension()));
                 }
+                // 鍙繚鐣欐湰鏈熺湡姝d笅鍙戣繃浠诲姟鐨勬ā鏉匡細棰樺簱閲屾寕鐫�鐨勫巻鍙叉ā鏉匡紙浠庢湭涓嬪彂锛変笉鍐嶅崰琛�
+                scriptRefs = keepActiveTemplates(scriptRefs, activeTemplateIds(patSatisfactionReqVO, "2"));
                 buildSatisfactionDetailEntities(patSatisfactionReqVO, "2", false, scriptRefs, patSatisfactionDetailEntities, personTotals);
             }
         }
@@ -578,6 +586,8 @@
         statQuery.setEndTime(reqVO.getEndTime());
         statQuery.setDeptcodes(reqVO.getDeptcodes());
         statQuery.setHospitaldistrictcodes(reqVO.getHospitaldistrictcodes());
+        statQuery.setLeaveldeptcodes(reqVO.getLeaveldeptcodes());
+        statQuery.setLeavehospitaldistrictcodes(reqVO.getLeavehospitaldistrictcodes());
         statQuery.setLibTemplateIds(CollectionUtils.isEmpty(templateIds) ? templateIds
                 : templateIds.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList()));
         return statQuery;
@@ -763,31 +773,66 @@
         SatisfactionStatQuery statQuery = buildSatisfactionStatQuery(reqVO, type, templateIds);
         Map<Long, Long> sendCountMap = mapSatisfactionSendCount(statQuery);
         SatisfactionFillStatByMatchedtext fillStat = querySatisfactionFillStatByMatchedtext(statQuery);
+        //绛旈銆愪汉鏁般�戯細鎸� 妯℃澘+闂 鐨� distinct sub_id锛堜笌銆屽彂閫佷汉鏁般�嶅悓鍙e緞锛�
+        Map<String, Long> answerPersonMap = mapSatisfactionFillPersonCountByQuestion(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);
+            //绛旈銆愪汉鏁般�戯細鐢ㄤ簬 绛旈浜烘暟 / 鏈瓟棰樹汉鏁� / 绛旈鐜�
+            long answerPersonCount = answerPersonMap.getOrDefault(
+                    statKey(templateId, scriptRef.getScriptContent()), 0L);
 
             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);
+            //缁村害锛氬師鏈煡璇㈤噷宸插彇鍒帮紝浣嗘瀯閫� SatScriptRef 鏃惰涓㈡帀锛屽鑷村墠绔�岀淮搴︺�嶅垪涓�鐩翠负绌�
+            detail.setDimension(scriptRef.getDimension());
+            // 鈿狅笍 浜烘暟鍙e緞淇锛氬師鏉ヨ繖閲岀敤鐨勬槸 fillCount锛堟槑缁嗚鏁帮級锛�
+            //    鑰屽彂閫佷汉鏁版槸 count(distinct id)锛堜汉鏁帮級锛屼袱鑰呯浉鍑忎細鍑虹幇璐熸暟锛堝疄娴� -120 = 15 鈭� 135锛夈��
+            //    涓�鏉� (sub_id, questiontext) 鍙兘鏈夊琛屾槑缁嗭紝鎵�浠ョ瓟棰樹汉鏁板繀椤诲彇 distinct sub_id銆�
+            detail.setAnswerPerson((int) answerPersonCount);
+            detail.setNoAnswerPerson(answerPersonCount > 0L && sendCount > 0L ? (int) (sendCount - answerPersonCount)
+                    : 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.setAnswerRate(sendCount == 0L ? 0 : answerPersonCount == 0L ? 0 : answerPersonCount * 1.0 / sendCount);
             detail.setMatchedtextStats(buildMatchedtextStats(fillRows, fillCount));
             out.add(detail);
 
-            totals[0] += (int) fillCount;
+            totals[0] += (int) answerPersonCount;
             totals[1] += (int) sendCount;
         }
+    }
+
+    /**
+     * 涓�娆℃煡鍑恒�屽叏閮� 妯℃澘+闂銆嶇殑绛旈浜烘暟锛坽@code count(distinct ssd.sub_id)}锛夈��
+     * <p>
+     * key 鐢ㄤ笌 {@link #statKey(Long, String)} 鐩稿悓鐨勮鍒欐瀯閫狅紝淇濊瘉涓庤皟鐢ㄦ柟鐨勬煡鎵句竴鑷�
+     * 锛坽@code statKey} 宸插仛 trim + 灏忓啓锛岀瓑浠蜂簬 MySQL 鐨勫拷鐣ュぇ灏忓啓涓庡熬閮ㄧ┖鏍兼瘮杈冿級銆�
+     */
+    private Map<String, Long> mapSatisfactionFillPersonCountByQuestion(SatisfactionStatQuery statQuery) {
+        Map<String, Long> answerPersonMap = new HashMap<>();
+        if (statQuery == null || CollectionUtils.isEmpty(statQuery.getLibTemplateIds())) return answerPersonMap;
+        List<Map<String, Object>> rows = satisfactionMapper.selectSatisfactionFillPersonCountByQuestion(statQuery);
+        if (CollectionUtils.isEmpty(rows)) return answerPersonMap;
+        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");
+            answerPersonMap.merge(
+                    statKey(templateId, questiontext == null ? null : String.valueOf(questiontext)),
+                    cnt, Long::sum);
+        }
+        return answerPersonMap;
     }
 
     /**
@@ -914,7 +959,7 @@
     /**
      * 鑾峰彇骞冲潎鍒嗭紙鑱氬悎鐗堬細鍒嗗�间笌鏉℃暟锛�
      * <p>
-     * 鍙e緞涓� {@link #averageScore(List)} 涓�鑷达細鍒嗗瓙涓哄彲瑙f瀽鍒嗗�间箣鍜岋紝鍒嗘瘝涓烘槑缁嗚鏁帮紙鍚垎鍊间负绌虹殑琛岋級銆�
+     * 鍒嗗瓙涓哄彲瑙f瀽鍒嗗�间箣鍜岋紝鍒嗘瘝涓烘槑缁嗚鏁帮紙鍚垎鍊间负绌虹殑琛岋級銆�
      */
     private Double averageScoreByMatchedtext(List<MatchedtextCount> fillRows) {
         if (CollectionUtils.isEmpty(fillRows)) return 0.0;
@@ -932,7 +977,7 @@
     }
 
     /**
-     * 鑾峰彇鏈�楂樺垎锛堣仛鍚堢増锛屽彛寰勫悓 {@link #maxScore(List)}锛氱┖鍒楄〃杩斿洖 0.0锛�
+     * 鑾峰彇鏈�楂樺垎锛堣仛鍚堢増锛岀┖鍒楄〃杩斿洖 0.0锛�
      */
     private Double maxScoreOf(List<String> scores) {
         if (CollectionUtils.isEmpty(scores)) return 0.0;
@@ -941,7 +986,7 @@
     }
 
     /**
-     * 鑾峰彇鏈�浣庡垎锛堣仛鍚堢増锛屽彛寰勫悓 {@link #minScore(List)}锛氱┖鍒楄〃杩斿洖 0.0锛�
+     * 鑾峰彇鏈�浣庡垎锛堣仛鍚堢増锛屽彛寰勫悓 {绌哄垪琛ㄨ繑鍥� 0.0锛�
      */
     private Double minScoreOf(List<String> scores) {
         if (CollectionUtils.isEmpty(scores)) return 0.0;
@@ -950,17 +995,19 @@
     }
 
     /**
-     * 婊℃剰搴︾粺璁$敤鐨勯棶棰樺紩鐢細妯℃澘id銆侀�夐」琛ㄥ叧鑱旂殑闂id锛堝彲鑳戒负 null锛夈�侀棶棰樺唴瀹�
+     * 婊℃剰搴︾粺璁$敤鐨勯棶棰樺紩鐢細妯℃澘id銆侀�夐」琛ㄥ叧鑱旂殑闂id锛堝彲鑳戒负 null锛夈�侀棶棰樺唴瀹广�佺淮搴�
      */
     private static class SatScriptRef {
         private final Long templateId;
         private final Long optionScriptId;
         private final String scriptContent;
+        private final String dimension;
 
-        SatScriptRef(Long templateId, Long optionScriptId, String scriptContent) {
+        SatScriptRef(Long templateId, Long optionScriptId, String scriptContent, String dimension) {
             this.templateId = templateId;
             this.optionScriptId = optionScriptId;
             this.scriptContent = scriptContent;
+            this.dimension = dimension;
         }
 
         Long getTemplateId() {
@@ -973,6 +1020,10 @@
 
         String getScriptContent() {
             return scriptContent;
+        }
+
+        String getDimension() {
+            return dimension;
         }
     }
 
@@ -1038,19 +1089,74 @@
     // 鍘熷疄鐜扮洿鎺� new smartor 鐨勫疄浣撳綋鍏ュ弬锛涙ā鍧楀寲鍚庣粺涓�鐢� SatisfactionScriptQuery锛�
     // 杩欓噷鎶婁笁澶勬瀯閫犳敹鏁涗负甯姪鏂规硶锛屾潯浠朵笌鍘熸潵閫愬瓧瀵瑰簲銆�
 
-    /** 婊℃剰搴﹀垎绫绘煡璇紙orgid + type=myd锛� */
+    /**
+     * 鏈湡鍐�<b>鐪熸涓嬪彂杩囦换鍔�</b>鐨勬ā鏉� id 闆嗗悎锛堢┖闆嗗悎琛ㄧず鏈鏉′欢涓嬫病鏈変换浣曚换鍔★級銆�
+     * <p>
+     * 鑳屾櫙锛歿@code /statistics} 鐨勯鐩潵婧愭槸銆屾弧鎰忓害鍒嗙被銆嶄笅鐨勫叏閲忛搴撻鐩�
+     * 锛坽@link SatisfactionScriptMapper#querySvyScriptByCategory} /
+     * {@link SatisfactionScriptMapper#queryIvrScriptByAssort}锛夛紝
+     * 鏃笉鐪嬫ā鏉夸篃涓嶇湅鏃堕棿銆傞搴撻噷鍙鎸傝繘杩囦竴濂楀巻鍙查棶鍗锋ā鏉�
+     * 锛堥鐩繕鍦ㄣ�佷絾浠庢潵娌′笅鍙戣繃浠诲姟锛夛紝缁熻缁撴灉灏变細澶氬嚭涓�鏁存壒
+     * 銆屽钩鍧囧垎 0 / 鏈�楂樺垎 0 / 绛旈浜烘暟 0銆嶇殑琛屻��
+     * <p>
+     * 瀹炴祴锛堜附姘� smartor_sltd锛屾煇娆″叆鍙傦級锛氭弧鎰忓害鍒嗙被涓� 6 濂楁ā鏉垮叡 69 閬撻锛�
+     * 鑰屾湰鏈熷彧鏈� 2 濂楁ā鏉垮叡 25 閬撻鐪熸涓嬪彂杩囷紝浜庢槸椤甸潰鏄剧ず 69 琛屻�佸叾涓� 44 琛屽叏 0銆�
+     * 鐢ㄦ湰鏂规硶瑁佹帀鏃犱换鍔℃ā鏉垮悗锛岃鏁板洖鍒� 25銆�
+     *
+     * @param reqVO 鍘熷璇锋眰锛堟潯浠朵笌銆屾湁鏁版嵁銆嶅垽鏂悓鍙e緞锛氭満鏋勩�佹湇鍔$被鍨嬨�佺瀹� OR 鐥呭尯銆佹椂闂村厹搴曪級
+     * @param type  service_subtask.type锛�1 璇煶銆�2 闂嵎
+     */
+    private Set<Long> activeTemplateIds(PatSatisfactionReqVO reqVO, String type) {
+        List<Long> ids = satisfactionMapper.selectSatisfactionActiveTemplateIds(reqVO, type);
+        if (CollectionUtils.isEmpty(ids)) return Collections.emptySet();
+        return new HashSet<>(ids);
+    }
+
+    /**
+     * 鍙繚鐣欐湰鏈熺湡姝d笅鍙戣繃浠诲姟鐨勬ā鏉跨殑棰樼洰锛堢┖闆嗗悎鏃惰繑鍥炵┖鍒楄〃锛屽嵆銆屾湰鏈熸病鏈変换鍔� 鈫� 涓嶅嚭琛屻�嶏級銆�
+     * <p>
+     * 淇濈暀 {@code scriptRefs} 鐨勫師鏈夐『搴忥紝鍥犱负杩斿洖椤哄簭灏辨槸椤甸潰灞曠ず椤哄簭銆�
+     */
+    private List<SatScriptRef> keepActiveTemplates(List<SatScriptRef> scriptRefs, Set<Long> activeTemplateIds) {
+        if (CollectionUtils.isEmpty(scriptRefs) || CollectionUtils.isEmpty(activeTemplateIds)) {
+            return new ArrayList<>();
+        }
+        List<SatScriptRef> kept = new ArrayList<>(scriptRefs.size());
+        for (SatScriptRef scriptRef : scriptRefs) {
+            if (scriptRef.getTemplateId() != null && activeTemplateIds.contains(scriptRef.getTemplateId())) {
+                kept.add(scriptRef);
+            }
+        }
+        return kept;
+    }
+
+    /**
+     * 婊℃剰搴﹀垎绫绘煡璇紙璇煶渚э級銆�
+     * <p>
+     * 鈿狅笍 <b>涓庡師鏂囦竴鑷达細鍙紶 orgid锛�<u>涓嶄紶 type</u></b>銆傚師瀹炵幇鏄�
+     * <pre>
+     * IvrLibaScriptAssort e = new IvrLibaScriptAssort();
+     * e.setOrgid(reqVO.getOrgid());      // 鈫� 鍙湁 orgid
+     * mapper.selectIvrLibaScriptAssortList(e);
+     * </pre>
+     * 鍒嗙被鐨勩�屾槸涓嶆槸婊℃剰搴�(myd)銆嶆槸鍦� <b>Java 渚�</b>鐢�
+     * {@code item.getType().contains("myd")} 杩囨护鐨勶紙瑙� {@link #statistics} /
+     * {@link #satisfactionGraph}锛夈��
+     * <p>
+     * 濡傛灉鍦ㄨ繖閲岄『鎵嬪姞涓� {@code type="myd"}锛孲QL 灏变細澶氬嚭涓�涓�
+     * {@code type like '%myd%'} 鏉′欢 鈥斺�� 鑰� MySQL 鐨� LIKE 榛樿<b>涓嶅尯鍒嗗ぇ灏忓啓</b>锛�
+     * 浼氭瘮 Java 鐨� {@code contains("myd")} 澶氬懡涓垎绫伙紝瀵艰嚧缁熻缁撴灉鍑虹幇宸紓銆�
+     */
     private SatisfactionScriptQuery ivrCategoryQuery(PatSatisfactionReqVO reqVO) {
         SatisfactionScriptQuery q = new SatisfactionScriptQuery();
         q.setOrgid(reqVO.getOrgid());
-        q.setType("myd");
         return q;
     }
 
-    /** 婊℃剰搴﹀垎绫绘煡璇紙闂嵎渚э紝鏉′欢鍚岃闊充晶锛� */
+    /** 婊℃剰搴﹀垎绫绘煡璇紙闂嵎渚э紝鍚屾牱鍙紶 orgid锛岃 {@link #ivrCategoryQuery}锛� */
     private SatisfactionScriptQuery svyCategoryQuery(PatSatisfactionReqVO reqVO) {
         SatisfactionScriptQuery q = new SatisfactionScriptQuery();
         q.setOrgid(reqVO.getOrgid());
-        q.setType("myd");
         return q;
     }
 

--
Gitblit v1.9.3