mirror of
https://gitee.com/dromara/sms4j.git
synced 2025-12-06 08:58:38 +08:00
Merge branch 'dev-3.0.x' of https://gitee.com/dromara/sms4j
# Conflicts: # pom.xml # sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/Constant.java
This commit is contained in:
commit
bfdc75d538
4
pom.xml
4
pom.xml
@ -53,12 +53,12 @@
|
||||
</scm>
|
||||
|
||||
<properties>
|
||||
<revision>3.3.3</revision>
|
||||
<revision>3.3.4</revision>
|
||||
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<spring.boot.version>2.7.18</spring.boot.version>
|
||||
<solon.version>2.6.5</solon.version>
|
||||
<solon.version>3.0.1</solon.version>
|
||||
<redisson.version>3.17.0</redisson.version>
|
||||
<jdcloud.version>1.3.3</jdcloud.version>
|
||||
<hutool.version>5.8.28</hutool.version>
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
package org.dromara.sms4j.api.universal;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 短信代理配置类
|
||||
*/
|
||||
@Data
|
||||
public class ProxyConfig implements Serializable {
|
||||
|
||||
/**
|
||||
* 是否启用代理 默认不启用
|
||||
*/
|
||||
private Boolean enable = false;
|
||||
|
||||
/**
|
||||
* 代理服务器地址
|
||||
*/
|
||||
private String host;
|
||||
|
||||
/**
|
||||
* 代理服务器端口
|
||||
*/
|
||||
private Integer port;
|
||||
}
|
||||
@ -22,4 +22,9 @@ public interface SupplierConfig {
|
||||
*/
|
||||
String getSupplier();
|
||||
|
||||
/**
|
||||
* 获取代理配置
|
||||
*
|
||||
*/
|
||||
ProxyConfig getProxy();
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ public abstract class Constant {
|
||||
/**
|
||||
* 项目版本号
|
||||
*/
|
||||
public static final String VERSION = "V 3.3.3";
|
||||
public static final String VERSION = "V 3.3.4";
|
||||
|
||||
/**
|
||||
* 用于格式化鉴权头域,给"Authorization"参数赋值
|
||||
|
||||
@ -93,4 +93,8 @@ public abstract class SupplierConstant {
|
||||
* danmi sms
|
||||
*/
|
||||
public static final String DAN_MI = "danmi";
|
||||
/**
|
||||
* 联通一信通 sms
|
||||
*/
|
||||
public static final String YIXINTONG = "yixintong";
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
package org.dromara.sms4j.comm.utils;
|
||||
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.Method;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
@ -12,15 +14,108 @@ import java.util.Map;
|
||||
|
||||
public class SmsHttpUtils {
|
||||
|
||||
/**
|
||||
* 是否启用代理 默认不启用
|
||||
*/
|
||||
private final Boolean enable;
|
||||
|
||||
/**
|
||||
* 代理服务器地址
|
||||
*/
|
||||
private final String host;
|
||||
|
||||
/**
|
||||
* 代理服务器端口
|
||||
*/
|
||||
private final Integer port;
|
||||
|
||||
// 无代理单例(饿汉式加载)
|
||||
private static final SmsHttpUtils NON_PROXY_INSTANCE = new SmsHttpUtils();
|
||||
|
||||
// 代理单例(双重校验锁延迟加载)
|
||||
private static volatile SmsHttpUtils PROXY_INSTANCE;
|
||||
|
||||
// 无代理构造方法
|
||||
private SmsHttpUtils() {
|
||||
this.enable = false;
|
||||
this.host = null;
|
||||
this.port = null;
|
||||
}
|
||||
|
||||
private static class SmsHttpHolder {
|
||||
private static final SmsHttpUtils INSTANCE = new SmsHttpUtils();
|
||||
// 代理构造方法
|
||||
private SmsHttpUtils(String host, Integer port) {
|
||||
this.enable = true;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取无代理单例
|
||||
*/
|
||||
public static SmsHttpUtils instance() {
|
||||
return SmsHttpHolder.INSTANCE;
|
||||
return NON_PROXY_INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取代理单例(线程安全 + 参数校验)
|
||||
*/
|
||||
public static SmsHttpUtils instance(String host, Integer port) {
|
||||
if (PROXY_INSTANCE == null) {
|
||||
synchronized (SmsHttpUtils.class) {
|
||||
if (PROXY_INSTANCE == null) {
|
||||
validateProxyParams(host, port);
|
||||
PROXY_INSTANCE = new SmsHttpUtils(host, port);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 二次调用时校验参数一致性
|
||||
if (!PROXY_INSTANCE.host.equals(host) || !PROXY_INSTANCE.port.equals(port)) {
|
||||
throw new IllegalStateException("Proxy parameters cannot be modified after initialization");
|
||||
}
|
||||
}
|
||||
return PROXY_INSTANCE;
|
||||
}
|
||||
|
||||
// 代理参数校验
|
||||
private static void validateProxyParams(String host, Integer port) {
|
||||
if (StrUtil.isBlank(host) || port == null || port <= 0) {
|
||||
throw new IllegalArgumentException("Invalid proxy host or port");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置请求 是否走代理
|
||||
* @param url 请求地址
|
||||
* @return HttpRequest
|
||||
*/
|
||||
private HttpRequest request(String url){
|
||||
HttpRequest request = HttpRequest.of(url);
|
||||
if (enable){
|
||||
request.setHttpProxy(host, port);
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造post请求
|
||||
* @param url 请求地址
|
||||
* @return HttpRequest
|
||||
*/
|
||||
private HttpRequest post(String url){
|
||||
HttpRequest post = request(url);
|
||||
post.setMethod(Method.POST);
|
||||
return post;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造get请求
|
||||
* @param url 请求地址
|
||||
* @return HttpRequest
|
||||
*/
|
||||
private HttpRequest get(String url){
|
||||
HttpRequest get = request(url);
|
||||
get.setMethod(Method.GET);
|
||||
return get;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -32,7 +127,7 @@ public class SmsHttpUtils {
|
||||
* @return 返回体
|
||||
*/
|
||||
public JSONObject postJson(String url, Map<String, String> headers, String body) {
|
||||
try (HttpResponse response = HttpRequest.post(url)
|
||||
try (HttpResponse response = post(url)
|
||||
.addHeaders(headers)
|
||||
.body(body)
|
||||
.execute()) {
|
||||
@ -63,7 +158,7 @@ public class SmsHttpUtils {
|
||||
* @return 返回体
|
||||
*/
|
||||
public JSONObject postFrom(String url, Map<String, String> headers, Map<String, Object> body) {
|
||||
try (HttpResponse response = HttpRequest.post(url)
|
||||
try (HttpResponse response = post(url)
|
||||
.addHeaders(headers)
|
||||
.form(body)
|
||||
.execute()) {
|
||||
@ -84,7 +179,7 @@ public class SmsHttpUtils {
|
||||
* @return 返回体
|
||||
*/
|
||||
public JSONObject postBasicFrom(String url, Map<String, String> headers, String username, String password, Map<String, Object> body) {
|
||||
try (HttpResponse response = HttpRequest.post(url)
|
||||
try (HttpResponse response = post(url)
|
||||
.addHeaders(headers)
|
||||
.basicAuth(username, password)
|
||||
.form(body)
|
||||
@ -105,7 +200,7 @@ public class SmsHttpUtils {
|
||||
*/
|
||||
public JSONObject postUrl(String url, Map<String, String> headers, Map<String, Object> params) {
|
||||
String urlWithParams = url + "?" + URLUtil.buildQuery(params, null);
|
||||
try (HttpResponse response = HttpRequest.post(urlWithParams)
|
||||
try (HttpResponse response = post(urlWithParams)
|
||||
.addHeaders(headers)
|
||||
.execute()) {
|
||||
return JSONUtil.parseObj(response.body());
|
||||
@ -121,7 +216,7 @@ public class SmsHttpUtils {
|
||||
* @return 返回体
|
||||
*/
|
||||
public JSONObject getBasic(String url, String username, String password) {
|
||||
try (HttpResponse response = HttpRequest.get(url)
|
||||
try (HttpResponse response = get(url)
|
||||
.basicAuth(username, password)
|
||||
.execute()) {
|
||||
return JSONUtil.parseObj(response.body());
|
||||
@ -137,7 +232,7 @@ public class SmsHttpUtils {
|
||||
* @return 返回体
|
||||
*/
|
||||
public JSONObject getUrl(String url) {
|
||||
try (HttpResponse response = HttpRequest.get(url)
|
||||
try (HttpResponse response = get(url)
|
||||
.execute()) {
|
||||
return JSONUtil.parseObj(response.body());
|
||||
} catch (Exception e) {
|
||||
|
||||
@ -10,7 +10,12 @@ import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
|
||||
@ -10,6 +10,8 @@ import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||
import org.dromara.sms4j.provider.config.SmsConfig;
|
||||
import org.dromara.sms4j.provider.factory.BeanFactory;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@ -26,7 +28,6 @@ import java.util.Objects;
|
||||
@Slf4j
|
||||
public class RestrictedProcessor implements CoreMethodProcessor, SmsDaoAware {
|
||||
static Long minTimer = 60 * 1000L;
|
||||
static Long accTimer = 24 * 60 * 60 * 1000L;
|
||||
private static final String REDIS_KEY = "sms:restricted:";
|
||||
|
||||
/**
|
||||
@ -59,6 +60,13 @@ public class RestrictedProcessor implements CoreMethodProcessor, SmsDaoAware {
|
||||
doRestricted(phones);
|
||||
}
|
||||
|
||||
private long calculateExpiryTime() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LocalDateTime tomorrowMidnight = now.toLocalDate().plusDays(1).atStartOfDay();
|
||||
Duration duration = Duration.between(now, tomorrowMidnight);
|
||||
return duration.getSeconds();
|
||||
}
|
||||
|
||||
public void doRestricted(List<String> phones) {
|
||||
if (Objects.isNull(smsDao)) {
|
||||
throw new SmsBlendException("The smsDao tool could not be found");
|
||||
@ -86,12 +94,12 @@ public class RestrictedProcessor implements CoreMethodProcessor, SmsDaoAware {
|
||||
if (dailyMaxLimitExists) {
|
||||
Integer dailyCount = (Integer) smsDao.get(accountMaxKey);
|
||||
if (SmsUtils.isEmpty(dailyCount)) {
|
||||
smsDao.set(accountMaxKey, 1, accTimer / 1000);
|
||||
smsDao.set(accountMaxKey, 1, calculateExpiryTime());
|
||||
} else if (dailyCount >= accountMax) {
|
||||
log.info("The phone: {},number of short messages reached the maximum today", phone);
|
||||
throw new SmsBlendException("The phone: {},number of short messages reached the maximum today", phone);
|
||||
} else {
|
||||
smsDao.set(accountMaxKey, dailyCount + 1, accTimer / 1000);
|
||||
smsDao.set(accountMaxKey, dailyCount + 1, calculateExpiryTime());
|
||||
}
|
||||
}
|
||||
// 是否配置了每分钟最大限制
|
||||
@ -105,7 +113,7 @@ public class RestrictedProcessor implements CoreMethodProcessor, SmsDaoAware {
|
||||
if (dailyMaxLimitExists) {
|
||||
Integer dailyCount = (Integer) smsDao.get(accountMaxKey);
|
||||
if (dailyCount > 1) {
|
||||
smsDao.set(accountMaxKey, dailyCount - 1, accTimer / 1000);
|
||||
smsDao.set(accountMaxKey, dailyCount - 1, calculateExpiryTime());
|
||||
} else {
|
||||
smsDao.remove(accountMaxKey);
|
||||
}
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* <p> 邮件插件api模块
|
||||
* @author :Wind
|
||||
* 2024/10/23 10:58
|
||||
**/
|
||||
package org.dromara.email.jakarta.api;
|
||||
@ -3,6 +3,7 @@ package org.dromara.email.jakarta.comm.entity;
|
||||
import lombok.Getter;
|
||||
import org.dromara.email.jakarta.comm.utils.ReflectUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -27,6 +28,12 @@ public class MailMessage {
|
||||
/** html模板文件的输入流,可来自任意可读取位置*/
|
||||
private InputStream htmlInputStream;
|
||||
|
||||
/** html内容,可以存在模板变量*/
|
||||
private String htmlContent;
|
||||
|
||||
/** html 模板文件的File对象*/
|
||||
private File htmlFile;
|
||||
|
||||
/** html 模板参数*/
|
||||
private Map<String,String> htmlValues;
|
||||
|
||||
@ -141,6 +148,18 @@ public class MailMessage {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** html模板文件的File对象*/
|
||||
public MailsBuilder html(File htmlFile){
|
||||
mailMessage.htmlFile = htmlFile;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** html内容直接输入*/
|
||||
public MailsBuilder htmlContent(String htmlContent){
|
||||
mailMessage.htmlContent = htmlContent;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** html 模板参数*/
|
||||
public MailsBuilder htmlValues(String key, String value){
|
||||
if (mailMessage.htmlValues == null){
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* <p> 邮件插件通用模块
|
||||
* @author :Wind
|
||||
* 2024/10/23 10:58
|
||||
**/
|
||||
package org.dromara.email.jakarta.comm;
|
||||
@ -32,8 +32,8 @@ public final class HtmlUtil {
|
||||
* @param name 模板文件名
|
||||
* @author :Wind
|
||||
*/
|
||||
public static List<String> readHtml(String name) throws MailException {
|
||||
try (InputStream is = HtmlUtil.class.getResourceAsStream("/template/" + name)) {
|
||||
public static List<String> readHtml(String name,Class<?> clazz) throws MailException {
|
||||
try (InputStream is = clazz.getResourceAsStream("/template/" + name)) {
|
||||
return readHtml(is);
|
||||
} catch (IOException e) {
|
||||
throw new MailException(e);
|
||||
@ -75,6 +75,12 @@ public final class HtmlUtil {
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new MailException(e);
|
||||
} finally {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ import org.dromara.email.jakarta.comm.utils.ZipUtils;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -50,8 +51,14 @@ public class MailService implements MailClient {
|
||||
if (mailMessage.getHtmlInputStream() != null) {
|
||||
html = HtmlUtil.readHtml(mailMessage.getHtmlInputStream());
|
||||
}
|
||||
if (StrUtil.isNotBlank(mailMessage.getHtmlPath())){
|
||||
html = HtmlUtil.readHtml(mailMessage.getHtmlPath());
|
||||
if (StrUtil.isNotBlank(mailMessage.getHtmlPath())) {
|
||||
html = HtmlUtil.readHtml(mailMessage.getHtmlPath(), MailService.class);
|
||||
}
|
||||
if (mailMessage.getHtmlFile() != null) {
|
||||
html = HtmlUtil.readHtml(mailMessage.getHtmlFile());
|
||||
}
|
||||
if (StrUtil.isNotBlank(mailMessage.getHtmlContent())) {
|
||||
html = Arrays.asList(mailMessage.getHtmlContent().split("\n"));
|
||||
}
|
||||
send(mailMessage.getMailAddress(),
|
||||
mailMessage.getTitle(),
|
||||
@ -186,11 +193,17 @@ public class MailService implements MailClient {
|
||||
message.setSubject(title);
|
||||
|
||||
Multipart multipart = new MimeMultipart("alternative");
|
||||
if (CollUtil.isNotEmpty(html) && MapUtil.isNotEmpty(parameter)) {
|
||||
if (CollUtil.isNotEmpty(html)) {
|
||||
String htmlData;
|
||||
List<String> strings;
|
||||
if (MapUtil.isNotEmpty(parameter)) {
|
||||
//读取模板并进行变量替换
|
||||
List<String> strings = HtmlUtil.replacePlaceholder(html, parameter);
|
||||
strings = HtmlUtil.replacePlaceholder(html, parameter);
|
||||
//拼合HTML数据
|
||||
String htmlData = HtmlUtil.pieceHtml(strings);
|
||||
htmlData = HtmlUtil.pieceHtml(strings);
|
||||
}else {
|
||||
htmlData = HtmlUtil.pieceHtml(html);
|
||||
}
|
||||
MimeBodyPart htmlPart = new MimeBodyPart();
|
||||
htmlPart.setContent(htmlData, "text/html;charset=UTF-8");
|
||||
multipart.addBodyPart(htmlPart);
|
||||
|
||||
@ -18,6 +18,7 @@ import org.dromara.sms4j.api.universal.SupplierConfig;
|
||||
import org.dromara.sms4j.api.verify.PhoneVerify;
|
||||
import org.dromara.sms4j.baidu.config.BaiduFactory;
|
||||
import org.dromara.sms4j.budingyun.config.BudingV2Factory;
|
||||
import org.dromara.sms4j.chuanglan.config.ChuangLanFactory;
|
||||
import org.dromara.sms4j.cloopen.config.CloopenFactory;
|
||||
import org.dromara.sms4j.comm.constant.Constant;
|
||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
@ -36,7 +37,6 @@ import org.dromara.sms4j.emay.config.EmayFactory;
|
||||
import org.dromara.sms4j.huawei.config.HuaweiFactory;
|
||||
import org.dromara.sms4j.javase.util.YamlUtils;
|
||||
import org.dromara.sms4j.jdcloud.config.JdCloudFactory;
|
||||
import org.dromara.sms4j.chuanglan.config.ChuangLanFactory;
|
||||
import org.dromara.sms4j.jg.config.JgFactory;
|
||||
import org.dromara.sms4j.lianlu.config.LianLuFactory;
|
||||
import org.dromara.sms4j.luosimao.config.LuoSiMaoFactory;
|
||||
@ -50,6 +50,7 @@ import org.dromara.sms4j.qiniu.config.QiNiuFactory;
|
||||
import org.dromara.sms4j.submail.config.SubMailFactory;
|
||||
import org.dromara.sms4j.tencent.config.TencentFactory;
|
||||
import org.dromara.sms4j.unisms.config.UniFactory;
|
||||
import org.dromara.sms4j.yixintong.config.YiXintongFactory;
|
||||
import org.dromara.sms4j.yunpian.config.YunPianFactory;
|
||||
import org.dromara.sms4j.zhutong.config.ZhutongFactory;
|
||||
|
||||
@ -144,9 +145,7 @@ public class SEInitializer {
|
||||
//如果手机号校验器存在实现,则注册手机号校验器
|
||||
ServiceLoader<PhoneVerify> loader = ServiceLoader.load(PhoneVerify.class);
|
||||
if (loader.iterator().hasNext()) {
|
||||
loader.forEach(f -> {
|
||||
SmsProxyFactory.addPreProcessor(new CoreMethodParamValidateProcessor(f));
|
||||
});
|
||||
loader.forEach(f -> SmsProxyFactory.addPreProcessor(new CoreMethodParamValidateProcessor(f)));
|
||||
} else {
|
||||
SmsProxyFactory.addPreProcessor(new CoreMethodParamValidateProcessor(null));
|
||||
}
|
||||
@ -217,9 +216,7 @@ public class SEInitializer {
|
||||
//如果手机号校验器存在实现,则注册手机号校验器
|
||||
ServiceLoader<PhoneVerify> loader = ServiceLoader.load(PhoneVerify.class);
|
||||
if (loader.iterator().hasNext()) {
|
||||
loader.forEach(f -> {
|
||||
SmsProxyFactory.addPreProcessor(new CoreMethodParamValidateProcessor(f));
|
||||
});
|
||||
loader.forEach(f -> SmsProxyFactory.addPreProcessor(new CoreMethodParamValidateProcessor(f)));
|
||||
} else {
|
||||
SmsProxyFactory.addPreProcessor(new CoreMethodParamValidateProcessor(null));
|
||||
}
|
||||
@ -266,6 +263,7 @@ public class SEInitializer {
|
||||
ProviderFactoryHolder.registerFactory(LuoSiMaoFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(SubMailFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(DanMiFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(YiXintongFactory.instance());
|
||||
if (SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) {
|
||||
ProviderFactoryHolder.registerFactory(JdCloudFactory.instance());
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package org.dromara.oa.core.config;
|
||||
import org.dromara.oa.api.OaSender;
|
||||
import org.dromara.oa.core.provider.config.OaConfig;
|
||||
import org.dromara.oa.core.provider.factory.OaBaseProviderFactory;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@ -31,7 +32,7 @@ public class OaSupplierConfig {
|
||||
protected OaBlendsInitializer smsOasInitializer(
|
||||
List<OaBaseProviderFactory<? extends OaSender, ? extends org.dromara.oa.comm.config.OaSupplierConfig>> factoryList,
|
||||
OaConfig oaConfig,
|
||||
Map<String, Map<String, Object>> oas) {
|
||||
@Qualifier("oas") Map<String, Map<String, Object>> oas) {
|
||||
return new OaBlendsInitializer(factoryList,oaConfig,oas);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package org.dromara.oa.core.provider.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.oa.api.OaCallBack;
|
||||
import org.dromara.oa.api.OaSender;
|
||||
import org.dromara.oa.comm.config.OaSupplierConfig;
|
||||
@ -19,6 +20,7 @@ import java.util.concurrent.PriorityBlockingQueue;
|
||||
* @author dongfeng
|
||||
* 2023-10-22 21:03
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class AbstractOaBlend<C extends OaSupplierConfig> implements OaSender {
|
||||
|
||||
@Getter
|
||||
@ -57,12 +59,16 @@ public abstract class AbstractOaBlend<C extends OaSupplierConfig> implements OaS
|
||||
pool.execute(() -> {
|
||||
Thread.currentThread().setName("oa-priorityQueueMap-thread");
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
Request request = priorityQueueMap.poll();
|
||||
if (!Objects.isNull(request)) {
|
||||
try{
|
||||
Request request = priorityQueueMap.take() ;
|
||||
pool.execute(() -> {
|
||||
System.out.println("优先级为"+request.getPriority()+"已发送");
|
||||
log.info("优先级为"+request.getPriority()+"已发送");
|
||||
sender(request, request.getMessageType());
|
||||
});
|
||||
}catch (InterruptedException e){
|
||||
log.info("[Dispatcher]-priorityQueueMap-task-dispatcher has been interrupt to close.");
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -116,7 +116,7 @@ public class AlibabaSmsImpl extends AbstractSmsBlend<AlibabaConfig> {
|
||||
} catch (SmsBlendException e) {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
|
||||
@ -2,8 +2,8 @@ package org.dromara.sms4j.baidu.config;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.sms4j.comm.constant.SupplierConstant;
|
||||
import org.dromara.sms4j.baidu.service.BaiduSmsImpl;
|
||||
import org.dromara.sms4j.comm.constant.SupplierConstant;
|
||||
import org.dromara.sms4j.provider.factory.AbstractProviderFactory;
|
||||
|
||||
/**
|
||||
|
||||
@ -6,12 +6,12 @@ import cn.hutool.json.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||
import org.dromara.sms4j.api.utils.SmsRespUtils;
|
||||
import org.dromara.sms4j.baidu.config.BaiduConfig;
|
||||
import org.dromara.sms4j.baidu.utils.BaiduUtils;
|
||||
import org.dromara.sms4j.comm.constant.SupplierConstant;
|
||||
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
|
||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||
import org.dromara.sms4j.baidu.config.BaiduConfig;
|
||||
import org.dromara.sms4j.baidu.utils.BaiduUtils;
|
||||
import org.dromara.sms4j.provider.service.AbstractSmsBlend;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
@ -12,7 +12,10 @@ import org.dromara.sms4j.comm.constant.Constant;
|
||||
import org.dromara.sms4j.comm.utils.SmsDateUtils;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@ -98,6 +101,7 @@ public class BaiduUtils {
|
||||
Map<String, String> headers = new HashMap<>(2);
|
||||
headers.put(Constant.AUTHORIZATION, authorization);
|
||||
headers.put("host", config.getHost());
|
||||
headers.put("x-bce-date", SmsDateUtils.normDateGmt8(new Date()));
|
||||
return headers;
|
||||
}
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ import org.dromara.sms4j.comm.delayedTime.DelayedTime;
|
||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
import org.dromara.sms4j.provider.service.AbstractSmsBlend;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@ -72,7 +73,7 @@ public class BudingV2SmsImpl extends AbstractSmsBlend<BudingV2Config> {
|
||||
} catch (SmsBlendException e) {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
@ -150,7 +151,12 @@ public class BudingV2SmsImpl extends AbstractSmsBlend<BudingV2Config> {
|
||||
*/
|
||||
@Override
|
||||
public SmsResponse massTexting(List<String> phones, String templateId, LinkedHashMap<String, String> messages) {
|
||||
throw new SmsBlendException("布丁云V2暂不支持多条短信发送");
|
||||
List<SmsResponse> list = new ArrayList<>();
|
||||
for (String phone : phones) {
|
||||
SmsResponse smsResponse = sendMessage(phone, templateId, messages);
|
||||
list.add(smsResponse);
|
||||
}
|
||||
return SmsRespUtils.resp(list, true, getConfigId());
|
||||
}
|
||||
|
||||
private Map<String, String> getHeaders() {
|
||||
|
||||
@ -107,7 +107,7 @@ public class ChuangLanSmsImpl extends AbstractSmsBlend<ChuangLanConfig> {
|
||||
}catch (SmsBlendException e) {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ package org.dromara.sms4j.danmi.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||
import org.dromara.sms4j.api.utils.SmsRespUtils;
|
||||
@ -17,7 +16,6 @@ import org.dromara.sms4j.provider.service.AbstractSmsBlend;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
|
||||
@ -21,13 +21,14 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.dromara.sms4j.huawei.utils.HuaweiBuilder.listToString;
|
||||
|
||||
@Slf4j
|
||||
public class HuaweiSmsImpl extends AbstractSmsBlend<HuaweiConfig> {
|
||||
|
||||
private int retry = 0;
|
||||
private volatile int retry = 0;
|
||||
|
||||
public HuaweiSmsImpl(HuaweiConfig config, Executor pool, DelayedTime delayed) {
|
||||
super(config, pool, delayed);
|
||||
@ -80,7 +81,7 @@ public class HuaweiSmsImpl extends AbstractSmsBlend<HuaweiConfig> {
|
||||
} catch (SmsBlendException e) {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ public class JdCloudSmsImpl extends AbstractSmsBlend<JdCloudConfig> {
|
||||
} catch (SmsBlendException e) {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ public class JgSmsImpl extends AbstractSmsBlend<JgConfig> {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
|
||||
@ -9,7 +9,12 @@ import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||
import org.dromara.sms4j.jg.config.JgConfig;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
||||
@ -13,7 +13,11 @@ import org.dromara.sms4j.luosimao.config.LuoSiMaoConfig;
|
||||
import org.dromara.sms4j.luosimao.utils.LuoSiMaoUtils;
|
||||
import org.dromara.sms4j.provider.service.AbstractSmsBlend;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package org.dromara.sms4j.luosimao.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.comm.constant.Constant;
|
||||
import org.dromara.sms4j.comm.utils.SmsDateUtils;
|
||||
@ -13,24 +12,24 @@ import java.util.List;
|
||||
@Slf4j
|
||||
public class LuoSiMaoUtils {
|
||||
|
||||
public static LinkedHashMap<String, String> buildHeaders(){
|
||||
public static LinkedHashMap<String, String> buildHeaders() {
|
||||
LinkedHashMap<String, String> headers = new LinkedHashMap<>(1);
|
||||
headers.put(Constant.CONTENT_TYPE, Constant.APPLICATION_FROM_URLENCODED);
|
||||
return headers;
|
||||
}
|
||||
|
||||
public static LinkedHashMap<String, Object> buildBody(String phone, String message){
|
||||
public static LinkedHashMap<String, Object> buildBody(String phone, String message) {
|
||||
LinkedHashMap<String, Object> body = new LinkedHashMap<>(2);
|
||||
body.put("mobile", StrUtil.addPrefixIfNot(phone, "+86"));
|
||||
body.put("mobile", phone);
|
||||
body.put("message", message);
|
||||
return body;
|
||||
}
|
||||
|
||||
public static LinkedHashMap<String, Object> buildBody(List<String> phones, String message, Date date){
|
||||
public static LinkedHashMap<String, Object> buildBody(List<String> phones, String message, Date date) {
|
||||
LinkedHashMap<String, Object> body = new LinkedHashMap<>(2);
|
||||
body.put("mobile", SmsUtils.addCodePrefixIfNot(phones));
|
||||
body.put("mobile", SmsUtils.joinComma(phones));
|
||||
body.put("message", message);
|
||||
if (date != null){
|
||||
if (date != null) {
|
||||
body.put("time", SmsDateUtils.normDatetimeGmt8(date));
|
||||
}
|
||||
return body;
|
||||
|
||||
@ -97,7 +97,7 @@ public class MasSmsImpl extends AbstractSmsBlend<MasConfig> {
|
||||
} catch (SmsBlendException e) {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
|
||||
@ -65,6 +65,8 @@ public class MasUtils {
|
||||
if (StrUtil.isNotEmpty(config.getAddSerial())){
|
||||
map.put("addSerial", config.getAddSerial().trim());
|
||||
sb.append(config.getAddSerial().trim());
|
||||
}else {
|
||||
map.put("addSerial", "");
|
||||
}
|
||||
|
||||
map.put("mac", DigestUtil.md5Hex(sb.toString(), StandardCharsets.UTF_8));
|
||||
|
||||
@ -145,7 +145,7 @@ public class NeteaseSmsImpl extends AbstractSmsBlend<NeteaseConfig> {
|
||||
} catch (SmsBlendException e) {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package org.dromara.sms4j.provider.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.dromara.sms4j.api.universal.ProxyConfig;
|
||||
import org.dromara.sms4j.api.universal.SupplierConfig;
|
||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
|
||||
@ -56,6 +57,12 @@ public abstract class BaseConfig implements SupplierConfig {
|
||||
*/
|
||||
private String configId;
|
||||
|
||||
/**
|
||||
* 代理配置
|
||||
*
|
||||
*/
|
||||
private ProxyConfig proxy;
|
||||
|
||||
/**
|
||||
* 重试间隔(单位:秒),默认为5秒
|
||||
*/
|
||||
|
||||
@ -5,6 +5,7 @@ import lombok.Getter;
|
||||
import org.dromara.sms4j.api.SmsBlend;
|
||||
import org.dromara.sms4j.api.callback.CallBack;
|
||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||
import org.dromara.sms4j.api.universal.ProxyConfig;
|
||||
import org.dromara.sms4j.api.universal.SupplierConfig;
|
||||
import org.dromara.sms4j.api.utils.SmsRespUtils;
|
||||
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
|
||||
@ -32,13 +33,19 @@ public abstract class AbstractSmsBlend<C extends SupplierConfig> implements SmsB
|
||||
|
||||
protected final DelayedTime delayed;
|
||||
|
||||
protected final SmsHttpUtils http = SmsHttpUtils.instance();
|
||||
protected final SmsHttpUtils http;
|
||||
|
||||
protected AbstractSmsBlend(C config, Executor pool, DelayedTime delayed) {
|
||||
this.configId = StrUtil.isEmpty(config.getConfigId()) ? getSupplier() : config.getConfigId();
|
||||
this.config = config;
|
||||
this.pool = pool;
|
||||
this.delayed = delayed;
|
||||
ProxyConfig proxy = config.getProxy();
|
||||
if (proxy != null && proxy.getEnable()){
|
||||
this.http = SmsHttpUtils.instance(proxy.getHost(), proxy.getPort());
|
||||
}else {
|
||||
this.http = SmsHttpUtils.instance();
|
||||
}
|
||||
}
|
||||
|
||||
protected AbstractSmsBlend(C config) {
|
||||
@ -46,6 +53,12 @@ public abstract class AbstractSmsBlend<C extends SupplierConfig> implements SmsB
|
||||
this.config = config;
|
||||
this.pool = BeanFactory.getExecutor();
|
||||
this.delayed = BeanFactory.getDelayedTime();
|
||||
ProxyConfig proxy = config.getProxy();
|
||||
if (proxy != null && proxy.getEnable()){
|
||||
this.http = SmsHttpUtils.instance(proxy.getHost(), proxy.getPort());
|
||||
}else {
|
||||
this.http = SmsHttpUtils.instance();
|
||||
}
|
||||
}
|
||||
|
||||
protected C getConfig() {
|
||||
|
||||
@ -88,7 +88,7 @@ public class QiNiuSmsImpl extends AbstractSmsBlend<QiNiuConfig> {
|
||||
}catch (SmsBlendException e){
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
|
||||
@ -17,7 +17,10 @@ import org.dromara.sms4j.provider.service.AbstractSmsBlend;
|
||||
import org.dromara.sms4j.submail.config.SubMailConfig;
|
||||
import org.dromara.sms4j.submail.utils.SubMailUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
@ -360,6 +363,6 @@ public class SubMailSmsImpl extends AbstractSmsBlend<SubMailConfig> {
|
||||
|
||||
private String timestamp(){
|
||||
JSONObject resp = http.getUrl("https://api-v4.mysubmail.com/service/timestamp");
|
||||
return resp.getStr("resp");
|
||||
return resp.getStr("timestamp");
|
||||
}
|
||||
}
|
||||
@ -87,7 +87,7 @@ public class TencentSmsImpl extends AbstractSmsBlend<TencentConfig> {
|
||||
} catch (SmsBlendException e) {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
package org.dromara.sms4j.yixintong.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.sms4j.comm.constant.SupplierConstant;
|
||||
import org.dromara.sms4j.provider.config.BaseConfig;
|
||||
|
||||
/**
|
||||
* <p>类名: YiXintongConfig
|
||||
* <p>说明:联通一信通平台配置类
|
||||
* <p>所用到配置项:spCode、f、accessKeyId(用户名)、accessKeySecret(接口密钥)、signCode、templateId、retryInterval、maxRetries
|
||||
*
|
||||
* @author moat
|
||||
* @create 2024-07-30 16:50
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class YiXintongConfig extends BaseConfig {
|
||||
|
||||
/**
|
||||
* 短信发送请求地址
|
||||
*/
|
||||
private String requestUrl = "https://api.ums86.com:9600/sms/Api/Send.do";
|
||||
|
||||
/**
|
||||
* 企业编号
|
||||
*/
|
||||
private String spCode;
|
||||
|
||||
/**
|
||||
* 签名编号
|
||||
*/
|
||||
private String signCode;
|
||||
|
||||
/**
|
||||
* 提交时检测方式
|
||||
* 1 --- 提交号码中有效的号码仍正常发出短信,无效的号码在返回参数faillist中列出
|
||||
*
|
||||
* 不为1 或该参数不存在 --- 提交号码中只要有无效的号码,那么所有的号码都不发出短信,无效号码在返回参数faillist中列出
|
||||
*/
|
||||
private String f = "1";
|
||||
|
||||
|
||||
@Override
|
||||
public String getSupplier() {
|
||||
return SupplierConstant.YIXINTONG;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package org.dromara.sms4j.yixintong.config;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.sms4j.comm.constant.SupplierConstant;
|
||||
import org.dromara.sms4j.provider.factory.AbstractProviderFactory;
|
||||
import org.dromara.sms4j.yixintong.service.YiXintongSmsImpl;
|
||||
|
||||
/**
|
||||
* <p>类名: YiXintongFactory
|
||||
* <p>说明:联通一信通平台短信对象建造
|
||||
*
|
||||
* @author moat
|
||||
* @create 2024-07-30 17:10
|
||||
*/
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class YiXintongFactory extends AbstractProviderFactory<YiXintongSmsImpl, YiXintongConfig> {
|
||||
|
||||
private static final YiXintongFactory INSTANCE = new YiXintongFactory();
|
||||
|
||||
/**
|
||||
* 获取建造者实例
|
||||
* @return 建造者实例
|
||||
*/
|
||||
public static YiXintongFactory instance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* createSms
|
||||
* <p> 建造一个短信实现对像
|
||||
*/
|
||||
@Override
|
||||
public YiXintongSmsImpl createSms(YiXintongConfig yiXintongConfig) {
|
||||
return new YiXintongSmsImpl(yiXintongConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取供应商
|
||||
* @return 供应商
|
||||
*/
|
||||
@Override
|
||||
public String getSupplier() {
|
||||
return SupplierConstant.YIXINTONG;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,129 @@
|
||||
package org.dromara.sms4j.yixintong.service;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||
import org.dromara.sms4j.api.utils.SmsRespUtils;
|
||||
import org.dromara.sms4j.comm.constant.SupplierConstant;
|
||||
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
|
||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||
import org.dromara.sms4j.provider.service.AbstractSmsBlend;
|
||||
import org.dromara.sms4j.yixintong.config.YiXintongConfig;
|
||||
import org.dromara.sms4j.yixintong.utils.YiXintongUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* <p>类名: YiXintongSmsImpl
|
||||
* <p>说明:联通一信通 sms
|
||||
*
|
||||
* @author moat
|
||||
* @create 2024-07-30 16:59
|
||||
*/
|
||||
@Slf4j
|
||||
public class YiXintongSmsImpl extends AbstractSmsBlend<YiXintongConfig> {
|
||||
|
||||
private int retry = 0;
|
||||
|
||||
public YiXintongSmsImpl(YiXintongConfig config, Executor pool, DelayedTime delayedTime) {
|
||||
super(config, pool, delayedTime);
|
||||
}
|
||||
|
||||
public YiXintongSmsImpl(YiXintongConfig config) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSupplier() {
|
||||
return SupplierConstant.YIXINTONG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResponse sendMessage(String phone, String message) {
|
||||
return getSmsResponse(phone, message, getConfig().getTemplateId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResponse massTexting(List<String> phones, String message) {
|
||||
return getSmsResponse(SmsUtils.joinComma(phones), message, getConfig().getTemplateId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResponse sendMessage(String phone, LinkedHashMap<String, String> messages) {
|
||||
throw new SmsBlendException("不支持此方法");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap<String, String> messages) {
|
||||
throw new SmsBlendException("不支持此方法");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SmsResponse massTexting(List<String> phones, String templateId, LinkedHashMap<String, String> messages) {
|
||||
throw new SmsBlendException("不支持此方法");
|
||||
}
|
||||
|
||||
|
||||
private SmsResponse getSmsResponse(String phone, String message, String templateId) {
|
||||
final YiXintongConfig config = getConfig();
|
||||
if (StrUtil.isBlank(phone)){
|
||||
log.error("phone is required.");
|
||||
throw new SmsBlendException("phone is required.");
|
||||
}
|
||||
if (StrUtil.isBlank(message)){
|
||||
log.error("message is required.");
|
||||
throw new SmsBlendException("message is required.");
|
||||
}
|
||||
// 生成20位流水号
|
||||
String serialNumber = SmsUtils.getRandomInt(20);
|
||||
|
||||
Map<String, Object> forms = new HashMap<>();
|
||||
forms.put("SpCode", config.getSpCode());
|
||||
forms.put("LoginName", config.getAccessKeyId());
|
||||
forms.put("Password", config.getAccessKeySecret());
|
||||
forms.put("MessageContent", message);
|
||||
forms.put("UserNumber", phone);
|
||||
forms.put("templateId", templateId);
|
||||
forms.put("SerialNumber", serialNumber);
|
||||
forms.put("ScheduleTime", ""); // 立即发送
|
||||
forms.put("f", config.getF());
|
||||
forms.put("signCode", config.getSignCode());
|
||||
|
||||
SmsResponse smsResponse;
|
||||
try {
|
||||
smsResponse = getResponse(YiXintongUtils.postForm(config.getRequestUrl(), forms));
|
||||
} catch (SmsBlendException e) {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == config.getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
return requestRetry(phone, message, templateId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private SmsResponse requestRetry(String phone, String message, String templateId) {
|
||||
http.safeSleep(getConfig().getRetryInterval());
|
||||
retry ++;
|
||||
log.warn("The SMS has been resent for the {}th time.", retry);
|
||||
return getSmsResponse(phone, message, templateId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构造统一短信返回信息
|
||||
* @param body 原始响应信息
|
||||
* @return 短信返回信息
|
||||
*/
|
||||
private SmsResponse getResponse(String body) {
|
||||
return SmsRespUtils.resp(body, StrUtil.contains(body, "result=0&"), getConfigId());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package org.dromara.sms4j.yixintong.utils;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>类名: YiXintongUtils
|
||||
* <p>说明:联通一信通工具类
|
||||
*
|
||||
* @author moat
|
||||
* @create 2024-07-31 9:55
|
||||
*/
|
||||
public class YiXintongUtils {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 发送post form请求
|
||||
*
|
||||
* @param url 请求地址
|
||||
* @param forms 表单参数
|
||||
* @return 返回体
|
||||
*/
|
||||
public static String postForm(String url, Map<String, Object> forms) {
|
||||
return postForm(url, null, forms, "gbk");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发送post form请求
|
||||
*
|
||||
* @param url 请求地址
|
||||
* @param headers 请求头
|
||||
* @param forms 表单参数
|
||||
* @param charset 字符集编码
|
||||
* @return 返回体
|
||||
*/
|
||||
public static String postForm(String url, Map<String, String> headers, Map<String, Object> forms, String charset) {
|
||||
try (HttpResponse response = HttpRequest.post(url)
|
||||
.addHeaders(headers)
|
||||
.form(forms)
|
||||
.charset(charset)
|
||||
.execute()) {
|
||||
return response.body();
|
||||
} catch (Exception e) {
|
||||
throw new SmsBlendException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -58,7 +58,7 @@ public class YunPianSmsImpl extends AbstractSmsBlend<YunpianConfig> {
|
||||
} catch (SmsBlendException e) {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
@ -92,9 +92,9 @@ public class YunPianSmsImpl extends AbstractSmsBlend<YunpianConfig> {
|
||||
try {
|
||||
smsResponse = getResponse(http.postFrom(Constant.YUNPIAN_URL + "/sms/tpl_single_send.json", headers, body));
|
||||
} catch (SmsBlendException e) {
|
||||
return requestRetry(phone, templateId, messages);
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
|
||||
@ -155,7 +155,7 @@ public class ZhutongSmsImpl extends AbstractSmsBlend<ZhutongConfig> {
|
||||
} catch (SmsBlendException e) {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
@ -241,7 +241,7 @@ public class ZhutongSmsImpl extends AbstractSmsBlend<ZhutongConfig> {
|
||||
} catch (SmsBlendException e) {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||
import org.dromara.sms4j.api.utils.SmsRespUtils;
|
||||
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
|
||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||
@ -90,11 +91,9 @@ public class ZhangJunSmsImpl extends AbstractSmsBlend<ZhangJunConfig> {
|
||||
try {
|
||||
smsResponse = getResponse(http.postJson(getConfig().getUrl(), null, message));
|
||||
} catch (SmsBlendException e) {
|
||||
smsResponse = new SmsResponse();
|
||||
smsResponse.setSuccess(false);
|
||||
smsResponse.setData(e.getMessage());
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
@ -109,11 +108,7 @@ public class ZhangJunSmsImpl extends AbstractSmsBlend<ZhangJunConfig> {
|
||||
}
|
||||
|
||||
private SmsResponse getResponse(JSONObject resJson) {
|
||||
SmsResponse smsResponse = new SmsResponse();
|
||||
smsResponse.setSuccess("OK".equals(resJson.getStr("Code")));
|
||||
smsResponse.setData(resJson);
|
||||
smsResponse.setConfigId(getConfigId());
|
||||
return smsResponse;
|
||||
return SmsRespUtils.resp(resJson, "OK".equals(resJson.getStr("Code")), getConfigId());
|
||||
}
|
||||
|
||||
}
|
||||
@ -79,13 +79,13 @@ sms:
|
||||
access-key-secret: 你的Access Key Secret
|
||||
sdkAppId: 你的应用ID
|
||||
#自定义广州掌骏短信,添加factory全路径。config,factory,SmsImpl复制其他默认实现即可,修改对应的supplier和发送核心逻辑即可
|
||||
# zhangjun:
|
||||
# supplier: zhangjun
|
||||
# factory: org.dromara.sms4j.example.zhangjun.ZhangJunFactory
|
||||
# templateId: d2a****777
|
||||
# appId: 64c52d2a****77775fe72e3
|
||||
# sid: d2a****777
|
||||
# url: https://sms.idowe.com/**/**/**/send
|
||||
# zhangjun:
|
||||
# supplier: zhangjun
|
||||
# factory: org.dromara.sms4j.example.zhangjun.ZhangJunFactory
|
||||
# templateId: d2a****777
|
||||
# appId: 64c52d2a****77775fe72e3
|
||||
# sid: d2a****777
|
||||
# url: https://sms.idowe.com/**/**/**/send
|
||||
qiniu:
|
||||
access-key-id: EQcDflLTCYnU1******CmqIYLhog1lkWHb2
|
||||
access-key-secret: NeS2ptvZQoIy*****err2DdLe7wxFfQvji1
|
||||
@ -155,21 +155,29 @@ sms:
|
||||
accessKeyId: ACCOUNT SID
|
||||
accessKeySecret: AUTH TOKEN
|
||||
action: 默认请求方法 distributor/sendSMS
|
||||
# 一信通
|
||||
yixintong:
|
||||
sp-code: xxxxxx #(必填)企业编号
|
||||
access-key-id: xxxxxx #(必填)用户名
|
||||
access-key-secret: 324gaxxxxxxxxxxxxxxxxx9sdf89 #(必填)接口密钥(正式帐户需要登陆平台,接口业务-接口申请右侧钥匙状图标查看或获取,接口密钥获取后十分钟生效)
|
||||
template-id: #(可选)模板编号(若配置此参数,则会默认使用该模板,以便提高服务方性能)
|
||||
sign-code: #(可选)短信前置签名编号(登陆平台-接口业务-我的签名查看)
|
||||
f: 1 #(可选)默认为1,提交时检测方式
|
||||
|
||||
sms-oa:
|
||||
config-type: yaml
|
||||
oas:
|
||||
oaDingTalkByYaml: # configId
|
||||
isEnable: true # 表示该配置是否生效(默认生效,false表示不生效)
|
||||
supplier: dingding # 厂商标识
|
||||
supplier: ding_ding # 厂商标识
|
||||
tokenId: 您的accessKey
|
||||
sign: 您的sign
|
||||
oaByteTalkByYaml: # configId
|
||||
supplier: feishu # 厂商标识
|
||||
supplier: byte_talk # 厂商标识
|
||||
tokenId: 您的accessKey
|
||||
sign: 您的sign
|
||||
oaWeTalkByYaml:
|
||||
supplier: wetalk # 厂商标识
|
||||
supplier: we_talk # 厂商标识
|
||||
tokenId: 您的sign
|
||||
core-pool-size: 20
|
||||
queue-capacity: 20
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package org.dromara.sms4j.example;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.lang.UUID;
|
||||
@ -18,14 +19,16 @@ import org.dromara.sms4j.jg.service.JgSmsImpl;
|
||||
import org.dromara.sms4j.lianlu.service.LianLuSmsImpl;
|
||||
import org.dromara.sms4j.luosimao.service.LuoSiMaoSmsImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.noear.solon.test.SolonJUnit5Extension;
|
||||
import org.noear.solon.test.SolonTest;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@ExtendWith(SolonJUnit5Extension.class)
|
||||
@SolonTest
|
||||
public class Sms4jTest {
|
||||
|
||||
@ -528,4 +531,31 @@ public class Sms4jTest {
|
||||
SmsResponse smsResponse5 = danMiSms.voiceTemplate(PHONE, "opipedlqza", "111,222,333");
|
||||
Assert.isTrue(smsResponse5.isSuccess());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 联通一信通模板
|
||||
*/
|
||||
@Test
|
||||
public void yixintongSmsTest() {
|
||||
if (StrUtil.isBlank(PHONE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//短信发送模板:你有一项编号为{xxxxxxxxx}的事务需要处理{x}
|
||||
//其中的{xxxxxx}代表短信模板中的变量部分,可变化,一个x代表一个字或者字符,{}为变量标识,在发送时不用传。实发变量字数小于等于x的个数。
|
||||
|
||||
// 单发
|
||||
String message1 = StrUtil.format("你有一项编号为{}的事务需要处理。", SmsUtils.getRandomInt(6));
|
||||
SmsResponse smsResponse1 = SmsFactory.getBySupplier(SupplierConstant.YIXINTONG).sendMessage(PHONE, message1);
|
||||
log.info(JSONUtil.toJsonStr(smsResponse1));
|
||||
Assert.isTrue(smsResponse1.isSuccess());
|
||||
|
||||
// 群发
|
||||
List<String> phones = CollectionUtil.toList(PHONE);
|
||||
String message2 = StrUtil.format("你有一项编号为{}的事务需要处理。", SmsUtils.getRandomInt(6));
|
||||
SmsResponse smsResponse2 = SmsFactory.getBySupplier(SupplierConstant.YIXINTONG).massTexting(phones, message2);
|
||||
log.info(JSONUtil.toJsonStr(smsResponse2));
|
||||
Assert.isTrue(smsResponse2.isSuccess());
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,8 +10,6 @@ import org.dromara.oa.core.dingTalk.config.DingTalkConfig;
|
||||
import org.dromara.oa.core.provider.factory.OaFactory;
|
||||
import org.dromara.oa.core.weTalk.config.WeTalkConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.noear.solon.test.SolonJUnit5Extension;
|
||||
import org.noear.solon.test.SolonTest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -20,7 +18,6 @@ import java.util.concurrent.CountDownLatch;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@ExtendWith(SolonJUnit5Extension.class)
|
||||
@SolonTest
|
||||
public class SmsOaTest {
|
||||
//***********************DingTalk-Test************************//
|
||||
|
||||
@ -9,8 +9,6 @@ import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||
import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||
import org.dromara.sms4j.core.factory.SmsFactory;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.noear.solon.test.SolonJUnit5Extension;
|
||||
import org.noear.solon.test.SolonTest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -21,7 +19,6 @@ import java.util.LinkedHashMap;
|
||||
* @author sh1yu
|
||||
*/
|
||||
@Slf4j
|
||||
@ExtendWith(SolonJUnit5Extension.class)
|
||||
@SolonTest
|
||||
public class SmsProcessorTest {
|
||||
/**
|
||||
|
||||
@ -5,8 +5,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.aliyun.config.AlibabaConfig;
|
||||
import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.noear.solon.test.SolonJUnit5Extension;
|
||||
import org.noear.solon.test.SolonTest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -16,7 +14,6 @@ import java.util.List;
|
||||
* @author handy
|
||||
*/
|
||||
@Slf4j
|
||||
@ExtendWith(SolonJUnit5Extension.class)
|
||||
@SolonTest
|
||||
public class SmsUtilsTest {
|
||||
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
package org.dromara.sms4j.solon;
|
||||
|
||||
import org.dromara.sms4j.solon.config.SmsMainConfigure;
|
||||
import org.dromara.sms4j.solon.config.SupplierConfigure;
|
||||
import org.noear.solon.core.AppContext;
|
||||
import org.noear.solon.core.Plugin;
|
||||
|
||||
/**
|
||||
* @author noear 2023/5/16 created
|
||||
*/
|
||||
public class Sms4jPlugin implements Plugin {
|
||||
@Override
|
||||
public void start(AppContext context) {
|
||||
context.beanMake(SmsMainConfigure.class);
|
||||
context.beanMake(SupplierConfigure.class);
|
||||
}
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
package org.dromara.sms4j.solon;
|
||||
|
||||
import org.dromara.sms4j.solon.config.SmsAutowiredConfig;
|
||||
import org.dromara.sms4j.solon.config.SupplierConfig;
|
||||
import org.noear.solon.core.AppContext;
|
||||
import org.noear.solon.core.Plugin;
|
||||
|
||||
/**
|
||||
* @author noear 2023/5/16 created
|
||||
*/
|
||||
public class XPluginImpl implements Plugin {
|
||||
@Override
|
||||
public void start(AppContext context) {
|
||||
context.beanMake(SmsAutowiredConfig.class);
|
||||
context.beanMake(SupplierConfig.class);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package org.dromara.sms4j.solon.adaptor;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import org.dromara.sms4j.core.datainterface.SmsReadConfig;
|
||||
import org.dromara.sms4j.provider.config.BaseConfig;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ConfigCombineMapAdaptor<S, M> extends HashMap {
|
||||
@Override
|
||||
public M get(Object key) {
|
||||
Object o = super.get(key);
|
||||
if (null == o){
|
||||
Set configKeySet = this.keySet();
|
||||
for (Object insideMapKey : configKeySet) {
|
||||
if (((String)insideMapKey).startsWith(SmsReadConfig.class.getSimpleName())){
|
||||
Map smsBlendsConfigInsideMap = (Map) this.get(insideMapKey);
|
||||
SmsReadConfig config = (SmsReadConfig) smsBlendsConfigInsideMap.get(insideMapKey);
|
||||
BaseConfig supplierConfig = config.getSupplierConfig((String)key);
|
||||
List<BaseConfig> supplierConfigList = config.getSupplierConfigList();
|
||||
if (null == supplierConfigList){
|
||||
supplierConfigList = new ArrayList<>();
|
||||
}
|
||||
if (null != supplierConfig){
|
||||
supplierConfigList.add(supplierConfig);
|
||||
}
|
||||
for (BaseConfig baseConfig : supplierConfigList) {
|
||||
if (key.equals(baseConfig.getConfigId())){
|
||||
Map<String, Object> configMap = BeanUtil.beanToMap(baseConfig);
|
||||
this.put(baseConfig.getConfigId(),configMap);
|
||||
return (M)configMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return (M)o;
|
||||
}
|
||||
}
|
||||
@ -1,60 +0,0 @@
|
||||
package org.dromara.sms4j.solon.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.comm.constant.Constant;
|
||||
import org.dromara.sms4j.comm.delayedTime.DelayedTime;
|
||||
import org.dromara.sms4j.provider.config.SmsBanner;
|
||||
import org.dromara.sms4j.provider.config.SmsConfig;
|
||||
import org.dromara.sms4j.provider.factory.BeanFactory;
|
||||
import org.noear.solon.annotation.Bean;
|
||||
import org.noear.solon.annotation.Configuration;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
import org.noear.solon.core.AppContext;
|
||||
import org.noear.solon.core.bean.LifecycleBean;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class SmsAutowiredConfig implements LifecycleBean {
|
||||
|
||||
@Inject
|
||||
AppContext context;
|
||||
|
||||
private <T> T injectObj(String prefix, T obj) {
|
||||
//@Inject 只支持在字段、参数、类型上注入
|
||||
context.cfg().getProp(prefix).bindTo(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SmsConfig smsConfig() {
|
||||
return injectObj("sms", BeanFactory.getSmsConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入一个定时器
|
||||
*/
|
||||
@Bean
|
||||
public DelayedTime delayedTime() {
|
||||
return BeanFactory.getDelayedTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 注入线程池
|
||||
*/
|
||||
@Bean("smsExecutor")
|
||||
public Executor taskExecutor(@Inject SmsConfig config) {
|
||||
return BeanFactory.setExecutor(config);
|
||||
}
|
||||
|
||||
|
||||
//是在 solon 容器扫描完成之后执行的
|
||||
@Override
|
||||
public void start() {
|
||||
//打印banner
|
||||
if (BeanFactory.getSmsConfig().getIsPrint()) {
|
||||
SmsBanner.PrintBanner(Constant.VERSION);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -10,9 +10,12 @@ import org.dromara.sms4j.api.universal.SupplierConfig;
|
||||
import org.dromara.sms4j.api.verify.PhoneVerify;
|
||||
import org.dromara.sms4j.baidu.config.BaiduFactory;
|
||||
import org.dromara.sms4j.budingyun.config.BudingV2Factory;
|
||||
import org.dromara.sms4j.chuanglan.config.ChuangLanFactory;
|
||||
import org.dromara.sms4j.cloopen.config.CloopenFactory;
|
||||
import org.dromara.sms4j.comm.constant.Constant;
|
||||
import org.dromara.sms4j.comm.enums.ConfigType;
|
||||
import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||
import org.dromara.sms4j.core.datainterface.SmsReadConfig;
|
||||
import org.dromara.sms4j.core.factory.SmsFactory;
|
||||
import org.dromara.sms4j.core.proxy.EnvirmentHolder;
|
||||
import org.dromara.sms4j.core.proxy.SmsProxyFactory;
|
||||
@ -26,7 +29,6 @@ import org.dromara.sms4j.dingzhong.config.DingZhongFactory;
|
||||
import org.dromara.sms4j.emay.config.EmayFactory;
|
||||
import org.dromara.sms4j.huawei.config.HuaweiFactory;
|
||||
import org.dromara.sms4j.jdcloud.config.JdCloudFactory;
|
||||
import org.dromara.sms4j.chuanglan.config.ChuangLanFactory;
|
||||
import org.dromara.sms4j.jg.config.JgFactory;
|
||||
import org.dromara.sms4j.lianlu.config.LianLuFactory;
|
||||
import org.dromara.sms4j.luosimao.config.LuoSiMaoFactory;
|
||||
@ -36,14 +38,15 @@ import org.dromara.sms4j.provider.config.SmsConfig;
|
||||
import org.dromara.sms4j.provider.factory.BaseProviderFactory;
|
||||
import org.dromara.sms4j.provider.factory.ProviderFactoryHolder;
|
||||
import org.dromara.sms4j.qiniu.config.QiNiuFactory;
|
||||
import org.dromara.sms4j.solon.holder.SolonSmsDaoHolder;
|
||||
import org.dromara.sms4j.solon.adaptor.ConfigCombineMapAdaptor;
|
||||
import org.dromara.sms4j.submail.config.SubMailFactory;
|
||||
import org.dromara.sms4j.tencent.config.TencentFactory;
|
||||
import org.dromara.sms4j.unisms.config.UniFactory;
|
||||
import org.dromara.sms4j.yixintong.config.YiXintongFactory;
|
||||
import org.dromara.sms4j.yunpian.config.YunPianFactory;
|
||||
import org.dromara.sms4j.zhutong.config.ZhutongFactory;
|
||||
import org.noear.solon.core.AppContext;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
@ -55,58 +58,69 @@ public class SmsBlendsInitializer {
|
||||
|
||||
private final SmsConfig smsConfig;
|
||||
private final Map<String, Map<String, Object>> blends;
|
||||
private final AppContext context;
|
||||
private final List<SmsReadConfig> extendsSmsConfigs;
|
||||
|
||||
public SmsBlendsInitializer(List<BaseProviderFactory<? extends SmsBlend, ? extends SupplierConfig>> factoryList,
|
||||
SmsConfig smsConfig,
|
||||
Map<String, Map<String, Object>> blends,
|
||||
AppContext context
|
||||
){
|
||||
List<SmsReadConfig> extendsSmsConfigs){
|
||||
this.factoryList = factoryList;
|
||||
this.smsConfig = smsConfig;
|
||||
this.blends = blends;
|
||||
this.context = context;
|
||||
onApplicationEvent();
|
||||
this.extendsSmsConfigs = extendsSmsConfigs;
|
||||
|
||||
this.initDo();
|
||||
}
|
||||
|
||||
public void onApplicationEvent() {
|
||||
private void initDo() {
|
||||
this.registerDefaultFactory();
|
||||
// 注册短信对象工厂
|
||||
ProviderFactoryHolder.registerFactory(factoryList);
|
||||
//持有初始化配置信息
|
||||
EnvirmentHolder.frozenEnvirmet(smsConfig, blends);
|
||||
//框架依赖持有缓存扩展
|
||||
new SolonSmsDaoHolder(context);
|
||||
//注册执行器实现
|
||||
SmsProxyFactory.addPreProcessor(new RestrictedProcessor());
|
||||
SmsProxyFactory.addPreProcessor(new BlackListProcessor());
|
||||
SmsProxyFactory.addPreProcessor(new BlackListRecordingProcessor());
|
||||
//如果手机号校验器存在实现,则注册手机号校验器
|
||||
//如果手机号校验器存在实现,则注册手机号校验器(暂不可用)
|
||||
ServiceLoader<PhoneVerify> loader = ServiceLoader.load(PhoneVerify.class);
|
||||
if (loader.iterator().hasNext()) {
|
||||
loader.forEach(f -> {
|
||||
SmsProxyFactory.addPreProcessor(new CoreMethodParamValidateProcessor(f));
|
||||
});
|
||||
loader.forEach(f -> SmsProxyFactory.addPreProcessor(new CoreMethodParamValidateProcessor(f)));
|
||||
} else {
|
||||
SmsProxyFactory.addPreProcessor(new CoreMethodParamValidateProcessor(null));
|
||||
}
|
||||
//注册执行器实现
|
||||
if(this.smsConfig.getRestricted()){
|
||||
SmsProxyFactory.addPreProcessor(new RestrictedProcessor());
|
||||
SmsProxyFactory.addPreProcessor(new BlackListProcessor());
|
||||
SmsProxyFactory.addPreProcessor(new BlackListRecordingProcessor());
|
||||
}
|
||||
if (ConfigType.YAML.equals(this.smsConfig.getConfigType())) {
|
||||
//持有初始化配置信息
|
||||
Map<String, Map<String, Object>> blendsInclude = new ConfigCombineMapAdaptor<String, Map<String, Object>>();
|
||||
blendsInclude.putAll(this.blends);
|
||||
int num = 0;
|
||||
for (SmsReadConfig smsReadConfig : extendsSmsConfigs) {
|
||||
String key = SmsReadConfig.class.getSimpleName() + num;
|
||||
Map<String, Object> insideMap = new HashMap<>();
|
||||
insideMap.put(key, smsReadConfig);
|
||||
blendsInclude.put(key, insideMap);
|
||||
num++;
|
||||
}
|
||||
EnvirmentHolder.frozenEnvirmet(smsConfig, blendsInclude);
|
||||
// 解析供应商配置
|
||||
for(String configId : blends.keySet()) {
|
||||
for (String configId : blends.keySet()) {
|
||||
Map<String, Object> configMap = blends.get(configId);
|
||||
Object supplierObj = configMap.get(Constant.SUPPLIER_KEY);
|
||||
String supplier = supplierObj == null ? "" : String.valueOf(supplierObj);
|
||||
supplier = StrUtil.isEmpty(supplier) ? configId : supplier;
|
||||
BaseProviderFactory<SmsBlend, SupplierConfig> providerFactory = (BaseProviderFactory<SmsBlend, SupplierConfig>) ProviderFactoryHolder.requireForSupplier(supplier);
|
||||
if(providerFactory == null) {
|
||||
BaseProviderFactory<SmsBlend, SupplierConfig> providerFactory = (BaseProviderFactory<SmsBlend, org.dromara.sms4j.api.universal.SupplierConfig>) ProviderFactoryHolder.requireForSupplier(supplier);
|
||||
if (providerFactory == null) {
|
||||
log.warn("创建\"{}\"的短信服务失败,未找到供应商为\"{}\"的服务", configId, supplier);
|
||||
continue;
|
||||
}
|
||||
configMap.put("config-id", configId);
|
||||
SmsUtils.replaceKeysSeparator(configMap, "-", "_");
|
||||
JSONObject configJson = new JSONObject(configMap);
|
||||
SupplierConfig supplierConfig = JSONUtil.toBean(configJson, providerFactory.getConfigClass());
|
||||
org.dromara.sms4j.api.universal.SupplierConfig supplierConfig = JSONUtil.toBean(configJson, providerFactory.getConfigClass());
|
||||
SmsFactory.createSmsBlend(supplierConfig);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -135,9 +149,13 @@ public class SmsBlendsInitializer {
|
||||
ProviderFactoryHolder.registerFactory(LuoSiMaoFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(SubMailFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(DanMiFactory.instance());
|
||||
if(SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) {
|
||||
ProviderFactoryHolder.registerFactory(YiXintongFactory.instance());
|
||||
if (SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) {
|
||||
if (SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) {
|
||||
ProviderFactoryHolder.registerFactory(JdCloudFactory.instance());
|
||||
}
|
||||
log.debug("加载内置运营商完成!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
package org.dromara.sms4j.solon.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.comm.constant.Constant;
|
||||
import org.dromara.sms4j.provider.config.SmsBanner;
|
||||
import org.dromara.sms4j.provider.config.SmsConfig;
|
||||
import org.dromara.sms4j.provider.factory.BeanFactory;
|
||||
import org.noear.solon.annotation.Bean;
|
||||
import org.noear.solon.annotation.Configuration;
|
||||
import org.noear.solon.annotation.Init;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
import org.noear.solon.core.AppContext;
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class SmsMainConfigure {
|
||||
@Inject
|
||||
AppContext context;
|
||||
|
||||
@Bean
|
||||
public SmsConfig smsConfig() {
|
||||
return context.cfg().getProp("sms")
|
||||
.bindTo(BeanFactory.getSmsConfig());
|
||||
}
|
||||
|
||||
//是在 solon 容器扫描完成之后执行的
|
||||
@Init
|
||||
public void init() {
|
||||
//打印banner
|
||||
if (BeanFactory.getSmsConfig().getIsPrint()) {
|
||||
SmsBanner.PrintBanner(Constant.VERSION);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
package org.dromara.sms4j.solon.config;
|
||||
|
||||
import org.dromara.sms4j.api.SmsBlend;
|
||||
import org.dromara.sms4j.provider.config.SmsConfig;
|
||||
import org.dromara.sms4j.provider.factory.BaseProviderFactory;
|
||||
import org.noear.solon.annotation.Bean;
|
||||
import org.noear.solon.annotation.Condition;
|
||||
import org.noear.solon.annotation.Configuration;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
import org.noear.solon.core.AppContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* smsConfig参数意义为确保注入时smsConfig已经存在
|
||||
*/
|
||||
@Condition(onProperty = "${sms.configType}=yaml")
|
||||
@Configuration
|
||||
public class SupplierConfig {
|
||||
@Inject
|
||||
AppContext context;
|
||||
|
||||
private <T> T injectObj(String prefix, T obj) {
|
||||
//@Inject 只支持在字段、参数、类型上注入
|
||||
context.cfg().getProp(prefix).bindTo(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Bean
|
||||
protected Map<String, Map<String, Object>> blends() {
|
||||
return injectObj("sms.blends", new LinkedHashMap<>());
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
protected SmsBlendsInitializer smsBlendsInitializer(List<BaseProviderFactory> factoryList,
|
||||
SmsConfig smsConfig,
|
||||
Map<String, Map<String, Object>> blends) {
|
||||
|
||||
//todo: solon 不支持泛型的 List[Bean] 注入
|
||||
List<BaseProviderFactory<? extends SmsBlend, ? extends org.dromara.sms4j.api.universal.SupplierConfig>> factoryList2 = new ArrayList<>(factoryList.size());
|
||||
for (BaseProviderFactory factory : factoryList) {
|
||||
factoryList2.add((BaseProviderFactory<? extends SmsBlend, ? extends org.dromara.sms4j.api.universal.SupplierConfig>) factory);
|
||||
}
|
||||
|
||||
|
||||
return new SmsBlendsInitializer(factoryList2, smsConfig, blends, context);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
package org.dromara.sms4j.solon.config;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import org.dromara.sms4j.api.SmsBlend;
|
||||
import org.dromara.sms4j.api.universal.SupplierConfig;
|
||||
import org.dromara.sms4j.comm.constant.Constant;
|
||||
import org.dromara.sms4j.comm.enums.ConfigType;
|
||||
import org.dromara.sms4j.core.datainterface.SmsReadConfig;
|
||||
import org.dromara.sms4j.provider.config.SmsConfig;
|
||||
import org.dromara.sms4j.provider.factory.BaseProviderFactory;
|
||||
import org.noear.solon.annotation.Bean;
|
||||
import org.noear.solon.annotation.Condition;
|
||||
import org.noear.solon.annotation.Configuration;
|
||||
import org.noear.solon.annotation.Inject;
|
||||
import org.noear.solon.core.AppContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* smsConfig 参数意义为确保注入时 smsConfig 已经存在
|
||||
*/
|
||||
@Configuration
|
||||
public class SupplierConfigure {
|
||||
@Inject
|
||||
AppContext context;
|
||||
|
||||
private <T> T injectObj(String prefix, T obj) {
|
||||
//@Inject 只支持在字段、参数、类型上注入
|
||||
context.cfg().getProp(prefix).bindTo(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Bean("blends")
|
||||
public Map<String, Map<String, Object>> blends() {
|
||||
//确保能产生(给下面用)//springboot 就算没产生,也会给个默认
|
||||
return context.cfg().getProp("sms.blends").bindTo(new LinkedHashMap<>());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Condition(onBean = SmsConfig.class)
|
||||
public List<BaseProviderFactory<? extends SmsBlend, ? extends SupplierConfig>> factoryList(
|
||||
@Inject("blends") Map<String, Map<String, Object>> blends,
|
||||
SmsConfig smsConfig) throws Exception {
|
||||
//注入自定义实现工厂
|
||||
List<BaseProviderFactory<? extends SmsBlend, ? extends SupplierConfig>> factoryList = new ArrayList<>();
|
||||
if (ConfigType.YAML.equals(smsConfig.getConfigType())) {
|
||||
for (String configId : blends.keySet()) {
|
||||
Map<String, Object> configMap = blends.get(configId);
|
||||
Object factoryPath = configMap.get(Constant.FACTORY_PATH);
|
||||
if (ObjectUtil.isNotEmpty(factoryPath)) {
|
||||
//反射创建实例
|
||||
Class<BaseProviderFactory<? extends SmsBlend, ? extends SupplierConfig>> newClass = (Class<BaseProviderFactory<? extends SmsBlend, ? extends SupplierConfig>>) Class.forName(factoryPath.toString());
|
||||
BaseProviderFactory<? extends SmsBlend, ? extends SupplierConfig> factory = newClass.newInstance();
|
||||
factoryList.add(factory);
|
||||
}
|
||||
}
|
||||
}
|
||||
return factoryList;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public SmsBlendsInitializer smsBlendsInitializer(List<BaseProviderFactory<? extends SmsBlend, ? extends SupplierConfig>> factoryList,
|
||||
SmsConfig smsConfig,
|
||||
@Inject("blends") Map<String, Map<String, Object>> blends,
|
||||
List<SmsReadConfig> extendsSmsConfigs) {
|
||||
return new SmsBlendsInitializer(factoryList, smsConfig, blends, extendsSmsConfigs);
|
||||
}
|
||||
}
|
||||
@ -1,22 +1,10 @@
|
||||
package org.dromara.sms4j.solon.holder;
|
||||
|
||||
import org.dromara.sms4j.api.dao.SmsDao;
|
||||
import org.dromara.sms4j.api.dao.SmsDaoDefaultImpl;
|
||||
import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||
import org.noear.solon.core.AppContext;
|
||||
|
||||
public class SolonSmsDaoHolder{
|
||||
|
||||
private static SmsDao smsDao;
|
||||
|
||||
public SolonSmsDaoHolder(AppContext context) {
|
||||
context.getBeanAsync(SmsDao.class, bean -> smsDao = bean);
|
||||
}
|
||||
import org.noear.solon.Solon;
|
||||
|
||||
public class SolonSmsDaoHolder {
|
||||
public static SmsDao getSmsDao() {
|
||||
if (SmsUtils.isEmpty(smsDao)){
|
||||
smsDao = SmsDaoDefaultImpl.getInstance();
|
||||
}
|
||||
return smsDao;
|
||||
return Solon.context().getBean(SmsDao.class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,2 @@
|
||||
#???????
|
||||
solon.plugin=org.dromara.sms4j.solon.XPluginImpl
|
||||
#?????????????????0
|
||||
solon.plugin=org.dromara.sms4j.solon.Sms4jPlugin
|
||||
solon.plugin.priority=1
|
||||
@ -93,7 +93,7 @@ public class ZhangJunSmsImpl extends AbstractSmsBlend<ZhangJunConfig> {
|
||||
} catch (SmsBlendException e) {
|
||||
smsResponse = errorResp(e.message);
|
||||
}
|
||||
if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) {
|
||||
if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) {
|
||||
retry = 0;
|
||||
return smsResponse;
|
||||
}
|
||||
|
||||
@ -18,6 +18,12 @@ sms:
|
||||
template-id: SMS_272470496
|
||||
# 模版名称
|
||||
templateName: code
|
||||
# 代理
|
||||
proxy:
|
||||
# 是否启用代理 默认关闭 需手动开启
|
||||
enable: true
|
||||
host: 127.0.0.1
|
||||
port: 8080
|
||||
# 腾讯短信例子
|
||||
tx:
|
||||
#厂商标识
|
||||
@ -155,21 +161,29 @@ sms:
|
||||
accessKeyId: ACCOUNT SID
|
||||
accessKeySecret: AUTH TOKEN
|
||||
action: 默认请求方法 distributor/sendSMS
|
||||
# 一信通
|
||||
yixintong:
|
||||
sp-code: xxxxxx #(必填)企业编号
|
||||
access-key-id: xxxxxx #(必填)用户名
|
||||
access-key-secret: 324gaxxxxxxxxxxxxxxxxx9sdf89 #(必填)接口密钥(正式帐户需要登陆平台,接口业务-接口申请右侧钥匙状图标查看或获取,接口密钥获取后十分钟生效)
|
||||
template-id: #(可选)模板编号(若配置此参数,则会默认使用该模板,以便提高服务方性能)
|
||||
sign-code: #(可选)短信前置签名编号(登陆平台-接口业务-我的签名查看)
|
||||
f: 1 #(可选)默认为1,提交时检测方式
|
||||
|
||||
sms-oa:
|
||||
config-type: yaml
|
||||
oas:
|
||||
oaDingTalkByYaml: # configId
|
||||
isEnable: true # 表示该配置是否生效(默认生效,false表示不生效)
|
||||
supplier: dingding # 厂商标识
|
||||
supplier: ding_ding # 厂商标识
|
||||
tokenId: 您的accessKey
|
||||
sign: 您的sign
|
||||
oaByteTalkByYaml: # configId
|
||||
supplier: feishu # 厂商标识
|
||||
supplier: byte_talk # 厂商标识
|
||||
tokenId: 您的accessKey
|
||||
sign: 您的sign
|
||||
oaWeTalkByYaml:
|
||||
supplier: wetalk # 厂商标识
|
||||
supplier: we_talk # 厂商标识
|
||||
tokenId: 您的sign
|
||||
core-pool-size: 20
|
||||
queue-capacity: 20
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package org.dromara.sms4j.example;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.lang.UUID;
|
||||
@ -20,7 +21,12 @@ import org.dromara.sms4j.luosimao.service.LuoSiMaoSmsImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@SpringBootTest
|
||||
@ -526,4 +532,31 @@ public class Sms4jTest {
|
||||
Assert.isTrue(smsResponse5.isSuccess());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 联通一信通模板
|
||||
*/
|
||||
@Test
|
||||
public void yixintongSmsTest() {
|
||||
if (StrUtil.isBlank(PHONE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//短信发送模板:你有一项编号为{xxxxxxxxx}的事务需要处理{x}
|
||||
//其中的{xxxxxx}代表短信模板中的变量部分,可变化,一个x代表一个字或者字符,{}为变量标识,在发送时不用传。实发变量字数小于等于x的个数。
|
||||
|
||||
// 单发
|
||||
String message1 = StrUtil.format("你有一项编号为{}的事务需要处理。", SmsUtils.getRandomInt(6));
|
||||
SmsResponse smsResponse1 = SmsFactory.getBySupplier(SupplierConstant.YIXINTONG).sendMessage(PHONE, message1);
|
||||
log.info(JSONUtil.toJsonStr(smsResponse1));
|
||||
Assert.isTrue(smsResponse1.isSuccess());
|
||||
|
||||
// 群发
|
||||
List<String> phones = CollectionUtil.toList(PHONE);
|
||||
String message2 = StrUtil.format("你有一项编号为{}的事务需要处理。", SmsUtils.getRandomInt(6));
|
||||
SmsResponse smsResponse2 = SmsFactory.getBySupplier(SupplierConstant.YIXINTONG).massTexting(phones, message2);
|
||||
log.info(JSONUtil.toJsonStr(smsResponse2));
|
||||
Assert.isTrue(smsResponse2.isSuccess());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package org.dromara.sms4j.starter.adepter;
|
||||
package org.dromara.sms4j.starter.adaptor;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import org.dromara.sms4j.core.datainterface.SmsReadConfig;
|
||||
@ -38,10 +38,11 @@ import org.dromara.sms4j.provider.config.SmsConfig;
|
||||
import org.dromara.sms4j.provider.factory.BaseProviderFactory;
|
||||
import org.dromara.sms4j.provider.factory.ProviderFactoryHolder;
|
||||
import org.dromara.sms4j.qiniu.config.QiNiuFactory;
|
||||
import org.dromara.sms4j.starter.adepter.ConfigCombineMapAdaptor;
|
||||
import org.dromara.sms4j.starter.adaptor.ConfigCombineMapAdaptor;
|
||||
import org.dromara.sms4j.submail.config.SubMailFactory;
|
||||
import org.dromara.sms4j.tencent.config.TencentFactory;
|
||||
import org.dromara.sms4j.unisms.config.UniFactory;
|
||||
import org.dromara.sms4j.yixintong.config.YiXintongFactory;
|
||||
import org.dromara.sms4j.yunpian.config.YunPianFactory;
|
||||
import org.dromara.sms4j.zhutong.config.ZhutongFactory;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
@ -78,9 +79,7 @@ public class SmsBlendsInitializer {
|
||||
//如果手机号校验器存在实现,则注册手机号校验器(暂不可用)
|
||||
ServiceLoader<PhoneVerify> loader = ServiceLoader.load(PhoneVerify.class);
|
||||
if (loader.iterator().hasNext()) {
|
||||
loader.forEach(f -> {
|
||||
SmsProxyFactory.addPreProcessor(new CoreMethodParamValidateProcessor(f));
|
||||
});
|
||||
loader.forEach(f -> SmsProxyFactory.addPreProcessor(new CoreMethodParamValidateProcessor(f)));
|
||||
} else {
|
||||
SmsProxyFactory.addPreProcessor(new CoreMethodParamValidateProcessor(null));
|
||||
}
|
||||
@ -150,6 +149,7 @@ public class SmsBlendsInitializer {
|
||||
ProviderFactoryHolder.registerFactory(LuoSiMaoFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(SubMailFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(DanMiFactory.instance());
|
||||
ProviderFactoryHolder.registerFactory(YiXintongFactory.instance());
|
||||
if (SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) {
|
||||
if (SmsUtils.isClassExists("com.jdcloud.sdk.auth.CredentialsProvider")) {
|
||||
ProviderFactoryHolder.registerFactory(JdCloudFactory.instance());
|
||||
|
||||
@ -9,6 +9,7 @@ import org.dromara.sms4j.core.datainterface.SmsReadConfig;
|
||||
import org.dromara.sms4j.provider.config.SmsConfig;
|
||||
import org.dromara.sms4j.provider.factory.BaseProviderFactory;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
@ -34,7 +35,7 @@ public class SupplierConfig {
|
||||
@Bean
|
||||
@ConditionalOnBean({SmsConfig.class})
|
||||
@SneakyThrows
|
||||
protected List<BaseProviderFactory<? extends SmsBlend, ? extends org.dromara.sms4j.api.universal.SupplierConfig>> factoryList(Map<String, Map<String, Object>> blends, SmsConfig smsConfig) {
|
||||
protected List<BaseProviderFactory<? extends SmsBlend, ? extends org.dromara.sms4j.api.universal.SupplierConfig>> factoryList(@Qualifier("blends") Map<String, Map<String, Object>> blends, SmsConfig smsConfig) {
|
||||
//注入自定义实现工厂
|
||||
List<BaseProviderFactory<? extends SmsBlend, ? extends org.dromara.sms4j.api.universal.SupplierConfig>> factoryList = new ArrayList<>();
|
||||
if (ConfigType.YAML.equals(smsConfig.getConfigType())) {
|
||||
@ -55,7 +56,7 @@ public class SupplierConfig {
|
||||
@Bean
|
||||
protected SmsBlendsInitializer smsBlendsInitializer(List<BaseProviderFactory<? extends SmsBlend, ? extends org.dromara.sms4j.api.universal.SupplierConfig>> factoryList,
|
||||
SmsConfig smsConfig,
|
||||
Map<String, Map<String, Object>> blends,
|
||||
@Qualifier("blends") Map<String, Map<String, Object>> blends,
|
||||
ObjectProvider<SmsReadConfig> extendsSmsConfigs) {
|
||||
return new SmsBlendsInitializer(factoryList, smsConfig, blends, extendsSmsConfigs);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user