package com.ruoyi.satisfaction.service.strategy; import com.ruoyi.satisfaction.domain.ServiceSubtaskDetailRatioExport; import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.List; /** * 通用口径(南华使用)的综合满意度得分策略。 *

* 口径与原实现完全一致(等于 {@code PatSatisfactionServiceImpl#averageScoreByStat}): *

 *   分子 = Σ(可解析的 score × 该分值的明细行数)
 *   分母 = 全部明细行数(包含分值为空的行)
 *   结果 = 分子 / 分母,保留 1 位、HALF_UP;无行时 0.0
 * 
* ⚠️ 两个"不能改"的点(原注释已强调,这里原样保留): *
    *
  1. 分母是明细行数,不是"有分值的行数" —— 改成后者会改变 {@code averageScore};
  2. *
  3. 分值解析用 {@code Double.parseDouble},脏值会抛 {@code NumberFormatException} * (原实现即如此,未加 try/catch,保持一致)。
  4. *
*/ @Component public class CommonSatisfactionScoreStrategy implements SatisfactionScoreStrategy { /** * 通用口径的保留位数(1 位,与 {@code averageScoreByStat} 一致) */ private static final int SCALE = 1; @Override public String site() { return SatisfactionSites.COMMON; } @Override public String siteName() { return "通用口径(南华)"; } @Override public BigDecimal comprehensiveScore(List rows) { if (CollectionUtils.isEmpty(rows)) { return BigDecimal.ZERO.setScale(SCALE); } double sum = 0.0; long totalRows = 0L; for (ServiceSubtaskDetailRatioExport row : rows) { long count = parseCount(row.getCount()); // 与原文一致:非正数的聚合行直接跳过 if (count <= 0L) continue; totalRows += count; String score = row.getScore(); if (score != null && !score.isEmpty()) { sum += Double.parseDouble(score) * count; } } if (totalRows == 0L) { return BigDecimal.ZERO.setScale(SCALE); } return new BigDecimal(sum / totalRows).setScale(SCALE, RoundingMode.HALF_UP); } /** * 明细行数解析:与 {@code ScoreCount.getCount()} 等价(原始是 long,这里从字符串取) */ private long parseCount(String count) { if (count == null || count.isEmpty()) { return 0L; } try { return Long.parseLong(count.trim()); } catch (NumberFormatException e) { return 0L; } } }