短信推送demo
This commit is contained in:
@@ -35,19 +35,19 @@ public class ClientConfiguration {
|
|||||||
|
|
||||||
for (ChannelProviderConfigDO config : activeProviders) {
|
for (ChannelProviderConfigDO config : activeProviders) {
|
||||||
switch (config.getProviderType()) {
|
switch (config.getProviderType()) {
|
||||||
case MsgPushConstant.ALI_YUN: {
|
case MsgPushConstant.PROVIDER_TYPE_ALI_YUN: {
|
||||||
MessageProviderFactory orDefault = messageProviderFactoryMap.getOrDefault(MsgPushConstant.ALI_YUN, new AliyunProviderFactory());
|
MessageProviderFactory orDefault = messageProviderFactoryMap.getOrDefault(MsgPushConstant.PROVIDER_TYPE_ALI_YUN, new AliyunProviderFactory());
|
||||||
messageProviderFactoryMap.put(MsgPushConstant.ALI_YUN, orDefault);
|
messageProviderFactoryMap.put(MsgPushConstant.PROVIDER_TYPE_ALI_YUN, orDefault);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MsgPushConstant.TELECOM: {
|
case MsgPushConstant.PROVIDER_TYPE_TELECOM: {
|
||||||
MessageProviderFactory orDefault = messageProviderFactoryMap.getOrDefault(MsgPushConstant.TELECOM, new AliyunProviderFactory());
|
MessageProviderFactory orDefault = messageProviderFactoryMap.getOrDefault(MsgPushConstant.PROVIDER_TYPE_TELECOM, new AliyunProviderFactory());
|
||||||
messageProviderFactoryMap.put(MsgPushConstant.TELECOM, orDefault);
|
messageProviderFactoryMap.put(MsgPushConstant.PROVIDER_TYPE_TELECOM, orDefault);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MsgPushConstant.UNI_PUSH: {
|
case MsgPushConstant.PROVIDER_TYPE_UNI_PUSH: {
|
||||||
MessageProviderFactory orDefault = messageProviderFactoryMap.getOrDefault(MsgPushConstant.UNI_PUSH, new AliyunProviderFactory());
|
MessageProviderFactory orDefault = messageProviderFactoryMap.getOrDefault(MsgPushConstant.PROVIDER_TYPE_UNI_PUSH, new AliyunProviderFactory());
|
||||||
messageProviderFactoryMap.put(MsgPushConstant.UNI_PUSH, orDefault);
|
messageProviderFactoryMap.put(MsgPushConstant.PROVIDER_TYPE_UNI_PUSH, orDefault);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public interface MessageProviderFactory {
|
|||||||
/**
|
/**
|
||||||
* 创建短信发送器
|
* 创建短信发送器
|
||||||
*/
|
*/
|
||||||
SmsSender createSmsSender(ChannelProviderConfigDO config) throws Exception;
|
SmsSender createSmsSender(ChannelProviderConfigDO config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建邮件发送器
|
* 创建邮件发送器
|
||||||
@@ -23,5 +23,5 @@ public interface MessageProviderFactory {
|
|||||||
/**
|
/**
|
||||||
* 创建APP推送发送器
|
* 创建APP推送发送器
|
||||||
*/
|
*/
|
||||||
AppPushSender createAppPushSender();
|
AppPushSender createAppPushSender(ChannelProviderConfigDO config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,16 @@ import com.njcn.msgpush.module.push.client.sender.impl.AliyunEmailSender;
|
|||||||
import com.njcn.msgpush.module.push.client.sender.impl.AliyunSmsSender;
|
import com.njcn.msgpush.module.push.client.sender.impl.AliyunSmsSender;
|
||||||
import com.njcn.msgpush.module.push.client.setting.impl.AliYunMailSetting;
|
import com.njcn.msgpush.module.push.client.setting.impl.AliYunMailSetting;
|
||||||
import com.njcn.msgpush.module.push.dal.dataobject.channel.ChannelProviderConfigDO;
|
import com.njcn.msgpush.module.push.dal.dataobject.channel.ChannelProviderConfigDO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author caozehui
|
* @author caozehui
|
||||||
* @data 2026-02-11
|
* @data 2026-02-11
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class AliyunProviderFactory implements MessageProviderFactory {
|
public class AliyunProviderFactory implements MessageProviderFactory {
|
||||||
@Override
|
@Override
|
||||||
public SmsSender createSmsSender(ChannelProviderConfigDO config) throws Exception {
|
public SmsSender createSmsSender(ChannelProviderConfigDO config) {
|
||||||
AliYunMailSetting aliYunSmsSetting = AliYunMailSetting.builder()
|
AliYunMailSetting aliYunSmsSetting = AliYunMailSetting.builder()
|
||||||
.accessKeyId(config.getAppKey())
|
.accessKeyId(config.getAppKey())
|
||||||
.accessKeySecret(config.getAppSecret())
|
.accessKeySecret(config.getAppSecret())
|
||||||
@@ -38,7 +40,8 @@ public class AliyunProviderFactory implements MessageProviderFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AppPushSender createAppPushSender() {
|
public AppPushSender createAppPushSender(ChannelProviderConfigDO config) {
|
||||||
|
log.error("阿里云暂不支持app推送");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ import com.njcn.msgpush.module.push.client.sender.impl.TelecomSmsSender;
|
|||||||
import com.njcn.msgpush.module.push.client.setting.impl.TelecomSmsSetting;
|
import com.njcn.msgpush.module.push.client.setting.impl.TelecomSmsSetting;
|
||||||
import com.njcn.msgpush.module.push.dal.dataobject.channel.ChannelProviderConfigDO;
|
import com.njcn.msgpush.module.push.dal.dataobject.channel.ChannelProviderConfigDO;
|
||||||
import com.njcn.msgpush.module.push.util.RestTemplateUtil;
|
import com.njcn.msgpush.module.push.util.RestTemplateUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author caozehui
|
* @author caozehui
|
||||||
* @data 2026-02-11
|
* @data 2026-02-11
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class TelecomProviderFactory implements MessageProviderFactory {
|
public class TelecomProviderFactory implements MessageProviderFactory {
|
||||||
private RestTemplateUtil restTemplateUtil;
|
private RestTemplateUtil restTemplateUtil;
|
||||||
|
|
||||||
@@ -21,7 +23,7 @@ public class TelecomProviderFactory implements MessageProviderFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SmsSender createSmsSender(ChannelProviderConfigDO config) throws Exception {
|
public SmsSender createSmsSender(ChannelProviderConfigDO config) {
|
||||||
TelecomSmsSetting telecomSmsSetting = TelecomSmsSetting.builder()
|
TelecomSmsSetting telecomSmsSetting = TelecomSmsSetting.builder()
|
||||||
.account(config.getAppKey())
|
.account(config.getAppKey())
|
||||||
.password(config.getAppSecret())
|
.password(config.getAppSecret())
|
||||||
@@ -35,7 +37,8 @@ public class TelecomProviderFactory implements MessageProviderFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AppPushSender createAppPushSender() {
|
public AppPushSender createAppPushSender(ChannelProviderConfigDO config) {
|
||||||
|
log.error("电信暂不支持app推送");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,24 +5,29 @@ import com.njcn.msgpush.module.push.client.sender.AppPushSender;
|
|||||||
import com.njcn.msgpush.module.push.client.sender.EmailSender;
|
import com.njcn.msgpush.module.push.client.sender.EmailSender;
|
||||||
import com.njcn.msgpush.module.push.client.sender.SmsSender;
|
import com.njcn.msgpush.module.push.client.sender.SmsSender;
|
||||||
import com.njcn.msgpush.module.push.dal.dataobject.channel.ChannelProviderConfigDO;
|
import com.njcn.msgpush.module.push.dal.dataobject.channel.ChannelProviderConfigDO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author caozehui
|
* @author caozehui
|
||||||
* @data 2026-02-11
|
* @data 2026-02-11
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
public class UniPushProviderFactory implements MessageProviderFactory {
|
public class UniPushProviderFactory implements MessageProviderFactory {
|
||||||
@Override
|
@Override
|
||||||
public SmsSender createSmsSender(ChannelProviderConfigDO config) throws Exception {
|
public SmsSender createSmsSender(ChannelProviderConfigDO config) {
|
||||||
|
log.error("uniPush暂不支持短信推送");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EmailSender createEmailSender(ChannelProviderConfigDO config) throws Exception {
|
public EmailSender createEmailSender(ChannelProviderConfigDO config) throws Exception {
|
||||||
|
log.error("uniPush暂不支持email推送");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AppPushSender createAppPushSender() {
|
public AppPushSender createAppPushSender(ChannelProviderConfigDO config) {
|
||||||
|
log.error("阿里云暂不支持app推送");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package com.njcn.msgpush.module.push.client.sender;
|
package com.njcn.msgpush.module.push.client.sender;
|
||||||
|
|
||||||
|
import com.njcn.msgpush.module.push.dal.dataobject.message.MessageRecordDO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author caozehui
|
* @author caozehui
|
||||||
* @data 2026-02-11
|
* @data 2026-02-11
|
||||||
*/
|
*/
|
||||||
public interface AppPushSender {
|
public interface AppPushSender {
|
||||||
|
|
||||||
boolean appPush();
|
boolean appPush(MessageRecordDO message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,5 +15,5 @@ public interface EmailSender {
|
|||||||
* @param toAddressList 接收地址集合
|
* @param toAddressList 接收地址集合
|
||||||
* @return 发送结果
|
* @return 发送结果
|
||||||
*/
|
*/
|
||||||
boolean sendEmail(Map<String, Object> params, List<String> toAddressList) throws Exception;
|
boolean sendEmail(Map<String, Object> params, List<String> toAddressList);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.njcn.msgpush.module.push.client.sender;
|
package com.njcn.msgpush.module.push.client.sender;
|
||||||
|
|
||||||
|
import com.njcn.msgpush.module.push.dal.dataobject.message.MessageRecordDO;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -11,18 +13,16 @@ public interface SmsSender {
|
|||||||
/**
|
/**
|
||||||
* 向单个手机号发送短信
|
* 向单个手机号发送短信
|
||||||
*
|
*
|
||||||
* @param phoneNumber 手机号
|
* @param message 消息
|
||||||
* @param params 参数
|
|
||||||
* @return 发送结果
|
* @return 发送结果
|
||||||
*/
|
*/
|
||||||
boolean sendSms(Map<String, Object> params, String phoneNumber) throws Exception;
|
boolean sendSms(MessageRecordDO message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 向多个手机号发送短信
|
* 向多个手机号发送短信
|
||||||
*
|
*
|
||||||
* @param phoneNumbers 手机号集合
|
* @param messageList 消息集合
|
||||||
* @param params 参数
|
|
||||||
* @return 发送结果
|
* @return 发送结果
|
||||||
*/
|
*/
|
||||||
boolean sendBatchSms(Map<String, Object> params, List<String> phoneNumbers);
|
boolean sendBatchSms(List<MessageRecordDO> messageList);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class AliyunEmailSender implements EmailSender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sendEmail(Map<String, Object> params, List<String> toAddressList) throws Exception {
|
public boolean sendEmail(Map<String, Object> params, List<String> toAddressList) {
|
||||||
RuntimeOptions runtimeOptions = new RuntimeOptions();
|
RuntimeOptions runtimeOptions = new RuntimeOptions();
|
||||||
runtimeOptions.autoretry = true;
|
runtimeOptions.autoretry = true;
|
||||||
SingleSendMailRequest request = new SingleSendMailRequest()
|
SingleSendMailRequest request = new SingleSendMailRequest()
|
||||||
@@ -75,7 +75,11 @@ public class AliyunEmailSender implements EmailSender {
|
|||||||
.setHtmlBody(params.get(HTML_BODY).toString())
|
.setHtmlBody(params.get(HTML_BODY).toString())
|
||||||
.setTextBody(params.get(TEXT_BODY).toString());
|
.setTextBody(params.get(TEXT_BODY).toString());
|
||||||
|
|
||||||
SingleSendMailResponse response = this.emailClient.singleSendMailWithOptions(request, runtimeOptions);
|
try {
|
||||||
|
SingleSendMailResponse response = this.emailClient.singleSendMailWithOptions(request, runtimeOptions);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
// if(OK.equals(response.)){
|
// if(OK.equals(response.)){
|
||||||
// return true;
|
// return true;
|
||||||
// }else {
|
// }else {
|
||||||
|
|||||||
@@ -2,18 +2,19 @@ package com.njcn.msgpush.module.push.client.sender.impl;
|
|||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.aliyun.dysmsapi20170525.Client;
|
import com.aliyun.dysmsapi20170525.Client;
|
||||||
import com.aliyun.dysmsapi20170525.models.SendBatchSmsRequest;
|
|
||||||
import com.aliyun.dysmsapi20170525.models.SendBatchSmsResponse;
|
|
||||||
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
|
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
|
||||||
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
|
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
|
||||||
import com.aliyun.teaopenapi.models.Config;
|
import com.aliyun.teaopenapi.models.Config;
|
||||||
import com.aliyun.teautil.models.RuntimeOptions;
|
import com.aliyun.teautil.models.RuntimeOptions;
|
||||||
import com.njcn.msgpush.module.push.client.sender.SmsSender;
|
import com.njcn.msgpush.module.push.client.sender.SmsSender;
|
||||||
import com.njcn.msgpush.module.push.client.setting.impl.AliYunMailSetting;
|
import com.njcn.msgpush.module.push.client.setting.impl.AliYunMailSetting;
|
||||||
|
import com.njcn.msgpush.module.push.constant.MessageStatusConstant;
|
||||||
|
import com.njcn.msgpush.module.push.dal.dataobject.message.MessageRecordDO;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -41,14 +42,14 @@ public class AliyunSmsSender implements SmsSender {
|
|||||||
new java.util.concurrent.ArrayBlockingQueue<>(1000),
|
new java.util.concurrent.ArrayBlockingQueue<>(1000),
|
||||||
r -> {
|
r -> {
|
||||||
Thread thread = new Thread(r);
|
Thread thread = new Thread(r);
|
||||||
thread.setName("AliYunSmsClient-Pool-" + thread.getId());
|
thread.setName("AliyunSmsSender-Pool-" + thread.getId());
|
||||||
thread.setDaemon(false);
|
thread.setDaemon(false);
|
||||||
return thread;
|
return thread;
|
||||||
},
|
},
|
||||||
new ThreadPoolExecutor.CallerRunsPolicy()
|
new ThreadPoolExecutor.CallerRunsPolicy()
|
||||||
);
|
);
|
||||||
|
|
||||||
public AliyunSmsSender(AliYunMailSetting aliYunSmsSetting) throws Exception {
|
public AliyunSmsSender(AliYunMailSetting aliYunSmsSetting) {
|
||||||
if (ObjectUtil.isNotNull(aliYunSmsSetting)) {
|
if (ObjectUtil.isNotNull(aliYunSmsSetting)) {
|
||||||
Config config = new Config()
|
Config config = new Config()
|
||||||
.setAccessKeyId(aliYunSmsSetting.getAccessKeyId())
|
.setAccessKeyId(aliYunSmsSetting.getAccessKeyId())
|
||||||
@@ -60,27 +61,31 @@ public class AliyunSmsSender implements SmsSender {
|
|||||||
this.smsClient = new Client(config);
|
this.smsClient = new Client(config);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("阿里云-短信服务初始化失败,请检查配置信息");
|
log.error("阿里云-短信服务初始化失败,请检查配置信息");
|
||||||
throw e;
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sendSms(Map<String, Object> params, String phoneNumber) throws Exception {
|
public boolean sendSms(MessageRecordDO message) {
|
||||||
Future<Boolean> future = THREAD_POOL_EXECUTOR.submit(() -> {
|
Future<Boolean> future = THREAD_POOL_EXECUTOR.submit(() -> {
|
||||||
// todo 修改消息的状态为 sending
|
message.setStatus(MessageStatusConstant.SENDING);
|
||||||
|
|
||||||
RuntimeOptions runtimeOptions = new RuntimeOptions();
|
RuntimeOptions runtimeOptions = new RuntimeOptions();
|
||||||
// 设置自动重试,默认是不开启的。重试次数默认是3次
|
// 设置自动重试,默认是不开启的。重试次数默认是3次
|
||||||
runtimeOptions.autoretry = true;
|
runtimeOptions.autoretry = true;
|
||||||
SendSmsRequest request = new SendSmsRequest()
|
SendSmsRequest request = new SendSmsRequest()
|
||||||
.setPhoneNumbers(phoneNumber)
|
.setPhoneNumbers(message.getReceiver())
|
||||||
.setSignName(params.get(SIGN_NAME).toString())
|
.setSignName(message.getTitle())
|
||||||
.setTemplateCode(params.get(TEMPLATE_CODE).toString())
|
.setTemplateCode(message.getTemplateCode())
|
||||||
.setTemplateParam(params.get(TEMPLATE_PARAM).toString());
|
.setTemplateParam(message.getTemplateParams());
|
||||||
try {
|
try {
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
long start = now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
||||||
|
message.setSendTime(now);
|
||||||
SendSmsResponse response = this.smsClient.sendSmsWithOptions(request, runtimeOptions);
|
SendSmsResponse response = this.smsClient.sendSmsWithOptions(request, runtimeOptions);
|
||||||
|
LocalDateTime end = LocalDateTime.now();
|
||||||
|
message.setCostTime((int) (end.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - start));
|
||||||
System.out.println(toJSONString(response));
|
System.out.println(toJSONString(response));
|
||||||
if (OK.equals(response.body.code)) {
|
if (OK.equals(response.body.code)) {
|
||||||
return true;
|
return true;
|
||||||
@@ -92,36 +97,27 @@ public class AliyunSmsSender implements SmsSender {
|
|||||||
throw new Exception(e);
|
throw new Exception(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Boolean b = future.get(3, TimeUnit.SECONDS);
|
Boolean b = null;
|
||||||
|
try {
|
||||||
|
b = future.get(3, TimeUnit.SECONDS);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
if (b) {
|
if (b) {
|
||||||
// todo 修改消息的状态为 success
|
message.setStatus(MessageStatusConstant.SUCCESS);
|
||||||
} else {
|
} else {
|
||||||
// todo 修改消息的状态为 failed
|
message.setStatus(MessageStatusConstant.FAILED);
|
||||||
}
|
}
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sendBatchSms(Map<String, Object> params, List<String> phoneNumbers) {
|
public boolean sendBatchSms(List<MessageRecordDO> messageIdList) {
|
||||||
RuntimeOptions runtimeOptions = new RuntimeOptions();
|
boolean res = true;
|
||||||
// 设置自动重试,默认是不开启的。重试次数默认是3次
|
for (MessageRecordDO message : messageIdList) {
|
||||||
runtimeOptions.autoretry = true;
|
res &= this.sendSms(message);
|
||||||
SendBatchSmsRequest request = new SendBatchSmsRequest()
|
|
||||||
.setPhoneNumberJson(toJSONString(phoneNumbers))
|
|
||||||
.setSignNameJson(toJSONString(params.get(SIGN_NAME)))
|
|
||||||
.setTemplateCode(params.get(TEMPLATE_CODE).toString())
|
|
||||||
.setTemplateParamJson(toJSONString(params.get(TEMPLATE_PARAM)));
|
|
||||||
try {
|
|
||||||
SendBatchSmsResponse response = this.smsClient.sendBatchSmsWithOptions(request, runtimeOptions);
|
|
||||||
System.out.println(toJSONString(response));
|
|
||||||
if (OK.equals(response.body.code)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("阿里云-短信服务发送失败");
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,22 @@
|
|||||||
package com.njcn.msgpush.module.push.client.sender.impl;
|
package com.njcn.msgpush.module.push.client.sender.impl;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.njcn.msgpush.module.push.client.sender.SmsSender;
|
import com.njcn.msgpush.module.push.client.sender.SmsSender;
|
||||||
import com.njcn.msgpush.module.push.client.setting.impl.TelecomSmsSetting;
|
import com.njcn.msgpush.module.push.client.setting.impl.TelecomSmsSetting;
|
||||||
|
import com.njcn.msgpush.module.push.constant.MessageStatusConstant;
|
||||||
|
import com.njcn.msgpush.module.push.dal.dataobject.message.MessageRecordDO;
|
||||||
import com.njcn.msgpush.module.push.util.RestTemplateUtil;
|
import com.njcn.msgpush.module.push.util.RestTemplateUtil;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author caozehui
|
* @author caozehui
|
||||||
@@ -29,12 +36,40 @@ public class TelecomSmsSender implements SmsSender {
|
|||||||
*/
|
*/
|
||||||
private static final String CONTENT_TYPE = "application/json;charset=utf-8";
|
private static final String CONTENT_TYPE = "application/json;charset=utf-8";
|
||||||
|
|
||||||
public static final String CONTENT = "content";
|
|
||||||
|
|
||||||
private TelecomSmsSetting telecomSmsSetting;
|
private TelecomSmsSetting telecomSmsSetting;
|
||||||
|
|
||||||
private RestTemplateUtil restTemplateUtil;
|
private RestTemplateUtil restTemplateUtil;
|
||||||
|
|
||||||
|
private final ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
|
||||||
|
5,
|
||||||
|
5,
|
||||||
|
1000,
|
||||||
|
TimeUnit.MILLISECONDS,
|
||||||
|
new java.util.concurrent.ArrayBlockingQueue<>(1000),
|
||||||
|
r -> {
|
||||||
|
Thread thread = new Thread(r);
|
||||||
|
thread.setName("TelecomSmsSender-Pool-" + thread.getId());
|
||||||
|
thread.setDaemon(false);
|
||||||
|
return thread;
|
||||||
|
},
|
||||||
|
new ThreadPoolExecutor.CallerRunsPolicy()
|
||||||
|
);
|
||||||
|
|
||||||
|
private class TelecomSmsResponse {
|
||||||
|
private String status;
|
||||||
|
private Double balance;
|
||||||
|
private List<TelecomSmsMessageRes> list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TelecomSmsMessageRes {
|
||||||
|
//消息ID(用于状态报告匹配)
|
||||||
|
private String mid;
|
||||||
|
//手机号码
|
||||||
|
private String mobile;
|
||||||
|
//短信提交错误代码
|
||||||
|
private Integer result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public TelecomSmsSender(TelecomSmsSetting telecomSmsSetting, RestTemplateUtil restTemplateUtil) {
|
public TelecomSmsSender(TelecomSmsSetting telecomSmsSetting, RestTemplateUtil restTemplateUtil) {
|
||||||
this.telecomSmsSetting = telecomSmsSetting;
|
this.telecomSmsSetting = telecomSmsSetting;
|
||||||
@@ -42,25 +77,79 @@ public class TelecomSmsSender implements SmsSender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sendSms(Map<String, Object> params, String phoneNumber) throws Exception {
|
public boolean sendSms(MessageRecordDO message) {
|
||||||
return this.sendBatchSms(params, List.of(phoneNumber));
|
Future<Boolean> future = THREAD_POOL_EXECUTOR.submit(() -> {
|
||||||
|
message.setStatus(MessageStatusConstant.SENDING);
|
||||||
|
// 构建请求参数
|
||||||
|
Map<String, Object> request = new HashMap<>();
|
||||||
|
request.put("action", "send");
|
||||||
|
request.put("account", telecomSmsSetting.getAccount());
|
||||||
|
request.put("password", telecomSmsSetting.getPassword());
|
||||||
|
request.put("mobile", message.getReceiver());
|
||||||
|
request.put("content", message.getContent());
|
||||||
|
request.put("extno", ACCESS_CODE);
|
||||||
|
|
||||||
|
// 设置请求头
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.set("Content-Type", CONTENT_TYPE);
|
||||||
|
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
long start = now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
||||||
|
message.setSendTime(now);
|
||||||
|
// 发送请求
|
||||||
|
ResponseEntity<String> response = restTemplateUtil.post(
|
||||||
|
API_URL,
|
||||||
|
request,
|
||||||
|
headers,
|
||||||
|
String.class
|
||||||
|
);
|
||||||
|
LocalDateTime end = LocalDateTime.now();
|
||||||
|
message.setCostTime((int) (end.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - start));
|
||||||
|
TelecomSmsResponse telecomSmsResponse = JSON.parseObject(response.getBody(), TelecomSmsResponse.class);
|
||||||
|
|
||||||
|
if (telecomSmsResponse.list.get(0).result == 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Boolean b = null;
|
||||||
|
try {
|
||||||
|
b = future.get(3, TimeUnit.SECONDS);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b) {
|
||||||
|
message.setStatus(MessageStatusConstant.SUCCESS);
|
||||||
|
} else {
|
||||||
|
message.setStatus(MessageStatusConstant.FAILED);
|
||||||
|
}
|
||||||
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sendBatchSms(Map<String, Object> params, List<String> phoneNumbers) {
|
public boolean sendBatchSms(List<MessageRecordDO> messageList) {
|
||||||
// 构建请求参数
|
|
||||||
Map<String, Object> request = new HashMap<>();
|
Map<String, Object> request = new HashMap<>();
|
||||||
request.put("action", "send");
|
request.put("action", "p2p");
|
||||||
request.put("account", telecomSmsSetting.getAccount());
|
request.put("account", telecomSmsSetting.getAccount());
|
||||||
request.put("password", telecomSmsSetting.getPassword());
|
request.put("password", telecomSmsSetting.getPassword());
|
||||||
request.put("mobile", StrUtil.join(StrUtil.COMMA, phoneNumbers));
|
Map<String, String> mobileContentKvp = new HashMap<>();
|
||||||
request.put("content", params.get(CONTENT).toString());
|
for (MessageRecordDO message : messageList) {
|
||||||
|
mobileContentKvp.put(message.getReceiver(), "【" + message.getTitle() + "】" + message.getContent());
|
||||||
|
message.setStatus(MessageStatusConstant.SENDING);
|
||||||
|
}
|
||||||
|
request.put("mobileContentKvp", JSON.toJSONString(mobileContentKvp));
|
||||||
request.put("extno", ACCESS_CODE);
|
request.put("extno", ACCESS_CODE);
|
||||||
|
|
||||||
// 设置请求头
|
// 设置请求头
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
headers.set("Content-Type", CONTENT_TYPE);
|
headers.set("Content-Type", CONTENT_TYPE);
|
||||||
|
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
long start = now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
||||||
|
|
||||||
// 发送请求
|
// 发送请求
|
||||||
ResponseEntity<String> response = restTemplateUtil.post(
|
ResponseEntity<String> response = restTemplateUtil.post(
|
||||||
API_URL,
|
API_URL,
|
||||||
@@ -68,12 +157,16 @@ public class TelecomSmsSender implements SmsSender {
|
|||||||
headers,
|
headers,
|
||||||
String.class
|
String.class
|
||||||
);
|
);
|
||||||
String body = response.getBody();
|
LocalDateTime end = LocalDateTime.now();
|
||||||
|
for (MessageRecordDO message : messageList) {
|
||||||
if (body.contains("\"status\": 0")) {
|
message.setSendTime(now);
|
||||||
return true;
|
message.setCostTime((int) (end.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - start));
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
TelecomSmsResponse telecomSmsResponse = JSON.parseObject(response.getBody(), TelecomSmsResponse.class);
|
||||||
|
boolean res = true;
|
||||||
|
for (TelecomSmsMessageRes telecomSmsMessageRes : telecomSmsResponse.list) {
|
||||||
|
res &= telecomSmsMessageRes.result == 0;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.njcn.msgpush.module.push.client.sender.impl;
|
||||||
|
|
||||||
|
import com.njcn.msgpush.module.push.client.sender.AppPushSender;
|
||||||
|
import com.njcn.msgpush.module.push.client.setting.impl.UniPushAppPushSetting;
|
||||||
|
import com.njcn.msgpush.module.push.dal.dataobject.message.MessageRecordDO;
|
||||||
|
import com.njcn.msgpush.module.push.util.RestTemplateUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author caozehui
|
||||||
|
* @data 2026-02-26
|
||||||
|
*/
|
||||||
|
public class UniPushEmailSender implements AppPushSender {
|
||||||
|
private UniPushAppPushSetting uniPushAppPushSetting;
|
||||||
|
|
||||||
|
private RestTemplateUtil restTemplateUtil;
|
||||||
|
|
||||||
|
public UniPushEmailSender(UniPushAppPushSetting uniPushAppPushSetting, RestTemplateUtil restTemplateUtil) {
|
||||||
|
this.uniPushAppPushSetting = uniPushAppPushSetting;
|
||||||
|
this.restTemplateUtil = restTemplateUtil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean appPush(MessageRecordDO message) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,8 @@ import lombok.*;
|
|||||||
@Builder
|
@Builder
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class UniPushAppPushSetting extends AppPushSetting {
|
public class UniPushAppPushSetting extends AppPushSetting {
|
||||||
private String accessKeyId;
|
private String appId;
|
||||||
private String accessKeySecret;
|
private String appKey;
|
||||||
|
private String appSecret;
|
||||||
|
private String masterSecret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.njcn.msgpush.module.push.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author caozehui
|
||||||
|
* @data 2026-02-26
|
||||||
|
*/
|
||||||
|
public class MessageStatusConstant {
|
||||||
|
//待发送
|
||||||
|
public static final String PENDING = "pending";
|
||||||
|
//发送中
|
||||||
|
public static final String SENDING = "sending";
|
||||||
|
//发送成功
|
||||||
|
public static final String SUCCESS = "success";
|
||||||
|
//发送失败(可重试)
|
||||||
|
public static final String FAILED = "failed";
|
||||||
|
//最终失败(超过最大重试次数,系统自动判定)
|
||||||
|
public static final String FINALFAILED = "final_failed";
|
||||||
|
//黑名单拦截
|
||||||
|
public static final String BLACKLISTED = "blacklisted";
|
||||||
|
//配额超限
|
||||||
|
public static final String QUOTAEXCEEDED = "quota_exceeded";
|
||||||
|
//频率限制
|
||||||
|
public static final String RATE_LIMITED = "rate_limited";
|
||||||
|
//手动终止重试(运维在重试队列管理中主动终止,区别于系统自动判定的final_failed)
|
||||||
|
public static final String ABANDONED = "abandoned";
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,7 +5,11 @@ package com.njcn.msgpush.module.push.constant;
|
|||||||
* @data 2026-02-11
|
* @data 2026-02-11
|
||||||
*/
|
*/
|
||||||
public class MsgPushConstant {
|
public class MsgPushConstant {
|
||||||
public static final String ALI_YUN = "aliyun";
|
public static final String PROVIDER_TYPE_ALI_YUN = "aliyun";
|
||||||
public static final String TELECOM = "telecom";
|
public static final String PROVIDER_TYPE_TELECOM = "telecom";
|
||||||
public static final String UNI_PUSH = "UniPush";
|
public static final String PROVIDER_TYPE_UNI_PUSH = "UniPush";
|
||||||
|
|
||||||
|
public static final String CHANNEL_SMS = "sms";
|
||||||
|
public static final String CHANNEL_EMAIL = "email";
|
||||||
|
public static final String CHANNEL_APP_PUSH = "app_push";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.njcn.msgpush.module.push.controller.admin.channel;
|
|||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.njcn.msgpush.framework.common.pojo.CommonResult;
|
import com.njcn.msgpush.framework.common.pojo.CommonResult;
|
||||||
|
import com.njcn.msgpush.module.push.client.factory.MessageProviderFactory;
|
||||||
import com.njcn.msgpush.module.push.controller.admin.channel.vo.ChannelProviderConfigReqVO;
|
import com.njcn.msgpush.module.push.controller.admin.channel.vo.ChannelProviderConfigReqVO;
|
||||||
import com.njcn.msgpush.module.push.dal.dataobject.channel.ChannelProviderConfigDO;
|
import com.njcn.msgpush.module.push.dal.dataobject.channel.ChannelProviderConfigDO;
|
||||||
import com.njcn.msgpush.module.push.service.channel.ChannelProviderConfigService;
|
import com.njcn.msgpush.module.push.service.channel.ChannelProviderConfigService;
|
||||||
@@ -10,11 +11,13 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Tag(name = "管理后台 - 渠道服务商")
|
@Tag(name = "管理后台 - 渠道服务商")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -26,6 +29,10 @@ public class ChannelProviderConfigController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ChannelProviderConfigService channelProviderConfigService;
|
private ChannelProviderConfigService channelProviderConfigService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("messageProviderFactoryMap")
|
||||||
|
private Map<String, MessageProviderFactory> messageProviderFactoryMap;
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("/list")
|
@PostMapping("/list")
|
||||||
@Operation(summary = "分页查询渠道服务商列表")
|
@Operation(summary = "分页查询渠道服务商列表")
|
||||||
@@ -35,7 +42,7 @@ public class ChannelProviderConfigController {
|
|||||||
return CommonResult.success(res);
|
return CommonResult.success(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("add")
|
@PostMapping("/add")
|
||||||
@Operation(summary = "新增渠道服务商")
|
@Operation(summary = "新增渠道服务商")
|
||||||
@PreAuthorize("@ss.hasPermission('push:channel:add')")
|
@PreAuthorize("@ss.hasPermission('push:channel:add')")
|
||||||
public CommonResult<Boolean> addChannelProvider(@Validated @RequestBody ChannelProviderConfigReqVO reqVO) {
|
public CommonResult<Boolean> addChannelProvider(@Validated @RequestBody ChannelProviderConfigReqVO reqVO) {
|
||||||
@@ -43,7 +50,7 @@ public class ChannelProviderConfigController {
|
|||||||
return CommonResult.success(res);
|
return CommonResult.success(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("update")
|
@PostMapping("/update")
|
||||||
@Operation(summary = "更新渠道服务商")
|
@Operation(summary = "更新渠道服务商")
|
||||||
@PreAuthorize("@ss.hasPermission('push:channel:update')")
|
@PreAuthorize("@ss.hasPermission('push:channel:update')")
|
||||||
public CommonResult<Boolean> updateChannelProvider(@Validated @RequestBody ChannelProviderConfigReqVO reqVO) {
|
public CommonResult<Boolean> updateChannelProvider(@Validated @RequestBody ChannelProviderConfigReqVO reqVO) {
|
||||||
@@ -51,7 +58,7 @@ public class ChannelProviderConfigController {
|
|||||||
return CommonResult.success(res);
|
return CommonResult.success(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("delete")
|
@PostMapping("/delete")
|
||||||
@Operation(summary = "删除渠道服务商")
|
@Operation(summary = "删除渠道服务商")
|
||||||
@PreAuthorize("@ss.hasPermission('push:channel:delete')")
|
@PreAuthorize("@ss.hasPermission('push:channel:delete')")
|
||||||
public CommonResult<Boolean> deleteChannelProvider(@RequestBody List<String> ids) {
|
public CommonResult<Boolean> deleteChannelProvider(@RequestBody List<String> ids) {
|
||||||
@@ -59,11 +66,39 @@ public class ChannelProviderConfigController {
|
|||||||
return CommonResult.success(res);
|
return CommonResult.success(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("toggle")
|
@GetMapping("/toggle")
|
||||||
@Operation(summary = "启用/禁用渠道服务商")
|
@Operation(summary = "启用/禁用渠道服务商")
|
||||||
@PreAuthorize("@ss.hasPermission('push:channel:toggle')")
|
@PreAuthorize("@ss.hasPermission('push:channel:toggle')")
|
||||||
public CommonResult<Boolean> toggleEnableChannelProvider(@RequestParam("id") String id) {
|
public CommonResult<Boolean> toggleEnableChannelProvider(@RequestParam("id") String id) {
|
||||||
boolean res = channelProviderConfigService.toggleEnableField(id);
|
boolean res = channelProviderConfigService.toggleEnableField(id);
|
||||||
return CommonResult.success(res);
|
return CommonResult.success(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加指定providerType服务商对应的bean
|
||||||
|
*
|
||||||
|
* @param providerType 服务商类型,例如:aliyun\telecom\UniPush
|
||||||
|
*/
|
||||||
|
public void registerProviderBean(String providerType) {
|
||||||
|
// DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
|
||||||
|
// BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(beanClass);
|
||||||
|
// for (Object arg : args) {
|
||||||
|
// builder.addConstructorArgValue(arg);
|
||||||
|
// }
|
||||||
|
// beanFactory.registerBeanDefinition(beanName, builder.getBeanDefinition());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除指定providerType服务商对应的bean
|
||||||
|
*
|
||||||
|
* @param providerType 服务商类型,例如:aliyun\telecom\UniPush
|
||||||
|
*/
|
||||||
|
public void removeProviderBean(String providerType) {
|
||||||
|
// DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
|
||||||
|
// if (beanFactory.containsBeanDefinition(beanName)) {
|
||||||
|
// beanFactory.removeBeanDefinition(beanName);
|
||||||
|
// }
|
||||||
|
messageProviderFactoryMap.remove(providerType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,4 +19,13 @@ public interface ChannelProviderConfigService extends IService<ChannelProviderCo
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
boolean toggleEnableField(String id);
|
boolean toggleEnableField(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据类型和渠道获取服务提供商
|
||||||
|
*
|
||||||
|
* @param providerType 服务提供商类型
|
||||||
|
* @param channel 渠道
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ChannelProviderConfigDO getByTypeAndChannel(String providerType, String channel);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,18 +7,12 @@ import com.njcn.msgpush.framework.common.util.object.PageUtils;
|
|||||||
import com.njcn.msgpush.module.push.controller.admin.channel.vo.ChannelProviderConfigReqVO;
|
import com.njcn.msgpush.module.push.controller.admin.channel.vo.ChannelProviderConfigReqVO;
|
||||||
import com.njcn.msgpush.module.push.dal.dataobject.channel.ChannelProviderConfigDO;
|
import com.njcn.msgpush.module.push.dal.dataobject.channel.ChannelProviderConfigDO;
|
||||||
import com.njcn.msgpush.module.push.dal.mysql.channel.ChannelProviderConfigMapper;
|
import com.njcn.msgpush.module.push.dal.mysql.channel.ChannelProviderConfigMapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
|
||||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class ChannelProviderConfigServiceImpl extends ServiceImpl<ChannelProviderConfigMapper, ChannelProviderConfigDO> implements ChannelProviderConfigService {
|
public class ChannelProviderConfigServiceImpl extends ServiceImpl<ChannelProviderConfigMapper, ChannelProviderConfigDO> implements ChannelProviderConfigService {
|
||||||
@Autowired
|
|
||||||
private ConfigurableApplicationContext applicationContext;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<ChannelProviderConfigDO> listChannelProviderCfg(ChannelProviderConfigReqVO pageReqVO) {
|
public Page<ChannelProviderConfigDO> listChannelProviderCfg(ChannelProviderConfigReqVO pageReqVO) {
|
||||||
@@ -44,19 +38,10 @@ public class ChannelProviderConfigServiceImpl extends ServiceImpl<ChannelProvide
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerBean(String beanName, Class<?> beanClass, Object... args) {
|
@Override
|
||||||
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
|
public ChannelProviderConfigDO getByTypeAndChannel(String providerType, String channel) {
|
||||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(beanClass);
|
return this.lambdaQuery().eq(ChannelProviderConfigDO::getProviderType, providerType)
|
||||||
for (Object arg : args) {
|
.eq(ChannelProviderConfigDO::getChannel, channel)
|
||||||
builder.addConstructorArgValue(arg);
|
.one();
|
||||||
}
|
|
||||||
beanFactory.registerBeanDefinition(beanName, builder.getBeanDefinition());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeBean(String beanName) {
|
|
||||||
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
|
|
||||||
if (beanFactory.containsBeanDefinition(beanName)) {
|
|
||||||
beanFactory.removeBeanDefinition(beanName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,4 +11,12 @@ public interface MessageRecordService {
|
|||||||
* @return 发送是否成功的结果
|
* @return 发送是否成功的结果
|
||||||
*/
|
*/
|
||||||
Boolean send(MessageRecordSendReqVO messageRecordSendReqVO);
|
Boolean send(MessageRecordSendReqVO messageRecordSendReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加消息记录
|
||||||
|
*
|
||||||
|
* @param messageRecordSendReqVO
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Boolean add(MessageRecordSendReqVO messageRecordSendReqVO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,55 @@
|
|||||||
package com.njcn.msgpush.module.push.service.message;
|
package com.njcn.msgpush.module.push.service.message;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.njcn.msgpush.module.push.client.factory.MessageProviderFactory;
|
||||||
|
import com.njcn.msgpush.module.push.constant.MessageStatusConstant;
|
||||||
|
import com.njcn.msgpush.module.push.constant.MsgPushConstant;
|
||||||
import com.njcn.msgpush.module.push.controller.admin.message.vo.MessageRecordSendReqVO;
|
import com.njcn.msgpush.module.push.controller.admin.message.vo.MessageRecordSendReqVO;
|
||||||
|
import com.njcn.msgpush.module.push.dal.dataobject.channel.ChannelProviderConfigDO;
|
||||||
|
import com.njcn.msgpush.module.push.dal.dataobject.message.MessageRecordDO;
|
||||||
|
import com.njcn.msgpush.module.push.dal.mysql.message.MessageRecordMapper;
|
||||||
|
import com.njcn.msgpush.module.push.service.channel.ChannelProviderConfigService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class MessageRecordServiceImpl implements MessageRecordService{
|
public class MessageRecordServiceImpl extends ServiceImpl<MessageRecordMapper, MessageRecordDO> implements MessageRecordService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("messageProviderFactoryMap")
|
||||||
|
private Map<String, MessageProviderFactory> messageProviderFactoryMap;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ChannelProviderConfigService channelProviderConfigService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean send(MessageRecordSendReqVO messageRecordSendReqVO) {
|
public Boolean send(MessageRecordSendReqVO messageRecordSendReqVO) {
|
||||||
|
MessageRecordDO messageRecordDO = BeanUtil.copyProperties(messageRecordSendReqVO, MessageRecordDO.class);
|
||||||
|
messageRecordDO.setStatus(MessageStatusConstant.PENDING);
|
||||||
|
this.save(messageRecordDO);
|
||||||
|
|
||||||
|
ChannelProviderConfigDO channelProviderConfigDO = channelProviderConfigService.getByTypeAndChannel(messageRecordDO.getProviderType(), messageRecordDO.getChannel());
|
||||||
|
//channelProviderConfigDO.setAppKey("LTAI4FxsR76x2dq3w9c5puUe");
|
||||||
|
//channelProviderConfigDO.setAppSecret("GxkTR8fsrvHtixTlD9UPmOGli35tZs");
|
||||||
|
MessageProviderFactory messageProviderFactory = messageProviderFactoryMap.get(messageRecordDO.getProviderType());
|
||||||
|
boolean sendResult = switch (messageRecordDO.getChannel()) {
|
||||||
|
case MsgPushConstant.CHANNEL_SMS -> messageProviderFactory.createSmsSender(channelProviderConfigDO).sendSms(messageRecordDO);
|
||||||
|
//case MsgPushConstant.CHANNEL_EMAIL ->
|
||||||
|
//messageProviderFactory.createEmailSender(channelProviderConfigDO).sendEmail(messageRecordDO.getTemplateParams(), messageRecordDO.getReceiver());
|
||||||
|
case MsgPushConstant.CHANNEL_APP_PUSH -> messageProviderFactory.createAppPushSender(channelProviderConfigDO).appPush(messageRecordDO);
|
||||||
|
default -> throw new RuntimeException("暂不支持该渠道:" + messageRecordDO.getChannel());
|
||||||
|
};
|
||||||
|
|
||||||
|
return sendResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean add(MessageRecordSendReqVO messageRecordSendReqVO) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import com.njcn.msgpush.module.push.client.sender.SmsSender;
|
|||||||
import com.njcn.msgpush.module.push.client.sender.impl.AliyunSmsSender;
|
import com.njcn.msgpush.module.push.client.sender.impl.AliyunSmsSender;
|
||||||
import com.njcn.msgpush.module.push.constant.MsgPushConstant;
|
import com.njcn.msgpush.module.push.constant.MsgPushConstant;
|
||||||
import com.njcn.msgpush.module.push.dal.dataobject.channel.ChannelProviderConfigDO;
|
import com.njcn.msgpush.module.push.dal.dataobject.channel.ChannelProviderConfigDO;
|
||||||
|
import com.njcn.msgpush.module.push.dal.dataobject.message.MessageRecordDO;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -27,17 +29,21 @@ public class MsgPushClientTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSendSms() throws Exception {
|
public void testSendSms() throws Exception {
|
||||||
Map<String, Object> params = new HashMap<>();
|
|
||||||
params.put(AliyunSmsSender.SIGN_NAME, "灿能云");
|
|
||||||
params.put(AliyunSmsSender.TEMPLATE_CODE, "SMS_481710295");
|
|
||||||
params.put(AliyunSmsSender.TEMPLATE_PARAM, "{\"code\":\"123456\"}");
|
|
||||||
|
|
||||||
ChannelProviderConfigDO channelProviderConfigDO = new ChannelProviderConfigDO();
|
ChannelProviderConfigDO channelProviderConfigDO = new ChannelProviderConfigDO();
|
||||||
channelProviderConfigDO.setAppKey("LTAI4FxsR76x2dq3w9c5puUe");
|
channelProviderConfigDO.setAppKey("LTAI4FxsR76x2dq3w9c5puUe");
|
||||||
channelProviderConfigDO.setAppSecret("GxkTR8fsrvHtixTlD9UPmOGli35tZs");
|
channelProviderConfigDO.setAppSecret("GxkTR8fsrvHtixTlD9UPmOGli35tZs");
|
||||||
SmsSender smsSender = messageProviderFactoryMap.get(MsgPushConstant.ALI_YUN).createSmsSender(channelProviderConfigDO);
|
SmsSender smsSender = messageProviderFactoryMap.get(MsgPushConstant.PROVIDER_TYPE_ALI_YUN).createSmsSender(channelProviderConfigDO);
|
||||||
|
|
||||||
boolean b = smsSender.sendSms(params, "18839431215");
|
MessageRecordDO message = new MessageRecordDO();
|
||||||
|
message.setMessageId("1c2w1e2a3c456");
|
||||||
|
message.setChannel(MsgPushConstant.CHANNEL_SMS);
|
||||||
|
message.setTitle("灿能云");
|
||||||
|
message.setReceiver("18839431215");
|
||||||
|
message.setTemplateCode("SMS_481710295");
|
||||||
|
message.setTemplateParams("{\"code\":\"123456\"}");
|
||||||
|
message.setProviderType(MsgPushConstant.PROVIDER_TYPE_ALI_YUN);
|
||||||
|
boolean b = smsSender.sendSms(message);
|
||||||
System.out.println(System.currentTimeMillis() + " " + b);
|
System.out.println(System.currentTimeMillis() + " " + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,12 +54,25 @@ public class MsgPushClientTest {
|
|||||||
params.put(AliyunSmsSender.TEMPLATE_CODE, "SMS_481710295");
|
params.put(AliyunSmsSender.TEMPLATE_CODE, "SMS_481710295");
|
||||||
params.put(AliyunSmsSender.TEMPLATE_PARAM, List.of("{\"code\":\"123456\"}"));
|
params.put(AliyunSmsSender.TEMPLATE_PARAM, List.of("{\"code\":\"123456\"}"));
|
||||||
|
|
||||||
|
List<MessageRecordDO> messageIdList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
MessageRecordDO message = new MessageRecordDO();
|
||||||
|
message.setMessageId(i + "c518e2a3c");
|
||||||
|
message.setChannel(MsgPushConstant.CHANNEL_SMS);
|
||||||
|
message.setTitle("灿能云");
|
||||||
|
message.setReceiver("18839431215");
|
||||||
|
message.setTemplateCode("SMS_481710295");
|
||||||
|
message.setTemplateParams("{\"code\":\"65432" + i + "\"}");
|
||||||
|
message.setProviderType(MsgPushConstant.PROVIDER_TYPE_ALI_YUN);
|
||||||
|
messageIdList.add(message);
|
||||||
|
}
|
||||||
|
|
||||||
ChannelProviderConfigDO channelProviderConfigDO = new ChannelProviderConfigDO();
|
ChannelProviderConfigDO channelProviderConfigDO = new ChannelProviderConfigDO();
|
||||||
channelProviderConfigDO.setAppKey("LTAI4FxsR76x2dq3w9c5puUe");
|
channelProviderConfigDO.setAppKey("LTAI4FxsR76x2dq3w9c5puUe");
|
||||||
channelProviderConfigDO.setAppSecret("GxkTR8fsrvHtixTlD9UPmOGli35tZs");
|
channelProviderConfigDO.setAppSecret("GxkTR8fsrvHtixTlD9UPmOGli35tZs");
|
||||||
SmsSender smsSender = messageProviderFactoryMap.get(MsgPushConstant.ALI_YUN).createSmsSender(channelProviderConfigDO);
|
SmsSender smsSender = messageProviderFactoryMap.get(MsgPushConstant.PROVIDER_TYPE_ALI_YUN).createSmsSender(channelProviderConfigDO);
|
||||||
|
|
||||||
boolean b = smsSender.sendBatchSms(params, List.of("18839431215"));
|
boolean b = smsSender.sendBatchSms(messageIdList);
|
||||||
System.out.println(System.currentTimeMillis() + " " + b);
|
System.out.println(System.currentTimeMillis() + " " + b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user