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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package com.ruoyi.message.sms;
 
import com.ruoyi.message.SendException;
import com.ruoyi.message.SendResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
 
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
 
/**
 * 短信发送方工厂:按 key 路由到一个具体实现,调用方不再需要 {@code if (active.equals("xx"))} 硬分支。
 * <p>
 * Spring 会自动把所有 {@link SmsSender} 注入进来,新增一个站点只需新增一个实现类。
 */
@Slf4j
@Component
public class SmsSenderFactory {
 
    /**
     * 站点 profile → 短信通道 key 的映射。
     * <p>
     * 目前两边取值完全一致({@code spring.profiles.active} 直接就是渠道名),
     * 单独留出映射表是为了将来 profile 名与渠道名解耦时不改调用方。
     */
    private static final Map<String, String> PROFILE_ALIAS = new LinkedHashMap<>();
 
    static {
        PROFILE_ALIAS.put("xh", "xh");
        PROFILE_ALIAS.put("ls", "ls");
        PROFILE_ALIAS.put("sltd", "sltd");
        PROFILE_ALIAS.put("nhfy", "nhfy");
        PROFILE_ALIAS.put("hzszlyy", "hzszlyy");
    }
 
    private final Map<String, SmsSender> senders = new LinkedHashMap<>();
 
    public SmsSenderFactory(List<SmsSender> senderList) {
        for (SmsSender sender : senderList) {
            SmsSender exists = senders.put(sender.key(), sender);
            if (exists != null) {
                throw new IllegalStateException("短信发送方 key 重复:" + sender.key()
                        + ",冲突实现:" + exists.getClass().getName() + " 与 " + sender.getClass().getName());
            }
        }
        log.info("【SmsSenderFactory】已注册短信发送方:{}", senders.keySet());
    }
 
    /**
     * 按 key 获取发送方
     *
     * @param key 渠道 key(即 {@code spring.profiles.active} 取值)
     * @return 发送方实现
     * @throws SendException 找不到对应实现时抛出
     */
    public SmsSender get(String key) {
        String resolved = resolveSmsKey(key);
        SmsSender sender = resolved == null ? null : senders.get(resolved);
        if (sender == null) {
            throw new SendException("未找到短信发送方,key=" + key + ",已注册:" + senders.keySet());
        }
        return sender;
    }
 
    /**
     * 按 key 获取发送方,找不到返回 {@code null}
     */
    public SmsSender getOrNull(String key) {
        String resolved = resolveSmsKey(key);
        return resolved == null ? null : senders.get(resolved);
    }
 
    /**
     * 按 key 发送短信(等价于旧代码里那 200 行 if-else 的结果)
     */
    public SendResult send(String key, SmsSendRequest request) {
        return get(key).send(request);
    }
 
    /**
     * 判断是否存在该 key 的发送方
     */
    public boolean supports(String key) {
        return getOrNull(key) != null;
    }
 
    /**
     * 已注册的渠道 key
     */
    public Set<String> keys() {
        return new TreeSet<>(senders.keySet());
    }
 
    /**
     * 站点 profile → 渠道 key
     */
    public static String resolveSmsKey(String profile) {
        if (StringUtils.isEmpty(profile)) {
            return null;
        }
        String alias = PROFILE_ALIAS.get(profile);
        return alias == null ? profile : alias;
    }
}