liusheng
14 小时以前 c24d16a37523a49080392610357872ce580cbc38
ruoyi-satisfaction/src/main/java/com/ruoyi/satisfaction/config/SatisfactionSwitch.java
@@ -52,6 +52,24 @@
    public static final String CONFIG_KEY = "satisfaction.enabled";
    /**
     * 满意度「综合得分口径」站点参数键名。
     * <p>
     * 值取 {@link com.ruoyi.satisfaction.service.strategy.SatisfactionSites} 的标识:
     * <ul>
     *   <li>{@code sltd}(默认)—— 省立同德口径:按选项文案判五档加权;</li>
     *   <li>{@code common}(别名 {@code nanhua})—— 通用/南华口径:按明细 score 求平均。</li>
     * </ul>
     * 本参数是 2026-10-21 新增的:{@code /smartor/serviceSubtaskDetail/sltdMydTotalByScore}
     * 原来把口径写死成 SLTD,南华调用时五档文案一条都匹配不上,综合得分恒为 0.00。
     */
    public static final String SITE_CONFIG_KEY = "satisfaction.site";
    /**
     * 未配置站点时的默认口径:保持历史行为(SLTD 口径)
     */
    private static final String DEFAULT_SITE = com.ruoyi.satisfaction.service.strategy.SatisfactionSites.SLTD;
    /**
     * 进程内缓存有效期(毫秒)
     */
    private static final long CACHE_TTL_MILLIS = 10_000L;
@@ -77,6 +95,16 @@
    private volatile long cachedAt;
    /**
     * 最近一次解析到的「综合得分口径」站点
     */
    private volatile String cachedSite;
    /**
     * 最近一次解析站点的时间戳
     */
    private volatile long cachedSiteAt;
    /**
     * Spring 使用的构造器。
     * <p>
     * ⚠️ <b>必须显式标注 {@code @Autowired}</b>:本类有两个公开构造器
@@ -99,6 +127,9 @@
        // 非 Spring 环境下没有"改配置后等 10 秒"的概念,直接禁用缓存,保证断言即时可见
        this.cachedEnabled = resolve();
        this.cachedAt = System.currentTimeMillis() + CACHE_TTL_MILLIS * 1000L;
        // 测试用的 FixedProvider 对任何 key 都返回同一个值,这里不要误把它当成站点配置
        this.cachedSite = DEFAULT_SITE;
        this.cachedSiteAt = System.currentTimeMillis() + CACHE_TTL_MILLIS * 1000L;
    }
    /**
@@ -121,13 +152,48 @@
     */
    public void invalidateCache() {
        this.cachedEnabled = null;
        this.cachedSite = null;
    }
    /**
     * 当前的<b>综合得分口径站点</b>({@code sys_config: satisfaction.site},运行时热读,最多 10 秒延迟)
     * <p>
     * 未配置时返回 {@link #DEFAULT_SITE}({@code sltd}),保持历史行为不变;
     * 南华部署请把该参数配成 {@code common}(别名 {@code nanhua})。
     *
     * @return 归一化后的站点标识(见 {@link com.ruoyi.satisfaction.service.strategy.SatisfactionSites})
     */
    public String site() {
        long now = System.currentTimeMillis();
        String cached = this.cachedSite;
        if (cached != null && now - this.cachedSiteAt < CACHE_TTL_MILLIS) {
            return cached;
        }
        String site = resolveSite();
        this.cachedSite = site;
        this.cachedSiteAt = now;
        return site;
    }
    /**
     * 解析站点口径:sys_config 优先,缺省用 {@link #DEFAULT_SITE}
     */
    private String resolveSite() {
        String value = readConfig(SITE_CONFIG_KEY);
        if (value != null) {
            String site = com.ruoyi.satisfaction.service.strategy.SatisfactionSites.normalize(value);
            log.debug("【满意度】综合得分口径取自 sys_config:{}={} -> site={}", SITE_CONFIG_KEY, value, site);
            return site;
        }
        log.debug("【满意度】sys_config 中未配置 {},回落默认站点 {}(同德口径)", SITE_CONFIG_KEY, DEFAULT_SITE);
        return DEFAULT_SITE;
    }
    /**
     * 解析当前开关值:sys_config 优先,其次 yml 兜底
     */
    private boolean resolve() {
        String value = readFromSysConfig();
        String value = readConfig(CONFIG_KEY);
        if (value != null) {
            if (!"true".equalsIgnoreCase(value) && !"false".equalsIgnoreCase(value)) {
                log.warn("【满意度】sys_config 中 {} 的值不是 true/false(实际=「{}」),将按「不是 false 即启用」处理",
@@ -145,7 +211,7 @@
    /**
     * 读 sys_config 的原始键值;没有实现、没有这一行、或读库失败都返回 {@code null}
     */
    private String readFromSysConfig() {
    private String readConfig(String key) {
        if (configServiceProvider == null) {
            return null;
        }
@@ -154,7 +220,7 @@
            if (configService == null) {
                return null;
            }
            String value = configService.selectConfigByKey(CONFIG_KEY);
            String value = configService.selectConfigByKey(key);
            if (value == null || value.trim().isEmpty()) {
                return null;
            }
@@ -162,7 +228,7 @@
        } catch (Exception e) {
            // 容器没有实现、数据源异常、SQL 报错……一律按"参数缺失"处理(fail-open),绝不影响主流程
            log.warn("【满意度】读取 sys_config 的 {} 失败,本次按未配置处理(fail-open):{}",
                    CONFIG_KEY, e.toString());
                    key, e.toString());
            return null;
        }
    }