package cn.iocoder.dashboard.modules.system.sms; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.dashboard.common.enums.SmsChannelEnum; import cn.iocoder.dashboard.common.exception.ServiceException; import cn.iocoder.dashboard.framework.sms.SmsBody; import cn.iocoder.dashboard.framework.sms.SmsClient; import cn.iocoder.dashboard.framework.sms.SmsClientAdapter; import cn.iocoder.dashboard.framework.sms.SmsResult; import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsChannelAllVO; import cn.iocoder.dashboard.modules.system.controller.sms.vo.SmsTemplateVO; import cn.iocoder.dashboard.modules.system.sms.client.AliSmsClient; import cn.iocoder.dashboard.modules.system.sms.proxy.SmsClientLogProxy; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; /** * 短信发送者工厂 * * @author zzf * @date 2021/1/25 16:18 */ public class SmsSenderUtils { /** * 短信渠道id:短信客户端map * key: channelId * val: SmsClient */ private static final Map> smsSenderMap = new ConcurrentHashMap<>(8); /** * 短信模板code: 短信渠道id map * key: templateCode * val: channelId */ private static final Map templateCode2ChannelIdMap = new HashMap<>(); /** * 将短信渠道信息初始化成短信客户端 * * @param smsChannelAllVOList 短信渠道信息 * @return 短信渠道id:短信客户端map */ public synchronized static Map> init(List smsChannelAllVOList) { if (ObjectUtil.isEmpty(smsChannelAllVOList)) { throw new ServiceException(SMS_CHANNEL_NOT_FOUND); } addSender(smsChannelAllVOList); return smsSenderMap; } /** * 重置短信客户端信息 * * @param smsClientAdapter 短信客户端适配器 * @param smsChannelAllVOList 短信渠道信息集合 */ public synchronized static void flush(SmsClientAdapter smsClientAdapter, List smsChannelAllVOList) { smsSenderMap.clear(); smsClientAdapter.flushClient(init(smsChannelAllVOList)); } /** * 发送短信 * * @param smsClientAdapter 短信客户端适配器 * @param smsBody 短信内容 * @param targetPhones 对象手机集合 * @return 短信发送结果 */ public static SmsResult send(SmsClientAdapter smsClientAdapter, SmsBody smsBody, Collection targetPhones) { Long channelId = templateCode2ChannelIdMap.get(smsBody.getCode()); if (channelId == null) { throw new ServiceException(SMS_SENDER_NOT_FOUND); } return smsClientAdapter.send(channelId, smsBody, targetPhones); } /** * 发送短信 * * @param smsClientAdapter 短信客户端适配器 * @param smsBody 短信内容 * @param targetPhone 对象手机 * @return 短信发送结果 */ public static SmsResult send(SmsClientAdapter smsClientAdapter, SmsBody smsBody, String targetPhone) { Long channelId = templateCode2ChannelIdMap.get(smsBody.getCode()); if (channelId == null) { throw new ServiceException(SMS_SENDER_NOT_FOUND); } return smsClientAdapter.send(channelId, smsBody, Collections.singletonList(targetPhone)); } /** * 发送短信 * * @param smsClientAdapter 短信客户端适配器 * @param smsBody 短信内容 * @param targetPhones 对象手机数组 * @return 短信发送结果 */ public static SmsResult send(SmsClientAdapter smsClientAdapter, SmsBody smsBody, String... targetPhones) { Long channelId = templateCode2ChannelIdMap.get(smsBody.getCode()); if (channelId == null) { throw new ServiceException(SMS_SENDER_NOT_FOUND); } return smsClientAdapter.send(channelId, smsBody, Arrays.asList(targetPhones)); } private static void addSender(List smsChannelAllVOList) { smsChannelAllVOList.forEach(channelAllVO -> addSender(SmsChannelEnum.getByCode(channelAllVO.getCode()), channelAllVO)); } private static void addSender(SmsChannelEnum channelEnum, SmsChannelAllVO channelAllVO) { if (channelEnum == null) { throw new ServiceException(INVALID_CHANNEL_CODE); } List templateList = channelAllVO.getTemplateList(); if (ObjectUtil.isEmpty(templateList)) { throw new ServiceException(SMS_TEMPLATE_NOT_FOUND); } SmsClient aliSmsClient = getSender(channelEnum, channelAllVO); templateList.forEach(smsTemplateVO -> templateCode2ChannelIdMap.put(smsTemplateVO.getCode(), channelAllVO.getId())); smsSenderMap.put(channelAllVO.getId(), aliSmsClient); } private static SmsClient getSender(SmsChannelEnum channelEnum, SmsChannelAllVO channelAllVO) { switch (channelEnum) { case ALI: return new SmsClientLogProxy<>(new AliSmsClient(channelAllVO)); // TODO fill more channel default: break; } throw new ServiceException(SMS_SENDER_NOT_FOUND); } }