houzhongjian
2024-10-16 7da8f196dee8e3c526c009a4bc7f5983ece6bb97
提交 | 用户 | 时间
e7c126 1 package com.iailab.module.system.service.sms;
H 2
3 import cn.hutool.core.util.StrUtil;
4 import com.iailab.framework.common.pojo.PageResult;
5 import com.iailab.framework.common.util.object.BeanUtils;
6 import com.iailab.module.system.framework.sms.core.client.SmsClient;
7 import com.iailab.module.system.framework.sms.core.client.SmsClientFactory;
8 import com.iailab.module.system.framework.sms.core.property.SmsChannelProperties;
9 import com.iailab.module.system.controller.admin.sms.vo.channel.SmsChannelPageReqVO;
10 import com.iailab.module.system.controller.admin.sms.vo.channel.SmsChannelSaveReqVO;
11 import com.iailab.module.system.dal.dataobject.sms.SmsChannelDO;
12 import com.iailab.module.system.dal.mysql.sms.SmsChannelMapper;
13 import com.google.common.cache.CacheLoader;
14 import com.google.common.cache.LoadingCache;
15 import lombok.Getter;
16 import lombok.extern.slf4j.Slf4j;
17 import org.springframework.stereotype.Service;
18
19 import javax.annotation.Resource;
20 import java.time.Duration;
21 import java.util.List;
22
23 import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception;
24 import static com.iailab.framework.common.util.cache.CacheUtils.buildAsyncReloadingCache;
25 import static com.iailab.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_HAS_CHILDREN;
26 import static com.iailab.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_NOT_EXISTS;
27
28 /**
29  * 短信渠道 Service 实现类
30  *
31  * @author zzf
32  */
33 @Service
34 @Slf4j
35 public class SmsChannelServiceImpl implements SmsChannelService {
36
37     /**
38      * {@link SmsClient} 缓存,通过它异步刷新 smsClientFactory
39      */
40     @Getter
41     private final LoadingCache<Long, SmsClient> idClientCache = buildAsyncReloadingCache(Duration.ofSeconds(10L),
42             new CacheLoader<Long, SmsClient>() {
43
44                 @Override
45                 public SmsClient load(Long id) {
46                     // 查询,然后尝试刷新
47                     SmsChannelDO channel = smsChannelMapper.selectById(id);
48                     if (channel != null) {
49                         SmsChannelProperties properties = BeanUtils.toBean(channel, SmsChannelProperties.class);
50                         smsClientFactory.createOrUpdateSmsClient(properties);
51                     }
52                     return smsClientFactory.getSmsClient(id);
53                 }
54
55             });
56
57     /**
58      * {@link SmsClient} 缓存,通过它异步刷新 smsClientFactory
59      */
60     @Getter
61     private final LoadingCache<String, SmsClient> codeClientCache = buildAsyncReloadingCache(Duration.ofSeconds(60L),
62             new CacheLoader<String, SmsClient>() {
63
64                 @Override
65                 public SmsClient load(String code) {
66                     // 查询,然后尝试刷新
67                     SmsChannelDO channel = smsChannelMapper.selectByCode(code);
68                     if (channel != null) {
69                         SmsChannelProperties properties = BeanUtils.toBean(channel, SmsChannelProperties.class);
70                         smsClientFactory.createOrUpdateSmsClient(properties);
71                     }
72                     return smsClientFactory.getSmsClient(code);
73                 }
74
75             });
76
77     @Resource
78     private SmsClientFactory smsClientFactory;
79
80     @Resource
81     private SmsChannelMapper smsChannelMapper;
82
83     @Resource
84     private SmsTemplateService smsTemplateService;
85
86     @Override
87     public Long createSmsChannel(SmsChannelSaveReqVO createReqVO) {
88         SmsChannelDO channel = BeanUtils.toBean(createReqVO, SmsChannelDO.class);
89         smsChannelMapper.insert(channel);
90         return channel.getId();
91     }
92
93     @Override
94     public void updateSmsChannel(SmsChannelSaveReqVO updateReqVO) {
95         // 校验存在
96         SmsChannelDO channel = validateSmsChannelExists(updateReqVO.getId());
97         // 更新
98         SmsChannelDO updateObj = BeanUtils.toBean(updateReqVO, SmsChannelDO.class);
99         smsChannelMapper.updateById(updateObj);
100
101         // 清空缓存
102         clearCache(updateReqVO.getId(), channel.getCode());
103     }
104
105     @Override
106     public void deleteSmsChannel(Long id) {
107         // 校验存在
108         SmsChannelDO channel = validateSmsChannelExists(id);
109         // 校验是否有在使用该账号的模版
110         if (smsTemplateService.getSmsTemplateCountByChannelId(id) > 0) {
111             throw exception(SMS_CHANNEL_HAS_CHILDREN);
112         }
113         // 删除
114         smsChannelMapper.deleteById(id);
115
116         // 清空缓存
117         clearCache(id, channel.getCode());
118     }
119
120     /**
121      * 清空指定渠道编号的缓存
122      *
123      * @param id 渠道编号
124      * @param code 渠道编码
125      */
126     private void clearCache(Long id, String code) {
127         idClientCache.invalidate(id);
128         if (StrUtil.isNotEmpty(code)) {
129             codeClientCache.invalidate(code);
130         }
131     }
132
133     private SmsChannelDO validateSmsChannelExists(Long id) {
134         SmsChannelDO channel = smsChannelMapper.selectById(id);
135         if (channel == null) {
136             throw exception(SMS_CHANNEL_NOT_EXISTS);
137         }
138         return channel;
139     }
140
141     @Override
142     public SmsChannelDO getSmsChannel(Long id) {
143         return smsChannelMapper.selectById(id);
144     }
145
146     @Override
147     public List<SmsChannelDO> getSmsChannelList() {
148         return smsChannelMapper.selectList();
149     }
150
151     @Override
152     public PageResult<SmsChannelDO> getSmsChannelPage(SmsChannelPageReqVO pageReqVO) {
153         return smsChannelMapper.selectPage(pageReqVO);
154     }
155
156     @Override
157     public SmsClient getSmsClient(Long id) {
158         return idClientCache.getUnchecked(id);
159     }
160
161     @Override
162     public SmsClient getSmsClient(String code) {
163         return codeClientCache.getUnchecked(code);
164     }
165
166 }