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<String,Object> 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<String> setKey = redisService.scan(match);
|
List<String> listKey = redisService.getListKey(setKey);
|
if (listKey.size() >= limit) {
|
throw new BusinessException(errorMsg);
|
}
|
|
return true;
|
}
|
|
|
|
|
|
|
}
|