liusheng
9 天以前 f0a09ee996ab2605869844d6a3d812709e2bf0fa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.ruoyi.satisfaction.service.strategy;
 
import com.ruoyi.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
 
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
 
/**
 * 满意度站点口径策略解析器。
 * <p>
 * 由 Spring 注入全部 {@link SatisfactionScoreStrategy} 实现,按站点标识选择;
 * 站点为空或未知时<b>回落到通用口径</b>并打 WARN(保证调用方永远不会因为
 * "传了个没见过的站点"而失败)。
 * <p>
 * 用法:
 * <pre>
 * BigDecimal score = resolver.resolve(SatisfactionSites.SLTD).comprehensiveScore(rows);
 * </pre>
 * 以后新增站点:只加一个 {@code SatisfactionScoreStrategy} 实现类即可,本类无需改动。
 */
@Slf4j
@Component
public class SatisfactionScoreStrategyResolver {
 
    private final Map<String, SatisfactionScoreStrategy> strategies;
 
    private final SatisfactionScoreStrategy fallback;
 
    public SatisfactionScoreStrategyResolver(List<SatisfactionScoreStrategy> strategyList) {
        Map<String, SatisfactionScoreStrategy> map = new LinkedHashMap<>();
        if (strategyList != null) {
            for (SatisfactionScoreStrategy strategy : strategyList) {
                map.put(SatisfactionSites.normalize(strategy.site()), strategy);
            }
        }
        this.strategies = Collections.unmodifiableMap(map);
        this.fallback = map.get(SatisfactionSites.COMMON);
        if (this.fallback == null) {
            // 只可能在配置错误时发生(通用口径实现被误删),尽早暴露
            throw new ServiceException("满意度模块缺少通用口径策略实现(site=" + SatisfactionSites.COMMON + ")");
        }
    }
 
    /**
     * 按站点取策略;未知站点回落到通用口径并打 WARN
     *
     * @param site 站点标识({@link SatisfactionSites} 中的常量,或其别名)
     */
    public SatisfactionScoreStrategy resolve(String site) {
        String key = SatisfactionSites.normalize(site);
        SatisfactionScoreStrategy strategy = strategies.get(key);
        if (strategy == null) {
            log.warn("【满意度】未找到站点口径策略 site={},回落到通用口径({})", site, SatisfactionSites.COMMON);
            return fallback;
        }
        return strategy;
    }
 
    /**
     * 已注册的站点标识(供校验/文档使用)
     */
    public Set<String> supportedSites() {
        return Collections.unmodifiableSet(new TreeSet<>(strategies.keySet()));
    }
}