From 665cb08f5e74996d417f26ab2bad6d7fe210ea2b Mon Sep 17 00:00:00 2001
From: liusheng <337615773@qq.com>
Date: 星期二, 22 九月 2026 14:05:16 +0800
Subject: [PATCH] 1.修改省立同德满意度统计接口

---
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskDetailController.java |  101 +++++++++++++++++++++++++++++----
 smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java                  |   20 +++++-
 smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml                             |   39 ++++++++++++
 3 files changed, 143 insertions(+), 17 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskDetailController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskDetailController.java
index 85ceebe..d29f168 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskDetailController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/smartor/ServiceSubtaskDetailController.java
@@ -26,6 +26,7 @@
 import org.springframework.web.bind.annotation.*;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -204,9 +205,14 @@
 
 
     /**
-     * 鏌ヨ鎮h�呴殢璁夸俊鎭�
+     * 鐪佺珛鍚屽痉婊℃剰搴︽暟鎹粺璁★紙鎸夐鐩粺璁¢�夐」鏁伴噺/鍗犳瘮锛屽苟缁欏嚭璇ラ鐨勭患鍚堝緱鍒嗭級
+     * <p>
+     * 缁煎悎婊℃剰搴� = 危(閫夐」鍒嗗�� 脳 椤规暟) / 危椤规暟 / 鏈鏈�楂樺垎鍊� 脳 100%锛�
+     * 鍒嗗�煎彇 1銆�0.8銆�0.6銆�0.4銆�0.2 浜旀。锛堝緢婊℃剰銆佹弧鎰忋�佷竴鑸�佷笉婊℃剰銆佸緢涓嶆弧鎰忥級锛�
+     * 銆屼笉閫傜敤銆嶃��0 鍒嗐�佺┖鍊肩瓑鏃笉杩涘垎瀛愪篃涓嶈繘鍒嗘瘝銆�
      */
     @ApiOperation("鐪佺珛鍚屽痉婊℃剰搴︽暟鎹粺璁�")
+    @AddOrgId(field = "orgid", paramIndex = 0, campusField = "campusid")
     @PostMapping("/sltdMydTotalByScore")
     public Map<String, Object> sltdMydTotalByScore(@RequestBody SltdMydTotalVO sltdMydTotalVO) {
         List<ServiceSubtaskRes> serviceSubtaskResList = null;
@@ -220,6 +226,9 @@
                 serviceSubtaskEntity.setDeptOrDistrict(sltdMydTotalVO.getDeptOrDistrict());
                 serviceSubtaskEntity.setLeavehospitaldistrictcodes(sltdMydTotalVO.getLeavehospitaldistrictcodes());
                 serviceSubtaskEntity.setLeaveldeptcodes(sltdMydTotalVO.getLeaveldeptcodes());
+                //鏈烘瀯/闄㈠尯鐢� @AddOrgId 娉ㄥ叆锛岃惤鍒版煡璇㈡潯浠朵笂锛岄伩鍏嶈法鏈烘瀯鍙栨暟
+                serviceSubtaskEntity.setOrgid(sltdMydTotalVO.getOrgid());
+                serviceSubtaskEntity.setCampusid(sltdMydTotalVO.getCampusid());
                 if (serviceSubtaskEntity != null) {
                     List<ServiceSubtask> serviceSubtasks = serviceSubtaskService.getServiceSubtasks(serviceSubtaskEntity);
                     List<ServiceSubtaskRes> serviceSubtaskRes = DtoConversionUtils.sourceToTarget(serviceSubtasks, ServiceSubtaskRes.class);
@@ -236,6 +245,10 @@
         if (CollectionUtils.isNotEmpty(serviceSubtaskResList)) {
             List<ServiceSubtaskDetailRatioExport> detailList = serviceSubtaskService.getDetailRatio(sltdMydTotalVO, serviceSubtaskResList);
 
+            if (detailList == null) {
+                //serviceType 缁勫悎涓嶅湪鏀寔鑼冨洿鍐咃紙濡傚悓鏃跺惈闅忚 2 鍜屾弧鎰忓害 6/14锛夛紝缁欐槑纭彁绀鸿�屼笉鏄倓鎮勮繑鍥炵┖鏁扮粍
+                return error("褰撳墠 serviceType 缁勫悎鏆備笉鏀寔缁熻闂鍗犳瘮锛岃鍒嗗紑鏌ヨ锛堜粎鏀寔闅忚 2 鎴栨弧鎰忓害 6/14锛�");
+            }
             if (CollectionUtils.isNotEmpty(detailList)) {
                 Map<String, List<ServiceSubtaskDetailRatioExport>> groupedMap = detailList.stream().collect(Collectors.groupingBy(ServiceSubtaskDetailRatioExport::getQuestiontext));
 
@@ -243,17 +256,8 @@
                     QuestionResultDTO questionResultDTO = new QuestionResultDTO();
                     questionResultDTO.setQeustionText(questionText);
                     questionResultDTO.setSubtaskDetailRatioExportList(exportList);
-                    BigDecimal allCount = new BigDecimal("0");
-                    BigDecimal allScore = new BigDecimal("0.00");
-
-                    for (ServiceSubtaskDetailRatioExport ssdre : exportList) {
-                        if (StringUtils.isNotEmpty(ssdre.getCount()))
-                            allCount.add(BigDecimal.valueOf(Long.valueOf(ssdre.getCount())));
-                        allScore.add(BigDecimal.valueOf(Double.valueOf(ssdre.getScore())));
-                    }
-
-                    if (allCount.compareTo(BigDecimal.ZERO) > 0)
-                        questionResultDTO.setAvgScore(allScore.divide(allCount, 2).toString());
+                    //缁煎悎寰楀垎锛毼�(鍒嗗�济楅」鏁�) / 危椤规暟 / 鏈鏈�楂樺垎鍊� 脳 100%锛屼笉閫傜敤/0鍒�/绌哄�间笉杩涘垎瀛愪篃涓嶈繘鍒嗘瘝
+                    questionResultDTO.setAvgScore(calcMydScore(exportList));
                     result.add(questionResultDTO);
                 });
             }
@@ -287,4 +291,77 @@
         return success(serviceSubtaskService.mzMydScoreRank(mzMydScoreRankVO));
     }
 
+    /**
+     * 澶氶�夐鐨勯棶棰樼被鍨�
+     */
+    private static final String VALUE_TYPE_MULTIPLE = "2";
+
+    /**
+     * 璁$畻涓�閬撻鐨勬弧鎰忓害缁煎悎寰楀垎锛堢櫨鍒嗗埗锛屼繚鐣欎袱浣嶅皬鏁帮級
+     * <p>
+     * 缁煎悎婊℃剰搴� = 危(閫夐」鍒嗗�� 脳 椤规暟) / 危椤规暟 / 鏈鏈�楂樺垎鍊� 脳 100%
+     * 绛変环浜� 危(寰堟弧鎰徝�1 + 婊℃剰脳0.8 + 涓�鑸�0.6 + 涓嶆弧鎰徝�0.4 + 寰堜笉婊℃剰脳0.2) / 危(浜旀。椤规暟) 脳 100%銆�
+     * 鐢ㄦ湰棰樻渶楂樺垎鍊煎綊涓�鍖栵紝鍏煎鏄庣粏鍒嗗�煎瓨 0-1 鏉冮噸锛�1銆�0.8鈥︼級鍜屽瓨 5 鍒嗗埗锛�5銆�4鈥︼級涓ょ鍙e緞銆�
+     *
+     * @param exportList 鍚屼竴閬撻鐩殑閫夐」缁熻鏄庣粏
+     * @return 鐧惧垎鍒剁患鍚堝緱鍒嗭紝鏃犳湁鏁堥」鏁版椂杩斿洖 "0.00"
+     */
+    private String calcMydScore(List<ServiceSubtaskDetailRatioExport> exportList) {
+        if (CollectionUtils.isEmpty(exportList)) return "0.00";
+
+        BigDecimal scoreSum = BigDecimal.ZERO;   //鍒嗗瓙锛毼�(閫夐」鍒嗗�� 脳 椤规暟)
+        BigDecimal countSum = BigDecimal.ZERO;   //鍒嗘瘝锛毼i」鏁�
+        BigDecimal maxScore = null;              //鏈鏈�楂樺垎鍊硷紝鐢ㄤ簬褰掍竴鍖�
+
+        for (ServiceSubtaskDetailRatioExport detail : exportList) {
+            //澶氶�夐涓�琛屾槸澶氫釜閫夐」鐨勫垎鍊间箣鍜岋紝鍒嗘瘝鍙畻 1 椤癸紝浼氭妸寰楀垎绠楅珮锛屼笉璁″叆缁煎悎寰楀垎
+            if (VALUE_TYPE_MULTIPLE.equals(detail.getValueType())) continue;
+            //銆屼笉閫傜敤銆嶄笉鍦ㄥ叕寮忕殑浜旀。閲岋紝涓嶈鍏ョ患鍚堝緱鍒�
+            if (isNotApplicable(detail)) continue;
+
+            BigDecimal score = parseDecimal(detail.getScore());
+            BigDecimal count = parseDecimal(detail.getCount());
+            if (score == null || count == null) continue;
+            //0 鍒嗭紙鏈瓟/绌虹瓟锛夈�佺┖鏁伴噺锛氭棦涓嶈繘鍒嗗瓙涔熶笉杩涘垎姣�
+            if (score.signum() <= 0 || count.signum() <= 0) continue;
+
+            if (maxScore == null || score.compareTo(maxScore) > 0) maxScore = score;
+            scoreSum = scoreSum.add(score.multiply(count));
+            countSum = countSum.add(count);
+        }
+
+        if (maxScore == null || countSum.signum() <= 0) return "0.00";
+
+        return scoreSum.divide(countSum, 6, RoundingMode.HALF_UP)
+                .divide(maxScore, 6, RoundingMode.HALF_UP)
+                .multiply(BigDecimal.valueOf(100))
+                .setScale(2, RoundingMode.HALF_UP)
+                .toPlainString();
+    }
+
+    /**
+     * 鏄惁銆屼笉閫傜敤銆嶉�夐」
+     */
+    private boolean isNotApplicable(ServiceSubtaskDetailRatioExport detail) {
+        return containsNotApplicable(detail.getOptionresult()) || containsNotApplicable(detail.getTargetvalue());
+    }
+
+    private boolean containsNotApplicable(String optionText) {
+        if (StringUtils.isEmpty(optionText)) return false;
+        String text = optionText.trim();
+        return text.contains("涓嶉�傜敤") || text.contains("鏈瓟") || text.contains("鎷掔瓟");
+    }
+
+    /**
+     * 瀛楃涓茶浆 BigDecimal锛岀┖鍊�/闈炴硶鍊艰繑鍥� null
+     */
+    private BigDecimal parseDecimal(String value) {
+        if (StringUtils.isEmpty(value)) return null;
+        try {
+            return new BigDecimal(value.trim());
+        } catch (NumberFormatException e) {
+            return null;
+        }
+    }
+
 }
diff --git a/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java b/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
index 7afbcc6..53f6da1 100644
--- a/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
+++ b/smartor/src/main/java/com/smartor/service/impl/ServiceSubtaskServiceImpl.java
@@ -6181,17 +6181,29 @@
      */
     public List<ServiceSubtaskDetailRatioExport> getDetailRatio(SltdMydTotalVO sltdMydTotalVO, List<ServiceSubtaskRes> serviceSubtaskRes) {
         List<ServiceSubtaskDetailRatioExport> serviceSubtaskDetailRatioExports = null;
-        if (CollectionUtils.isNotEmpty(sltdMydTotalVO.getServiceTypeList()) && sltdMydTotalVO.getServiceTypeList().contains("2") && (sltdMydTotalVO.getServiceTypeList().contains("6") || sltdMydTotalVO.getServiceTypeList().contains("14"))) {
-            //serviceType锛屽嵆鏈夐殢璁垮張鏈夋弧鎰忓害锛屾殏鏃舵病娉曠粺璁�
+        List<String> serviceTypeList = sltdMydTotalVO.getServiceTypeList();
+        if (CollectionUtils.isEmpty(serviceTypeList)) {
+            log.warn("getDetailRatio 鏈紶 serviceTypeList锛屾棤娉曠粺璁¢棶棰樺崰姣�");
             return serviceSubtaskDetailRatioExports;
-        } else if (CollectionUtils.isNotEmpty(sltdMydTotalVO.getServiceTypeList()) && sltdMydTotalVO.getServiceTypeList().contains("2")) {
+        }
+        // 鍒ゆ柇鍙e緞锛�2=闅忚锛堟寜 taskid 缁熻锛夛紝6/14=婊℃剰搴︼紙鎸� subtask id 缁熻锛�
+        boolean hasFollowUp = serviceTypeList.contains("2");
+        boolean hasSatisfaction = serviceTypeList.contains("6") || serviceTypeList.contains("14");
+        if (hasFollowUp && hasSatisfaction) {
+            //serviceType锛屽嵆鏈夐殢璁垮張鏈夋弧鎰忓害锛屾殏鏃舵病娉曠粺璁�
+            log.warn("getDetailRatio 鏆備笉鏀寔鍚屾椂缁熻闅忚(2)涓庢弧鎰忓害(6/14)锛宻erviceTypeList={}", serviceTypeList);
+            return serviceSubtaskDetailRatioExports;
+        }
+        if (hasFollowUp) {
             //鑾峰彇serviceSubtaskList涓殑鎵�鏈塼askid
             List<Long> taskIds = serviceSubtaskRes.stream().map(ServiceSubtaskRes::getTaskid).filter(ObjectUtils::isNotEmpty).distinct().collect(Collectors.toList());
             serviceSubtaskDetailRatioExports = statQuestionOption(taskIds, sltdMydTotalVO.getStartFinishTime(), sltdMydTotalVO.getEndFinishTime(), sltdMydTotalVO.getStartOutHospTime(), sltdMydTotalVO.getEndOutHospTime(), sltdMydTotalVO.getQuestionContent(), sltdMydTotalVO.getStartScore(), sltdMydTotalVO.getEndScore(), sltdMydTotalVO.getValueType());
-        } else if (CollectionUtils.isNotEmpty(sltdMydTotalVO.getServiceTypeList()) && sltdMydTotalVO.getServiceTypeList().contains("6") || sltdMydTotalVO.getServiceTypeList().contains("14")) {
+        } else if (hasSatisfaction) {
             //婊℃剰搴︾粺璁� 锛堥�氳繃 subtask 鐨� id 鍘荤粺璁★級
             List<Long> subtaskIds = serviceSubtaskRes.stream().map(ServiceSubtaskRes::getId).collect(Collectors.toList());
             serviceSubtaskDetailRatioExports = statQuestionOptionBySubtaskIds(subtaskIds, sltdMydTotalVO.getStartOutHospTime(), sltdMydTotalVO.getEndOutHospTime(), sltdMydTotalVO.getStartFinishTime(), sltdMydTotalVO.getEndFinishTime(), sltdMydTotalVO.getQuestionContent(), sltdMydTotalVO.getStartScore(), sltdMydTotalVO.getEndScore(), sltdMydTotalVO.getValueType());
+        } else {
+            log.warn("getDetailRatio 鏆備笉鏀寔鐨� serviceTypeList={}锛堜粎鏀寔 2 鎴� 6/14锛�", serviceTypeList);
         }
         return serviceSubtaskDetailRatioExports;
     }
diff --git a/smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml b/smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
index f902060..1603d17 100644
--- a/smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
+++ b/smartor/src/main/resources/mapper/smartor/ServiceSubtaskMapper.xml
@@ -3329,6 +3329,14 @@
         service_task t
         INNER JOIN service_subtask s ON s.taskid = t.taskid
         INNER JOIN service_subtask_detail d ON d.sub_id = s.id
+        <!-- 鍘婚噸锛氬悓涓�瀛愪换鍔″悓涓�棰樼洰鍙繚鐣欐渶鏂颁竴鏉★紝閬垮厤閲嶇瓟/閲嶅鍥炶皟鎶婂悓涓�閬撻閲嶅璁″叆椤规暟锛堜笌 mzMydScoreRank 鍙e緞涓�鑷达級 -->
+        AND d.id = (
+        SELECT MAX(d2.id)
+        FROM service_subtask_detail d2
+        WHERE d2.sub_id = d.sub_id
+        AND d2.questiontext &lt;=&gt; d.questiontext
+        AND d2.del_flag = '0'
+        )
         INNER JOIN (
         SELECT
         d.questiontext,
@@ -3337,6 +3345,14 @@
         service_task t
         INNER JOIN service_subtask s ON s.taskid = t.taskid
         INNER JOIN service_subtask_detail d ON d.sub_id = s.id
+        <!-- 鍘婚噸锛氬垎姣嶏紙璇ラ鏈夋晥绛斿嵎鎬绘暟锛変笌鏄庣粏鍙e緞淇濇寔涓�鑷达紝淇濊瘉鍚勯�夐」姣斾緥鍚堣 100% -->
+        AND d.id = (
+        SELECT MAX(d4.id)
+        FROM service_subtask_detail d4
+        WHERE d4.sub_id = d.sub_id
+        AND d4.questiontext &lt;=&gt; d.questiontext
+        AND d4.del_flag = '0'
+        )
         WHERE 1=1
         <if test="subtaskIds != null and subtaskIds.size() > 0">
             AND s.id IN
@@ -3345,16 +3361,37 @@
             </foreach>
         </if>
         <if test="valueType != null">AND d.value_type &gt;= #{valueType}</if>
-        <if test="scoreStart != null">AND d.score = #{scoreStart}</if>
+        <if test="scoreStart != null">AND d.score &gt;= #{scoreStart}</if>
         <if test="scoreEnd != null">AND d.score &lt;= #{scoreEnd}</if>
         <if test="questiontext != null  and questiontext != ''">and d.questiontext like concat('%', #{questiontext},
             '%')
         </if>
         AND s.sendstate = 6
         AND d.del_flag=0
+        <!-- 鍒嗘瘝涓庢槑缁嗙敤鍚屼竴濂楁椂闂存潯浠讹紝鍚﹀垯閫変簡鏃ユ湡鍖洪棿鍚庡悇閫夐」姣斾緥鍚堣涓嶅埌 100% -->
+        <if test="startOutHospTime != null">
+            AND date_format(s.endtime,'%y%m%d') &gt;= date_format(#{startOutHospTime},'%y%m%d')
+        </if>
+        <if test="endOutHospTime != null">
+            AND date_format(s.endtime,'%y%m%d') &lt;= date_format(#{endOutHospTime},'%y%m%d')
+        </if>
+        <if test="startFinishTime != null">
+            AND date_format(s.finishtime,'%y%m%d') &gt;= date_format(#{startFinishTime},'%y%m%d')
+        </if>
+        <if test="endFinishTime != null">
+            AND date_format(s.finishtime,'%y%m%d') &lt;= date_format(#{endFinishTime},'%y%m%d')
+        </if>
         GROUP BY d.questiontext
         ) t2 ON t2.questiontext = d.questiontext
         WHERE 1=1
+        <!-- 鍘婚噸锛氭槑缁嗚鍚屼竴瀛愪换鍔″悓涓�棰樼洰鍙繚鐣欐渶鏂颁竴鏉★紝閲嶇瓟涓嶉噸澶嶈鍏ラ」鏁� -->
+        AND d.id = (
+        SELECT MAX(d3.id)
+        FROM service_subtask_detail d3
+        WHERE d3.sub_id = d.sub_id
+        AND d3.questiontext &lt;=&gt; d.questiontext
+        AND d3.del_flag = '0'
+        )
         <if test="subtaskIds != null and subtaskIds.size() > 0">
             AND s.id IN
             <foreach collection="subtaskIds" item="subtaskId" open="(" separator="," close=")">

--
Gitblit v1.9.3