diff --git a/pom.xml b/pom.xml index 57778c81..b38b4de8 100644 --- a/pom.xml +++ b/pom.xml @@ -53,12 +53,12 @@ - 3.3.3 + 3.3.4 UTF-8 UTF-8 2.7.18 - 2.6.5 + 3.0.1 3.17.0 1.3.3 5.8.28 diff --git a/sms4j-api/src/main/java/org/dromara/sms4j/api/universal/ProxyConfig.java b/sms4j-api/src/main/java/org/dromara/sms4j/api/universal/ProxyConfig.java new file mode 100644 index 00000000..4c54325a --- /dev/null +++ b/sms4j-api/src/main/java/org/dromara/sms4j/api/universal/ProxyConfig.java @@ -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; +} diff --git a/sms4j-api/src/main/java/org/dromara/sms4j/api/universal/SupplierConfig.java b/sms4j-api/src/main/java/org/dromara/sms4j/api/universal/SupplierConfig.java index 4537cab3..8d2d8ba5 100644 --- a/sms4j-api/src/main/java/org/dromara/sms4j/api/universal/SupplierConfig.java +++ b/sms4j-api/src/main/java/org/dromara/sms4j/api/universal/SupplierConfig.java @@ -22,4 +22,9 @@ public interface SupplierConfig { */ String getSupplier(); + /** + * 获取代理配置 + * + */ + ProxyConfig getProxy(); } diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/Constant.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/Constant.java index 9d33c8e8..2fd7290b 100644 --- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/Constant.java +++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/Constant.java @@ -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"参数赋值 diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/SupplierConstant.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/SupplierConstant.java index 59de4921..31057f38 100644 --- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/SupplierConstant.java +++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/constant/SupplierConstant.java @@ -93,4 +93,8 @@ public abstract class SupplierConstant { * danmi sms */ public static final String DAN_MI = "danmi"; + /** + * 联通一信通 sms + */ + public static final String YIXINTONG = "yixintong"; } diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsHttpUtils.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsHttpUtils.java index 7048e0e4..c931e9db 100644 --- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsHttpUtils.java +++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsHttpUtils.java @@ -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 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 headers, Map 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 headers, String username, String password, Map 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 headers, Map 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) { diff --git a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtils.java b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtils.java index 257b94e2..b6bf505a 100644 --- a/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtils.java +++ b/sms4j-comm/src/main/java/org/dromara/sms4j/comm/utils/SmsUtils.java @@ -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; diff --git a/sms4j-core/src/main/java/org/dromara/sms4j/core/proxy/processor/RestrictedProcessor.java b/sms4j-core/src/main/java/org/dromara/sms4j/core/proxy/processor/RestrictedProcessor.java index 21f187ca..e92a071d 100644 --- a/sms4j-core/src/main/java/org/dromara/sms4j/core/proxy/processor/RestrictedProcessor.java +++ b/sms4j-core/src/main/java/org/dromara/sms4j/core/proxy/processor/RestrictedProcessor.java @@ -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 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); } diff --git a/sms4j-email-jakarta/sms4j-email-jakarta-api/src/main/java/org/dromara/email/jakarta/api/package-info.java b/sms4j-email-jakarta/sms4j-email-jakarta-api/src/main/java/org/dromara/email/jakarta/api/package-info.java new file mode 100644 index 00000000..9332030e --- /dev/null +++ b/sms4j-email-jakarta/sms4j-email-jakarta-api/src/main/java/org/dromara/email/jakarta/api/package-info.java @@ -0,0 +1,6 @@ +/** + *

邮件插件api模块 + * @author :Wind + * 2024/10/23 10:58 + **/ +package org.dromara.email.jakarta.api; \ No newline at end of file diff --git a/sms4j-email-jakarta/sms4j-email-jakarta-comm/src/main/java/org/dromara/email/jakarta/comm/entity/MailMessage.java b/sms4j-email-jakarta/sms4j-email-jakarta-comm/src/main/java/org/dromara/email/jakarta/comm/entity/MailMessage.java index 829715ad..827264c3 100644 --- a/sms4j-email-jakarta/sms4j-email-jakarta-comm/src/main/java/org/dromara/email/jakarta/comm/entity/MailMessage.java +++ b/sms4j-email-jakarta/sms4j-email-jakarta-comm/src/main/java/org/dromara/email/jakarta/comm/entity/MailMessage.java @@ -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 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){ diff --git a/sms4j-email-jakarta/sms4j-email-jakarta-comm/src/main/java/org/dromara/email/jakarta/comm/package-info.java b/sms4j-email-jakarta/sms4j-email-jakarta-comm/src/main/java/org/dromara/email/jakarta/comm/package-info.java new file mode 100644 index 00000000..c6ad6bc4 --- /dev/null +++ b/sms4j-email-jakarta/sms4j-email-jakarta-comm/src/main/java/org/dromara/email/jakarta/comm/package-info.java @@ -0,0 +1,6 @@ +/** + *

邮件插件通用模块 + * @author :Wind + * 2024/10/23 10:58 + **/ +package org.dromara.email.jakarta.comm; \ No newline at end of file diff --git a/sms4j-email-jakarta/sms4j-email-jakarta-comm/src/main/java/org/dromara/email/jakarta/comm/utils/HtmlUtil.java b/sms4j-email-jakarta/sms4j-email-jakarta-comm/src/main/java/org/dromara/email/jakarta/comm/utils/HtmlUtil.java index 376aa5c6..2fd7bd1d 100644 --- a/sms4j-email-jakarta/sms4j-email-jakarta-comm/src/main/java/org/dromara/email/jakarta/comm/utils/HtmlUtil.java +++ b/sms4j-email-jakarta/sms4j-email-jakarta-comm/src/main/java/org/dromara/email/jakarta/comm/utils/HtmlUtil.java @@ -32,8 +32,8 @@ public final class HtmlUtil { * @param name 模板文件名 * @author :Wind */ - public static List readHtml(String name) throws MailException { - try (InputStream is = HtmlUtil.class.getResourceAsStream("/template/" + name)) { + public static List 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; } diff --git a/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/factory/MailFactory.java b/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/factory/MailFactory.java index 644298d4..5c284d1c 100644 --- a/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/factory/MailFactory.java +++ b/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/factory/MailFactory.java @@ -24,7 +24,7 @@ public class MailFactory{ *

从工厂获取一个邮件发送实例 * @param key 配置的标识key * @author :Wind - */ + */ public static MailClient createMailClient(Object key){ try { return MailBuild.build(CONFIGS.get(key)); @@ -40,7 +40,7 @@ public class MailFactory{ * @param key 配置的标识key * @param blacklist 黑名单接口,实例将从这里获取黑名单数据 * @author :Wind - */ + */ public static MailClient createMailClient(Object key, Blacklist blacklist){ try { return MailBuild.build(CONFIGS.get(key),blacklist); @@ -55,7 +55,7 @@ public class MailFactory{ * @param key 标识 * @param config 配置对象 * @author :Wind - */ + */ public static void put(Object key, MailSmtpConfig config){ CONFIGS.put(key,config); } diff --git a/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/factory/MonitorFactory.java b/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/factory/MonitorFactory.java index 39c0af66..ac67bb9a 100644 --- a/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/factory/MonitorFactory.java +++ b/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/factory/MonitorFactory.java @@ -28,7 +28,7 @@ public class MonitorFactory { * @param config 监听配置 * @param monitor 回调对象 * @author :Wind - */ + */ public static void put(String key, MailImapConfig config, Monitor monitor){ SERVICES.put(key,new MonitorService(config,monitor)); } @@ -38,9 +38,9 @@ public class MonitorFactory { *

开始监听指定标识的邮箱 * @param key 标识 * @author :Wind - */ + */ public static void start(String key){ - SERVICES.get(key).start(); + SERVICES.get(key).start(); } /** @@ -48,7 +48,7 @@ public class MonitorFactory { *

停止监听指定标识的邮箱 * @param key 标识 * @author :Wind - */ + */ public static void stop(String key){ SERVICES.get(key).stop(); } @@ -58,7 +58,7 @@ public class MonitorFactory { *

获取指定标识的配置信息 * @param key 标识 * @author :Wind - */ + */ public static MailImapConfig getConfig(String key) { return SERVICES.get(key).getMailImapConfig(); } diff --git a/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/service/MailBuild.java b/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/service/MailBuild.java index fcf339c0..272590a9 100644 --- a/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/service/MailBuild.java +++ b/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/service/MailBuild.java @@ -99,7 +99,7 @@ public class MailBuild { return MailService.instance(new MailBuild(config)); } public static MailClient build(MailSmtpConfig config,Blacklist blacklist)throws MessagingException { - return MailService.instance(new MailBuild(config,blacklist)); + return MailService.instance(new MailBuild(config,blacklist)); } /** @@ -120,7 +120,7 @@ public class MailBuild { list.add(s); } } - return InternetAddress.parse(CollUtil.join(list, ",")); + return InternetAddress.parse(CollUtil.join(list, ",")); } catch (AddressException e) { throw new MailException(e); } diff --git a/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/service/MailService.java b/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/service/MailService.java index d7fbd3b4..139419eb 100644 --- a/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/service/MailService.java +++ b/sms4j-email-jakarta/sms4j-email-jakarta-core/src/main/java/org/dromara/email/jakarta/core/service/MailService.java @@ -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)) { - //读取模板并进行变量替换 - List strings = HtmlUtil.replacePlaceholder(html, parameter); - //拼合HTML数据 - String htmlData = HtmlUtil.pieceHtml(strings); + if (CollUtil.isNotEmpty(html)) { + String htmlData; + List strings; + if (MapUtil.isNotEmpty(parameter)) { + //读取模板并进行变量替换 + strings = HtmlUtil.replacePlaceholder(html, parameter); + //拼合HTML数据 + htmlData = HtmlUtil.pieceHtml(strings); + }else { + htmlData = HtmlUtil.pieceHtml(html); + } MimeBodyPart htmlPart = new MimeBodyPart(); htmlPart.setContent(htmlData, "text/html;charset=UTF-8"); multipart.addBodyPart(htmlPart); diff --git a/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java b/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java index fce1f3bc..bc263536 100644 --- a/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java +++ b/sms4j-javase-plugin/src/main/java/org/dromara/sms4j/javase/config/SEInitializer.java @@ -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 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 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()); } diff --git a/sms4j-oa-plugin/sms4j-oa-core/src/main/java/org/dromara/oa/core/config/OaSupplierConfig.java b/sms4j-oa-plugin/sms4j-oa-core/src/main/java/org/dromara/oa/core/config/OaSupplierConfig.java index bc56064d..e4dbbb6f 100644 --- a/sms4j-oa-plugin/sms4j-oa-core/src/main/java/org/dromara/oa/core/config/OaSupplierConfig.java +++ b/sms4j-oa-plugin/sms4j-oa-core/src/main/java/org/dromara/oa/core/config/OaSupplierConfig.java @@ -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> factoryList, OaConfig oaConfig, - Map> oas) { + @Qualifier("oas") Map> oas) { return new OaBlendsInitializer(factoryList,oaConfig,oas); } } diff --git a/sms4j-oa-plugin/sms4j-oa-core/src/main/java/org/dromara/oa/core/provider/service/AbstractOaBlend.java b/sms4j-oa-plugin/sms4j-oa-core/src/main/java/org/dromara/oa/core/provider/service/AbstractOaBlend.java index cb7eb16a..fd197671 100644 --- a/sms4j-oa-plugin/sms4j-oa-core/src/main/java/org/dromara/oa/core/provider/service/AbstractOaBlend.java +++ b/sms4j-oa-plugin/sms4j-oa-core/src/main/java/org/dromara/oa/core/provider/service/AbstractOaBlend.java @@ -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 implements OaSender { @Getter @@ -57,12 +59,16 @@ public abstract class AbstractOaBlend 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; } } }); diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/service/AlibabaSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/service/AlibabaSmsImpl.java index d522c2fe..c8b3e0e9 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/service/AlibabaSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/aliyun/service/AlibabaSmsImpl.java @@ -116,7 +116,7 @@ public class AlibabaSmsImpl extends AbstractSmsBlend { } catch (SmsBlendException e) { smsResponse = errorResp(e.message); } - if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) { retry = 0; return smsResponse; } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/config/BaiduFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/config/BaiduFactory.java index b59dd6ce..cd7ef78a 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/config/BaiduFactory.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/config/BaiduFactory.java @@ -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; /** diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/service/BaiduSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/service/BaiduSmsImpl.java index 3b88c154..cd9ab456 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/service/BaiduSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/service/BaiduSmsImpl.java @@ -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; diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/utils/BaiduUtils.java b/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/utils/BaiduUtils.java index fe609a0b..27f6ab9f 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/utils/BaiduUtils.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/baidu/utils/BaiduUtils.java @@ -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 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; } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/budingyun/service/BudingV2SmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/budingyun/service/BudingV2SmsImpl.java index 2605be01..f1f77346 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/budingyun/service/BudingV2SmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/budingyun/service/BudingV2SmsImpl.java @@ -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 { } 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 { */ @Override public SmsResponse massTexting(List phones, String templateId, LinkedHashMap messages) { - throw new SmsBlendException("布丁云V2暂不支持多条短信发送"); + List list = new ArrayList<>(); + for (String phone : phones) { + SmsResponse smsResponse = sendMessage(phone, templateId, messages); + list.add(smsResponse); + } + return SmsRespUtils.resp(list, true, getConfigId()); } private Map getHeaders() { diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/service/ChuangLanSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/service/ChuangLanSmsImpl.java index 61a5c57e..03cba1d9 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/service/ChuangLanSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/chuanglan/service/ChuangLanSmsImpl.java @@ -107,7 +107,7 @@ public class ChuangLanSmsImpl extends AbstractSmsBlend { }catch (SmsBlendException e) { smsResponse = errorResp(e.message); } - if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) { retry = 0; return smsResponse; } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/danmi/service/DanMiSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/danmi/service/DanMiSmsImpl.java index 5287433c..1d5a62d7 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/danmi/service/DanMiSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/danmi/service/DanMiSmsImpl.java @@ -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; /** diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/service/HuaweiSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/service/HuaweiSmsImpl.java index b3415aa6..83b0f8dc 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/service/HuaweiSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/huawei/service/HuaweiSmsImpl.java @@ -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 { - 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 { } catch (SmsBlendException e) { smsResponse = errorResp(e.message); } - if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) { retry = 0; return smsResponse; } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/service/JdCloudSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/service/JdCloudSmsImpl.java index 886d9141..52ee7479 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/service/JdCloudSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/jdcloud/service/JdCloudSmsImpl.java @@ -99,7 +99,7 @@ public class JdCloudSmsImpl extends AbstractSmsBlend { } catch (SmsBlendException e) { smsResponse = errorResp(e.message); } - if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) { retry = 0; return smsResponse; } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jg/service/JgSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/service/JgSmsImpl.java index 77fa6110..69ad7928 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/jg/service/JgSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/service/JgSmsImpl.java @@ -119,7 +119,7 @@ public class JgSmsImpl extends AbstractSmsBlend { smsResponse = errorResp(e.message); } - if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) { retry = 0; return smsResponse; } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/jg/util/JgUtils.java b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/util/JgUtils.java index a7f6cf98..64028ff8 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/jg/util/JgUtils.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/jg/util/JgUtils.java @@ -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; /** diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/luosimao/service/LuoSiMaoSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/luosimao/service/LuoSiMaoSmsImpl.java index 6447e1d2..4c223a31 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/luosimao/service/LuoSiMaoSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/luosimao/service/LuoSiMaoSmsImpl.java @@ -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; /** diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/luosimao/utils/LuoSiMaoUtils.java b/sms4j-provider/src/main/java/org/dromara/sms4j/luosimao/utils/LuoSiMaoUtils.java index 3f3a6356..ece889be 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/luosimao/utils/LuoSiMaoUtils.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/luosimao/utils/LuoSiMaoUtils.java @@ -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 buildHeaders(){ + public static LinkedHashMap buildHeaders() { LinkedHashMap headers = new LinkedHashMap<>(1); headers.put(Constant.CONTENT_TYPE, Constant.APPLICATION_FROM_URLENCODED); return headers; } - public static LinkedHashMap buildBody(String phone, String message){ + public static LinkedHashMap buildBody(String phone, String message) { LinkedHashMap body = new LinkedHashMap<>(2); - body.put("mobile", StrUtil.addPrefixIfNot(phone, "+86")); + body.put("mobile", phone); body.put("message", message); return body; } - public static LinkedHashMap buildBody(List phones, String message, Date date){ + public static LinkedHashMap buildBody(List phones, String message, Date date) { LinkedHashMap 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; diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/mas/service/MasSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/mas/service/MasSmsImpl.java index b19dfa68..5e9fb61c 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/mas/service/MasSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/mas/service/MasSmsImpl.java @@ -97,7 +97,7 @@ public class MasSmsImpl extends AbstractSmsBlend { } catch (SmsBlendException e) { smsResponse = errorResp(e.message); } - if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) { retry = 0; return smsResponse; } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/mas/utils/MasUtils.java b/sms4j-provider/src/main/java/org/dromara/sms4j/mas/utils/MasUtils.java index 7c64e78d..f3e7be43 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/mas/utils/MasUtils.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/mas/utils/MasUtils.java @@ -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)); diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/netease/service/NeteaseSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/netease/service/NeteaseSmsImpl.java index f5ac172a..8972be81 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/netease/service/NeteaseSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/netease/service/NeteaseSmsImpl.java @@ -145,7 +145,7 @@ public class NeteaseSmsImpl extends AbstractSmsBlend { } catch (SmsBlendException e) { smsResponse = errorResp(e.message); } - if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) { retry = 0; return smsResponse; } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/provider/config/BaseConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/provider/config/BaseConfig.java index 99b1a002..24826d64 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/provider/config/BaseConfig.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/provider/config/BaseConfig.java @@ -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秒 */ diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/provider/service/AbstractSmsBlend.java b/sms4j-provider/src/main/java/org/dromara/sms4j/provider/service/AbstractSmsBlend.java index 915a9b82..daadbc8f 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/provider/service/AbstractSmsBlend.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/provider/service/AbstractSmsBlend.java @@ -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 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 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() { diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/service/QiNiuSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/service/QiNiuSmsImpl.java index 296fded0..d0dd632b 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/service/QiNiuSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/qiniu/service/QiNiuSmsImpl.java @@ -88,7 +88,7 @@ public class QiNiuSmsImpl extends AbstractSmsBlend { }catch (SmsBlendException e){ smsResponse = errorResp(e.message); } - if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) { retry = 0; return smsResponse; } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/submail/service/SubMailSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/submail/service/SubMailSmsImpl.java index 9ead7692..e577072d 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/submail/service/SubMailSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/submail/service/SubMailSmsImpl.java @@ -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 { private String timestamp(){ JSONObject resp = http.getUrl("https://api-v4.mysubmail.com/service/timestamp"); - return resp.getStr("resp"); + return resp.getStr("timestamp"); } } \ No newline at end of file diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/service/TencentSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/service/TencentSmsImpl.java index 1ed7a034..c92b789b 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/service/TencentSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/tencent/service/TencentSmsImpl.java @@ -87,7 +87,7 @@ public class TencentSmsImpl extends AbstractSmsBlend { } catch (SmsBlendException e) { smsResponse = errorResp(e.message); } - if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) { retry = 0; return smsResponse; } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/yixintong/config/YiXintongConfig.java b/sms4j-provider/src/main/java/org/dromara/sms4j/yixintong/config/YiXintongConfig.java new file mode 100644 index 00000000..36fabb2e --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/yixintong/config/YiXintongConfig.java @@ -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; + +/** + *

类名: YiXintongConfig + *

说明:联通一信通平台配置类 + *

所用到配置项: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; + } +} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/yixintong/config/YiXintongFactory.java b/sms4j-provider/src/main/java/org/dromara/sms4j/yixintong/config/YiXintongFactory.java new file mode 100644 index 00000000..4c9573ea --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/yixintong/config/YiXintongFactory.java @@ -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; + +/** + *

类名: YiXintongFactory + *

说明:联通一信通平台短信对象建造 + * + * @author moat + * @create 2024-07-30 17:10 + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class YiXintongFactory extends AbstractProviderFactory { + + private static final YiXintongFactory INSTANCE = new YiXintongFactory(); + + /** + * 获取建造者实例 + * @return 建造者实例 + */ + public static YiXintongFactory instance() { + return INSTANCE; + } + + /** + * createSms + *

建造一个短信实现对像 + */ + @Override + public YiXintongSmsImpl createSms(YiXintongConfig yiXintongConfig) { + return new YiXintongSmsImpl(yiXintongConfig); + } + + /** + * 获取供应商 + * @return 供应商 + */ + @Override + public String getSupplier() { + return SupplierConstant.YIXINTONG; + } +} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/yixintong/service/YiXintongSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/yixintong/service/YiXintongSmsImpl.java new file mode 100644 index 00000000..c6b2996b --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/yixintong/service/YiXintongSmsImpl.java @@ -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; + +/** + *

类名: YiXintongSmsImpl + *

说明:联通一信通 sms + * + * @author moat + * @create 2024-07-30 16:59 + */ +@Slf4j +public class YiXintongSmsImpl extends AbstractSmsBlend { + + 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 phones, String message) { + return getSmsResponse(SmsUtils.joinComma(phones), message, getConfig().getTemplateId()); + } + + @Override + public SmsResponse sendMessage(String phone, LinkedHashMap messages) { + throw new SmsBlendException("不支持此方法"); + } + + @Override + public SmsResponse sendMessage(String phone, String templateId, LinkedHashMap messages) { + throw new SmsBlendException("不支持此方法"); + } + + @Override + public SmsResponse massTexting(List phones, String templateId, LinkedHashMap 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 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()); + } + +} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/yixintong/utils/YiXintongUtils.java b/sms4j-provider/src/main/java/org/dromara/sms4j/yixintong/utils/YiXintongUtils.java new file mode 100644 index 00000000..83cb665c --- /dev/null +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/yixintong/utils/YiXintongUtils.java @@ -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; + +/** + *

类名: YiXintongUtils + *

说明:联通一信通工具类 + * + * @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 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 headers, Map 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()); + } + } + + +} diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/service/YunPianSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/service/YunPianSmsImpl.java index a5c4b930..07013176 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/service/YunPianSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/yunpian/service/YunPianSmsImpl.java @@ -58,7 +58,7 @@ public class YunPianSmsImpl extends AbstractSmsBlend { } 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 { 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; } diff --git a/sms4j-provider/src/main/java/org/dromara/sms4j/zhutong/service/ZhutongSmsImpl.java b/sms4j-provider/src/main/java/org/dromara/sms4j/zhutong/service/ZhutongSmsImpl.java index 2b15ee6a..311936c9 100644 --- a/sms4j-provider/src/main/java/org/dromara/sms4j/zhutong/service/ZhutongSmsImpl.java +++ b/sms4j-provider/src/main/java/org/dromara/sms4j/zhutong/service/ZhutongSmsImpl.java @@ -155,7 +155,7 @@ public class ZhutongSmsImpl extends AbstractSmsBlend { } 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 { } catch (SmsBlendException e) { smsResponse = errorResp(e.message); } - if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) { retry = 0; return smsResponse; } diff --git a/sms4j-solon-plugin-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java b/sms4j-solon-plugin-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java index fc99662e..31f1b5a2 100644 --- a/sms4j-solon-plugin-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java +++ b/sms4j-solon-plugin-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java @@ -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 { 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 { } 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()); } } \ No newline at end of file diff --git a/sms4j-solon-plugin-example/src/main/resources/app.yml b/sms4j-solon-plugin-example/src/main/resources/app.yml index 1780baae..63ef4e5a 100644 --- a/sms4j-solon-plugin-example/src/main/resources/app.yml +++ b/sms4j-solon-plugin-example/src/main/resources/app.yml @@ -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 diff --git a/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java b/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java index af1f2c43..12534da3 100644 --- a/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java +++ b/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java @@ -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 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()); + } } diff --git a/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/SmsOaTest.java b/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/SmsOaTest.java index f1c1d76d..4ec1653f 100644 --- a/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/SmsOaTest.java +++ b/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/SmsOaTest.java @@ -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************************// diff --git a/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/SmsProcessorTest.java b/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/SmsProcessorTest.java index c5f28537..9e318f35 100644 --- a/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/SmsProcessorTest.java +++ b/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/SmsProcessorTest.java @@ -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 { /** diff --git a/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/SmsUtilsTest.java b/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/SmsUtilsTest.java index 3c294863..c5dda3f2 100644 --- a/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/SmsUtilsTest.java +++ b/sms4j-solon-plugin-example/src/test/java/org/dromara/sms4j/example/SmsUtilsTest.java @@ -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 { diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/Sms4jPlugin.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/Sms4jPlugin.java new file mode 100644 index 00000000..240598d2 --- /dev/null +++ b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/Sms4jPlugin.java @@ -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); + } +} diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/XPluginImpl.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/XPluginImpl.java deleted file mode 100644 index fea6bb21..00000000 --- a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/XPluginImpl.java +++ /dev/null @@ -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); - } -} diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/adaptor/ConfigCombineMapAdaptor.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/adaptor/ConfigCombineMapAdaptor.java new file mode 100644 index 00000000..560be275 --- /dev/null +++ b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/adaptor/ConfigCombineMapAdaptor.java @@ -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 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 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 configMap = BeanUtil.beanToMap(baseConfig); + this.put(baseConfig.getConfigId(),configMap); + return (M)configMap; + } + } + } + } + return null; + } + return (M)o; + } +} diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsAutowiredConfig.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsAutowiredConfig.java deleted file mode 100644 index 55a5ddfc..00000000 --- a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsAutowiredConfig.java +++ /dev/null @@ -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 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); - } - } -} diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java index b31578e5..7c891076 100644 --- a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java +++ b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsBlendsInitializer.java @@ -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> blends; - private final AppContext context; + private final List extendsSmsConfigs; public SmsBlendsInitializer(List> factoryList, SmsConfig smsConfig, Map> blends, - AppContext context - ){ + List 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 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)); } - // 解析供应商配置 - for(String configId : blends.keySet()) { - Map 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 providerFactory = (BaseProviderFactory) 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()); - SmsFactory.createSmsBlend(supplierConfig); + //注册执行器实现 + if(this.smsConfig.getRestricted()){ + SmsProxyFactory.addPreProcessor(new RestrictedProcessor()); + SmsProxyFactory.addPreProcessor(new BlackListProcessor()); + SmsProxyFactory.addPreProcessor(new BlackListRecordingProcessor()); } + if (ConfigType.YAML.equals(this.smsConfig.getConfigType())) { + //持有初始化配置信息 + Map> blendsInclude = new ConfigCombineMapAdaptor>(); + blendsInclude.putAll(this.blends); + int num = 0; + for (SmsReadConfig smsReadConfig : extendsSmsConfigs) { + String key = SmsReadConfig.class.getSimpleName() + num; + Map insideMap = new HashMap<>(); + insideMap.put(key, smsReadConfig); + blendsInclude.put(key, insideMap); + num++; + } + EnvirmentHolder.frozenEnvirmet(smsConfig, blendsInclude); + // 解析供应商配置 + for (String configId : blends.keySet()) { + Map 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 providerFactory = (BaseProviderFactory) ProviderFactoryHolder.requireForSupplier(supplier); + if (providerFactory == null) { + log.warn("创建\"{}\"的短信服务失败,未找到供应商为\"{}\"的服务", configId, supplier); + continue; + } + configMap.put("config-id", configId); + SmsUtils.replaceKeysSeparator(configMap, "-", "_"); + JSONObject configJson = new JSONObject(configMap); + org.dromara.sms4j.api.universal.SupplierConfig supplierConfig = JSONUtil.toBean(configJson, providerFactory.getConfigClass()); + SmsFactory.createSmsBlend(supplierConfig); + } + } + } @@ -135,8 +149,12 @@ 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(JdCloudFactory.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()); + } + log.debug("加载内置运营商完成!"); } } diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsMainConfigure.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsMainConfigure.java new file mode 100644 index 00000000..08120099 --- /dev/null +++ b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SmsMainConfigure.java @@ -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); + } + } +} diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SupplierConfig.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SupplierConfig.java deleted file mode 100644 index 194ceedd..00000000 --- a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SupplierConfig.java +++ /dev/null @@ -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 injectObj(String prefix, T obj) { - //@Inject 只支持在字段、参数、类型上注入 - context.cfg().getProp(prefix).bindTo(obj); - return obj; - } - - @Bean - protected Map> blends() { - return injectObj("sms.blends", new LinkedHashMap<>()); - } - - - @Bean - protected SmsBlendsInitializer smsBlendsInitializer(List factoryList, - SmsConfig smsConfig, - Map> blends) { - - //todo: solon 不支持泛型的 List[Bean] 注入 - List> factoryList2 = new ArrayList<>(factoryList.size()); - for (BaseProviderFactory factory : factoryList) { - factoryList2.add((BaseProviderFactory) factory); - } - - - return new SmsBlendsInitializer(factoryList2, smsConfig, blends, context); - } -} diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SupplierConfigure.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SupplierConfigure.java new file mode 100644 index 00000000..d4568950 --- /dev/null +++ b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/config/SupplierConfigure.java @@ -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 injectObj(String prefix, T obj) { + //@Inject 只支持在字段、参数、类型上注入 + context.cfg().getProp(prefix).bindTo(obj); + return obj; + } + + @Bean("blends") + public Map> blends() { + //确保能产生(给下面用)//springboot 就算没产生,也会给个默认 + return context.cfg().getProp("sms.blends").bindTo(new LinkedHashMap<>()); + } + + @Bean + @Condition(onBean = SmsConfig.class) + public List> factoryList( + @Inject("blends") Map> blends, + SmsConfig smsConfig) throws Exception { + //注入自定义实现工厂 + List> factoryList = new ArrayList<>(); + if (ConfigType.YAML.equals(smsConfig.getConfigType())) { + for (String configId : blends.keySet()) { + Map configMap = blends.get(configId); + Object factoryPath = configMap.get(Constant.FACTORY_PATH); + if (ObjectUtil.isNotEmpty(factoryPath)) { + //反射创建实例 + Class> newClass = (Class>) Class.forName(factoryPath.toString()); + BaseProviderFactory factory = newClass.newInstance(); + factoryList.add(factory); + } + } + } + return factoryList; + } + + + @Bean + public SmsBlendsInitializer smsBlendsInitializer(List> factoryList, + SmsConfig smsConfig, + @Inject("blends") Map> blends, + List extendsSmsConfigs) { + return new SmsBlendsInitializer(factoryList, smsConfig, blends, extendsSmsConfigs); + } +} diff --git a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/holder/SolonSmsDaoHolder.java b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/holder/SolonSmsDaoHolder.java index cef3c875..e5a28eed 100644 --- a/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/holder/SolonSmsDaoHolder.java +++ b/sms4j-solon-plugin/src/main/java/org/dromara/sms4j/solon/holder/SolonSmsDaoHolder.java @@ -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); } } diff --git a/sms4j-solon-plugin/src/main/resources/META-INF/solon/sms4j-solon-plugin.properties b/sms4j-solon-plugin/src/main/resources/META-INF/solon/sms4j-solon-plugin.properties index 07519a28..1c2e6360 100644 --- a/sms4j-solon-plugin/src/main/resources/META-INF/solon/sms4j-solon-plugin.properties +++ b/sms4j-solon-plugin/src/main/resources/META-INF/solon/sms4j-solon-plugin.properties @@ -1,4 +1,2 @@ -#??????? -solon.plugin=org.dromara.sms4j.solon.XPluginImpl -#?????????????????0 +solon.plugin=org.dromara.sms4j.solon.Sms4jPlugin solon.plugin.priority=1 \ No newline at end of file diff --git a/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java b/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java index bcb6ef29..31f1b5a2 100644 --- a/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java +++ b/sms4j-spring-boot-example/src/main/java/org/dromara/sms4j/example/zhangjun/ZhangJunSmsImpl.java @@ -93,7 +93,7 @@ public class ZhangJunSmsImpl extends AbstractSmsBlend { } catch (SmsBlendException e) { smsResponse = errorResp(e.message); } - if (smsResponse.isSuccess() || retry == getConfig().getMaxRetries()) { + if (smsResponse.isSuccess() || retry >= getConfig().getMaxRetries()) { retry = 0; return smsResponse; } diff --git a/sms4j-spring-boot-example/src/main/resources/application.yml b/sms4j-spring-boot-example/src/main/resources/application.yml index 1780baae..84556af2 100644 --- a/sms4j-spring-boot-example/src/main/resources/application.yml +++ b/sms4j-spring-boot-example/src/main/resources/application.yml @@ -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 diff --git a/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java b/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java index a45a69c8..1ed3ab3a 100644 --- a/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java +++ b/sms4j-spring-boot-example/src/test/java/org/dromara/sms4j/example/Sms4jTest.java @@ -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 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()); + } + } diff --git a/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/adepter/ConfigCombineMapAdaptor.java b/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/adaptor/ConfigCombineMapAdaptor.java similarity index 97% rename from sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/adepter/ConfigCombineMapAdaptor.java rename to sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/adaptor/ConfigCombineMapAdaptor.java index 1320e42f..c6d2c335 100644 --- a/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/adepter/ConfigCombineMapAdaptor.java +++ b/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/adaptor/ConfigCombineMapAdaptor.java @@ -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; diff --git a/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java b/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java index 53fe8f30..34327577 100644 --- a/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java +++ b/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SmsBlendsInitializer.java @@ -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 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()); diff --git a/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SupplierConfig.java b/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SupplierConfig.java index a4760904..db71fbe4 100644 --- a/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SupplierConfig.java +++ b/sms4j-spring-boot-starter/src/main/java/org/dromara/sms4j/starter/config/SupplierConfig.java @@ -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> factoryList(Map> blends, SmsConfig smsConfig) { + protected List> factoryList(@Qualifier("blends") Map> blends, SmsConfig smsConfig) { //注入自定义实现工厂 List> factoryList = new ArrayList<>(); if (ConfigType.YAML.equals(smsConfig.getConfigType())) { @@ -55,7 +56,7 @@ public class SupplierConfig { @Bean protected SmsBlendsInitializer smsBlendsInitializer(List> factoryList, SmsConfig smsConfig, - Map> blends, + @Qualifier("blends") Map> blends, ObjectProvider extendsSmsConfigs) { return new SmsBlendsInitializer(factoryList, smsConfig, blends, extendsSmsConfigs); }