package com.gk.hotwork.Service.ServiceImpl; import com.alibaba.fastjson.JSONObject; import com.gk.hotwork.Config.Oauth2.IRedisService; import com.gk.hotwork.Domain.Enum.RedisServiceEnum; import com.gk.hotwork.Domain.Enum.SendStatus; import com.gk.hotwork.Domain.Enum.SmsSource; import com.gk.hotwork.Domain.Exception.BusinessException; import com.gk.hotwork.Domain.SmsLog; import com.gk.hotwork.Domain.Utils.HttpUtils; import com.gk.hotwork.Service.SmsLogService; import com.gk.hotwork.Service.SmsService; import com.gk.hotwork.Sms.SmsServiceConfig; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.text.SimpleDateFormat; import java.util.*; @Service("smsService") public class SmsServiceImpl implements SmsService { private static final Logger logger = Logger.getLogger(SmsService.class); private final static String limit_60 = "60:"; private final static String limit_600 = "600:"; private final static String limit_3600 = "3600:"; @Autowired private IRedisService redisService; @Autowired private SmsLogService smsLogService; @Autowired private SmsServiceConfig smsServiceConfig; /** * @Description: 发送短信(记录保存,条数限制,发送操作) * @date 2022/5/18 8:39 */ @Override /** 运营商限制同1个号码同1个签名的内容1分钟内只能接收1条,10分钟3条,1小时内4条,一天20条,否则可能会被运营商屏蔽 **/ public void send(String phone,String phoneUser,String tplId, Map params) { //配置开关 if (!smsServiceConfig.isEnable()) return; Date now = new Date(); SmsLog smsLog = new SmsLog(); //短信发送保存到数据库 { smsLog.setContent(params.toString()); smsLog.setCreateTime(now); smsLog.setPhone(phone); smsLog.setPhoneUser(phoneUser); smsLog.setSource(SmsSource.WARN.getCode()); smsLog.setSendStatus(SendStatus.UN_SEND.getStatus()); smsLogService.save(smsLog); } Calendar instance = Calendar.getInstance(); instance.setTime(now); instance.set(Calendar.HOUR, 23); instance.set(Calendar.MINUTE, 59); instance.set(Calendar.SECOND, 59); try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String format = sdf.format(now); String totalKey = RedisServiceEnum.SMS_SERVICE.getService() + format; Object totalValueObj = redisService.get(totalKey); if (totalValueObj == null) { //初始化 0 redisService.set(totalKey, 0); //当日23:59:59 过期 redisService.expireAt(totalKey, instance.getTime()); } else { //否则判断总数 int totalValue = Integer.parseInt(totalValueObj.toString()); if (totalValue >= smsServiceConfig.getLimit()) throw new BusinessException("已经超过当日限制" + smsServiceConfig.getLimit() + "条"); } String prefix = RedisServiceEnum.SMS_SERVICE.getService() + phone + ":"; this.isMaxLimited(prefix + limit_60 + "*", 1, "1分钟限制1条"); this.isMaxLimited(prefix + limit_600 + "*", 3, "10分钟限制3条"); this.isMaxLimited(prefix + limit_3600 + "*", 4, "1小时限制4条"); //发送短信 tplId为模板id smsServiceConfig.getActiveSupplier().sendSms( phone, tplId, params); //并且设置过期时间 //更新数据状态 //发送成功更新状态 smsLog.setSendStatus(SendStatus.SUCCESS.getStatus()); smsLogService.updateById(smsLog); Object o = redisService.get(totalKey); int total = Integer.parseInt(o.toString()); //邮件个数 ↑1 redisService.set(totalKey, ++total); //过期时间点23:59:59 redisService.expireAt(totalKey, instance.getTime()); //1分钟的过期时间 redisService.set(prefix +":60:" + now.getTime(), "#",(long)60); //10分钟的过期时间 redisService.set(prefix + ":600:" + now.getTime(), "#",(long)600); //1小时的过期时间 redisService.set(prefix + ":3600:" + now.getTime(), "#",(long)3600); } catch (BusinessException e) { //日志打印 smsLog.setSendStatus(SendStatus.FAILURE.getStatus()); smsLog.setFailureReason(e.getMessage()); smsLogService.updateById(smsLog); } catch (Exception e) { e.printStackTrace(); } } /** * @Description: 判断是否超过限制 * @date 2022/5/18 8:38 */ @Override public boolean isMaxLimited(String match, Integer limit, String errorMsg) { Set setKey = redisService.scan(match); List listKey = redisService.getListKey(setKey); if (listKey.size() >= limit) { throw new BusinessException(errorMsg); } return true; } }