新增短信发送模块

This commit is contained in:
b2baccline
2020-10-22 19:20:04 +08:00
parent 1290146fb3
commit 4f9ded8b0e
26 changed files with 1041 additions and 0 deletions

View File

@@ -118,6 +118,13 @@
<artifactId>ballcat-spring-boot-starter-kafka</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.hccake</groupId>
<artifactId>ballcat-spring-boot-starter-sms</artifactId>
<version>${revision}</version>
</dependency>
<!-- extends -->
<dependency>
<groupId>com.hccake</groupId>
<artifactId>ballcat-extend-dingtalk</artifactId>

View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ballcat-starters</artifactId>
<groupId>com.hccake</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ballcat-spring-boot-starter-sms</artifactId>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>com.hccake</groupId>
<artifactId>ballcat-common-core</artifactId>
</dependency>
<!-- spring boot 配置所需依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>3.1.42</version>
</dependency>
<dependency>
<groupId>com.hccake</groupId>
<artifactId>ballcat-extend-mybatis-plus</artifactId>
<exclusions>
<exclusion>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,45 @@
package com.hccake.starter.sms;
import com.hccake.starter.sms.impl.TencentSenderImpl;
import com.hccake.starter.sms.impl.TianYiHongSenderImpl;
import com.hccake.starter.sms.impl.XinKuKaSenderImpl;
import com.hccake.starter.sms.impl.xinkuka.service.XinKuKaSmsSendService;
import com.hccake.starter.sms.properties.SmsProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
/**
* @author lingting 2020/4/26 9:45
*/
@EnableConfigurationProperties({ SmsProperties.class })
public class SmsAutoConfiguration {
@Autowired
private SmsProperties properties;
@Bean
@ConditionalOnMissingBean(com.hccake.starter.sms.SmsSender.class)
@ConditionalOnProperty(name = "sms.type", havingValue = "TENCENT")
public com.hccake.starter.sms.SmsSender<com.hccake.starter.sms.SmsSenderParams, com.hccake.starter.sms.SmsSenderResult> tencentSmsSender() {
return new TencentSenderImpl(properties);
}
@Bean
@ConditionalOnMissingBean(com.hccake.starter.sms.SmsSender.class)
@ConditionalOnProperty(name = "sms.type", havingValue = "TIAN_YI_HONG")
public com.hccake.starter.sms.SmsSender<com.hccake.starter.sms.SmsSenderParams, com.hccake.starter.sms.SmsSenderResult> tianYiHongSmsSender() {
return new TianYiHongSenderImpl(properties);
}
@Bean
@ConditionalOnMissingBean(com.hccake.starter.sms.SmsSender.class)
@ConditionalOnProperty(name = "sms.type", havingValue = "XIN_KU_KA")
public com.hccake.starter.sms.SmsSender<com.hccake.starter.sms.SmsSenderParams, com.hccake.starter.sms.SmsSenderResult> xinKuKaSmsSender(
XinKuKaSmsSendService sendService) {
return new XinKuKaSenderImpl(properties, sendService);
}
}

View File

@@ -0,0 +1,18 @@
package com.hccake.starter.sms;
/**
* 短信发送 接口类
*
* @author lingting 2020/4/26 9:55
*/
public interface SmsSender<T, R> {
/**
* 发送短信
* @param p 参数配置
* @return boolean
* @author lingting 2020-04-26 11:44:46
*/
R send(T p);
}

View File

@@ -0,0 +1,124 @@
package com.hccake.starter.sms;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.crypto.SecureUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hccake.ballcat.common.core.util.SpringUtil;
import com.hccake.starter.sms.constant.SmsConstants;
import com.hccake.starter.sms.properties.SmsProperties;
import com.hccake.starter.sms.properties.extra.Account;
import com.hccake.starter.sms.properties.extra.Tencent;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import lombok.experimental.Accessors;
/**
* @author lingting 2020/4/26 11:40
*/
@Getter
@Setter
@Accessors(chain = true)
public class SmsSenderParams {
/**
* 下发手机号码,采用 e.164 标准,格式为+[国家或地区码][手机号]单次请求最多支持200个手机号且要求全为境内手机号或全为境外手机号。
* 例如:+8613711112222 其中前面有一个+号 86为国家码13711112222为手机号。
*/
private Set<String> phoneNumbers;
/**
* 短信模板参数
*/
private List<Object> templateParam;
/**
* 短信内容
*/
private String content;
/**
* 使用此号码发送短信
*/
private String usePhone;
/**
* 国家代码 比如 CN
*/
private String country;
{
// 初始化参数
this.phoneNumbers = new HashSet<>();
this.templateParam = new ArrayList<>();
}
/**
* 添加电话
*/
public SmsSenderParams addPhone(String phone) {
this.phoneNumbers.add(phone);
return this;
}
/**
* 添加模板参数
*
* @author lingting 2020-04-26 11:07:36
*/
public SmsSenderParams addTemplateParam(Object param) {
this.templateParam.add(param);
return this;
}
/**
* 生成参数-腾讯云平台
*/
@SneakyThrows
public String generateTencentParams(Tencent tencent) {
Map<String, Object> json = new HashMap<>(5);
json.put("PhoneNumberSet", phoneNumbers);
json.put("SmsSdkAppid", tencent.getSdkId());
if (tencent.getTemplateId() != null) {
json.put("TemplateID", tencent.getTemplateId());
}
if (StrUtil.isNotEmpty(tencent.getSign())) {
json.put("Sign", tencent.getSign());
}
if (templateParam.size() != 0) {
json.put("TemplateParamSet", templateParam);
}
return SmsSenderResult.getObjectMapper().writeValueAsString(json);
}
/**
* 生成参数-码平台
*/
public String generateTianYiHongParams(SmsProperties properties) {
Account account = properties.getAccounts().get(country);
String dateTime = DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss");
return URLUtil.encode("account=" + account.getAccount() + "&sign="
+ SecureUtil.md5(account.getAccount() + account.getPassword() + dateTime) + "&datetime=" + dateTime
+ "&numbers=" + phoneNumbers.iterator().next() + "&content=" + content
+ (country.equals(SmsConstants.SENDER_ID_COUNTRY) ? "&senderid=THRONE" : ""));
}
@Override
@SneakyThrows
public String toString() {
return SmsSenderResult.getObjectMapper().writeValueAsString(this);
}
}

View File

@@ -0,0 +1,148 @@
package com.hccake.starter.sms;
import cn.hutool.core.convert.Convert;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hccake.ballcat.common.core.util.SpringUtil;
import com.hccake.starter.sms.enums.TypeEnum;
import java.util.Map;
import java.util.Set;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.experimental.Accessors;
/**
* 短信发送结果
*
* @author lingting 2020/4/26 13:22
*/
@Getter
@Accessors(chain = true)
public class SmsSenderResult {
public static ObjectMapper getObjectMapper() {
return SpringUtil.getBean(ObjectMapper.class);
}
/**
* 状态字段名
*/
private static final String TIAN_YI_HONG_STATUS = "status";
/**
* 信息字段名
*/
private static final String TIAN_YI_HONG_MSG = "desc";
/**
* 短信平台
*
* @see com.hccake.starter.sms.constant.SmsConstants
*/
protected String platform;
/**
* 发送的目标
*/
protected String target;
/**
* 是否发送成功
*/
protected boolean success;
/**
* 提示信息
*/
protected String msg;
/**
* 请求的详细信息-各平台自定义
*/
protected String req;
/**
* 返回结果信息
*/
protected String res;
private SmsSenderResult() {
}
/**
* 出现异常返回结果
* @param platform 平台
* @param phoneNumbers 目标手机号
* @param id 异常id
* @param e 异常信息
* @return com.hccake.starter.sms.domain.SendResult
* @author lingting 2020-04-26 13:43:39
*/
@SneakyThrows
public static SmsSenderResult generateException(TypeEnum platform, Set<String> phoneNumbers, String id,
Throwable e) {
SmsSenderResult result = new SmsSenderResult();
result.success = false;
result.msg = "短信发送失败,出现异常:" + e.getMessage() + "," + id;
result.target = getObjectMapper().writeValueAsString(phoneNumbers);
result.platform = platform.name();
return result;
}
/**
* 生成结果数据
* @param resp 请求的返回结果
* @param phoneNumbers 目标号码
*/
@SneakyThrows
public static SmsSenderResult generate(String resp, String req, Set<String> phoneNumbers) {
SmsSenderResult result = new SmsSenderResult();
result.res = resp;
// 没有异常就是成功!
result.success = true;
result.platform = TypeEnum.TENCENT.name();
result.target = getObjectMapper().writeValueAsString(phoneNumbers);
result.req = req;
return result;
}
@SneakyThrows
public static SmsSenderResult generateTianYiHong(String resp, String req, Set<String> phoneNumbers) {
SmsSenderResult result = new SmsSenderResult();
result.res = resp;
// 没有异常就是成功!
result.success = true;
result.platform = TypeEnum.TIAN_YI_HONG.name();
result.target = getObjectMapper().writeValueAsString(phoneNumbers);
result.req = req;
Map<String, Object> map = getObjectMapper().readValue(resp, new TypeReference<Map<String, Object>>() {
});
if (Convert.toInt(map.get(TIAN_YI_HONG_STATUS), -1) < 0) {
result.success = false;
result.msg = Convert.toStr(map.get(TIAN_YI_HONG_MSG), "获取错误信息失败!");
}
return result;
}
@SneakyThrows
public static SmsSenderResult generateXinKuKa(String resp, String req, Set<String> phoneNumbers) {
SmsSenderResult result = new SmsSenderResult();
result.res = resp;
// 没有异常就是成功!
result.success = true;
result.platform = TypeEnum.XIN_KU_KA.name();
result.target = getObjectMapper().writeValueAsString(phoneNumbers);
result.res = resp;
result.req = req;
return result;
}
@SneakyThrows
@Override
public String toString() {
return getObjectMapper().writeValueAsString(this);
}
}

View File

@@ -0,0 +1,13 @@
package com.hccake.starter.sms.constant;
/**
* @author lingting 2020/4/26 11:28
*/
public class SmsConstants {
/**
* 需要注明 sender id 的国家
*/
public static final String SENDER_ID_COUNTRY = "IN";
}

View File

@@ -0,0 +1,53 @@
package com.hccake.starter.sms.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author lingting 2020/5/6 21:41
*/
public class SmsSendConstants {
@Getter
@AllArgsConstructor
public enum state {
/**
* 状态值 说明
*/
notSend(0, "未发送"),
sending(1, "已在发送队列"),
success(2, "发送成功"),
failed(3, "发送失败"),
;
private final int val;
private final String text;
}
@Getter
@AllArgsConstructor
public enum type {
/**
* 状态值 说明
*/
sms(0, "短信"),
mms(1, "彩信"),
;
private final int val;
private final String text;
}
}

View File

@@ -0,0 +1,20 @@
package com.hccake.starter.sms.enums;
/**
* @author lingting 2020-08-30 22:20
*/
public enum TypeEnum {
/**
* 短信发送类型
*/
TENCENT,
TIAN_YI_HONG,
XIN_KU_KA,
;
}

View File

@@ -0,0 +1,16 @@
package com.hccake.starter.sms.exception;
/**
* @author lingting 2020/4/26 10:16
*/
public class SmsException extends RuntimeException {
public SmsException(String message) {
super(message);
}
public SmsException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,24 @@
package com.hccake.starter.sms.impl;
import cn.hutool.core.util.StrUtil;
import com.hccake.starter.sms.SmsSenderResult;
import com.hccake.starter.sms.enums.TypeEnum;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
/**
* @author lingting 2020/4/26 13:45
*/
@Slf4j
public class BaseServiceImpl {
/**
* b 异常返回处理
*/
public SmsSenderResult errRet(TypeEnum platform, Set<String> phoneNumbers, String msg, Exception e) {
String id = StrUtil.uuid();
log.error(msg + "\nerror_id: " + id, e);
return SmsSenderResult.generateException(platform, phoneNumbers, id, e);
}
}

View File

@@ -0,0 +1,54 @@
package com.hccake.starter.sms.impl;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20190711.SmsClient;
import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
import com.hccake.starter.sms.SmsSender;
import com.hccake.starter.sms.SmsSenderParams;
import com.hccake.starter.sms.SmsSenderResult;
import com.hccake.starter.sms.enums.TypeEnum;
import com.hccake.starter.sms.properties.SmsProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
/**
* @author lingting 2020/4/26 10:03
*/
@ConditionalOnProperty(name = "sms.type", havingValue = "TENCENT")
public class TencentSenderImpl extends BaseServiceImpl implements SmsSender<SmsSenderParams, SmsSenderResult> {
private final SmsProperties properties;
private final Credential cred;
public TencentSenderImpl(SmsProperties properties) {
this.properties = properties;
cred = new Credential(properties.getId(), properties.getKey());
}
@Override
public SmsSenderResult send(SmsSenderParams smsSenderParams) {
try {
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint(properties.getTencent().getEndpoint());
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
SmsClient client = new SmsClient(cred, properties.getTencent().getRegion(), clientProfile);
SendSmsRequest req = SendSmsRequest.fromJsonString(
smsSenderParams.generateTencentParams(properties.getTencent()), SendSmsRequest.class);
SendSmsResponse resp = client.SendSms(req);
return SmsSenderResult.generate(SendSmsRequest.toJsonString(resp), smsSenderParams.toString(),
smsSenderParams.getPhoneNumbers());
}
catch (TencentCloudSDKException e) {
return errRet(TypeEnum.TENCENT, smsSenderParams.getPhoneNumbers(), "腾讯云平台发送短信出现异常!", e);
}
}
}

View File

@@ -0,0 +1,35 @@
package com.hccake.starter.sms.impl;
import cn.hutool.http.HttpUtil;
import com.hccake.starter.sms.SmsSender;
import com.hccake.starter.sms.SmsSenderParams;
import com.hccake.starter.sms.SmsSenderResult;
import com.hccake.starter.sms.enums.TypeEnum;
import com.hccake.starter.sms.properties.SmsProperties;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
/**
* @author lingting 2020/4/26 10:03
*/
@ConditionalOnProperty(name = "sms.type", havingValue = "TIAN_YI_HONG")
@RequiredArgsConstructor
public class TianYiHongSenderImpl extends BaseServiceImpl implements SmsSender<SmsSenderParams, SmsSenderResult> {
private final SmsProperties properties;
@Override
public SmsSenderResult send(SmsSenderParams smsSenderParams) {
try {
String req = properties.getUrl() + "?" + smsSenderParams.generateTianYiHongParams(properties);
String res = HttpUtil.get(req);
return SmsSenderResult.generateTianYiHong(res, "方法参数:" + smsSenderParams.toString() + " ;请求: " + req,
smsSenderParams.getPhoneNumbers());
}
catch (Exception e) {
return errRet(TypeEnum.TIAN_YI_HONG, smsSenderParams.getPhoneNumbers(), "码平台发送短信出现异常!", e);
}
}
}

View File

@@ -0,0 +1,67 @@
package com.hccake.starter.sms.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.hccake.starter.sms.SmsSender;
import com.hccake.starter.sms.SmsSenderParams;
import com.hccake.starter.sms.SmsSenderResult;
import com.hccake.starter.sms.constant.SmsSendConstants;
import com.hccake.starter.sms.enums.TypeEnum;
import com.hccake.starter.sms.exception.SmsException;
import com.hccake.starter.sms.impl.xinkuka.model.XinKuKaSend;
import com.hccake.starter.sms.impl.xinkuka.service.XinKuKaSmsSendService;
import com.hccake.starter.sms.properties.SmsProperties;
import com.hccake.starter.sms.properties.extra.XinKuKa;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
/**
* @author lingting 2020/5/7 15:25
*/
@ConditionalOnProperty(name = "sms.type", havingValue = "XIN_KU_KA")
@RequiredArgsConstructor
public class XinKuKaSenderImpl extends BaseServiceImpl implements SmsSender<SmsSenderParams, SmsSenderResult> {
private final SmsProperties properties;
private final XinKuKaSmsSendService sendService;
private XinKuKa xinKuKa = null;
@Override
public SmsSenderResult send(SmsSenderParams smsSenderParams) {
if (xinKuKa == null) {
xinKuKa = properties.getXinKuKa();
}
List<XinKuKaSend> list = new ArrayList<>();
XinKuKaSend send;
// 配置发送数据
for (String p : smsSenderParams.getPhoneNumbers()) {
send = new XinKuKaSend();
// 指定发送短信
send.setSmsType(SmsSendConstants.type.sms.getVal());
// 指定号码发送
if (xinKuKa.getMode() == XinKuKa.Mode.number) {
send.setPhoNum(StrUtil.isEmpty(smsSenderParams.getUsePhone()) ? xinKuKa.getNumber()
: smsSenderParams.getUsePhone());
}
send.setSmsNumber(p);
// 不指定端口发送
send.setPortNum(-1);
send.setSmsContent(smsSenderParams.getContent());
send.setSmsState(SmsSendConstants.state.notSend.getVal());
list.add(send);
}
if (sendService.saveBatch(list)) {
return SmsSenderResult.generateXinKuKa("数据已全部入库-当前时间:" + DateUtil.now(), smsSenderParams.toString(),
smsSenderParams.getPhoneNumbers());
}
return errRet(TypeEnum.XIN_KU_KA, smsSenderParams.getPhoneNumbers(), "发送失败!", new SmsException("短信发送失败!"));
}
}

View File

@@ -0,0 +1,11 @@
package com.hccake.starter.sms.impl.xinkuka.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hccake.starter.sms.impl.xinkuka.model.XinKuKaSend;
/**
* @author lingting 2020/5/6 21:46
*/
public interface SmsSendMapper extends BaseMapper<XinKuKaSend> {
}

View File

@@ -0,0 +1,54 @@
package com.hccake.starter.sms.impl.xinkuka.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* @author lingting 2020/5/6 17:51
*/
@Data
@Accessors(chain = true)
@TableName("sms_send")
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "短信发送表")
public class XinKuKaSend extends Model<XinKuKaSend> {
@TableId
private Long id;
@ApiModelProperty("大于0表示指定端口号发送")
@TableField("PortNum")
private Integer portNum;
@ApiModelProperty("接收号码")
@TableField("smsNumber")
private String smsNumber;
@ApiModelProperty("彩信标题,如果发送彩信不能为空")
@TableField("smsSubject")
private String smsSubject;
@ApiModelProperty("发送内容")
@TableField("smsContent")
private String smsContent;
@ApiModelProperty("0:短信 1:彩信")
@TableField("smsType")
private Integer smsType;
@ApiModelProperty("手机号")
@TableField("PhoNum")
private String phoNum;
@ApiModelProperty("状态")
@TableField("smsState")
private Integer smsState;
}

View File

@@ -0,0 +1,11 @@
package com.hccake.starter.sms.impl.xinkuka.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.hccake.starter.sms.impl.xinkuka.model.XinKuKaSend;
/**
* @author lingting 2020/5/7 16:51
*/
public interface XinKuKaSmsSendService extends IService<XinKuKaSend> {
}

View File

@@ -0,0 +1,18 @@
package com.hccake.starter.sms.impl.xinkuka.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hccake.starter.sms.impl.xinkuka.mapper.SmsSendMapper;
import com.hccake.starter.sms.impl.xinkuka.model.XinKuKaSend;
import com.hccake.starter.sms.impl.xinkuka.service.XinKuKaSmsSendService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
/**
* @author lingting 2020/5/7 16:52
*/
@Service
@ConditionalOnProperty(name = "sms.type", havingValue = "XIN_KU_KA")
public class XinKuKaSmsSendServiceImpl extends ServiceImpl<SmsSendMapper, XinKuKaSend>
implements XinKuKaSmsSendService {
}

View File

@@ -0,0 +1,63 @@
package com.hccake.starter.sms.properties;
import com.hccake.starter.sms.enums.TypeEnum;
import com.hccake.starter.sms.properties.extra.Account;
import com.hccake.starter.sms.properties.extra.Tencent;
import com.hccake.starter.sms.properties.extra.TianYiHong;
import com.hccake.starter.sms.properties.extra.XinKuKa;
import java.util.Map;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
/**
* @author lingting 2020/4/26 9:43
*/
@Data
@ConfigurationProperties(prefix = "ballcat.starter.sms")
public class SmsProperties {
/**
* 类型
*/
private TypeEnum type = TypeEnum.XIN_KU_KA;
/**
* 请求路径
*/
private String url;
/**
* app id
*/
private String id;
/**
* app key
*/
private String key;
/**
* 部分平台需要使用账号密码,都在这里配置
*/
private Map<String, Account> accounts;
/**
* 腾讯云所需额外参数
*/
@NestedConfigurationProperty
private Tencent tencent;
/**
* 码平台所用发送短信所需额外参数
*/
@NestedConfigurationProperty
private TianYiHong tianYiHong;
/**
* 新酷卡猫池配置
*/
@NestedConfigurationProperty
private XinKuKa xinKuKa;
}

View File

@@ -0,0 +1,23 @@
package com.hccake.starter.sms.properties.extra;
import lombok.Data;
/**
* 用于需要 账号密码的 平台
*
* @author lingting 2020/4/26 19:51
*/
@Data
public class Account {
/**
* 账号
*/
private String account;
/**
* 密码
*/
private String password;
}

View File

@@ -0,0 +1,36 @@
package com.hccake.starter.sms.properties.extra;
import lombok.Data;
/**
* @author lingting 2020/5/6 17:16
*/
@Data
public class Tencent {
/**
* 调用api参数所需的 sdk ip
*/
private int sdkId;
/**
* 配置节点
*/
private String endpoint = "sms.tencentcloudapi.com";
/**
* 分区
*/
private String region = "";
/**
* 短信模板id
*/
private Integer templateId = null;
/**
* 短信签名,发往国内必填
*/
private String sign = null;
}

View File

@@ -0,0 +1,23 @@
package com.hccake.starter.sms.properties.extra;
import lombok.Data;
/**
* 天一泓 配置
*
* @author lingting 2020/5/6 17:16
*/
@Data
public class TianYiHong {
/**
* 密码的密钥
*/
private String passwordKey;
/**
* 安全密钥
*/
private String secretKey;
}

View File

@@ -0,0 +1,80 @@
package com.hccake.starter.sms.properties.extra;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
/**
* 新酷卡猫池配置
*
* @author lingting 2020/5/6 16:59
*/
@Data
public class XinKuKa {
/**
* 猫池短信发送模式
*/
private Mode mode = Mode.random;
/**
* 指定手机号
*/
private String number;
/**
* 指定端口
*/
private String port;
/**
* 数据库配置
*/
private DataBase dataBase;
@Getter
@AllArgsConstructor
public enum Mode {
/**
* 随机选择可用通道发送
*/
random,
/**
* 匹配指定手机号发送
*/
number,
/**
* 匹配指定端口发送
*/
@Deprecated
port,
;
}
@Data
public static class DataBase {
/**
* 使用哪种数据库
*/
private Kind kind = Kind.mysql;
@Getter
@AllArgsConstructor
public enum Kind {
/**
* 使用mysql 数据库
*/
mysql,
;
}
}
}

View File

@@ -0,0 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.hccake.starter.sms.SmsAutoConfiguration,\
com.hccake.starter.sms.impl.xinkuka.service.impl.XinKuKaSmsSendServiceImpl

View File

@@ -0,0 +1,40 @@
# 新酷卡所属表
CREATE TABLE IF NOT EXISTS `port_info`
(
`Id` int(11) NOT NULL AUTO_INCREMENT,
`PortNum` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '端口号',
`IMSI` varchar(255) NOT NULL DEFAULT '' COMMENT '用户识别码(IMSI)',
`ICCID` varchar(255) DEFAULT '' COMMENT '卡识别码(ICCID)',
`PhoNum` varchar(255) DEFAULT NULL COMMENT '手机号',
PRIMARY KEY (`Id`)
) ENGINE = INNODB
DEFAULT CHARSET = gbk;
CREATE TABLE IF NOT EXISTS `sms_recv`
(
`Id` int(11) NOT NULL AUTO_INCREMENT,
`PortNum` int(11) unsigned DEFAULT '0' COMMENT '接收短信的端口号',
`PhoNum` varchar(255) DEFAULT '' COMMENT '手机号',
`IMSI` varchar(255) DEFAULT NULL COMMENT '用户识别码(IMSI)',
`ICCID` varchar(255) DEFAULT NULL COMMENT '卡识别码(ICCID)',
`smsDate` varchar(255) NOT NULL DEFAULT '' COMMENT '短信日期注意是smsDate而不是smsData',
`smsNumber` varchar(255) NOT NULL DEFAULT '' COMMENT '短信号码',
`smsContent` varchar(255) NOT NULL DEFAULT '' COMMENT '短信内容',
PRIMARY KEY (`Id`)
) ENGINE = INNODB
DEFAULT CHARSET = gbk;
CREATE TABLE IF NOT EXISTS `sms_send`
(
`Id` int(11) NOT NULL AUTO_INCREMENT,
`PortNum` int(11) DEFAULT '-1' COMMENT '大于0表示指定端口号发送',
`smsNumber` varchar(255) NOT NULL DEFAULT '' COMMENT '接收号码',
`smsSubject` varchar(255) DEFAULT '' COMMENT '彩信标题,如果发送彩信不能为空',
`smsContent` varchar(255) NOT NULL DEFAULT '' COMMENT '发送内容',
`smsType` int(11) unsigned DEFAULT '0' COMMENT '0:短信 1:彩信',
`PhoNum` varchar(255) DEFAULT NULL COMMENT '手机号',
`smsState` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '0:未发送 1:已在发送队列 2:发送成功 3:发送失败',
PRIMARY KEY (`Id`)
) ENGINE = INNODB
DEFAULT CHARSET = gbk
ROW_FORMAT = DYNAMIC;

View File

@@ -23,6 +23,7 @@
<module>ballcat-spring-boot-starter-redis</module>
<module>ballcat-spring-boot-starter-storage</module>
<module>ballcat-spring-boot-starter-swagger</module>
<module>ballcat-spring-boot-starter-sms</module>
</modules>
</project>