新增腾讯短信
This commit is contained in:
@@ -1817,6 +1817,11 @@ public class Constant {
|
|||||||
*/
|
*/
|
||||||
public static final String INCOME_METHOD = "income_method";
|
public static final String INCOME_METHOD = "income_method";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信发送方式(阿里 aliyun 腾讯 tencent)
|
||||||
|
*/
|
||||||
|
public static final String SMS_SDK_TYPE = "sms_sdk_type";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ActiveMq {
|
public static class ActiveMq {
|
||||||
|
@@ -5,6 +5,8 @@ package com.accompany.common.constant;
|
|||||||
*/
|
*/
|
||||||
public class SmsConstant {
|
public class SmsConstant {
|
||||||
|
|
||||||
|
public static final int SMS_EXPIRE_MINUTE = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 短信过期时间60秒
|
* 短信过期时间60秒
|
||||||
*/
|
*/
|
||||||
@@ -20,30 +22,37 @@ public class SmsConstant {
|
|||||||
*/
|
*/
|
||||||
public static final int SMS_SEND_INTERVAL_SECONDS = 60;
|
public static final int SMS_SEND_INTERVAL_SECONDS = 60;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证码短信类型
|
* 验证码短信类型
|
||||||
*/
|
*/
|
||||||
public static class SmsType {
|
public static class SmsType {
|
||||||
public static final Byte REGISTER = 1;//注册
|
public static final Byte REGISTER = 1;//注册
|
||||||
public static final Byte LOGIN = 2; //登录
|
public static final Byte LOGIN = 2; //登录
|
||||||
public static final Byte RESET_LOGIN_PASSWORD = 3;//忘记登录密码
|
public static final Byte RESET_LOGIN_PASSWORD = 3;//忘记登录密码
|
||||||
public static final Byte BINDING_PHONE = 4; //绑定手机
|
public static final Byte BINDING_PHONE = 4; //绑定手机
|
||||||
public static final Byte BINDING_ALIPAY = 5; //绑定支付宝
|
public static final Byte BINDING_ALIPAY = 5; //绑定支付宝
|
||||||
public static final Byte RESET_PAY_PASSWORD = 6; //重置支付密码
|
public static final Byte RESET_PAY_PASSWORD = 6; //重置支付密码
|
||||||
public static final Byte UNBINDING_PHONE = 7; //更换绑定手机号码
|
public static final Byte UNBINDING_PHONE = 7; //更换绑定手机号码
|
||||||
public static final Byte CERTIFICATION = 8; //实名认证
|
public static final Byte CERTIFICATION = 8; //实名认证
|
||||||
public static final Byte H5_BINDING_ALIPAY = 9; //h5绑定支付宝
|
public static final Byte H5_BINDING_ALIPAY = 9; //h5绑定支付宝
|
||||||
public static final Byte SUPER_ADMIN_LOGIN = 10; //超管登录
|
public static final Byte SUPER_ADMIN_LOGIN = 10; //超管登录
|
||||||
public static final Byte BINDING_BANK_CARD = 11; //绑定提现银行卡
|
public static final Byte BINDING_BANK_CARD = 11; //绑定提现银行卡
|
||||||
public static final Byte H5_BINDING_BANK_CARD = 12; //h5 绑定提现银行卡
|
public static final Byte H5_BINDING_BANK_CARD = 12; //h5 绑定提现银行卡
|
||||||
public static final Byte AUTH_CODE = 13; // 获取手机授权码
|
public static final Byte AUTH_CODE = 13; // 获取手机授权码
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 阿里云短信返回码
|
* 阿里云短信返回码
|
||||||
*/
|
*/
|
||||||
public static class AliyunSmsResponseCode {
|
public static class AliyunSmsResponseCode {
|
||||||
public static final String OK = "OK";
|
public static final String OK = "OK";
|
||||||
public static final String BUSINESS_LIMIT_CONTROL = "isv.BUSINESS_LIMIT_CONTROL";
|
public static final String BUSINESS_LIMIT_CONTROL = "isv.BUSINESS_LIMIT_CONTROL";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ResCode {
|
||||||
|
|
||||||
|
String OK = "Ok";
|
||||||
|
|
||||||
|
String LimitExceeded = "LimitExceeded";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -45,4 +45,12 @@ public class SpringContextHolder {
|
|||||||
public static <T> T getBean(Class<T> requiredType) {
|
public static <T> T getBean(Class<T> requiredType) {
|
||||||
return applicationContext.getBean(requiredType);
|
return applicationContext.getBean(requiredType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> T getBeanOfClass(Class<T> requiredType) {
|
||||||
|
String simpleName = requiredType.getSimpleName();
|
||||||
|
char[] ch = simpleName.toCharArray();
|
||||||
|
ch[0] += 32;
|
||||||
|
return (T) applicationContext.getBean(new String(ch));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,12 @@
|
|||||||
<artifactId>accompany-core</artifactId>
|
<artifactId>accompany-core</artifactId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.tencentcloudapi</groupId>
|
||||||
|
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||||
|
<version>${tencentcloud-sdk-java.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
@@ -0,0 +1,46 @@
|
|||||||
|
package com.accompany.sms.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liaozetao
|
||||||
|
* @date: 2023/8/14 11:43
|
||||||
|
* @description:
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@RefreshScope
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "tencent.sms")
|
||||||
|
public class TencentSmsConfig {
|
||||||
|
|
||||||
|
private String secretId;
|
||||||
|
|
||||||
|
private String secretKey;
|
||||||
|
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
private String appKey;
|
||||||
|
|
||||||
|
private Map<String, AppConfig> apps;
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class AppConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签名ID
|
||||||
|
*/
|
||||||
|
private String signId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模版ID
|
||||||
|
*/
|
||||||
|
private String templateId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,65 @@
|
|||||||
|
package com.accompany.sms.config;
|
||||||
|
|
||||||
|
import com.tencentcloudapi.common.Credential;
|
||||||
|
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||||
|
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||||
|
import com.tencentcloudapi.sms.v20210111.SmsClient;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liaozetao
|
||||||
|
* @date: 2023/8/14 11:55
|
||||||
|
* @description:
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class TencentSmsConfiguration {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TencentSmsConfig tencentSmsConfig;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Credential credential() {
|
||||||
|
/* 必要步骤:
|
||||||
|
* 实例化一个认证对象,入参需要传入腾讯云账户密钥对secretId,secretKey。
|
||||||
|
* 这里采用的是从环境变量读取的方式,需要在环境变量中先设置这两个值。
|
||||||
|
* 你也可以直接在代码中写死密钥对,但是小心不要将代码复制、上传或者分享给他人,
|
||||||
|
* 以免泄露密钥对危及你的财产安全。
|
||||||
|
* SecretId、SecretKey 查询: https://console.cloud.tencent.com/cam/capi */
|
||||||
|
return new Credential(tencentSmsConfig.getSecretId(), tencentSmsConfig.getSecretKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public HttpProfile httpProfile() {
|
||||||
|
// 实例化一个http选项,可选,没有特殊需求可以跳过
|
||||||
|
HttpProfile httpProfile = new HttpProfile();
|
||||||
|
// 设置代理(无需要直接忽略)
|
||||||
|
// httpProfile.setProxyHost("真实代理ip");
|
||||||
|
// httpProfile.setProxyPort(真实代理端口);
|
||||||
|
/* SDK默认使用POST方法。
|
||||||
|
* 如果你一定要使用GET方法,可以在这里设置。GET方法无法处理一些较大的请求 */
|
||||||
|
httpProfile.setReqMethod("POST");
|
||||||
|
/* SDK有默认的超时时间,非必要请不要进行调整
|
||||||
|
* 如有需要请在代码中查阅以获取最新的默认值 */
|
||||||
|
httpProfile.setConnTimeout(60);
|
||||||
|
/* 指定接入地域域名,默认就近地域接入域名为 sms.tencentcloudapi.com ,也支持指定地域域名访问,例如广州地域的域名为 sms.ap-guangzhou.tencentcloudapi.com */
|
||||||
|
httpProfile.setEndpoint("sms.tencentcloudapi.com");
|
||||||
|
return httpProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SmsClient smsClient(Credential credential, HttpProfile httpProfile) {
|
||||||
|
/* 非必要步骤:
|
||||||
|
* 实例化一个客户端配置对象,可以指定超时时间等配置 */
|
||||||
|
ClientProfile clientProfile = new ClientProfile();
|
||||||
|
/* SDK默认用TC3-HMAC-SHA256进行签名
|
||||||
|
* 非必要请不要修改这个字段 */
|
||||||
|
clientProfile.setSignMethod("HmacSHA256");
|
||||||
|
clientProfile.setHttpProfile(httpProfile);
|
||||||
|
/* 实例化要请求产品(以sms为例)的client对象
|
||||||
|
* 第二个参数是地域信息,可以直接填写字符串ap-guangzhou,支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8 */
|
||||||
|
return new SmsClient(credential, "ap-guangzhou", clientProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,13 @@
|
|||||||
|
package com.accompany.sms.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liaozetao
|
||||||
|
* @date: 2023/8/14 15:14
|
||||||
|
* @description:
|
||||||
|
*/
|
||||||
|
public enum SmsTypeEnum {
|
||||||
|
|
||||||
|
ALIYUN,
|
||||||
|
|
||||||
|
TENCENT;
|
||||||
|
}
|
@@ -1,7 +1,15 @@
|
|||||||
package com.accompany.sms.service;
|
package com.accompany.sms.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.accompany.common.constant.Constant;
|
import com.accompany.common.constant.Constant;
|
||||||
|
import com.accompany.common.constant.SmsConstant;
|
||||||
import com.accompany.common.device.DeviceInfo;
|
import com.accompany.common.device.DeviceInfo;
|
||||||
|
import com.accompany.common.status.BusiStatus;
|
||||||
|
import com.accompany.common.utils.StringUtils;
|
||||||
|
import com.accompany.core.exception.ServiceException;
|
||||||
|
import com.accompany.sms.common.BeanMapper;
|
||||||
|
import com.accompany.sms.config.AliyunSmsConfig;
|
||||||
|
import com.accompany.sms.result.AliyunSmsRet;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.aliyuncs.DefaultAcsClient;
|
import com.aliyuncs.DefaultAcsClient;
|
||||||
import com.aliyuncs.IAcsClient;
|
import com.aliyuncs.IAcsClient;
|
||||||
@@ -10,13 +18,9 @@ import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
|
|||||||
import com.aliyuncs.exceptions.ClientException;
|
import com.aliyuncs.exceptions.ClientException;
|
||||||
import com.aliyuncs.profile.DefaultProfile;
|
import com.aliyuncs.profile.DefaultProfile;
|
||||||
import com.aliyuncs.profile.IClientProfile;
|
import com.aliyuncs.profile.IClientProfile;
|
||||||
import com.accompany.sms.config.AliyunSmsConfig;
|
|
||||||
import com.accompany.sms.result.AliyunSmsRet;
|
|
||||||
import com.accompany.sms.common.BeanMapper;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -41,41 +45,44 @@ public class AliyunSmsService implements InitializingBean {
|
|||||||
|
|
||||||
|
|
||||||
public AliyunSmsRet sendSms(String mobile, String code, DeviceInfo deviceInfo) throws ClientException {
|
public AliyunSmsRet sendSms(String mobile, String code, DeviceInfo deviceInfo) throws ClientException {
|
||||||
|
return sendSms(mobile, (deviceInfo != null ? deviceInfo.getApp() : null), code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AliyunSmsRet sendSms(String mobile, String app, String code) throws ClientException {
|
||||||
//组装请求对象-具体描述见控制台-文档部分内容
|
//组装请求对象-具体描述见控制台-文档部分内容
|
||||||
SendSmsRequest request = new SendSmsRequest();
|
SendSmsRequest request = new SendSmsRequest();
|
||||||
//必填:待发送手机号
|
//必填:待发送手机号
|
||||||
request.setPhoneNumbers(mobile);
|
request.setPhoneNumbers(mobile);
|
||||||
//必填:短信签名-可在短信控制台中找到
|
//必填:短信签名-可在短信控制台中找到
|
||||||
// 根据app参数选择不同的签名,如果没有配置特殊的,则使用默认的
|
// 根据app参数选择不同的签名,如果没有配置特殊的,则使用默认的
|
||||||
if (aliyunSmsConfig.getAppSignNameDic() != null && deviceInfo != null && aliyunSmsConfig.getAppSignNameDic().containsKey(deviceInfo.getApp())) {
|
if (aliyunSmsConfig.getAppSignNameDic() != null && StrUtil.isNotEmpty(app) && aliyunSmsConfig.getAppSignNameDic().containsKey(app)) {
|
||||||
String signName = aliyunSmsConfig.getAppSignNameDic().get(deviceInfo.getApp());
|
String signName = aliyunSmsConfig.getAppSignNameDic().get(app);
|
||||||
log.info("{} use signName {}", deviceInfo.getApp(), signName);
|
log.info("{} use signName {}", app, signName);
|
||||||
request.setSignName(signName);
|
request.setSignName(signName);
|
||||||
} else {
|
} else {
|
||||||
request.setSignName(aliyunSmsConfig.getSignName());
|
request.setSignName(aliyunSmsConfig.getSignName());
|
||||||
}
|
}
|
||||||
request.setTemplateCode(aliyunSmsConfig.getTemplateCode());
|
request.setTemplateCode(aliyunSmsConfig.getTemplateCode());
|
||||||
|
|
||||||
// 国际区分
|
// 国际区分
|
||||||
if (!mobile.startsWith(Constant.CHINA_MAINLAND_PHONE_AREA_CODE)) {
|
if (!mobile.startsWith(Constant.CHINA_MAINLAND_PHONE_AREA_CODE)) {
|
||||||
request.setSignName(aliyunSmsConfig.getIntlSignName());
|
request.setSignName(aliyunSmsConfig.getIntlSignName());
|
||||||
request.setTemplateCode(aliyunSmsConfig.getIntlTemplateCode());
|
request.setTemplateCode(aliyunSmsConfig.getIntlTemplateCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
|
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
|
||||||
request.setTemplateParam(gson.toJson(ImmutableMap.of("code", code)));
|
request.setTemplateParam(gson.toJson(ImmutableMap.of("code", code)));
|
||||||
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
|
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
|
||||||
//hint 此处可能会抛出异常,注意catch
|
//hint 此处可能会抛出异常,注意catch
|
||||||
SendSmsResponse acsResponse = acsClient.getAcsResponse(request);
|
SendSmsResponse acsResponse = acsClient.getAcsResponse(request);
|
||||||
AliyunSmsRet smsRet = BeanMapper.map(acsResponse, AliyunSmsRet.class);
|
log.info("acsResponse : {}", JSONObject.toJSON(acsResponse));
|
||||||
return smsRet;
|
return BeanMapper.map(acsResponse, AliyunSmsRet.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送短信
|
* 发送短信
|
||||||
* @param mobile 手机号
|
*
|
||||||
|
* @param mobile 手机号
|
||||||
* @param templateId 模板id
|
* @param templateId 模板id
|
||||||
* @param param 参数
|
* @param param 参数
|
||||||
* @return
|
* @return
|
||||||
* @throws ClientException
|
* @throws ClientException
|
||||||
*/
|
*/
|
||||||
@@ -86,10 +93,11 @@ public class AliyunSmsService implements InitializingBean {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送短信
|
* 发送短信
|
||||||
* @param mobile 手机号
|
*
|
||||||
|
* @param mobile 手机号
|
||||||
* @param templateId 模板id
|
* @param templateId 模板id
|
||||||
* @param signName 签名
|
* @param signName 签名
|
||||||
* @param param 参数
|
* @param param 参数
|
||||||
* @return
|
* @return
|
||||||
* @throws ClientException
|
* @throws ClientException
|
||||||
*/
|
*/
|
||||||
@@ -105,10 +113,24 @@ public class AliyunSmsService implements InitializingBean {
|
|||||||
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
|
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
|
||||||
request.setTemplateParam(gson.toJson(param));
|
request.setTemplateParam(gson.toJson(param));
|
||||||
SendSmsResponse acsResponse = acsClient.getAcsResponse(request);
|
SendSmsResponse acsResponse = acsClient.getAcsResponse(request);
|
||||||
AliyunSmsRet smsRet = BeanMapper.map(acsResponse, AliyunSmsRet.class);
|
return BeanMapper.map(acsResponse, AliyunSmsRet.class);
|
||||||
return smsRet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验
|
||||||
|
*
|
||||||
|
* @param resCode
|
||||||
|
*/
|
||||||
|
public void validResponseCode(String resCode) {
|
||||||
|
if (StringUtils.isNotEmpty(resCode) &&
|
||||||
|
resCode.equalsIgnoreCase(SmsConstant.AliyunSmsResponseCode.BUSINESS_LIMIT_CONTROL)) {
|
||||||
|
throw new ServiceException(BusiStatus.SMS_SENDING_FREQUENCY_TOO_HIGH);
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(resCode) ||
|
||||||
|
(!resCode.equalsIgnoreCase(SmsConstant.AliyunSmsResponseCode.OK))) {
|
||||||
|
throw new ServiceException(BusiStatus.SMS_SEND_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -11,6 +11,7 @@ import com.accompany.common.utils.StringUtils;
|
|||||||
import com.accompany.core.exception.ServiceException;
|
import com.accompany.core.exception.ServiceException;
|
||||||
import com.accompany.core.service.SysConfService;
|
import com.accompany.core.service.SysConfService;
|
||||||
import com.accompany.core.service.base.BaseService;
|
import com.accompany.core.service.base.BaseService;
|
||||||
|
import com.accompany.sms.enums.SmsTypeEnum;
|
||||||
import com.accompany.sms.result.AliyunSmsRet;
|
import com.accompany.sms.result.AliyunSmsRet;
|
||||||
import com.aliyuncs.exceptions.ClientException;
|
import com.aliyuncs.exceptions.ClientException;
|
||||||
import com.google.i18n.phonenumbers.NumberParseException;
|
import com.google.i18n.phonenumbers.NumberParseException;
|
||||||
@@ -29,36 +30,34 @@ import org.springframework.util.Assert;
|
|||||||
@Service
|
@Service
|
||||||
public class SmsService extends BaseService {
|
public class SmsService extends BaseService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SmsRecordService smsRecordService;
|
private SmsRecordService smsRecordService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AliyunSmsService aliyunSmsService;
|
private AliyunSmsService aliyunSmsService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SysConfService sysConfService;
|
private SysConfService sysConfService;
|
||||||
|
|
||||||
|
public BusiResult<Void> sendSmsCode(String mobile, Integer type, DeviceInfo deviceInfo, String ip, String code) {
|
||||||
public BusiResult sendSmsCode(String mobile, Integer type, DeviceInfo deviceInfo, String ip, String code) {
|
Boolean exits = jedisService.exits(getSmsIntervalKey(mobile, type));
|
||||||
Boolean exits = jedisService.exits(getSmsIntervalKey(mobile,type));
|
|
||||||
if (exits != null && exits) {
|
if (exits != null && exits) {
|
||||||
return new BusiResult(BusiStatus.SMS_NOT_EXPIRED);
|
return new BusiResult<>(BusiStatus.SMS_NOT_EXPIRED);
|
||||||
}
|
}
|
||||||
if (StringUtils.isBlank(code)) {
|
if (StringUtils.isBlank(code)) {
|
||||||
code = String.format("%d", RandomUtil.getFiveRandomNumber());
|
code = String.format("%d", RandomUtil.getFiveRandomNumber());
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// 格式化手机号
|
// 格式化手机号
|
||||||
String phone = "+" + mobile;
|
String phone = "+" + mobile;
|
||||||
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
|
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
|
||||||
Phonenumber.PhoneNumber swissNumberProto = phoneUtil.parse(phone, null);
|
Phonenumber.PhoneNumber swissNumberProto = phoneUtil.parse(phone, null);
|
||||||
String realPhone = String.valueOf(swissNumberProto.getCountryCode()) + String.valueOf(swissNumberProto.getNationalNumber());
|
String realPhone = swissNumberProto.getCountryCode() + String.valueOf(swissNumberProto.getNationalNumber());
|
||||||
|
|
||||||
AliyunSmsRet smsRet = aliyunSmsService.sendSms(realPhone, code, deviceInfo);
|
AliyunSmsRet smsRet = aliyunSmsService.sendSms(realPhone, code, deviceInfo);
|
||||||
log.info("sendSmsCode to {}, response msg:{}", realPhone, gson.toJson(smsRet));
|
String smsType = sysConfService.getDefaultSysConfValueById(Constant.SysConfId.SMS_SDK_TYPE, SmsTypeEnum.ALIYUN.name().toLowerCase());
|
||||||
|
log.info("sendSmsCode to {}, response msg : {}", realPhone, gson.toJson(smsRet));
|
||||||
// 写入短信发送频率
|
// 写入短信发送频率
|
||||||
jedisService.setex(getSmsIntervalKey(mobile,type), SmsConstant.SMS_SEND_INTERVAL_SECONDS, "");
|
jedisService.setex(getSmsIntervalKey(mobile, type), SmsConstant.SMS_SEND_INTERVAL_SECONDS, "");
|
||||||
// 写入缓存
|
// 写入缓存
|
||||||
jedisService.setex(getSmsKey(mobile), SmsConstant.SMS_EXPIRE_SECONDS, code);
|
jedisService.setex(getSmsKey(mobile), SmsConstant.SMS_EXPIRE_SECONDS, code);
|
||||||
// 新增短信记录
|
// 新增短信记录
|
||||||
@@ -72,18 +71,17 @@ public class SmsService extends BaseService {
|
|||||||
(!resCode.equalsIgnoreCase(SmsConstant.AliyunSmsResponseCode.OK))) {
|
(!resCode.equalsIgnoreCase(SmsConstant.AliyunSmsResponseCode.OK))) {
|
||||||
throw new ServiceException(BusiStatus.SMS_SEND_ERROR);
|
throw new ServiceException(BusiStatus.SMS_SEND_ERROR);
|
||||||
}
|
}
|
||||||
} catch (ClientException | NumberParseException e) {
|
} catch (RuntimeException | ClientException | NumberParseException e) {
|
||||||
log.error("sendSmsCode error. mobile:{}", mobile, e);
|
log.error("sendSmsCode error. mobile:{}", mobile, e);
|
||||||
throw new ServiceException(BusiStatus.SMS_SEND_ERROR);
|
throw new ServiceException(BusiStatus.SMS_SEND_ERROR);
|
||||||
}
|
}
|
||||||
return new BusiResult(BusiStatus.SMS_SEND_SUCCESS);
|
return new BusiResult<>(BusiStatus.SMS_SEND_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean verifySmsCode(String mobile, String code) {
|
public boolean verifySmsCode(String mobile, String code) {
|
||||||
logger.info("verifySmsCode mobile : {}, code : {}", mobile, code);
|
logger.info("verifySmsCode mobile : {}, code : {}", mobile, code);
|
||||||
// 是否关掉验证码验证
|
// 是否关掉验证码验证
|
||||||
Boolean checkSms = Boolean.parseBoolean(
|
boolean checkSms = Boolean.parseBoolean(sysConfService.getDefaultSysConfValueById(Constant.SysConfId.VERIFY_SMS_CODE, "true"));
|
||||||
sysConfService.getDefaultSysConfValueById(Constant.SysConfId.VERIFY_SMS_CODE, "true"));
|
|
||||||
if (!checkSms) {
|
if (!checkSms) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -93,7 +91,7 @@ public class SmsService extends BaseService {
|
|||||||
String smsKey = getSmsKey(mobile);
|
String smsKey = getSmsKey(mobile);
|
||||||
String codeCache = jedisService.get(smsKey);
|
String codeCache = jedisService.get(smsKey);
|
||||||
logger.info("verifySmsCode smsKey : {}, codeCache : {}", smsKey, codeCache);
|
logger.info("verifySmsCode smsKey : {}, codeCache : {}", smsKey, codeCache);
|
||||||
if (org.apache.commons.lang3.StringUtils.equalsIgnoreCase(codeCache, code)) {
|
if (StringUtils.equalsIgnoreCase(codeCache, code)) {
|
||||||
jedisService.del(getSmsKey(mobile));
|
jedisService.del(getSmsKey(mobile));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -102,6 +100,7 @@ public class SmsService extends BaseService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取短信验证码的RedisKey
|
* 获取短信验证码的RedisKey
|
||||||
|
*
|
||||||
* @param mobile
|
* @param mobile
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -111,11 +110,12 @@ public class SmsService extends BaseService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 短信验证码发送频率RedisKey
|
* 短信验证码发送频率RedisKey
|
||||||
|
*
|
||||||
* @param mobile
|
* @param mobile
|
||||||
* @param type
|
* @param type
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String getSmsIntervalKey(String mobile, Integer type) {
|
private String getSmsIntervalKey(String mobile, Integer type) {
|
||||||
return RedisKey.sms_send_interval.getKey(mobile+"_"+type);
|
return RedisKey.sms_send_interval.getKey(mobile + "_" + type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,30 @@
|
|||||||
|
package com.accompany.sms.service;
|
||||||
|
|
||||||
|
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||||
|
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liaozetao
|
||||||
|
* @date: 2023/8/14 11:52
|
||||||
|
* @description:
|
||||||
|
*/
|
||||||
|
public interface TencentSmsService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送短信
|
||||||
|
*
|
||||||
|
* @param mobile
|
||||||
|
* @param app
|
||||||
|
* @param code
|
||||||
|
* @return
|
||||||
|
* @throws TencentCloudSDKException
|
||||||
|
*/
|
||||||
|
SendStatus sendSms(String mobile, String app, String code) throws TencentCloudSDKException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验返回结果
|
||||||
|
*
|
||||||
|
* @param resCode
|
||||||
|
*/
|
||||||
|
void validResponseCode(String resCode);
|
||||||
|
}
|
@@ -0,0 +1,105 @@
|
|||||||
|
package com.accompany.sms.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import com.accompany.common.constant.SmsConstant;
|
||||||
|
import com.accompany.common.exception.ApiException;
|
||||||
|
import com.accompany.common.status.BusiStatus;
|
||||||
|
import com.accompany.common.utils.StringUtils;
|
||||||
|
import com.accompany.sms.config.TencentSmsConfig;
|
||||||
|
import com.accompany.sms.service.TencentSmsService;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||||
|
import com.tencentcloudapi.sms.v20210111.SmsClient;
|
||||||
|
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
|
||||||
|
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
|
||||||
|
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liaozetao
|
||||||
|
* @date: 2023/8/14 11:52
|
||||||
|
* @description:
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class TencentSmsServiceImpl implements TencentSmsService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TencentSmsConfig tencentSmsConfig;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SmsClient smsClient;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SendStatus sendSms(String mobile, String app, String code) throws TencentCloudSDKException {
|
||||||
|
log.info("mobile : {}, app : {}, code : {}", mobile, app, code);
|
||||||
|
String appId = tencentSmsConfig.getAppId();
|
||||||
|
Map<String, TencentSmsConfig.AppConfig> apps = tencentSmsConfig.getApps();
|
||||||
|
if (CollectionUtil.isEmpty(apps) || !apps.containsKey(app)) {
|
||||||
|
log.info("sms config app : {}", app);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String signId = apps.get(app).getSignId();
|
||||||
|
String templateId = apps.get(app).getTemplateId();
|
||||||
|
/* 实例化一个请求对象,根据调用的接口和实际情况,可以进一步设置请求参数
|
||||||
|
* 你可以直接查询SDK源码确定接口有哪些属性可以设置
|
||||||
|
* 属性可能是基本类型,也可能引用了另一个数据结构
|
||||||
|
* 推荐使用IDE进行开发,可以方便的跳转查阅各个接口和数据结构的文档说明 */
|
||||||
|
SendSmsRequest req = new SendSmsRequest();
|
||||||
|
/* 填充请求参数,这里request对象的成员变量即对应接口的入参
|
||||||
|
* 你可以通过官网接口文档或跳转到request对象的定义处查看请求参数的定义
|
||||||
|
* 基本类型的设置:
|
||||||
|
* 帮助链接:
|
||||||
|
* 短信控制台: https://console.cloud.tencent.com/smsv2
|
||||||
|
* 腾讯云短信小助手: https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81 */
|
||||||
|
/* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId,示例如1400006666 */
|
||||||
|
// 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看
|
||||||
|
req.setSmsSdkAppId(appId);
|
||||||
|
/* 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名 */
|
||||||
|
// 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看
|
||||||
|
/* 模板 ID: 必须填写已审核通过的模板 ID */
|
||||||
|
// 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看
|
||||||
|
req.setSignName(signId);
|
||||||
|
req.setTemplateId(templateId);
|
||||||
|
/* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致,若无模板参数,则设置为空 */
|
||||||
|
String[] templateParamSet = {code, String.valueOf(SmsConstant.SMS_EXPIRE_MINUTE)};
|
||||||
|
req.setTemplateParamSet(templateParamSet);
|
||||||
|
/* 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号]
|
||||||
|
* 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号 */
|
||||||
|
mobile = "+" + mobile;
|
||||||
|
String[] phoneNumberSet = {mobile};
|
||||||
|
req.setPhoneNumberSet(phoneNumberSet);
|
||||||
|
/* 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的
|
||||||
|
* 返回的 res 是一个 SendSmsResponse 类的实例,与请求对象对应 */
|
||||||
|
SendSmsResponse res = smsClient.SendSms(req);
|
||||||
|
if (res != null) {
|
||||||
|
log.info("SendSmsResponse : {}", JSONObject.toJSON(res));
|
||||||
|
/* 当出现以下错误码时,快速解决方案参考
|
||||||
|
* [FailedOperation.SignatureIncorrectOrUnapproved](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Afailedoperation.signatureincorrectorunapproved-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
|
||||||
|
* [FailedOperation.TemplateIncorrectOrUnapproved](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Afailedoperation.templateincorrectorunapproved-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
|
||||||
|
* [UnauthorizedOperation.SmsSdkAppIdVerifyFail](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Aunauthorizedoperation.smssdkappidverifyfail-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
|
||||||
|
* [UnsupportedOperation.ContainDomesticAndInternationalPhoneNumber](https://cloud.tencent.com/document/product/382/9558#.E7.9F.AD.E4.BF.A1.E5.8F.91.E9.80.81.E6.8F.90.E7.A4.BA.EF.BC.9Aunsupportedoperation.containdomesticandinternationalphonenumber-.E5.A6.82.E4.BD.95.E5.A4.84.E7.90.86.EF.BC.9F)
|
||||||
|
* 更多错误,可咨询[腾讯云助手](https://tccc.qcloud.com/web/im/index.html#/chat?webAppId=8fa15978f85cb41f7e2ea36920cb3ae1&title=Sms)
|
||||||
|
*/
|
||||||
|
return res.getSendStatusSet()[0];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validResponseCode(String resCode) {
|
||||||
|
if (SmsConstant.ResCode.OK.equals(resCode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(resCode) && resCode.startsWith(SmsConstant.ResCode.LimitExceeded)) {
|
||||||
|
throw new ApiException(BusiStatus.SMS_SENDING_FREQUENCY_TOO_HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ApiException(BusiStatus.SMS_SEND_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,49 @@
|
|||||||
|
package com.accompany.sms.strategy;
|
||||||
|
|
||||||
|
import com.accompany.core.base.SpringContextHolder;
|
||||||
|
import com.accompany.sms.enums.SmsTypeEnum;
|
||||||
|
import com.accompany.sms.result.AliyunSmsRet;
|
||||||
|
import com.accompany.sms.service.AliyunSmsService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liaozetao
|
||||||
|
* @date: 2023/8/14 15:17
|
||||||
|
* @description:
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class AliYunSmsStrategy extends SmsStrategy {
|
||||||
|
|
||||||
|
private final AliyunSmsService aliyunSmsService;
|
||||||
|
|
||||||
|
public AliYunSmsStrategy() {
|
||||||
|
aliyunSmsService = SpringContextHolder.getBeanOfClass(AliyunSmsService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String type() {
|
||||||
|
return SmsTypeEnum.ALIYUN.name().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
SmsResponse doSend(SmsContext context) {
|
||||||
|
SmsResponse response = new SmsResponse();
|
||||||
|
String mobile = context.getMobile();
|
||||||
|
String app = context.getApp();
|
||||||
|
String code = context.getCode();
|
||||||
|
try {
|
||||||
|
AliyunSmsRet aliyunSmsRet = aliyunSmsService.sendSms(mobile, app, code);
|
||||||
|
response.setCode(aliyunSmsRet.getCode());
|
||||||
|
response.setMessage(aliyunSmsRet.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validResCode(String resCode) {
|
||||||
|
aliyunSmsService.validResponseCode(resCode);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,27 @@
|
|||||||
|
package com.accompany.sms.strategy;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liaozetao
|
||||||
|
* @date: 2023/8/14 14:57
|
||||||
|
* @description:
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SmsContext {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号码
|
||||||
|
*/
|
||||||
|
private String mobile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用
|
||||||
|
*/
|
||||||
|
private String app;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码
|
||||||
|
*/
|
||||||
|
private String code;
|
||||||
|
}
|
@@ -0,0 +1,27 @@
|
|||||||
|
package com.accompany.sms.strategy;
|
||||||
|
|
||||||
|
import com.accompany.sms.enums.SmsTypeEnum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liaozetao
|
||||||
|
* @date: 2023/8/14 16:05
|
||||||
|
* @description:
|
||||||
|
*/
|
||||||
|
public class SmsFactory {
|
||||||
|
|
||||||
|
public SmsResponse send(String type, String mobile, String app, String code) {
|
||||||
|
SmsContext context = new SmsContext();
|
||||||
|
context.setMobile(mobile);
|
||||||
|
context.setApp(app);
|
||||||
|
context.setCode(code);
|
||||||
|
SmsStrategy smsStrategy = null;
|
||||||
|
if (SmsTypeEnum.ALIYUN.name().toLowerCase().equalsIgnoreCase(type)) {
|
||||||
|
smsStrategy = new AliYunSmsStrategy();
|
||||||
|
} else if (SmsTypeEnum.TENCENT.name().toLowerCase().equalsIgnoreCase(type)) {
|
||||||
|
smsStrategy = new TencentSmsStrategy();
|
||||||
|
} else {
|
||||||
|
smsStrategy = new AliYunSmsStrategy();
|
||||||
|
}
|
||||||
|
return smsStrategy.send(context);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,22 @@
|
|||||||
|
package com.accompany.sms.strategy;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liaozetao
|
||||||
|
* @date: 2023/8/14 15:06
|
||||||
|
* @description:
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SmsResponse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常编码
|
||||||
|
*/
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常信息
|
||||||
|
*/
|
||||||
|
private String message;
|
||||||
|
}
|
@@ -0,0 +1,42 @@
|
|||||||
|
package com.accompany.sms.strategy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liaozetao
|
||||||
|
* @date: 2023/8/14 14:59
|
||||||
|
* @description:
|
||||||
|
*/
|
||||||
|
public abstract class SmsStrategy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
abstract String type();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送验证码
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SmsResponse send(SmsContext context) {
|
||||||
|
return doSend(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送验证码
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
abstract SmsResponse doSend(SmsContext context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验返回结果
|
||||||
|
*
|
||||||
|
* @param resCode
|
||||||
|
*/
|
||||||
|
public abstract void validResCode(String resCode);
|
||||||
|
}
|
@@ -0,0 +1,50 @@
|
|||||||
|
package com.accompany.sms.strategy;
|
||||||
|
|
||||||
|
import com.accompany.core.base.SpringContextHolder;
|
||||||
|
import com.accompany.sms.enums.SmsTypeEnum;
|
||||||
|
import com.accompany.sms.service.TencentSmsService;
|
||||||
|
import com.accompany.sms.service.impl.TencentSmsServiceImpl;
|
||||||
|
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author: liaozetao
|
||||||
|
* @date: 2023/8/14 15:04
|
||||||
|
* @description:
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class TencentSmsStrategy extends SmsStrategy {
|
||||||
|
|
||||||
|
private final TencentSmsService tencentSmsService;
|
||||||
|
|
||||||
|
public TencentSmsStrategy() {
|
||||||
|
tencentSmsService = SpringContextHolder.getBeanOfClass(TencentSmsServiceImpl.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String type() {
|
||||||
|
return SmsTypeEnum.TENCENT.name().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SmsResponse doSend(SmsContext context) {
|
||||||
|
SmsResponse response = new SmsResponse();
|
||||||
|
String mobile = context.getMobile();
|
||||||
|
String app = context.getApp();
|
||||||
|
String code = context.getCode();
|
||||||
|
try {
|
||||||
|
SendStatus sendStatus = tencentSmsService.sendSms(mobile, app, code);
|
||||||
|
response.setCode(sendStatus.getCode());
|
||||||
|
response.setMessage(sendStatus.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validResCode(String resCode) {
|
||||||
|
tencentSmsService.validResponseCode(resCode);
|
||||||
|
}
|
||||||
|
}
|
7
pom.xml
7
pom.xml
@@ -101,6 +101,7 @@
|
|||||||
<ip2region.version>2.7.0</ip2region.version>
|
<ip2region.version>2.7.0</ip2region.version>
|
||||||
<opencc4j.version>1.7.2</opencc4j.version>
|
<opencc4j.version>1.7.2</opencc4j.version>
|
||||||
<rocketmq-spring-boot-starter.version>2.2.3</rocketmq-spring-boot-starter.version>
|
<rocketmq-spring-boot-starter.version>2.2.3</rocketmq-spring-boot-starter.version>
|
||||||
|
<tencentcloud-sdk-java.version>3.1.781</tencentcloud-sdk-java.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
@@ -966,6 +967,12 @@
|
|||||||
<version>1.5.0</version>
|
<version>1.5.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.tencentcloudapi</groupId>
|
||||||
|
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||||
|
<version>${tencentcloud-sdk-java.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
Reference in New Issue
Block a user